diff --git a/src/core/windows/SDL_gameinput.cpp b/src/core/windows/SDL_gameinput.cpp index baf7ed2165..7139a4c36d 100644 --- a/src/core/windows/SDL_gameinput.cpp +++ b/src/core/windows/SDL_gameinput.cpp @@ -77,6 +77,11 @@ bool SDL_InitGameInput(IGameInput **ppGameInput) return true; } +bool SDL_GameInputReady(void) +{ + return (g_pGameInput != NULL); +} + void SDL_QuitGameInput(void) { SDL_assert(g_nGameInputRefCount > 0); diff --git a/src/core/windows/SDL_gameinput.h b/src/core/windows/SDL_gameinput.h index d283831ff1..cf8a978a57 100644 --- a/src/core/windows/SDL_gameinput.h +++ b/src/core/windows/SDL_gameinput.h @@ -49,6 +49,7 @@ using namespace GameInput::v1; #endif extern bool SDL_InitGameInput(IGameInput **ppGameInput); +extern bool SDL_GameInputReady(void); extern void SDL_QuitGameInput(void); #endif // HAVE_GAMEINPUT_H diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.cpp index f05c62c487..7456190615 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp @@ -20,6 +20,8 @@ */ #include "SDL_internal.h" +#include "SDL_gameinputjoystick_c.h" + #ifdef SDL_JOYSTICK_GAMEINPUT #include "../SDL_sysjoystick.h" @@ -28,7 +30,7 @@ #include "../../core/windows/SDL_gameinput.h" // Default value for SDL_HINT_JOYSTICK_GAMEINPUT -#if defined(SDL_PLATFORM_GDK) +#if defined(SDL_PLATFORM_GDK) || (GAMEINPUT_API_VERSION >= 3) #define SDL_GAMEINPUT_DEFAULT true #else #define SDL_GAMEINPUT_DEFAULT false @@ -81,10 +83,6 @@ static IGameInput *g_pGameInput = NULL; static GameInputCallbackToken g_GameInputCallbackToken = 0; static Uint64 g_GameInputTimestampOffset; -extern "C" -{ - extern bool SDL_XINPUT_Enabled(void); -} static bool GAMEINPUT_InternalIsGamepad(const GameInputDeviceInfo *info) { @@ -242,9 +240,9 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) #endif if (!GAMEINPUT_InternalIsGamepad(info) && raw_type == SDL_GAMEINPUT_RAWTYPE_NONE) { -#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) - if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_DIRECTINPUT, true) || SDL_XINPUT_Enabled()) { - // Let other backends handle non-gamepad controllers to possibly avoid bugs and/or regressions. +#if defined(SDL_JOYSTICK_DINPUT) + // Let other backends handle non-gamepad controllers to possibly avoid bugs and/or regressions. + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_DIRECTINPUT, true)) { return true; } #endif @@ -1055,6 +1053,15 @@ static bool GAMEINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap return true; } +bool SDL_UsingGameInputForXInputControllers(void) +{ + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT) && + SDL_GameInputReady()) { + return true; + } + return false; +} + SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = { @@ -1082,4 +1089,11 @@ SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = }; +#else + +bool SDL_UsingGameInputForXInputControllers(void) +{ + return false; +} + #endif // SDL_JOYSTICK_GAMEINPUT diff --git a/src/joystick/gdk/SDL_gameinputjoystick_c.h b/src/joystick/gdk/SDL_gameinputjoystick_c.h new file mode 100644 index 0000000000..814166b63f --- /dev/null +++ b/src/joystick/gdk/SDL_gameinputjoystick_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2026 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +// Set up for C function definitions, even when using C++ +#ifdef __cplusplus +extern "C" { +#endif + +extern bool SDL_UsingGameInputForXInputControllers(void); + +// Ends C function definitions when using C++ +#ifdef __cplusplus +} +#endif diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 62ffbb46ec..e9c818aa00 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -29,6 +29,7 @@ #include "SDL_rawinputjoystick_c.h" #include "SDL_xinputjoystick_c.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" #ifndef DIDFT_OPTIONAL #define DIDFT_OPTIONAL 0x80000000 @@ -238,11 +239,12 @@ static bool SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char * #if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT) SDL_GamepadType type; - // XInput and RawInput backends will pick up XInput-compatible devices + // Some other backends will pick up XInput-compatible devices if (!SDL_XINPUT_Enabled() #ifdef SDL_JOYSTICK_RAWINPUT && !RAWINPUT_IsEnabled() #endif + && !SDL_UsingGameInputForXInputControllers() ) { return false; } diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index 7a69775e26..92c9e026a5 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -38,6 +38,7 @@ #include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_hid.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" /* SDL_JOYSTICK_RAWINPUT_XINPUT is disabled because using XInput at the same time as raw input will turn off the Xbox Series X controller when it is connected via the @@ -1022,7 +1023,8 @@ static bool RAWINPUT_JoystickInit(void) { SDL_assert(!SDL_RAWINPUT_inited); - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, false)) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, false) || + SDL_UsingGameInputForXInputControllers()) { return true; } diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index 6b74873a9c..f8840ac230 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -24,6 +24,7 @@ #include "../SDL_sysjoystick.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" #include "SDL_rawinputjoystick_c.h" #include "../../core/windows/SDL_windows.h" @@ -586,7 +587,8 @@ static bool WGI_JoystickInit(void) { HRESULT hr; - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, false)) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, false) || + SDL_UsingGameInputForXInputControllers()) { return true; } diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index d7a132e1d1..377defb07d 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -28,6 +28,7 @@ #include "SDL_xinputjoystick_c.h" #include "SDL_rawinputjoystick_c.h" #include "../hidapi/SDL_hidapijoystick_c.h" +#include "../gdk/SDL_gameinputjoystick_c.h" // Set up for C function definitions, even when using C++ #ifdef __cplusplus @@ -46,7 +47,12 @@ bool SDL_XINPUT_Enabled(void) bool SDL_XINPUT_JoystickInit(void) { - bool enabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, true); + bool enabled = true; + + if (!SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, true) || + SDL_UsingGameInputForXInputControllers()) { + enabled = false; + } if (enabled && !WIN_LoadXInputDLL()) { enabled = false; // oh well.