Browse Source

Fixed infinite recursion in SDL_IsGamepad()

SDL_IsGamepad() calls SDL_GetJoystickTypeForID(), which will call SDL_IsGamepad() if it's not a known controller type. The new code which is breaking was added to prevent Logitech FFB wheels from showing up as gamepads, which we check for separately.
Sam Lantinga 1 month ago
parent
commit
5985f0a327
3 changed files with 11 additions and 6 deletions
  1. 7 5
      src/joystick/SDL_gamepad.c
  2. 1 1
      src/joystick/SDL_joystick.c
  3. 3 0
      src/joystick/SDL_joystick_c.h

+ 7 - 5
src/joystick/SDL_gamepad.c

@@ -699,6 +699,12 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
 
     SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
 
+    if (SDL_IsJoystickWheel(vendor, product)) {
+        // We don't want to pick up Logitech FFB wheels here
+        // Some versions of WINE will also not treat devices that show up as gamepads as wheels
+        return NULL;
+    }
+
     if ((vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) ||
         (vendor == USB_VENDOR_DRAGONRISE &&
          (product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER1 ||
@@ -2633,11 +2639,7 @@ bool SDL_IsGamepad(SDL_JoystickID instance_id)
         if (SDL_FindInHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)instance_id, &value)) {
             result = (bool)(uintptr_t)value;
         } else {
-            SDL_JoystickType js_type = SDL_GetJoystickTypeForID(instance_id);
-            if (js_type != SDL_JOYSTICK_TYPE_GAMEPAD && js_type != SDL_JOYSTICK_TYPE_UNKNOWN) {
-                // avoid creating HIDAPI mapping if SDL_Joystick knows it is not a game pad
-                result = false;
-            } else if (SDL_PrivateGetGamepadMapping(instance_id, true) != NULL) {
+            if (SDL_PrivateGetGamepadMapping(instance_id, true) != NULL) {
                 result = true;
             } else {
                 result = false;

+ 1 - 1
src/joystick/SDL_joystick.c

@@ -3049,7 +3049,7 @@ bool SDL_IsJoystickVIRTUAL(SDL_GUID guid)
     return (guid.data[14] == 'v') ? true : false;
 }
 
-static bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id)
+bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id)
 {
     return SDL_VIDPIDInList(vendor_id, product_id, &wheel_devices);
 }

+ 3 - 0
src/joystick/SDL_joystick_c.h

@@ -156,6 +156,9 @@ extern bool SDL_IsJoystickRAWINPUT(SDL_GUID guid);
 // Function to return whether a joystick guid comes from the Virtual driver
 extern bool SDL_IsJoystickVIRTUAL(SDL_GUID guid);
 
+// Function to return whether a joystick is a wheel
+bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id);
+
 // Function to return whether a joystick should be ignored
 extern bool SDL_ShouldIgnoreJoystick(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);