From 5985f0a327910648aff75ca7134f3a7c7ff83721 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 17 Mar 2025 19:10:26 -0700 Subject: [PATCH] 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. --- src/joystick/SDL_gamepad.c | 12 +++++++----- src/joystick/SDL_joystick.c | 2 +- src/joystick/SDL_joystick_c.h | 3 +++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 59bd217f5b..0bff7bf5f8 100644 --- a/src/joystick/SDL_gamepad.c +++ b/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; diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index a4d86688c7..8f7947b825 100644 --- a/src/joystick/SDL_joystick.c +++ b/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); } diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index d931cf7ed7..6b82365c58 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/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);