Fix SDL3 keyboard

optimize stick
This commit is contained in:
madwind 2025-02-06 20:04:50 +08:00 committed by madwind
parent de58f97ca2
commit 430ee83864
7 changed files with 118 additions and 137 deletions

View File

@ -281,6 +281,34 @@ namespace Ryujinx.Input.SDL3
(float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]); (float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]);
(float rightStickX, float rightStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Right]); (float rightStickX, float rightStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Right]);
if (_configuration.LeftJoyconStick.InvertStickX)
{
leftStickX = -leftStickX;
}
if (_configuration.LeftJoyconStick.InvertStickY)
{
leftStickY = -leftStickY;
}
if (_configuration.RightJoyconStick.InvertStickX)
{
rightStickX = -rightStickX;
}
if (_configuration.RightJoyconStick.InvertStickY)
{
rightStickY = -rightStickY;
}
if (_configuration.LeftJoyconStick.Rotate90CW)
{
(leftStickX, leftStickY) = (leftStickY, -leftStickX);
}
if (_configuration.RightJoyconStick.Rotate90CW)
{
(rightStickX, rightStickY) = (rightStickY, -rightStickX);
}
result.SetStick(StickInputId.Left, leftStickX, leftStickY); result.SetStick(StickInputId.Left, leftStickX, leftStickY);
result.SetStick(StickInputId.Right, rightStickX, rightStickY); result.SetStick(StickInputId.Right, rightStickX, rightStickY);
} }
@ -295,28 +323,6 @@ namespace Ryujinx.Input.SDL3
return value * ConvertRate; return value * ConvertRate;
} }
private JoyconConfigControllerStick<GamepadInputId, Common.Configuration.Hid.Controller.StickInputId>
GetLogicalJoyStickConfig(StickInputId inputId)
{
switch (inputId)
{
case StickInputId.Left:
if (_configuration.RightJoyconStick.Joystick ==
Common.Configuration.Hid.Controller.StickInputId.Left)
return _configuration.RightJoyconStick;
else
return _configuration.LeftJoyconStick;
case StickInputId.Right:
if (_configuration.LeftJoyconStick.Joystick ==
Common.Configuration.Hid.Controller.StickInputId.Right)
return _configuration.LeftJoyconStick;
else
return _configuration.RightJoyconStick;
}
return null;
}
public (float, float) GetStick(StickInputId inputId) public (float, float) GetStick(StickInputId inputId)
{ {
if (inputId == StickInputId.Unbound) if (inputId == StickInputId.Unbound)
@ -327,27 +333,6 @@ namespace Ryujinx.Input.SDL3
float resultX = ConvertRawStickValue(stickX); float resultX = ConvertRawStickValue(stickX);
float resultY = -ConvertRawStickValue(stickY); float resultY = -ConvertRawStickValue(stickY);
if (HasConfiguration)
{
var joyconStickConfig = GetLogicalJoyStickConfig(inputId);
if (joyconStickConfig != null)
{
if (joyconStickConfig.InvertStickX)
resultX = -resultX;
if (joyconStickConfig.InvertStickY)
resultY = -resultY;
if (joyconStickConfig.Rotate90CW)
{
float temp = resultX;
resultX = resultY;
resultY = -temp;
}
}
}
return (resultX, resultY); return (resultX, resultY);
} }

View File

@ -1,5 +1,4 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Input.SDL3;
using Ryujinx.SDL3.Common; using Ryujinx.SDL3.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View File

