Skip to content

Commit ae13e4e

Browse files
committed
sdl3: Update
1 parent b22a00f commit ae13e4e

2 files changed

Lines changed: 91 additions & 108 deletions

File tree

input/drivers_joypad/sdl3_joypad.c

Lines changed: 86 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ typedef struct _sdl3_joypad
3030
{
3131
SDL_Joystick *joypad;
3232
SDL_Gamepad *gamepad;
33-
SDL_JoystickID jid; /* 0 = Invalid ID */
33+
SDL_JoystickID jid; /* 0 = Invalid ID */
3434
unsigned num_axes;
3535
unsigned num_buttons;
3636
unsigned num_hats;
@@ -78,73 +78,89 @@ static int16_t sdl3_joypad_get_axis(sdl3_joypad_t *pad, unsigned axis)
7878
static void sdl3_joypad_connect(SDL_JoystickID jid)
7979
{
8080
int i;
81-
int slot = -1;
82-
int32_t vendor = 0;
83-
int32_t product = 0;
84-
sdl3_joypad_t *pad = NULL;
85-
bool success = false;
86-
87-
/* Find a free slot */
88-
for (i = 0; i < MAX_USERS; i++)
81+
int slot = -1;
82+
int32_t vendor = 0;
83+
int32_t product = 0;
84+
sdl3_joypad_t *pad = NULL;
85+
SDL_Gamepad *gamepad = NULL;
86+
SDL_Joystick *joypad = NULL;
87+
88+
/* Connect to the device. */
89+
if (SDL_IsGamepad(jid))
8990
{
90-
if (!sdl3_joypads[i].jid)
91+
gamepad = SDL_OpenGamepad(jid);
92+
if (gamepad)
93+
joypad = SDL_GetGamepadJoystick(gamepad);
94+
95+
if (!gamepad || !joypad)
9196
{
92-
slot = i;
93-
break;
97+
RARCH_ERR("[SDL3] Couldn't open gamepad %" SDL_PRIu32 ": %s.\n", jid, SDL_GetError());
98+
if (gamepad)
99+
SDL_CloseGamepad(gamepad);
100+
return;
94101
}
95102
}
96-
97-
if (slot < 0)
103+
else
98104
{
99-
RARCH_WARN("[SDL3] No free joypad slots for joystick %" SDL_PRIu32 ".\n", jid);
100-
return;
105+
joypad = SDL_OpenJoystick(jid);
106+
if (!joypad)
107+
{
108+
RARCH_ERR("[SDL3] Couldn't open joystick %" SDL_PRIu32 ": %s.\n", jid, SDL_GetError());
109+
return;
110+
}
101111
}
102112

103-
pad = &sdl3_joypads[slot];
104-
pad->jid = jid;
105-
106-
if (SDL_IsGamepad(jid))
113+
/* Gamepads allow restoring the player index, so re-use that for the slot if possible. */
114+
if (gamepad)
107115
{
108-
pad->gamepad = SDL_OpenGamepad(jid);
109-
if (pad->gamepad)
110-
pad->joypad = SDL_GetGamepadJoystick(pad->gamepad);
111-
success = pad->gamepad != NULL && pad->joypad != NULL;
112-
}
113-
else
114-
{
115-
pad->joypad = SDL_OpenJoystick(jid);
116-
success = pad->joypad != NULL;
116+
int player = SDL_GetGamepadPlayerIndex(gamepad);
117+
if (player >= 0 && player < MAX_USERS && !sdl3_joypads[player].jid)
118+
slot = player;
117119
}
118120

119-
if (!success)
121+
/* Fallback to the first free slot. */
122+
if (slot < 0)
120123
{
121-
RARCH_ERR("[SDL3] Couldn't open joystick #%d: %s.\n", slot, SDL_GetError());
122-
123-
if (pad->gamepad)
124-
{
125-
SDL_CloseGamepad(pad->gamepad);
126-
pad->gamepad = NULL;
127-
pad->joypad = NULL;
128-
}
129-
else if (pad->joypad)
124+
for (i = 0; i < MAX_USERS; i++)
130125
{
131-
SDL_CloseJoystick(pad->joypad);
132-
pad->joypad = NULL;
126+
if (!sdl3_joypads[i].jid)
127+
{
128+
slot = i;
129+
break;
130+
}
133131
}
132+
}
134133

135-
pad->jid = 0;
134+
/* Fail if a slot is still not found. */
135+
if (slot < 0)
136+
{
137+
RARCH_WARN("[SDL3] No free joypad slots for joystick %" SDL_PRIu32 ".\n", jid);
138+
if (gamepad)
139+
SDL_CloseGamepad(gamepad);
140+
else
141+
SDL_CloseJoystick(joypad);
136142
return;
137143
}
138144

139-
if (pad->gamepad)
145+
pad = &sdl3_joypads[slot];
146+
pad->jid = jid;
147+
pad->gamepad = gamepad;
148+
pad->joypad = joypad;
149+
150+
if (gamepad)
140151
{
141-
vendor = SDL_GetGamepadVendor(pad->gamepad);
142-
product = SDL_GetGamepadProduct(pad->gamepad);
152+
vendor = SDL_GetGamepadVendor(gamepad);
153+
product = SDL_GetGamepadProduct(gamepad);
154+
155+
/* Ensure the player index matches the slot. */
156+
if (SDL_GetGamepadPlayerIndex(gamepad) != slot) {
157+
SDL_SetGamepadPlayerIndex(gamepad, (int)slot);
158+
}
143159
}
144160
else
145161
{
146-
vendor = SDL_GetJoystickVendor(pad->joypad);
147-
product = SDL_GetJoystickProduct(pad->joypad);
162+
vendor = SDL_GetJoystickVendor(joypad);
163+
product = SDL_GetJoystickProduct(joypad);
148164
}
149165

150166
input_autoconfigure_connect(
@@ -155,7 +171,7 @@ static void sdl3_joypad_connect(SDL_JoystickID jid)
155171
vendor,
156172
product);
157173

158-
if (pad->gamepad)
174+
if (gamepad)
159175
{
160176
/* SDL_Gamepad internally supports all axis/button IDs, even if
161177
* the controller's mapping does not have a binding for it.
@@ -174,17 +190,15 @@ static void sdl3_joypad_connect(SDL_JoystickID jid)
174190
}
175191
else
176192
{
177-
pad->num_axes = SDL_GetNumJoystickAxes(pad->joypad);
178-
pad->num_buttons = SDL_GetNumJoystickButtons(pad->joypad);
179-
pad->num_hats = SDL_GetNumJoystickHats(pad->joypad);
193+
pad->num_axes = SDL_GetNumJoystickAxes(joypad);
194+
pad->num_buttons = SDL_GetNumJoystickButtons(joypad);
195+
pad->num_hats = SDL_GetNumJoystickHats(joypad);
180196
}
181197
}
182198

183199
static void sdl3_joypad_disconnect(SDL_JoystickID jid)
184200
{
185-
int i;
186-
187-
for (i = 0; i < MAX_USERS; i++)
201+
for (int i = 0; i < MAX_USERS; i++)
188202
{
189203
if (sdl3_joypads[i].jid != jid)
190204
continue;
@@ -203,9 +217,7 @@ static void sdl3_joypad_disconnect(SDL_JoystickID jid)
203217

204218
static void sdl3_joypad_destroy(void)
205219
{
206-
int i;
207-
208-
for (i = 0; i < MAX_USERS; i++)
220+
for (int i = 0; i < MAX_USERS; i++)
209221
{
210222
if (sdl3_joypads[i].gamepad)
211223
SDL_CloseGamepad(sdl3_joypads[i].gamepad);
@@ -235,28 +247,12 @@ static void *sdl3_joypad_init(void *data)
235247

236248
memset(sdl3_joypads, 0, sizeof(sdl3_joypads));
237249

238-
{
239-
SDL_JoystickID *joysticks = SDL_GetJoysticks(&count);
240-
241-
if (joysticks)
242-
{
243-
int n = count;
244-
if (n > MAX_USERS)
245-
n = MAX_USERS;
246-
247-
for (i = 0; i < n; i++)
248-
sdl3_joypad_connect(joysticks[i]);
249-
250-
SDL_free(joysticks);
251-
}
252-
}
250+
/* Joystick connected events are triggered after load, so no need to initialize them here. */
253251

254252
return (void*)-1;
255253
}
256254

257-
static int32_t sdl3_joypad_button_state(
258-
sdl3_joypad_t *pad,
259-
unsigned port, uint16_t joykey)
255+
static int32_t sdl3_joypad_button_state(sdl3_joypad_t *pad, uint16_t joykey)
260256
{
261257
unsigned hat_dir = GET_HAT_DIR(joykey);
262258

@@ -293,21 +289,16 @@ static int32_t sdl3_joypad_button_state(
293289

294290
static int32_t sdl3_joypad_button(unsigned port, uint16_t joykey)
295291
{
296-
sdl3_joypad_t *pad;
297-
298292
if (port >= MAX_USERS)
299293
return 0;
300294

301-
pad = &sdl3_joypads[port];
302-
if (!pad->joypad)
295+
if (!sdl3_joypads[port].joypad)
303296
return 0;
304297

305-
return sdl3_joypad_button_state(pad, port, joykey);
298+
return sdl3_joypad_button_state(&sdl3_joypads[port], joykey);
306299
}
307300

308-
static int16_t sdl3_joypad_axis_state(
309-
sdl3_joypad_t *pad,
310-
unsigned port, uint32_t joyaxis)
301+
static int16_t sdl3_joypad_axis_state(sdl3_joypad_t *pad, uint32_t joyaxis)
311302
{
312303
if (AXIS_NEG_GET(joyaxis) < pad->num_axes)
313304
{
@@ -332,16 +323,13 @@ static int16_t sdl3_joypad_axis_state(
332323

333324
static int16_t sdl3_joypad_axis(unsigned port, uint32_t joyaxis)
334325
{
335-
sdl3_joypad_t *pad;
336-
337326
if (port >= MAX_USERS)
338327
return 0;
339328

340-
pad = &sdl3_joypads[port];
341-
if (!pad->joypad)
329+
if (!sdl3_joypads[port].joypad)
342330
return 0;
343331

344-
return sdl3_joypad_axis_state(pad, port, joyaxis);
332+
return sdl3_joypad_axis_state(&sdl3_joypads[port], joyaxis);
345333
}
346334

347335
static int16_t sdl3_joypad_state(
@@ -371,11 +359,11 @@ static int16_t sdl3_joypad_state(
371359

372360
if (
373361
(uint16_t)joykey != NO_BTN
374-
&& sdl3_joypad_button_state(pad, port_idx, (uint16_t)joykey)
362+
&& sdl3_joypad_button_state(pad, (uint16_t)joykey)
375363
)
376364
ret |= (1 << i);
377365
else if (joyaxis != AXIS_NONE &&
378-
((float)abs(sdl3_joypad_axis_state(pad, port_idx, joyaxis))
366+
((float)abs(sdl3_joypad_axis_state(pad, joyaxis))
379367
/ 0x8000) > joypad_info->axis_threshold)
380368
ret |= (1 << i);
381369
}
@@ -450,29 +438,25 @@ static bool sdl3_joypad_set_rumble(unsigned pad,
450438
static bool sdl3_joypad_set_sensor_state(unsigned pad,
451439
enum retro_sensor_action action, unsigned rate)
452440
{
453-
sdl3_joypad_t *joypad;
454-
455441
if (pad >= MAX_USERS)
456442
return false;
457443

458-
joypad = (sdl3_joypad_t*)&sdl3_joypads[pad];
459-
460-
if (!joypad->gamepad)
444+
if (!sdl3_joypads[pad].gamepad)
461445
return false;
462446

463447
switch (action)
464448
{
465449
case RETRO_SENSOR_GYROSCOPE_ENABLE:
466450
case RETRO_SENSOR_GYROSCOPE_DISABLE:
467-
if (SDL_GamepadHasSensor(joypad->gamepad, SDL_SENSOR_GYRO))
468-
return SDL_SetGamepadSensorEnabled(joypad->gamepad, SDL_SENSOR_GYRO,
451+
if (SDL_GamepadHasSensor(sdl3_joypads[pad].gamepad, SDL_SENSOR_GYRO))
452+
return SDL_SetGamepadSensorEnabled(sdl3_joypads[pad].gamepad, SDL_SENSOR_GYRO,
469453
action == RETRO_SENSOR_GYROSCOPE_ENABLE);
470454
return false;
471455

472456
case RETRO_SENSOR_ACCELEROMETER_ENABLE:
473457
case RETRO_SENSOR_ACCELEROMETER_DISABLE:
474-
if (SDL_GamepadHasSensor(joypad->gamepad, SDL_SENSOR_ACCEL))
475-
return SDL_SetGamepadSensorEnabled(joypad->gamepad, SDL_SENSOR_ACCEL,
458+
if (SDL_GamepadHasSensor(sdl3_joypads[pad].gamepad, SDL_SENSOR_ACCEL))
459+
return SDL_SetGamepadSensorEnabled(sdl3_joypads[pad].gamepad, SDL_SENSOR_ACCEL,
476460
action == RETRO_SENSOR_ACCELEROMETER_ENABLE);
477461
return false;
478462

@@ -488,16 +472,13 @@ static bool sdl3_joypad_set_sensor_state(unsigned pad,
488472
*/
489473
static bool sdl3_joypad_get_sensor_input(unsigned pad, unsigned id, float *value)
490474
{
491-
sdl3_joypad_t *joypad;
492475
SDL_SensorType sensor_type;
493476
float sensor_data[3];
494477

495478
if (pad >= MAX_USERS)
496479
return false;
497480

498-
joypad = (sdl3_joypad_t*)&sdl3_joypads[pad];
499-
500-
if (!joypad->gamepad)
481+
if (!sdl3_joypads[pad].gamepad)
501482
return false;
502483

503484
if ((id >= RETRO_SENSOR_ACCELEROMETER_X) && (id <= RETRO_SENSOR_ACCELEROMETER_Z))
@@ -507,7 +488,7 @@ static bool sdl3_joypad_get_sensor_input(unsigned pad, unsigned id, float *value
507488
else
508489
return false;
509490

510-
if (!SDL_GetGamepadSensorData(joypad->gamepad, sensor_type, sensor_data, 3))
491+
if (!SDL_GetGamepadSensorData(sdl3_joypads[pad].gamepad, sensor_type, sensor_data, 3))
511492
return false;
512493

513494
switch (id)
@@ -558,5 +539,5 @@ input_device_driver_t sdl_joypad = {
558539
sdl3_joypad_set_sensor_state,
559540
sdl3_joypad_get_sensor_input,
560541
sdl3_joypad_name,
561-
"sdl3",
542+
"sdl3", /* TODO: Rename all the SDL Controller Drivers to "sdl"? You can't use them at the same time anyway, and it will fix autoconfigs. */
562543
};

retroarch.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,9 @@
220220
#include "ai/game_ai.h"
221221
#endif
222222

223-
#if defined(HAVE_SDL) || defined(HAVE_SDL2) || defined(HAVE_SDL_DINGUX)
223+
#if defined(HAVE_SDL3)
224+
#include <SDL3/SDL.h>
225+
#elif defined(HAVE_SDL) || defined(HAVE_SDL2) || defined(HAVE_SDL_DINGUX)
224226
#include "SDL.h"
225227
#endif
226228

@@ -5900,7 +5902,7 @@ static void global_free(struct rarch_state *p_rarch)
59005902
retroarch_override_setting_free_state();
59015903
}
59025904

5903-
#if defined(HAVE_SDL) || defined(HAVE_SDL2) || defined(HAVE_SDL_DINGUX)
5905+
#if defined(HAVE_SDL) || defined(HAVE_SDL2) || defined(HAVE_SDL_DINGUX) || defined(HAVE_SDL3)
59045906
static void sdl_exit(void)
59055907
{
59065908
/* Quit any SDL subsystems, then quit
@@ -6002,7 +6004,7 @@ void main_exit(void *args)
60026004
CoUninitialize();
60036005
#endif
60046006

6005-
#if defined(HAVE_SDL) || defined(HAVE_SDL2) || defined(HAVE_SDL_DINGUX)
6007+
#if defined(HAVE_SDL) || defined(HAVE_SDL2) || defined(HAVE_SDL_DINGUX) || defined(HAVE_SDL3)
60066008
sdl_exit();
60076009
#endif
60086010
}

0 commit comments

Comments
 (0)