Fixed bug 4477 - Support more than 4 XInput-capable devices on Windows
Jimb Esser Add new RawInput controller API, and improved correlation with XInput/WGI Reorder joystick init so drivers can ask the others if they handle a device reliably Do not poll disconnected XInput devices (major perf issue) Fix various cases where incorrect correlation could happen Simple mechanism for propagating unhandled Guide button presses even before guaranteed correlation Correlate by axis motion as well as button presses Fix failing to zero other trigger Fix SDL_HINT_JOYSTICK_HIDAPI not working if set before calling SDL_Init() Add missing device to device names Disable RawInput if we have a mismatch of XInput-capable but not RawInput-capable devices Updated to SDL 2.0.13 code with the following notes: New HID driver: xbox360w - no idea what that is, hopefully urelated SDL_hidapijoystick.c had been refactored to couple data handling logic with device opening logic and device lists caused some problems, yields slightly uglier integration than previously when the 360 HID device driver was just handling the data. SDL_hidapijoystick.c now often pulls the device off of the joystick_hwdata structure for some rumble logic, but it appears that code path is never reached, so probably not a problem. Looks like joystick_hwdata was refactored to not include a mutex in other drivers, maintainers may want to do the same refactor here if that's useful for some reason. Something changed in how devices get names, so getting generic names. Had to fix a (new?) bug where removing an XInput controller caused existing controllers (that moved to a new XInput index) to get identified as 0x045e/0x02fd ("it's probably Bluetooth" in code), rendering the existing HIDAPI_IsDevicePresent and new RAWINPUT_IsDevicePresent unreliable.
parent
cc37ee8a0c
commit
4dea340ca7
|
@ -318,12 +318,15 @@
|
|||
<ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
|
||||
<ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
|
||||
<ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
|
||||
<ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
|
||||
<ClInclude Include="..\..\src\joystick\controller_type.h" />
|
||||
<ClInclude Include="..\..\src\joystick\hidapi\SDL_hidapijoystick_c.h" />
|
||||
<ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
|
||||
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
|
||||
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
|
||||
<ClInclude Include="..\..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
|
||||
<ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
|
||||
<ClInclude Include="..\..\src\joystick\windows\SDL_rawinputjoystick_c.h" />
|
||||
<ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
|
||||
<ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
|
||||
<ClInclude Include="..\..\src\libm\math_libm.h" />
|
||||
|
@ -432,6 +435,7 @@
|
|||
<ClCompile Include="..\..\src\joystick\virtual\SDL_virtualjoystick.c" />
|
||||
<ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
|
||||
<ClCompile Include="..\..\src\joystick\windows\SDL_mmjoystick.c" />
|
||||
<ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
|
||||
<ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
|
||||
<ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
|
||||
<ClCompile Include="..\..\src\libm\e_atan2.c" />
|
||||
|
|
|
@ -323,6 +323,9 @@
|
|||
<ClInclude Include="..\..\src\video\windows\SDL_windowswindow.h" />
|
||||
<ClInclude Include="..\..\src\video\windows\wmmsg.h" />
|
||||
<ClInclude Include="..\..\src\video\yuv2rgb\yuv_rgb.h" />
|
||||
<ClInclude Include="..\..\src\joystick\windows\SDL_rawinputjoystick_c.h" />
|
||||
<ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
|
||||
<ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\atomic\SDL_atomic.c" />
|
||||
|
@ -478,6 +481,7 @@
|
|||
<ClCompile Include="..\..\src\video\windows\SDL_windowsvulkan.c" />
|
||||
<ClCompile Include="..\..\src\video\windows\SDL_windowswindow.c" />
|
||||
<ClCompile Include="..\..\src\video\yuv2rgb\yuv_rgb.c" />
|
||||
<ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\src\main\windows\version.rc" />
|
||||
|
|
|
@ -24336,6 +24336,8 @@ fi
|
|||
|
||||
$as_echo "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define SDL_JOYSTICK_RAWINPUT 1" >>confdefs.h
|
||||
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi"
|
||||
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
|
||||
SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c"
|
||||
|
|
|
@ -3316,6 +3316,7 @@ AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[d
|
|||
|
||||
if test x$hidapi_support = xyes; then
|
||||
AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ])
|
||||
AC_DEFINE(SDL_JOYSTICK_RAWINPUT, 1, [ ])
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi"
|
||||
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
|
||||
SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c"
|
||||
|
|
|
@ -289,6 +289,7 @@
|
|||
#undef SDL_JOYSTICK_USBHID
|
||||
#undef SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
|
||||
#undef SDL_JOYSTICK_HIDAPI
|
||||
#undef SDL_JOYSTICK_RAWINPUT
|
||||
#undef SDL_JOYSTICK_EMSCRIPTEN
|
||||
#undef SDL_JOYSTICK_VIRTUAL
|
||||
#undef SDL_HAPTIC_DUMMY
|
||||
|
|
|
@ -197,6 +197,7 @@ typedef unsigned int uintptr_t;
|
|||
#define SDL_JOYSTICK_DINPUT 1
|
||||
#define SDL_JOYSTICK_XINPUT 1
|
||||
#define SDL_JOYSTICK_HIDAPI 1
|
||||
#define SDL_JOYSTICK_RAWINPUT 1
|
||||
#define SDL_HAPTIC_DINPUT 1
|
||||
#define SDL_HAPTIC_XINPUT 1
|
||||
|
||||
|
|
|
@ -634,10 +634,23 @@ extern "C" {
|
|||
* "0" - HIDAPI driver is not used
|
||||
* "1" - HIDAPI driver is used
|
||||
*
|
||||
* The default is the value of SDL_HINT_JOYSTICK_HIDAPI
|
||||
* The default is "0" on Windows, otherwise the value of SDL_HINT_JOYSTICK_HIDAPI
|
||||
*/
|
||||
#define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the HIDAPI driver for XBox controllers on Windows should pull correlated
|
||||
* data from XInput.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - HIDAPI Xbox driver will only use HIDAPI data
|
||||
* "1" - HIDAPI Xbox driver will also pull data from XInput, providing better trigger axes, guide button
|
||||
* presses, and rumble support
|
||||
*
|
||||
* The default is "1". This hint applies to any joysticks opened after setting the hint.
|
||||
*/
|
||||
#define SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT "SDL_JOYSTICK_HIDAPI_CORRELATE_XINPUT"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used.
|
||||
*
|
||||
|
@ -660,6 +673,15 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInput-capable devices.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - RAWINPUT drivers are not used
|
||||
* "1" - RAWINPUT drivers are used (the default)
|
||||
*
|
||||
*/
|
||||
#define SDL_HINT_JOYSTICK_RAWINPUT "SDL_JOYSTICK_RAWINPUT"
|
||||
|
||||
/**
|
||||
* \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it.
|
||||
|
|
|
@ -439,6 +439,12 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
|
|||
/* This is a HIDAPI device */
|
||||
return s_pHIDAPIMapping;
|
||||
}
|
||||
#if SDL_JOYSTICK_RAWINPUT
|
||||
if (SDL_IsJoystickRAWINPUT(*guid)) {
|
||||
/* This is a RAWINPUT device - same data as HIDAPI */
|
||||
return s_pHIDAPIMapping;
|
||||
}
|
||||
#endif
|
||||
#if SDL_JOYSTICK_XINPUT
|
||||
if (SDL_IsJoystickXInput(*guid)) {
|
||||
/* This is an XInput device */
|
||||
|
|
|
@ -51,6 +51,13 @@
|
|||
#endif
|
||||
|
||||
static SDL_JoystickDriver *SDL_joystick_drivers[] = {
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */
|
||||
/* Also before HIDAPI, as HIDAPI wants to check if this driver is handling things */
|
||||
&SDL_RAWINPUT_JoystickDriver,
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_HIDAPI /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */
|
||||
&SDL_HIDAPI_JoystickDriver,
|
||||
#endif
|
||||
#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
|
||||
&SDL_WINDOWS_JoystickDriver,
|
||||
#endif
|
||||
|
@ -75,9 +82,6 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
|
|||
#ifdef SDL_JOYSTICK_USBHID /* !!! FIXME: "USBHID" is a generic name, and doubly-confusing with HIDAPI next to it. This is the *BSD interface, rename this. */
|
||||
&SDL_BSD_JoystickDriver,
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
&SDL_HIDAPI_JoystickDriver,
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_VIRTUAL
|
||||
&SDL_VIRTUAL_JoystickDriver,
|
||||
#endif
|
||||
|
@ -1729,6 +1733,12 @@ SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
|
|||
return (guid.data[14] == 'h') ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IsJoystickRAWINPUT(SDL_JoystickGUID guid)
|
||||
{
|
||||
return (guid.data[14] == 'r') ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IsJoystickVirtual(SDL_JoystickGUID guid)
|
||||
{
|
||||
|
|
|
@ -73,6 +73,9 @@ extern SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid);
|
|||
/* Function to return whether a joystick guid comes from the HIDAPI driver */
|
||||
extern SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid);
|
||||
|
||||
/* Function to return whether a joystick guid comes from the RAWINPUT driver */
|
||||
extern SDL_bool SDL_IsJoystickRAWINPUT(SDL_JoystickGUID guid);
|
||||
|
||||
/* Function to return whether a joystick guid comes from the Virtual driver */
|
||||
extern SDL_bool SDL_IsJoystickVirtual(SDL_JoystickGUID guid);
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ extern SDL_JoystickDriver SDL_DUMMY_JoystickDriver;
|
|||
extern SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_HAIKU_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_HIDAPI_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_IOS_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_LINUX_JoystickDriver;
|
||||
extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver;
|
||||
|
|
|
@ -176,11 +176,11 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
|||
if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */
|
||||
if (ctx->joysticks[i] == -1) {
|
||||
ResetAxisRange(ctx, i);
|
||||
HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
|
||||
HIDAPI_JoystickConnected(device, &ctx->joysticks[i], SDL_FALSE);
|
||||
}
|
||||
} else {
|
||||
if (ctx->joysticks[i] != -1) {
|
||||
HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]);
|
||||
HIDAPI_JoystickDisconnected(device, ctx->joysticks[i], SDL_FALSE);
|
||||
ctx->joysticks[i] = -1;
|
||||
}
|
||||
continue;
|
||||
|
@ -252,7 +252,7 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */
|
||||
if (ctx->joysticks[i] == -1) {
|
||||
ResetAxisRange(ctx, i);
|
||||
HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
|
||||
HIDAPI_JoystickConnected(device, &ctx->joysticks[i], SDL_FALSE);
|
||||
}
|
||||
joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]);
|
||||
|
||||
|
@ -262,7 +262,7 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
}
|
||||
} else {
|
||||
if (ctx->joysticks[i] != -1) {
|
||||
HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]);
|
||||
HIDAPI_JoystickDisconnected(device, ctx->joysticks[i], SDL_FALSE);
|
||||
ctx->joysticks[i] = -1;
|
||||
}
|
||||
continue;
|
||||
|
|
|
@ -213,7 +213,7 @@ SetLedsForPlayerIndex(DS4EffectsState_t *effects, int player_index)
|
|||
static SDL_bool
|
||||
HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
return HIDAPI_JoystickConnected(device, NULL);
|
||||
return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -496,7 +496,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
|
||||
if (size < 0) {
|
||||
/* Read error, device is disconnected */
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id);
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
|
||||
}
|
||||
return (size >= 0);
|
||||
}
|
||||
|
|
|
@ -671,7 +671,7 @@ static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)
|
|||
static SDL_bool
|
||||
HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
return HIDAPI_JoystickConnected(device, NULL);
|
||||
return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1121,7 +1121,7 @@ HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
|
||||
if (size < 0) {
|
||||
/* Read error, device is disconnected */
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id);
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
|
||||
}
|
||||
return (size >= 0);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -231,10 +231,10 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
if (connected) {
|
||||
SDL_JoystickID joystickID;
|
||||
|
||||
HIDAPI_JoystickConnected(device, &joystickID);
|
||||
HIDAPI_JoystickConnected(device, &joystickID, SDL_FALSE);
|
||||
|
||||
} else if (device->num_joysticks > 0) {
|
||||
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
|
||||
HIDAPI_JoystickDisconnected(device, device->joysticks[0], SDL_FALSE);
|
||||
}
|
||||
}
|
||||
} else if (size == 29 && data[0] == 0x00 && data[1] == 0x0f && data[2] == 0x00 && data[3] == 0xf0) {
|
||||
|
@ -262,7 +262,7 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
if (joystick) {
|
||||
if (size < 0) {
|
||||
/* Read error, device is disconnected */
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id);
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
|
||||
}
|
||||
}
|
||||
return (size >= 0);
|
||||
|
|
|
@ -279,7 +279,7 @@ HIDAPI_DriverXboxOne_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
|||
static SDL_bool
|
||||
HIDAPI_DriverXboxOne_InitDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
return HIDAPI_JoystickConnected(device, NULL);
|
||||
return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -694,7 +694,7 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
!ControllerSendsWaitingForInit(device->vendor_id, device->product_id)) {
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->start_time + CONTROLLER_INIT_DELAY_MS)) {
|
||||
if (!SendControllerInit(device, ctx)) {
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id);
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
ctx->initialized = SDL_TRUE;
|
||||
|
@ -737,7 +737,7 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
SDL_Log("Delay after init: %ums\n", SDL_GetTicks() - ctx->start_time);
|
||||
#endif
|
||||
if (!SendControllerInit(device, ctx)) {
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id);
|
||||
HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
ctx->initialized = SDL_TRUE;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#if defined(__WIN32__)
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../windows/SDL_rawinputjoystick_c.h"
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
|
@ -419,6 +420,13 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT
|
||||
if (RAWINPUT_IsDevicePresent(device->vendor_id, device->product_id, device->version)) {
|
||||
/* The RAWINPUT driver is taking care of this device */
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (device->usage_page && device->usage_page != USAGE_PAGE_GENERIC_DESKTOP) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -502,7 +510,7 @@ HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
|
|||
|
||||
/* Disconnect any joysticks */
|
||||
while (device->num_joysticks) {
|
||||
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
|
||||
HIDAPI_JoystickDisconnected(device, device->joysticks[0], SDL_FALSE);
|
||||
}
|
||||
|
||||
device->driver->FreeDevice(device);
|
||||
|
@ -575,6 +583,11 @@ HIDAPI_JoystickInit(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
/* On Windows, turns out HIDAPI for Xbox controllers doesn't allow background input, so off by default */
|
||||
SDL_SetHintWithPriority(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0", SDL_HINT_DEFAULT);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
|
||||
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
|
||||
SDL_AddHintCallback(driver->hint, SDL_HIDAPIDriverHintChanged, NULL);
|
||||
|
@ -591,7 +604,7 @@ HIDAPI_JoystickInit(void)
|
|||
}
|
||||
|
||||
SDL_bool
|
||||
HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
|
||||
HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID, SDL_bool is_external)
|
||||
{
|
||||
SDL_JoystickID joystickID;
|
||||
SDL_JoystickID *joysticks = (SDL_JoystickID *)SDL_realloc(device->joysticks, (device->num_joysticks + 1)*sizeof(*device->joysticks));
|
||||
|
@ -602,7 +615,9 @@ HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
|
|||
joystickID = SDL_GetNextJoystickInstanceID();
|
||||
device->joysticks = joysticks;
|
||||
device->joysticks[device->num_joysticks++] = joystickID;
|
||||
++SDL_HIDAPI_numjoysticks;
|
||||
if (!is_external) {
|
||||
++SDL_HIDAPI_numjoysticks;
|
||||
}
|
||||
|
||||
SDL_PrivateJoystickAdded(joystickID);
|
||||
|
||||
|
@ -613,20 +628,22 @@ HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
|
|||
}
|
||||
|
||||
void
|
||||
HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID)
|
||||
HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID, SDL_bool is_external)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < device->num_joysticks; ++i) {
|
||||
if (device->joysticks[i] == joystickID) {
|
||||
SDL_Joystick *joystick = SDL_JoystickFromInstanceID(joystickID);
|
||||
if (joystick) {
|
||||
if (joystick && !is_external) {
|
||||
HIDAPI_JoystickClose(joystick);
|
||||
}
|
||||
|
||||
SDL_memmove(&device->joysticks[i], &device->joysticks[i+1], device->num_joysticks - i - 1);
|
||||
--device->num_joysticks;
|
||||
--SDL_HIDAPI_numjoysticks;
|
||||
if (!is_external) {
|
||||
--SDL_HIDAPI_numjoysticks;
|
||||
}
|
||||
if (device->num_joysticks == 0) {
|
||||
SDL_free(device->joysticks);
|
||||
device->joysticks = NULL;
|
||||
|
@ -882,6 +899,7 @@ HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, cons
|
|||
static void
|
||||
HIDAPI_JoystickDetect(void)
|
||||
{
|
||||
int i;
|
||||
if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) {
|
||||
HIDAPI_UpdateDiscovery();
|
||||
if (SDL_HIDAPI_discovery.m_bHaveDevicesChanged) {
|
||||
|
@ -891,6 +909,12 @@ HIDAPI_JoystickDetect(void)
|
|||
}
|
||||
SDL_AtomicUnlock(&SDL_HIDAPI_spinlock);
|
||||
}
|
||||
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
|
||||
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
|
||||
if (driver->enabled && driver->PostUpdate) {
|
||||
driver->PostUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
#ifdef __WINDOWS__
|
||||
/* On Windows, Xbox One controllers are handled by the Xbox 360 driver */
|
||||
#undef SDL_JOYSTICK_HIDAPI_XBOXONE
|
||||
/* It turns out HIDAPI for Xbox controllers doesn't allow background input */
|
||||
#undef SDL_JOYSTICK_HIDAPI_XBOX360
|
||||
#endif
|
||||
|
||||
#ifdef __MACOSX__
|
||||
|
@ -103,6 +101,10 @@ typedef struct _SDL_HIDAPI_DeviceDriver
|
|||
int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
|
||||
void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
void (*FreeDevice)(SDL_HIDAPI_Device *device);
|
||||
void (*PostUpdate)(void);
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT
|
||||
void (*HandleStatePacketFromRAWINPUT)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 *data, int size);
|
||||
#endif
|
||||
|
||||
} SDL_HIDAPI_DeviceDriver;
|
||||
|
||||
|
@ -120,8 +122,8 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube;
|
|||
extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
|
||||
|
||||
extern void HIDAPI_UpdateDevices(void);
|
||||
extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID);
|
||||
extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID);
|
||||
extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID, SDL_bool is_external);
|
||||
extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID, SDL_bool is_external);
|
||||
|
||||
#endif /* SDL_JOYSTICK_HIDAPI_H */
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "SDL_windowsjoystick_c.h"
|
||||
#include "SDL_dinputjoystick_c.h"
|
||||
#include "SDL_rawinputjoystick_c.h"
|
||||
#include "SDL_xinputjoystick_c.h"
|
||||
#include "../hidapi/SDL_hidapijoystick_c.h"
|
||||
|
||||
|
@ -672,6 +673,14 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT
|
||||
if (RAWINPUT_IsDevicePresent(vendor, product, 0)) {
|
||||
/* The RAWINPUT driver is taking care of this device */
|
||||
SDL_free(pNewJoystick);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
WINDOWS_AddJoystickDevice(pNewJoystick);
|
||||
|
||||
return DIENUM_CONTINUE; /* get next device, please */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "SDL_timer.h"
|
||||
#include "SDL_windowsjoystick_c.h"
|
||||
#include "SDL_xinputjoystick_c.h"
|
||||
#include "SDL_rawinputjoystick_c.h"
|
||||
#include "../hidapi/SDL_hidapijoystick_c.h"
|
||||
|
||||
/*
|
||||
|
@ -292,6 +293,14 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT
|
||||
if (RAWINPUT_IsDevicePresent(vendor, product, version)) {
|
||||
/* The RAWINPUT driver is taking care of this device */
|
||||
SDL_free(pNewJoystick);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
WINDOWS_AddJoystickDevice(pNewJoystick);
|
||||
}
|
||||
|
||||
|
@ -318,6 +327,18 @@ SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
|
|||
const Uint8 userid = (Uint8)iuserid;
|
||||
XINPUT_CAPABILITIES capabilities;
|
||||
if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
|
||||
/* Adding a new device, must handle all removes first, or GuessXInputDevice goes terribly wrong (returns
|
||||
a product/vendor ID that is not even attached to the system) when we get a remove and add on the same tick
|
||||
(e.g. when disconnecting a device and the OS reassigns which userid an already-attached controller is)
|
||||
*/
|
||||
int iuserid2;
|
||||
for (iuserid2 = iuserid - 1; iuserid2 >= 0; iuserid2--) {
|
||||
const Uint8 userid2 = (Uint8)iuserid2;
|
||||
XINPUT_CAPABILITIES capabilities2;
|
||||
if (XINPUTGETCAPABILITIES(userid2, XINPUT_FLAG_GAMEPAD, &capabilities2) != ERROR_SUCCESS) {
|
||||
DelXInputDevice(userid2);
|
||||
}
|
||||
}
|
||||
AddXInputDevice(userid, capabilities.SubType, pContext);
|
||||
} else {
|
||||
DelXInputDevice(userid);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
|
||||
#include "../../joystick/windows/SDL_rawinputjoystick_c.h"
|
||||
#include "SDL_windowsvideo.h"
|
||||
#include "SDL_windowswindow.h"
|
||||
#include "SDL_hints.h"
|
||||
|
@ -808,9 +809,18 @@ WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
|
|||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK SDL_HelperWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
#if SDL_JOYSTICK_RAWINPUT
|
||||
if (RAWINPUT_WindowProc(hWnd, msg, wParam, lParam) == 0) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a HelperWindow used for DirectInput events.
|
||||
* Creates a HelperWindow used for DirectInput and RawInput events.
|
||||
*/
|
||||
int
|
||||
SDL_HelperWindowCreate(void)
|
||||
|
@ -825,7 +835,7 @@ SDL_HelperWindowCreate(void)
|
|||
|
||||
/* Create the class. */
|
||||
SDL_zero(wce);
|
||||
wce.lpfnWndProc = DefWindowProc;
|
||||
wce.lpfnWndProc = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE) ? SDL_HelperWindowProc : DefWindowProc;
|
||||
wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
|
||||
wce.hInstance = hInstance;
|
||||
|
||||
|
|
Loading…
Reference in New Issue