mirror of
https://github.com/encounter/SDL.git
synced 2025-12-13 07:06:10 +00:00
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:
@@ -20,6 +20,11 @@
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int SDL_DINPUT_JoystickInit(void);
|
||||
extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
|
||||
extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version);
|
||||
@@ -30,4 +35,9 @@ extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick);
|
||||
extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick);
|
||||
extern void SDL_DINPUT_JoystickQuit(void);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#if !defined(__WINRT__)
|
||||
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
#include <dbt.h>
|
||||
#endif
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
|
||||
#define CR_SUCCESS (0x00000000)
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DECLARE_HANDLE(HCMNOTIFICATION);
|
||||
typedef HCMNOTIFICATION* PHCMNOTIFICATION;
|
||||
|
||||
@@ -141,7 +146,7 @@ static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB,
|
||||
|
||||
JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
|
||||
|
||||
#ifndef __WINRT__
|
||||
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
static HMODULE cfgmgr32_lib_handle;
|
||||
static CM_Register_NotificationFunc CM_Register_Notification;
|
||||
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
|
||||
@@ -327,7 +332,14 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
|
||||
return (lastret != -1) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
#endif /* !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */
|
||||
|
||||
|
||||
#if !defined(__WINRT__)
|
||||
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
static SDL_DeviceNotificationData s_notification_data;
|
||||
#endif
|
||||
|
||||
/* Function/thread to scan the system for joysticks. */
|
||||
static int SDLCALL
|
||||
@@ -338,13 +350,19 @@ SDL_JoystickThread(void *_data)
|
||||
SDL_zeroa(bOpenedXInputDevices);
|
||||
#endif
|
||||
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
if (SDL_CreateDeviceNotification(&s_notification_data) < 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_LockMutex(s_mutexJoyStickEnum);
|
||||
while (s_bJoystickThreadQuit == SDL_FALSE) {
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
if (SDL_WaitForDeviceNotification(&s_notification_data, s_mutexJoyStickEnum) == SDL_FALSE) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
#if SDL_JOYSTICK_XINPUT
|
||||
/* WM_DEVICECHANGE not working, poll for new XINPUT controllers */
|
||||
SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 1000);
|
||||
@@ -354,7 +372,7 @@ SDL_JoystickThread(void *_data)
|
||||
for (userId = 0; userId < XUSER_MAX_COUNT; userId++) {
|
||||
XINPUT_CAPABILITIES capabilities;
|
||||
const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
|
||||
const SDL_bool available = (result == ERROR_SUCCESS);
|
||||
const SDL_bool available = (result == ERROR_SUCCESS) ? SDL_TRUE : SDL_FALSE;
|
||||
if (bOpenedXInputDevices[userId] != available) {
|
||||
s_bWindowsDeviceChanged = SDL_TRUE;
|
||||
bOpenedXInputDevices[userId] = available;
|
||||
@@ -367,9 +385,12 @@ SDL_JoystickThread(void *_data)
|
||||
#endif /* SDL_JOYSTICK_XINPUT */
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(s_mutexJoyStickEnum);
|
||||
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
SDL_CleanupDeviceNotification(&s_notification_data);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -419,7 +440,7 @@ SDL_StopJoystickThread(void)
|
||||
s_joystickThread = NULL;
|
||||
}
|
||||
|
||||
#endif /* !__WINRT__ */
|
||||
#endif /* !defined(__WINRT__) */
|
||||
|
||||
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
|
||||
{
|
||||
@@ -453,7 +474,7 @@ WINDOWS_JoystickInit(void)
|
||||
|
||||
WINDOWS_JoystickDetect();
|
||||
|
||||
#ifndef __WINRT__
|
||||
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
SDL_CreateDeviceNotificationFunc();
|
||||
|
||||
s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE);
|
||||
@@ -467,6 +488,14 @@ WINDOWS_JoystickInit(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
/* On Xbox, force create the joystick thread for device detection (since other methods don't work */
|
||||
s_bJoystickThread = SDL_TRUE;
|
||||
if (SDL_StartJoystickThread() < 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -738,7 +767,7 @@ WINDOWS_JoystickQuit(void)
|
||||
}
|
||||
SYS_Joystick = NULL;
|
||||
|
||||
#ifndef __WINRT__
|
||||
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
if (s_bJoystickThread) {
|
||||
SDL_StopJoystickThread();
|
||||
} else {
|
||||
@@ -748,6 +777,12 @@ WINDOWS_JoystickQuit(void)
|
||||
SDL_CleanupDeviceNotificationFunc();
|
||||
#endif
|
||||
|
||||
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
if (s_bJoystickThread) {
|
||||
SDL_StopJoystickThread();
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_DINPUT_JoystickQuit();
|
||||
SDL_XINPUT_JoystickQuit();
|
||||
|
||||
@@ -784,6 +819,11 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
||||
WINDOWS_JoystickGetGamepadMapping
|
||||
};
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if SDL_JOYSTICK_RAWINPUT
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
|
||||
#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct JoyStick_DeviceData
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
@@ -91,4 +96,9 @@ extern const DIDATAFORMAT SDL_c_dfDIJoystick2;
|
||||
|
||||
extern void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
|
||||
#include "../../core/windows/SDL_xinput.h"
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern SDL_bool SDL_XINPUT_Enabled(void);
|
||||
extern int SDL_XINPUT_JoystickInit(void);
|
||||
extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
|
||||
@@ -32,4 +37,9 @@ extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick);
|
||||
extern void SDL_XINPUT_JoystickClose(SDL_Joystick * joystick);
|
||||
extern void SDL_XINPUT_JoystickQuit(void);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
Reference in New Issue
Block a user