@ -306,7 +306,33 @@ namespace Ryujinx.Input.SDL3
(float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]); (float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]);
(float rightStickX, float rightStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Right]); (float rightStickX, float rightStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Right]);
if (_configuration.LeftJoyconStick.InvertStickX)
{
leftStickX = -leftStickX;
}
if (_configuration.LeftJoyconStick.InvertStickY)
{
leftStickY = -leftStickY;
}
if (_configuration.RightJoyconStick.InvertStickX)
{
rightStickX = -rightStickX;
}
if (_configuration.RightJoyconStick.InvertStickY)
{
rightStickY = -rightStickY;
}
if (_configuration.LeftJoyconStick.Rotate90CW)
{
(leftStickX, leftStickY) = (leftStickY, -leftStickX);
}
if (_configuration.RightJoyconStick.Rotate90CW)
{
(rightStickX, rightStickY) = (rightStickY, -rightStickX);
}
result.SetStick(StickInputId.Left, leftStickX, leftStickY); result.SetStick(StickInputId.Left, leftStickX, leftStickY);
result.SetStick(StickInputId.Right, rightStickX, rightStickY); result.SetStick(StickInputId.Right, rightStickX, rightStickY);
} }
@ -322,29 +348,6 @@ namespace Ryujinx.Input.SDL3
return value * ConvertRate; return value * ConvertRate;
} }
private JoyconConfigControllerStick<GamepadInputId, Common.Configuration.Hid.Controller.StickInputId>
GetLogicalJoyStickConfig(StickInputId inputId)
{
switch (inputId)
{
case StickInputId.Left:
if (_configuration.RightJoyconStick.Joystick ==
Common.Configuration.Hid.Controller.StickInputId.Left)
return _configuration.RightJoyconStick;
else
return _configuration.LeftJoyconStick;
case StickInputId.Right:
if (_configuration.LeftJoyconStick.Joystick ==
Common.Configuration.Hid.Controller.StickInputId.Right)
return _configuration.LeftJoyconStick;
else
return _configuration.RightJoyconStick;
}
return null;
}
public (float, float) GetStick(StickInputId inputId) public (float, float) GetStick(StickInputId inputId)
{ {
if (inputId == StickInputId.Unbound) if (inputId == StickInputId.Unbound)
@ -356,32 +359,12 @@ namespace Ryujinx.Input.SDL3
return (0.0f, 0.0f); return (0.0f, 0.0f);
} }
(short stickX, short stickY) = GetStickXY(); (short stickX, short stickY) = (SDL_GetGamepadAxis(_gamepadHandle, SDL_GamepadAxis.SDL_GAMEPAD_AXIS_LEFTX),
SDL_GetGamepadAxis(_gamepadHandle, SDL_GamepadAxis.SDL_GAMEPAD_AXIS_LEFTY));
float resultX = ConvertRawStickValue(stickX); float resultX = ConvertRawStickValue(stickX);
float resultY = -ConvertRawStickValue(stickY); float resultY = -ConvertRawStickValue(stickY);
if (HasConfiguration)
{
var joyconStickConfig = GetLogicalJoyStickConfig(inputId);
if (joyconStickConfig != null)
{
if (joyconStickConfig.InvertStickX)
resultX = -resultX;
if (joyconStickConfig.InvertStickY)
resultY = -resultY;
if (joyconStickConfig.Rotate90CW)
{
float temp = resultX;
resultX = resultY;
resultY = -temp;
}
}
}
return inputId switch return inputId switch
{ {
StickInputId.Left when _gamepadType == SDL_GamepadType.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => (resultY, -resultX), StickInputId.Left when _gamepadType == SDL_GamepadType.SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT => (resultY, -resultX),
@ -390,13 +373,6 @@ namespace Ryujinx.Input.SDL3
}; };
} }
private (short, short) GetStickXY()
{
return (
SDL_GetGamepadAxis(_gamepadHandle, SDL_GamepadAxis.SDL_GAMEPAD_AXIS_LEFTX),
SDL_GetGamepadAxis(_gamepadHandle, SDL_GamepadAxis.SDL_GAMEPAD_AXIS_LEFTY));
}
public bool IsPressed(GamepadButtonInputId inputId) public bool IsPressed(GamepadButtonInputId inputId)
{ {
var button = _buttonsDriverMapping[(int)inputId]; var button = _buttonsDriverMapping[(int)inputId];

View File

@ -1,3 +1,4 @@
using JetBrains.Annotations;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller;
using System.Collections.Generic; using System.Collections.Generic;
@ -67,10 +68,36 @@ namespace Ryujinx.Input.SDL3
(float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]); (float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]);
(float rightStickX, float rightStickY) =rawState.GetStick(_stickUserMapping[(int)StickInputId.Right]); (float rightStickX, float rightStickY) =rawState.GetStick(_stickUserMapping[(int)StickInputId.Right]);
if (_configuration.LeftJoyconStick.InvertStickX)
{
leftStickX = -leftStickX;
}
if (_configuration.LeftJoyconStick.InvertStickY)
{
leftStickY = -leftStickY;
}
if (_configuration.RightJoyconStick.InvertStickX)
{
rightStickX = -rightStickX;
}
if (_configuration.RightJoyconStick.InvertStickY)
{
rightStickY = -rightStickY;
}
if (_configuration.LeftJoyconStick.Rotate90CW)
{
(leftStickX, leftStickY) = (leftStickY, -leftStickX);
}
if (_configuration.RightJoyconStick.Rotate90CW)
{
(rightStickX, rightStickY) = (rightStickY, -rightStickX);
}
result.SetStick(StickInputId.Left, leftStickX, leftStickY); result.SetStick(StickInputId.Left, leftStickX, leftStickY);
result.SetStick(StickInputId.Right, rightStickX, rightStickY); result.SetStick(StickInputId.Right, rightStickX, rightStickY);
} }
return result; return result;
} }

