From 430ee838644276b49fd2c37f23c9816d7fb2a911 Mon Sep 17 00:00:00 2001 From: madwind Date: Thu, 6 Feb 2025 20:04:50 +0800 Subject: [PATCH] Fix SDL3 keyboard optimize stick --- src/Ryujinx.Input.SDL3/SDL3Gamepad.cs | 71 +++++++--------- src/Ryujinx.Input.SDL3/SDL3GamepadDriver.cs | 1 - src/Ryujinx.Input.SDL3/SDL3JoyCon.cs | 80 +++++++------------ src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs | 31 ++++++- src/Ryujinx.Input.SDL3/SDL3Keyboard.cs | 8 +- src/Ryujinx.SDL3-CS/libSDL3.cs | 12 ++- .../Views/Input/ControllerInputView.axaml.cs | 52 ++++++------ 7 files changed, 118 insertions(+), 137 deletions(-) diff --git a/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs b/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs index ead7a3041..382ab9d00 100644 --- a/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs +++ b/src/Ryujinx.Input.SDL3/SDL3Gamepad.cs @@ -281,6 +281,34 @@ namespace Ryujinx.Input.SDL3 (float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]); (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.Right, rightStickX, rightStickY); } @@ -295,28 +323,6 @@ namespace Ryujinx.Input.SDL3 return value * ConvertRate; } - private JoyconConfigControllerStick - 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) { if (inputId == StickInputId.Unbound) @@ -327,27 +333,6 @@ namespace Ryujinx.Input.SDL3 float resultX = ConvertRawStickValue(stickX); 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); } diff --git a/src/Ryujinx.Input.SDL3/SDL3GamepadDriver.cs b/src/Ryujinx.Input.SDL3/SDL3GamepadDriver.cs index 14526cc77..eca615e2b 100644 --- a/src/Ryujinx.Input.SDL3/SDL3GamepadDriver.cs +++ b/src/Ryujinx.Input.SDL3/SDL3GamepadDriver.cs @@ -1,5 +1,4 @@ using Ryujinx.Common.Logging; -using Ryujinx.Input.SDL3; using Ryujinx.SDL3.Common; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs b/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs index 4f33eb4f2..2b5abf195 100644 --- a/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs +++ b/src/Ryujinx.Input.SDL3/SDL3JoyCon.cs @@ -306,7 +306,33 @@ namespace Ryujinx.Input.SDL3 (float leftStickX, float leftStickY) = rawState.GetStick(_stickUserMapping[(int)StickInputId.Left]); (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.Right, rightStickX, rightStickY); } @@ -322,29 +348,6 @@ namespace Ryujinx.Input.SDL3 return value * ConvertRate; } - private JoyconConfigControllerStick - 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) { if (inputId == StickInputId.Unbound) @@ -356,32 +359,12 @@ namespace Ryujinx.Input.SDL3 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 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 { 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) { var button = _buttonsDriverMapping[(int)inputId]; diff --git a/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs b/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs index 18d85080f..1a6087141 100644 --- a/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs +++ b/src/Ryujinx.Input.SDL3/SDL3JoyConPair.cs @@ -1,3 +1,4 @@ +using JetBrains.Annotations; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using System.Collections.Generic; @@ -65,12 +66,38 @@ namespace Ryujinx.Input.SDL3 } (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.Right, rightStickX, rightStickY); } - return result; } diff --git a/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs b/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs index 75d59d809..f22b19b38 100644 --- a/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs +++ b/src/Ryujinx.Input.SDL3/SDL3Keyboard.cs @@ -2,7 +2,6 @@ using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Keyboard; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; using System.Threading; @@ -223,14 +222,9 @@ namespace Ryujinx.Input.SDL3 public KeyboardStateSnapshot GetKeyboardStateSnapshot() { - Span rawKeyboardState; + Span rawKeyboardState=SDL_GetKeyboardState(); SDL_Keymod rawKeyboardModifierState = SDL_GetModState(); - unsafe - { - rawKeyboardState = SDL_GetKeyboardState(out int numKeys); - } - bool[] keysState = new bool[(int)Key.Count]; for (Key key = 0; key < Key.Count; key++) diff --git a/src/Ryujinx.SDL3-CS/libSDL3.cs b/src/Ryujinx.SDL3-CS/libSDL3.cs index adcc014c2..fef8ba899 100644 --- a/src/Ryujinx.SDL3-CS/libSDL3.cs +++ b/src/Ryujinx.SDL3-CS/libSDL3.cs @@ -4005,10 +4005,14 @@ public static unsafe partial class SDL [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial IntPtr SDL_GetKeyboardFocus(); - [LibraryImport(nativeLibName)] - [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] - [return: MarshalUsing(CountElementName = "numkeys")] - public static partial Span SDL_GetKeyboardState(out int numkeys); + public static Span SDL_GetKeyboardState() + { + var result = SDL_GetKeyboardState(out var numkeys); + return new Span((void*) result, numkeys); + } + [LibraryImport(nativeLibName)] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial IntPtr SDL_GetKeyboardState(out int numkeys); [LibraryImport(nativeLibName)] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs index 4de6d0311..7f07abd69 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs @@ -18,6 +18,7 @@ using System.Numerics; using System.Text; using System.Threading.Tasks; using Button = Ryujinx.Input.Button; +using ControllerType = Ryujinx.Common.Configuration.Hid.ControllerType; using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId; namespace Ryujinx.Ava.UI.Views.Input @@ -26,7 +27,6 @@ namespace Ryujinx.Ava.UI.Views.Input { private ButtonKeyAssigner _currentAssigner; private volatile bool _isRunning = true; - private const float StickMaxPosition = 3; public ControllerInputView() { @@ -255,24 +255,24 @@ namespace Ryujinx.Ava.UI.Views.Input _isRunning = false; } - private string BuildSvgCss(IGamepad gamepad, GamepadInputConfig config, JoystickPosition leftPosition, - JoystickPosition rightPosition) + private string BuildSvgCss(GamepadStateSnapshot gamepadStateSnapshot, JoystickPosition leftPosition, + JoystickPosition rightPosition, bool isProController) { - gamepad.SetConfiguration(config.GetConfig()); StringBuilder sb = new(); for (int i = 0; i < (int)GamepadInputId.Count; i++) { GamepadButtonInputId button = (GamepadButtonInputId)i; - if (gamepad.GetMappedStateSnapshot().IsPressed(button)) + if (gamepadStateSnapshot.IsPressed(button)) { sb.Append($"#{button}{{fill:#00bbdb;}}"); } } + int stickMaxPosition = isProController ? 30 : 3; 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( - $"#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(); } @@ -285,31 +285,27 @@ namespace Ryujinx.Ava.UI.Views.Input var viewModel = DataContext as ControllerInputViewModel; if (viewModel != null) { + GamepadInputConfig config = viewModel.Config; + bool isProController = viewModel.ParentModel.Controller == 0; IGamepad gamepad = viewModel.ParentModel.SelectedGamepad; - var config = viewModel.Config; - JoystickPosition leftPosition = default, rightposition = default; - if (config.LeftJoystick != StickInputId.Unbound) - { - var stickInputId = (Ryujinx.Input.StickInputId)(int)config.LeftJoystick; - (float leftAxisX, float leftAxisY) = gamepad.GetStick(stickInputId); - leftPosition = NpadController.GetJoystickPosition(leftAxisX, leftAxisY, - config.DeadzoneLeft, config.RangeLeft); - viewModel.LeftStickPosition = $"{leftPosition.Dx}, {leftPosition.Dy}"; - } + gamepad.SetConfiguration(config.GetConfig()); + GamepadStateSnapshot gamepadStateSnapshot = gamepad.GetMappedStateSnapshot(); - if (config.RightJoystick != StickInputId.Unbound) - { - StickInputId stickInputId = config.RightJoystick; - (float rightAxisX, float rightAxisY) = - gamepad.GetStick((Ryujinx.Input.StickInputId)stickInputId); - rightposition = NpadController.GetJoystickPosition(rightAxisX, rightAxisY, - config.DeadzoneRight, config.RangeRight); - viewModel.RightStickPosition = $"{rightposition.Dx}, {rightposition.Dy}"; - } + (float leftAxisX, float leftAxisY) = + gamepadStateSnapshot.GetStick(Ryujinx.Input.StickInputId.Left); + JoystickPosition leftPosition = NpadController.GetJoystickPosition(leftAxisX, leftAxisY, + config.DeadzoneLeft, config.RangeLeft); + viewModel.LeftStickPosition = $"{leftPosition.Dx}, {leftPosition.Dy}"; - viewModel.UpdateImageCss(BuildSvgCss(gamepad, config, leftPosition, rightposition)); + (float rightAxisX, float rightAxisY) = + gamepadStateSnapshot.GetStick(Ryujinx.Input.StickInputId.Right); + JoystickPosition rightposition = NpadController.GetJoystickPosition(rightAxisX, rightAxisY, + config.DeadzoneRight, config.RangeRight); + viewModel.RightStickPosition = $"{rightposition.Dx}, {rightposition.Dy}"; + + viewModel.UpdateImageCss(BuildSvgCss(gamepadStateSnapshot, leftPosition, rightposition, + isProController)); - // 假设你已获得加速度计和陀螺仪数据 Vector3 accelerometerData = gamepad.GetMotionData(MotionInputId.Accelerometer); Vector3 gyroscopeData = gamepad.GetMotionData(MotionInputId.Gyroscope);