Files
gen1recomp/ports/uwp/third_party/sdl2/patches/xbox-wgi-controller.patch
T
2026-08-04 15:35:52 +01:00

137 lines
6.7 KiB
Diff

diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index 035176b..04e1701 100644
--- a/src/joystick/SDL_gamecontroller.c
+++ b/src/joystick/SDL_gamecontroller.c
@@ -726,7 +726,12 @@ static ControllerMapping_t *SDL_CreateMappingForWGIController(SDL_JoystickGUID g
}
SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string));
+#ifdef __WINRT__
+ /* Xbox WGI exposes the canonical SDL axis and hat layout. */
+ SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,", sizeof(mapping_string));
+#else
SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:b10,dpdown:b12,dpleft:b13,dpright:b11,leftx:a1,lefty:a0~,rightx:a3,righty:a2~,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
+#endif
return SDL_PrivateAddMappingForGUID(guid, mapping_string, &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c
index 6f01b4e..26b8811 100644
--- a/src/joystick/windows/SDL_windows_gaming_input.c
+++ b/src/joystick/windows/SDL_windows_gaming_input.c
@@ -731,10 +731,19 @@ static int WGI_JoystickOpen(SDL_Joystick *joystick, int device_index)
__x_ABI_CWindows_CGaming_CInput_CIGameController_get_IsWireless(hwdata->gamecontroller, &wireless);
}
- /* Initialize the joystick capabilities */
- joystick->nbuttons = state->nbuttons;
- joystick->naxes = state->naxes;
- joystick->nhats = state->nhats;
+#ifdef __WINRT__
+ if (hwdata->gamepad) {
+ joystick->nbuttons = 10;
+ joystick->naxes = 6;
+ joystick->nhats = 1;
+ } else
+#endif
+ {
+ /* Initialize the joystick capabilities */
+ joystick->nbuttons = state->nbuttons;
+ joystick->naxes = state->naxes;
+ joystick->nhats = state->nhats;
+ }
joystick->epowerlevel = wireless ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED;
if (wireless && hwdata->battery) {
@@ -872,6 +881,51 @@ static void WGI_JoystickUpdate(SDL_Joystick *joystick)
{
struct joystick_hwdata *hwdata = joystick->hwdata;
HRESULT hr;
+
+#ifdef __WINRT__
+ if (hwdata->gamepad) {
+ struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading reading;
+ static const __x_ABI_CWindows_CGaming_CInput_CGamepadButtons button_masks[] = {
+ GamepadButtons_A, GamepadButtons_B, GamepadButtons_X, GamepadButtons_Y,
+ GamepadButtons_LeftShoulder, GamepadButtons_RightShoulder,
+ GamepadButtons_View, GamepadButtons_Menu,
+ GamepadButtons_LeftThumbstick, GamepadButtons_RightThumbstick
+ };
+ Uint8 hat = SDL_HAT_CENTERED;
+ Uint8 i;
+
+ hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_GetCurrentReading(hwdata->gamepad, &reading);
+ if (SUCCEEDED(hr) && (!reading.Timestamp || reading.Timestamp != hwdata->timestamp)) {
+ const DOUBLE left_x = SDL_max(-1.0, SDL_min(1.0, reading.LeftThumbstickX));
+ const DOUBLE left_y = SDL_max(-1.0, SDL_min(1.0, reading.LeftThumbstickY));
+ const DOUBLE right_x = SDL_max(-1.0, SDL_min(1.0, reading.RightThumbstickX));
+ const DOUBLE right_y = SDL_max(-1.0, SDL_min(1.0, reading.RightThumbstickY));
+ const DOUBLE left_trigger = SDL_max(0.0, SDL_min(1.0, reading.LeftTrigger));
+ const DOUBLE right_trigger = SDL_max(0.0, SDL_min(1.0, reading.RightTrigger));
+
+ SDL_PrivateJoystickAxis(joystick, 0, (Sint16)(left_x * 32767.0));
+ SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-left_y * 32767.0));
+ SDL_PrivateJoystickAxis(joystick, 2, (Sint16)(left_trigger * 65535.0 - 32768.0));
+ SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(right_x * 32767.0));
+ SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(-right_y * 32767.0));
+ SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(right_trigger * 65535.0 - 32768.0));
+
+ for (i = 0; i < (Uint8)SDL_arraysize(button_masks); ++i) {
+ SDL_PrivateJoystickButton(joystick, i,
+ (reading.Buttons & button_masks[i]) ? SDL_PRESSED : SDL_RELEASED);
+ }
+
+ if (reading.Buttons & GamepadButtons_DPadUp) hat |= SDL_HAT_UP;
+ if (reading.Buttons & GamepadButtons_DPadDown) hat |= SDL_HAT_DOWN;
+ if (reading.Buttons & GamepadButtons_DPadLeft) hat |= SDL_HAT_LEFT;
+ if (reading.Buttons & GamepadButtons_DPadRight) hat |= SDL_HAT_RIGHT;
+ SDL_PrivateJoystickHat(joystick, 0, hat);
+ hwdata->timestamp = reading.Timestamp;
+ }
+ return;
+ }
+#endif
+
UINT32 nbuttons = SDL_min(joystick->nbuttons, SDL_MAX_UINT8);
boolean *buttons = NULL;
UINT32 nhats = SDL_min(joystick->nhats, SDL_MAX_UINT8);
@@ -994,7 +1048,38 @@ static void WGI_JoystickQuit(void)
static SDL_bool WGI_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
+#ifdef __WINRT__
+ WindowsGamingInputControllerState *state = &wgi.controllers[device_index];
+
+ if (state->type != SDL_JOYSTICK_TYPE_GAMECONTROLLER) {
+ return SDL_FALSE;
+ }
+
+ SDL_zero(*out);
+ out->a = (SDL_InputMapping){ EMappingKind_Button, 0 };
+ out->b = (SDL_InputMapping){ EMappingKind_Button, 1 };
+ out->x = (SDL_InputMapping){ EMappingKind_Button, 2 };
+ out->y = (SDL_InputMapping){ EMappingKind_Button, 3 };
+ out->leftshoulder = (SDL_InputMapping){ EMappingKind_Button, 4 };
+ out->rightshoulder = (SDL_InputMapping){ EMappingKind_Button, 5 };
+ out->back = (SDL_InputMapping){ EMappingKind_Button, 6 };
+ out->start = (SDL_InputMapping){ EMappingKind_Button, 7 };
+ out->leftstick = (SDL_InputMapping){ EMappingKind_Button, 8 };
+ out->rightstick = (SDL_InputMapping){ EMappingKind_Button, 9 };
+ out->dpup = (SDL_InputMapping){ EMappingKind_Hat, SDL_HAT_UP };
+ out->dpdown = (SDL_InputMapping){ EMappingKind_Hat, SDL_HAT_DOWN };
+ out->dpleft = (SDL_InputMapping){ EMappingKind_Hat, SDL_HAT_LEFT };
+ out->dpright = (SDL_InputMapping){ EMappingKind_Hat, SDL_HAT_RIGHT };
+ out->leftx = (SDL_InputMapping){ EMappingKind_Axis, 0 };
+ out->lefty = (SDL_InputMapping){ EMappingKind_Axis, 1 };
+ out->lefttrigger = (SDL_InputMapping){ EMappingKind_Axis, 2 };
+ out->rightx = (SDL_InputMapping){ EMappingKind_Axis, 3 };
+ out->righty = (SDL_InputMapping){ EMappingKind_Axis, 4 };
+ out->righttrigger = (SDL_InputMapping){ EMappingKind_Axis, 5 };
+ return SDL_TRUE;
+#else
return SDL_FALSE;
+#endif
}
SDL_JoystickDriver SDL_WGI_JoystickDriver = {