diff --git a/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs b/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs index 02550ed279..04fc365de5 100644 --- a/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs +++ b/src/BizHawk.Bizware.Input/SDL2/SDL2Gamepad.cs @@ -135,7 +135,33 @@ namespace BizHawk.Bizware.Input buttonGetters.Add(("Paddle2", () => SDL_GameControllerGetButton(Opaque, SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE2) == 1)); buttonGetters.Add(("Paddle3", () => SDL_GameControllerGetButton(Opaque, SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE3) == 1)); buttonGetters.Add(("Paddle4", () => SDL_GameControllerGetButton(Opaque, SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE4) == 1)); - buttonGetters.Add(("Touchpad", () => SDL_GameControllerGetButton(Opaque, SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_TOUCHPAD) == 1)); + + var numTouchpads = SDL_GameControllerGetNumTouchpads(Opaque); + if (numTouchpads == 1) + { + // not sure which one should be used + //buttonGetters.Add(("Touchpad", () => SDL_GameControllerGetButton(Opaque, SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_TOUCHPAD) == 1)); + + // note: in practice there's always 1 touchpad if anything for any supported controller (ps4/ps5/shield) + // we only support 1 finger (TODO: how should multiple fingers be handled?) + buttonGetters.Add(("Touchpad", () => + { + _ = SDL_GameControllerGetTouchpadFinger(Opaque, 0, 0, out var state, out _, out _, out _); + return state != 0; + })); + } + else + { + for (var i = 0; i < numTouchpads; i++) + { + var j = i; + buttonGetters.Add(($"Touchpad{i}", () => + { + _ = SDL_GameControllerGetTouchpadFinger(Opaque, j, 0, out var state, out _, out _, out _); + return state != 0; + })); + } + } // note: SDL has flipped meaning for the Y axis compared to DirectInput/XInput (-/+ for u/d instead of +/- for u/d) @@ -153,6 +179,8 @@ namespace BizHawk.Bizware.Input buttonGetters.Add(("LeftTrigger", () => SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT) > dzt)); buttonGetters.Add(("RightTrigger", () => SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT) > dzt)); + + return buttonGetters; } @@ -254,22 +282,62 @@ namespace BizHawk.Bizware.Input static int Conv(short num) => (int)(num / f); // note: SDL has flipped meaning for the Y axis compared to DirectInput/XInput (-/+ for u/d instead of +/- for u/d) + List<(string AxisID, int Value)> values; if (IsGameController) { - return new[] - { + values = + [ ("LeftThumbX", Conv(SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTX))), ("LeftThumbY", -Conv(SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_LEFTY))), ("RightThumbX", Conv(SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTX))), ("RightThumbY", -Conv(SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_RIGHTY))), ("LeftTrigger", Conv(SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT))), - ("RightTrigger", Conv(SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT))), - }; + ("RightTrigger", Conv(SDL_GameControllerGetAxis(Opaque, SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT))) + ]; + + static int TouchConv(float num) => (int)((num * 2.0f - 1.0f) * 10000.0f); + var numTouchpads = SDL_GameControllerGetNumTouchpads(Opaque); + if (numTouchpads == 1) + { + // note: in practice there's always 1 touchpad if anything for any supported controller (ps4/ps5/shield) + // we only support 1 finger (TODO: how should multiple fingers be handled? average them out? note ps4/ps5 support 2 fingers) + // TODO: how should we handle pressure? for any supported controller in practice (ps4/ps5/shield) this is going to be 1.0f or 0.0f anyways + _ = SDL_GameControllerGetTouchpadFinger(Opaque, 0, 0, out var state, out var x, out var y, out _); + if (state != 0) + { + values.Add(("TouchpadX", TouchConv(x))); + values.Add(("TouchpadY", -TouchConv(y))); + } + else + { + values.Add(("TouchpadX", 0)); + values.Add(("TouchpadY", 0)); + } + } + else + { + for (var i = 0; i < numTouchpads; i++) + { + _ = SDL_GameControllerGetTouchpadFinger(Opaque, i, 0, out var state, out var x, out var y, out _); + if (state != 0) + { + values.Add(($"Touchpad{i}X", TouchConv(x))); + values.Add(($"Touchpad{i}Y", -TouchConv(y))); + } + else + { + values.Add(($"Touchpad{i}X", 0)); + values.Add(($"Touchpad{i}Y", 0)); + } + } + } + + return values; } - List<(string AxisID, int Value)> values = new() - { + values = + [ ("X", Conv(SDL_JoystickGetAxis(Opaque, 0))), ("Y", Conv(SDL_JoystickGetAxis(Opaque, 1))), ("Z", Conv(SDL_JoystickGetAxis(Opaque, 2))), @@ -279,13 +347,12 @@ namespace BizHawk.Bizware.Input ("Q", Conv(SDL_JoystickGetAxis(Opaque, 6))), ("P", Conv(SDL_JoystickGetAxis(Opaque, 7))), ("N", Conv(SDL_JoystickGetAxis(Opaque, 8))), - }; + ]; var naxes = SDL_JoystickNumAxes(Opaque); for (var i = 9; i < naxes; i++) { - var j = i; - values.Add(($"Axis{j}", Conv(SDL_JoystickGetAxis(Opaque, j)))); + values.Add(($"Axis{i}", Conv(SDL_JoystickGetAxis(Opaque, i)))); } return values;