SDL: Added SDL_HINT_JOYSTICK_GAMEINPUT

From c2085dad8f5fa69dc60c3d648b339a4e71abe989 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 9 Aug 2024 09:19:32 -0700
Subject: [PATCH] Added SDL_HINT_JOYSTICK_GAMEINPUT

---
 include/SDL3/SDL_hints.h                 | 15 +++++++++++++
 src/joystick/gdk/SDL_gameinputjoystick.c | 27 +++++++++++++-----------
 2 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h
index 575b81487014e..983efe23c7b52 100644
--- a/include/SDL3/SDL_hints.h
+++ b/include/SDL3/SDL_hints.h
@@ -1226,6 +1226,21 @@ extern "C" {
  */
 #define SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES_EXCLUDED "SDL_JOYSTICK_FLIGHTSTICK_DEVICES_EXCLUDED"
 
+/**
+ * A variable controlling whether GameInput should be used for
+ * controller handling on Windows.
+ *
+ * The variable can be set to the following values:
+ *
+ * - "0": GameInput is not used.
+ * - "1": GameInput is used. (default)
+ *
+ * This hint should be set before SDL is initialized.
+ *
+ * \since This hint is available since SDL 3.0.0.
+ */
+#define SDL_HINT_JOYSTICK_GAMEINPUT "SDL_JOYSTICK_GAMEINPUT"
+
 /**
  * A variable containing a list of devices known to have a GameCube form
  * factor.
diff --git a/src/joystick/gdk/SDL_gameinputjoystick.c b/src/joystick/gdk/SDL_gameinputjoystick.c
index f203bb7a7bead..63b233a11d442 100644
--- a/src/joystick/gdk/SDL_gameinputjoystick.c
+++ b/src/joystick/gdk/SDL_gameinputjoystick.c
@@ -234,6 +234,10 @@ static int GAMEINPUT_JoystickInit(void)
 {
     HRESULT hR;
 
+    if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_TRUE)) {
+        return 0;
+    }
+
     if (!g_hGameInputDLL) {
         g_hGameInputDLL = SDL_LoadObject("gameinput.dll");
         if (!g_hGameInputDLL) {
@@ -310,22 +314,21 @@ static void GAMEINPUT_JoystickDetect(void)
 
 static SDL_bool GAMEINPUT_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
 {
-    int idx = 0;
-    GAMEINPUT_InternalDevice *elem = NULL;
-
     SDL_AssertJoysticksLocked();
 
-    if (vendor_id == USB_VENDOR_MICROSOFT &&
-        product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) {
-        /* The Xbox One controller shows up as a hardcoded raw input VID/PID, which we definitely handle */
-        return SDL_TRUE;
-    }
-
-    for (idx = 0; idx < g_GameInputList.count; ++idx) {
-        elem = g_GameInputList.devices[idx];
-        if (elem && vendor_id == elem->info->vendorId && product_id == elem->info->productId) {
+    if (g_pGameInput) {
+        if (vendor_id == USB_VENDOR_MICROSOFT &&
+            product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) {
+            /* The Xbox One controller shows up as a hardcoded raw input VID/PID, which we definitely handle */
             return SDL_TRUE;
         }
+
+        for (int i = 0; i < g_GameInputList.count; ++i) {
+            GAMEINPUT_InternalDevice *elem = g_GameInputList.devices[i];
+            if (elem && vendor_id == elem->info->vendorId && product_id == elem->info->productId) {
+                return SDL_TRUE;
+            }
+        }
     }
     return SDL_FALSE;
 }