Enable GameInput v3 by default if it's available

GameInput is now the most functional Windows API for handling XInput controllers.
This commit is contained in:
Sam Lantinga
2026-05-14 10:18:58 -07:00
parent d57c3b685c
commit 2c4e6ed358
8 changed files with 77 additions and 12 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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.