@@ -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)
7878static 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
183199static 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
204218static 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
294290static 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
333324static 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
347335static 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,
450438static 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 */
489473static 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};
0 commit comments