From 6cf38b62928830c4fd42422b41fdf855070eb21a Mon Sep 17 00:00:00 2001 From: Bruno Cabral Date: Sat, 13 Sep 2025 01:17:17 -0700 Subject: [PATCH 1/2] fix SDL3 gamepad detection (#5176) --- src/platforms/rcore_desktop_sdl.c | 78 ++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index f07554762..a0ddac075 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -98,7 +98,7 @@ typedef struct { SDL_GLContext glContext; SDL_GameController *gamepad[MAX_GAMEPADS]; - SDL_JoystickID gamepadId[MAX_GAMEPADS]; // Joystick instance ids + SDL_JoystickID gamepadId[MAX_GAMEPADS]; // Joystick instance ids, they do not start from 0 SDL_Cursor *cursor; bool cursorRelative; } PlatformData; @@ -1706,19 +1706,34 @@ void PollInputEvents(void) { int jid = event.jdevice.which; // Joystick device index - if (CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS)) + // check if already added at InitPlatform + for (int i = 0; i < MAX_GAMEPADS; ++i) { - platform.gamepad[jid] = SDL_GameControllerOpen(jid); - platform.gamepadId[jid] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[jid])); - - if (platform.gamepad[jid]) + if (jid == platform.gamepadId[i]) { - CORE.Input.Gamepad.ready[jid] = true; - CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[jid])); - CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; - CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; - memset(CORE.Input.Gamepad.name[jid], 0, MAX_GAMEPAD_NAME_LENGTH); - strncpy(CORE.Input.Gamepad.name[jid], SDL_GameControllerNameForIndex(jid), MAX_GAMEPAD_NAME_LENGTH - 1); + return; + } + } + + int nextAvailableSlot = 0; + while (nextAvailableSlot < MAX_GAMEPADS && CORE.Input.Gamepad.ready[nextAvailableSlot]) + { + ++nextAvailableSlot; + } + + if ((nextAvailableSlot < MAX_GAMEPADS) && !CORE.Input.Gamepad.ready[nextAvailableSlot]) + { + platform.gamepad[nextAvailableSlot] = SDL_GameControllerOpen(jid); + platform.gamepadId[nextAvailableSlot] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[nextAvailableSlot])); + + if (platform.gamepad[nextAvailableSlot]) + { + CORE.Input.Gamepad.ready[nextAvailableSlot] = true; + CORE.Input.Gamepad.axisCount[nextAvailableSlot] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[nextAvailableSlot])); + CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; + memset(CORE.Input.Gamepad.name[nextAvailableSlot], 0, MAX_GAMEPAD_NAME_LENGTH); + strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], SDL_GameControllerNameForIndex(nextAvailableSlot), MAX_GAMEPAD_NAME_LENGTH - 1); } else { @@ -1746,7 +1761,7 @@ void PollInputEvents(void) { int button = -1; - switch (event.jbutton.button) + switch (event.gbutton.button) { case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; @@ -1774,7 +1789,7 @@ void PollInputEvents(void) { for (int i = 0; i < MAX_GAMEPADS; i++) { - if (platform.gamepadId[i] == event.jbutton.which) + if (platform.gamepadId[i] == event.gbutton.which) { CORE.Input.Gamepad.currentButtonState[i][button] = 1; CORE.Input.Gamepad.lastButtonPressed = button; @@ -1787,7 +1802,7 @@ void PollInputEvents(void) { int button = -1; - switch (event.jbutton.button) + switch (event.gbutton.button) { case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; @@ -1815,7 +1830,7 @@ void PollInputEvents(void) { for (int i = 0; i < MAX_GAMEPADS; i++) { - if (platform.gamepadId[i] == event.jbutton.which) + if (platform.gamepadId[i] == event.gbutton.which) { CORE.Input.Gamepad.currentButtonState[i][button] = 0; if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; @@ -2044,21 +2059,28 @@ int InitPlatform(void) platform.gamepadId[i] = -1; // Set all gamepad initial instance ids as invalid to not conflict with instance id zero } - for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++) - { - platform.gamepad[i] = SDL_GameControllerOpen(i); - platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i])); + int numJoysticks = 0; + SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks); // array of joystick IDs, they do not start from 0 - if (platform.gamepad[i]) + if (joysticks) + { + for (int i = 0; (i < numJoysticks) && (i < MAX_GAMEPADS); i++) { - CORE.Input.Gamepad.ready[i] = true; - CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i])); - CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; - CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; - strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1); - CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0'; + platform.gamepad[i] = SDL_GameControllerOpen(joysticks[i]); + platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i])); + + if (platform.gamepad[i]) + { + CORE.Input.Gamepad.ready[i] = true; + CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i])); + CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; + strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1); + CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0'; + } + else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); } - else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); + SDL_free(joysticks); } // Disable mouse events being interpreted as touch events From bb0c78476c32bca08fd4db515bd33ea3b6dfc1f1 Mon Sep 17 00:00:00 2001 From: Bruno Cabral Date: Sat, 13 Sep 2025 01:19:44 -0700 Subject: [PATCH 2/2] [build][cmake] Fix definition to use SDL3 (#5175) * fix definition to use SDL3 * [cmake] fix definition to use SDL3 * [build][cmake] prefer USING_VERSION_SDL3 over PLATFORM_DESKTOP_SDL3 * [build][cmake] when libs are added externally, consumer needs to import them too --- cmake/LibraryConfigurations.cmake | 8 ++++++-- cmake/raylib-config.cmake | 2 ++ src/CMakeLists.txt | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake index e4655500e..c0a7e3d4b 100644 --- a/cmake/LibraryConfigurations.cmake +++ b/cmake/LibraryConfigurations.cmake @@ -7,6 +7,8 @@ if(POLICY CMP0072) cmake_policy(SET CMP0072 NEW) endif() +set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)") + if (${PLATFORM} MATCHES "Desktop") set(PLATFORM_CPP "PLATFORM_DESKTOP") @@ -120,15 +122,17 @@ elseif ("${PLATFORM}" MATCHES "SDL") find_package(SDL3 QUIET) if(SDL3_FOUND) message(STATUS "Found SDL3 via find_package()") + set(LIBS_PUBLIC SDL3::SDL3) + set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL3 REQUIRED)") set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL") - set(LIBS_PRIVATE SDL3::SDL3) add_compile_definitions(USING_SDL3_PACKAGE) else() # Fallback to SDL2 find_package(SDL2 REQUIRED) message(STATUS "Found SDL2 via find_package()") set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL") - set(LIBS_PRIVATE SDL2::SDL2) + set(LIBS_PUBLIC SDL2::SDL2) + set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL3 REQUIRED)") add_compile_definitions(USING_SDL2_PACKAGE) endif() endif() diff --git a/cmake/raylib-config.cmake b/cmake/raylib-config.cmake index f34087ccd..16e677513 100644 --- a/cmake/raylib-config.cmake +++ b/cmake/raylib-config.cmake @@ -1,2 +1,4 @@ @PACKAGE_INIT@ +@RAYLIB_DEPENDENCIES@ + include("${CMAKE_CURRENT_LIST_DIR}/raylib-targets.cmake") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b3f87016..eb37f1a8e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,7 @@ if (BUILD_SHARED_LIBS) endif () target_link_libraries(raylib PRIVATE $) +target_link_libraries(raylib PUBLIC ${LIBS_PUBLIC}) # Sets some compile time definitions for the pre-processor # If CUSTOMIZE_BUILD option is on you will not use config.h by default