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 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<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)
{
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);
}

View File

@ -1,5 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.Input.SDL3;
using Ryujinx.SDL3.Common;
using System;
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 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<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)
{
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];

View File

@ -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;
}

View File

@ -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<SDLBool> rawKeyboardState;
Span<SDLBool> 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++)

View File

@ -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<SDLBool> SDL_GetKeyboardState(out int numkeys);
public static Span<SDLBool> SDL_GetKeyboardState()
{
var result = SDL_GetKeyboardState(out var numkeys);
return new Span<SDLBool>((void*) result, numkeys);
}
[LibraryImport(nativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
public static partial IntPtr SDL_GetKeyboardState(out int numkeys);
[LibraryImport(nativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]

View File

@ -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);