Xbox GDKX support (#5869)

* Xbox GDK support (14 squashed commits)

* Added basic keyboard testing

* Update readme

* Code review fixes

* Fixed issue where controller add/removal wasn't working (since the device notification events don't work on Xbox, have to use the joystick thread to poll XInput)
This commit is contained in:
chalonverse
2022-07-01 13:59:14 -07:00
committed by GitHub
parent 0025621b80
commit f317d619cc
77 changed files with 2573 additions and 74 deletions

View File

@@ -31,6 +31,11 @@
#include "SDL_rawinputjoystick_c.h"
#include "../hidapi/SDL_hidapijoystick_c.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/*
* Internal stuff.
*/
@@ -45,6 +50,8 @@ SDL_XInputUseOldJoystickMapping()
/* TODO: remove this __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
/* FIXME: Why are Win8/10 different here? -flibit */
return (NTDDI_VERSION < NTDDI_WIN10);
#elif defined(__XBOXONE__) || defined(__XBOXSERIES__)
return SDL_FALSE;
#else
static int s_XInputUseOldJoystickMapping = -1;
if (s_XInputUseOldJoystickMapping < 0) {
@@ -126,7 +133,7 @@ GetXInputName(const Uint8 userid, BYTE SubType)
static void
GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
{
#ifndef __WINRT__ /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
PRAWINPUTDEVICELIST devices = NULL;
UINT i, j, device_count = 0;
@@ -386,7 +393,7 @@ SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde
return SDL_SetError("Failed to obtain XInput device capabilities. Device disconnected?");
}
SDL_zero(state);
joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS);
joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS) ? SDL_TRUE : SDL_FALSE;
joystick->hwdata->userid = userId;
/* The XInput API has a hard coded button/axis mapping, so we just match it */
@@ -541,6 +548,10 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation);
}
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
/* XInputOnGameInput doesn't ever change dwPacketNumber, so have to just update every frame */
UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
#else
/* only fire events if the data changed from last time */
if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
if (SDL_XInputUseOldJoystickMapping()) {
@@ -550,6 +561,7 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
}
joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
}
#endif
}
void
@@ -565,6 +577,11 @@ SDL_XINPUT_JoystickQuit(void)
}
}
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#else /* !SDL_JOYSTICK_XINPUT */
typedef struct JoyStick_DeviceData JoyStick_DeviceData;