View File

@ -2,7 +2,6 @@ using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Configuration.Hid.Keyboard;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
@ -223,14 +222,9 @@ namespace Ryujinx.Input.SDL3
public KeyboardStateSnapshot GetKeyboardStateSnapshot() public KeyboardStateSnapshot GetKeyboardStateSnapshot()
{ {
Span<SDLBool> rawKeyboardState; Span<SDLBool> rawKeyboardState=SDL_GetKeyboardState();
SDL_Keymod rawKeyboardModifierState = SDL_GetModState(); SDL_Keymod rawKeyboardModifierState = SDL_GetModState();
unsafe
{
rawKeyboardState = SDL_GetKeyboardState(out int numKeys);
}
bool[] keysState = new bool[(int)Key.Count]; bool[] keysState = new bool[(int)Key.Count];
for (Key key = 0; key < Key.Count; key++) for (Key key = 0; key < Key.Count; key++)

View File

@ -4005,10 +4005,14 @@ public static unsafe partial class SDL
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial IntPtr SDL_GetKeyboardFocus(); public static partial IntPtr SDL_GetKeyboardFocus();
public static Span<SDLBool> SDL_GetKeyboardState()
{
var result = SDL_GetKeyboardState(out var numkeys);
return new Span<SDLBool>((void*) result, numkeys);
}
[LibraryImport(nativeLibName)] [LibraryImport(nativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
[return: MarshalUsing(CountElementName = "numkeys")] public static partial IntPtr SDL_GetKeyboardState(out int numkeys);
public static partial Span<SDLBool> SDL_GetKeyboardState(out int numkeys);
[LibraryImport(nativeLibName)] [LibraryImport(nativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]

View File

@ -18,6 +18,7 @@ using System.Numerics;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Button = Ryujinx.Input.Button; using Button = Ryujinx.Input.Button;
using ControllerType = Ryujinx.Common.Configuration.Hid.ControllerType;
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId; using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
namespace Ryujinx.Ava.UI.Views.Input namespace Ryujinx.Ava.UI.Views.Input
@ -26,7 +27,6 @@ namespace Ryujinx.Ava.UI.Views.Input
{ {
private ButtonKeyAssigner _currentAssigner; private ButtonKeyAssigner _currentAssigner;
private volatile bool _isRunning = true; private volatile bool _isRunning = true;
private const float StickMaxPosition = 3;
public ControllerInputView() public ControllerInputView()
{ {
@ -255,24 +255,24 @@ namespace Ryujinx.Ava.UI.Views.Input
_isRunning = false; _isRunning = false;
} }
private string BuildSvgCss(IGamepad gamepad, GamepadInputConfig config, JoystickPosition leftPosition, private string BuildSvgCss(GamepadStateSnapshot gamepadStateSnapshot, JoystickPosition leftPosition,
JoystickPosition rightPosition) JoystickPosition rightPosition, bool isProController)
{ {
gamepad.SetConfiguration(config.GetConfig());
StringBuilder sb = new(); StringBuilder sb = new();
for (int i = 0; i < (int)GamepadInputId.Count; i++) for (int i = 0; i < (int)GamepadInputId.Count; i++)
{ {
GamepadButtonInputId button = (GamepadButtonInputId)i; GamepadButtonInputId button = (GamepadButtonInputId)i;
if (gamepad.GetMappedStateSnapshot().IsPressed(button)) if (gamepadStateSnapshot.IsPressed(button))
{ {
sb.Append($"#{button}{{fill:#00bbdb;}}"); sb.Append($"#{button}{{fill:#00bbdb;}}");
} }
} }
int stickMaxPosition = isProController ? 30 : 3;
sb.Append( sb.Append(
$"#LeftStick{{transform: translate ({(float)leftPosition.Dx / short.MaxValue * StickMaxPosition} {-(float)leftPosition.Dy / short.MaxValue * StickMaxPosition});}}"); $"#LeftStick{{transform: translate ({(float)leftPosition.Dx / short.MaxValue * stickMaxPosition} {-(float)leftPosition.Dy / short.MaxValue * stickMaxPosition});}}");
sb.Append( sb.Append(
$"#RightStick{{transform: translate ({(float)rightPosition.Dx / short.MaxValue * StickMaxPosition} {-(float)rightPosition.Dy / short.MaxValue * StickMaxPosition});}}"); $"#RightStick{{transform: translate ({(float)rightPosition.Dx / short.MaxValue * stickMaxPosition} {-(float)rightPosition.Dy / short.MaxValue * stickMaxPosition});}}");
return sb.ToString(); return sb.ToString();
} }
@ -285,31 +285,27 @@ namespace Ryujinx.Ava.UI.Views.Input
var viewModel = DataContext as ControllerInputViewModel; var viewModel = DataContext as ControllerInputViewModel;
if (viewModel != null) if (viewModel != null)
{ {
GamepadInputConfig config = viewModel.Config;
bool isProController = viewModel.ParentModel.Controller == 0;
IGamepad gamepad = viewModel.ParentModel.SelectedGamepad; IGamepad gamepad = viewModel.ParentModel.SelectedGamepad;
var config = viewModel.Config; gamepad.SetConfiguration(config.GetConfig());
JoystickPosition leftPosition = default, rightposition = default; GamepadStateSnapshot gamepadStateSnapshot = gamepad.GetMappedStateSnapshot();
if (config.LeftJoystick != StickInputId.Unbound)
{ (float leftAxisX, float leftAxisY) =
var stickInputId = (Ryujinx.Input.StickInputId)(int)config.LeftJoystick; gamepadStateSnapshot.GetStick(Ryujinx.Input.StickInputId.Left);
(float leftAxisX, float leftAxisY) = gamepad.GetStick(stickInputId); JoystickPosition leftPosition = NpadController.GetJoystickPosition(leftAxisX, leftAxisY,
leftPosition = NpadController.GetJoystickPosition(leftAxisX, leftAxisY,
config.DeadzoneLeft, config.RangeLeft); config.DeadzoneLeft, config.RangeLeft);
viewModel.LeftStickPosition = $"{leftPosition.Dx}, {leftPosition.Dy}"; viewModel.LeftStickPosition = $"{leftPosition.Dx}, {leftPosition.Dy}";
}
if (config.RightJoystick != StickInputId.Unbound)
{
StickInputId stickInputId = config.RightJoystick;
(float rightAxisX, float rightAxisY) = (float rightAxisX, float rightAxisY) =
gamepad.GetStick((Ryujinx.Input.StickInputId)stickInputId); gamepadStateSnapshot.GetStick(Ryujinx.Input.StickInputId.Right);
rightposition = NpadController.GetJoystickPosition(rightAxisX, rightAxisY, JoystickPosition rightposition = NpadController.GetJoystickPosition(rightAxisX, rightAxisY,
config.DeadzoneRight, config.RangeRight); config.DeadzoneRight, config.RangeRight);
viewModel.RightStickPosition = $"{rightposition.Dx}, {rightposition.Dy}"; viewModel.RightStickPosition = $"{rightposition.Dx}, {rightposition.Dy}";
}
viewModel.UpdateImageCss(BuildSvgCss(gamepad, config, leftPosition, rightposition)); viewModel.UpdateImageCss(BuildSvgCss(gamepadStateSnapshot, leftPosition, rightposition,
isProController));
// 假设你已获得加速度计和陀螺仪数据
Vector3 accelerometerData = gamepad.GetMotionData(MotionInputId.Accelerometer); Vector3 accelerometerData = gamepad.GetMotionData(MotionInputId.Accelerometer);
Vector3 gyroscopeData = gamepad.GetMotionData(MotionInputId.Gyroscope); Vector3 gyroscopeData = gamepad.GetMotionData(MotionInputId.Gyroscope);