Skip to content

Commit 6cf38b6

Browse files
authored
fix SDL3 gamepad detection (#5176)
1 parent 8d48a12 commit 6cf38b6

File tree

1 file changed

+49
-27
lines changed

1 file changed

+49
-27
lines changed

src/platforms/rcore_desktop_sdl.c

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ typedef struct {
9898
SDL_GLContext glContext;
9999

100100
SDL_GameController *gamepad[MAX_GAMEPADS];
101-
SDL_JoystickID gamepadId[MAX_GAMEPADS]; // Joystick instance ids
101+
SDL_JoystickID gamepadId[MAX_GAMEPADS]; // Joystick instance ids, they do not start from 0
102102
SDL_Cursor *cursor;
103103
bool cursorRelative;
104104
} PlatformData;
@@ -1706,19 +1706,34 @@ void PollInputEvents(void)
17061706
{
17071707
int jid = event.jdevice.which; // Joystick device index
17081708

1709-
if (CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS))
1709+
// check if already added at InitPlatform
1710+
for (int i = 0; i < MAX_GAMEPADS; ++i)
17101711
{
1711-
platform.gamepad[jid] = SDL_GameControllerOpen(jid);
1712-
platform.gamepadId[jid] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[jid]));
1712+
if (jid == platform.gamepadId[i])
1713+
{
1714+
return;
1715+
}
1716+
}
17131717

1714-
if (platform.gamepad[jid])
1718+
int nextAvailableSlot = 0;
1719+
while (nextAvailableSlot < MAX_GAMEPADS && CORE.Input.Gamepad.ready[nextAvailableSlot])
1720+
{
1721+
++nextAvailableSlot;
1722+
}
1723+
1724+
if ((nextAvailableSlot < MAX_GAMEPADS) && !CORE.Input.Gamepad.ready[nextAvailableSlot])
1725+
{
1726+
platform.gamepad[nextAvailableSlot] = SDL_GameControllerOpen(jid);
1727+
platform.gamepadId[nextAvailableSlot] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[nextAvailableSlot]));
1728+
1729+
if (platform.gamepad[nextAvailableSlot])
17151730
{
1716-
CORE.Input.Gamepad.ready[jid] = true;
1717-
CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[jid]));
1718-
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
1719-
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
1720-
memset(CORE.Input.Gamepad.name[jid], 0, MAX_GAMEPAD_NAME_LENGTH);
1721-
strncpy(CORE.Input.Gamepad.name[jid], SDL_GameControllerNameForIndex(jid), MAX_GAMEPAD_NAME_LENGTH - 1);
1731+
CORE.Input.Gamepad.ready[nextAvailableSlot] = true;
1732+
CORE.Input.Gamepad.axisCount[nextAvailableSlot] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[nextAvailableSlot]));
1733+
CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
1734+
CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
1735+
memset(CORE.Input.Gamepad.name[nextAvailableSlot], 0, MAX_GAMEPAD_NAME_LENGTH);
1736+
strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], SDL_GameControllerNameForIndex(nextAvailableSlot), MAX_GAMEPAD_NAME_LENGTH - 1);
17221737
}
17231738
else
17241739
{
@@ -1746,7 +1761,7 @@ void PollInputEvents(void)
17461761
{
17471762
int button = -1;
17481763

1749-
switch (event.jbutton.button)
1764+
switch (event.gbutton.button)
17501765
{
17511766
case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
17521767
case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
@@ -1774,7 +1789,7 @@ void PollInputEvents(void)
17741789
{
17751790
for (int i = 0; i < MAX_GAMEPADS; i++)
17761791
{
1777-
if (platform.gamepadId[i] == event.jbutton.which)
1792+
if (platform.gamepadId[i] == event.gbutton.which)
17781793
{
17791794
CORE.Input.Gamepad.currentButtonState[i][button] = 1;
17801795
CORE.Input.Gamepad.lastButtonPressed = button;
@@ -1787,7 +1802,7 @@ void PollInputEvents(void)
17871802
{
17881803
int button = -1;
17891804

1790-
switch (event.jbutton.button)
1805+
switch (event.gbutton.button)
17911806
{
17921807
case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
17931808
case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
@@ -1815,7 +1830,7 @@ void PollInputEvents(void)
18151830
{
18161831
for (int i = 0; i < MAX_GAMEPADS; i++)
18171832
{
1818-
if (platform.gamepadId[i] == event.jbutton.which)
1833+
if (platform.gamepadId[i] == event.gbutton.which)
18191834
{
18201835
CORE.Input.Gamepad.currentButtonState[i][button] = 0;
18211836
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
@@ -2044,21 +2059,28 @@ int InitPlatform(void)
20442059
platform.gamepadId[i] = -1; // Set all gamepad initial instance ids as invalid to not conflict with instance id zero
20452060
}
20462061

2047-
for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++)
2048-
{
2049-
platform.gamepad[i] = SDL_GameControllerOpen(i);
2050-
platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i]));
2062+
int numJoysticks = 0;
2063+
SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks); // array of joystick IDs, they do not start from 0
20512064

2052-
if (platform.gamepad[i])
2065+
if (joysticks)
2066+
{
2067+
for (int i = 0; (i < numJoysticks) && (i < MAX_GAMEPADS); i++)
20532068
{
2054-
CORE.Input.Gamepad.ready[i] = true;
2055-
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i]));
2056-
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
2057-
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
2058-
strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1);
2059-
CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0';
2069+
platform.gamepad[i] = SDL_GameControllerOpen(joysticks[i]);
2070+
platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i]));
2071+
2072+
if (platform.gamepad[i])
2073+
{
2074+
CORE.Input.Gamepad.ready[i] = true;
2075+
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i]));
2076+
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
2077+
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
2078+
strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1);
2079+
CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0';
2080+
}
2081+
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
20602082
}
2061-
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
2083+
SDL_free(joysticks);
20622084
}
20632085

20642086
// Disable mouse events being interpreted as touch events

0 commit comments

Comments
 (0)