From a5ace0198963188b4e8cc595e16af47370e7124d Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Tue, 18 Jan 2022 18:45:43 +0100 Subject: [PATCH 1/4] sdl_joypad: fix hotplug, order ports --- input/drivers_joypad/sdl_joypad.c | 80 +++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 21 deletions(-) diff --git a/input/drivers_joypad/sdl_joypad.c b/input/drivers_joypad/sdl_joypad.c index 1213037626a..2f7bb732263 100644 --- a/input/drivers_joypad/sdl_joypad.c +++ b/input/drivers_joypad/sdl_joypad.c @@ -40,6 +40,7 @@ typedef struct _sdl_joypad #ifdef HAVE_SDL2 unsigned num_balls; #endif + int sdl_id; } sdl_joypad_t; /* TODO/FIXME - static globals */ @@ -55,10 +56,10 @@ static const char *sdl_joypad_name(unsigned pad) #ifdef HAVE_SDL2 if (sdl_pads[pad].controller) - return SDL_GameControllerNameForIndex(pad); - return SDL_JoystickNameForIndex(pad); + return SDL_GameControllerNameForIndex(sdl_pads[pad].sdl_id); + return SDL_JoystickNameForIndex(sdl_pads[pad].sdl_id); #else - return SDL_JoystickName(pad); + return SDL_JoystickName(sdl_pads[pad].sdl_id); #endif } @@ -91,9 +92,27 @@ static int16_t sdl_pad_get_axis(sdl_joypad_t *pad, unsigned axis) return SDL_JoystickGetAxis(pad->joypad, axis); } +// id is a SDL-side id static void sdl_pad_connect(unsigned id) { - sdl_joypad_t *pad = (sdl_joypad_t*)&sdl_pads[id]; + int port_num = -1; + + for (int i = 0; i < MAX_USERS; i++) { + if (sdl_pads[i].joypad != NULL && sdl_pads[i].sdl_id == id) { + RARCH_WARN("[SDL_JOYPAD]: %d already registered on port %d\n", id, i); + return; + } + } + + for (int i = 0; i < MAX_USERS; i++) { + if (sdl_pads[i].joypad == NULL) { + RARCH_WARN("[SDL_JOYPAD]: using port: %d\n", i); + port_num = i; + break; + } + } + + sdl_joypad_t *pad = (sdl_joypad_t*)&sdl_pads[port_num]; bool success = false; int32_t product = 0; int32_t vendor = 0; @@ -104,6 +123,7 @@ static void sdl_pad_connect(unsigned id) if (SDL_IsGameController(id)) { + RARCH_WARN("[SDL_JOYSTICK]: opening #%d as GameController\n", id); pad->controller = SDL_GameControllerOpen(id); pad->joypad = SDL_GameControllerGetJoystick(pad->controller); @@ -112,6 +132,7 @@ static void sdl_pad_connect(unsigned id) else #endif { + RARCH_WARN("[SDL_JOYSTICK]: opening #%d as Joystick\n", id); pad->joypad = SDL_JoystickOpen(id); success = pad->joypad != NULL; } @@ -124,6 +145,7 @@ static void sdl_pad_connect(unsigned id) SDL_JoystickClose(pad->joypad); pad->joypad = NULL; + pad->controller = NULL; return; } @@ -139,23 +161,29 @@ static void sdl_pad_connect(unsigned id) product = guid_ptr[1]; #endif #ifdef WEBOS + RARCH_WARN("[SDL_JOYPAD] #%d: vendor: %04x; product: %04x\n", id, vendor, product); if (vendor == 0x9999 && product == 0x9999) { - RARCH_WARN("[SDL_JOYPAD]: Ignoring pad #%d (vendor: %d; product: %d)\n", id, vendor, product); - if (pad->joypad) - SDL_JoystickClose(pad->joypad); + RARCH_WARN("[SDL_JOYPAD]: Ignoring pad #%d (vendor: %04x; product: %04x)\n", id, vendor, product); + if (pad->controller) + SDL_GameControllerClose(pad->controller); pad->joypad = NULL; + pad->controller = NULL; return; } #endif #endif + pad->sdl_id = id; + + RARCH_WARN("[SDL_JOYPAD]: registering %d as port %d\n", id, port_num); + input_autoconfigure_connect( - sdl_joypad_name(id), + sdl_joypad_name(port_num), NULL, sdl_joypad.ident, - id, + port_num, vendor, product); @@ -189,7 +217,7 @@ static void sdl_pad_connect(unsigned id) } pad->haptic = NULL; - + if (g_has_haptic) { pad->haptic = SDL_HapticOpenFromJoystick(pad->joypad); @@ -222,26 +250,26 @@ static void sdl_pad_connect(unsigned id) #endif } -static void sdl_pad_disconnect(unsigned id) +static void sdl_pad_disconnect(unsigned port_num) { #ifdef HAVE_SDL2 - if (sdl_pads[id].haptic) - SDL_HapticClose(sdl_pads[id].haptic); + if (sdl_pads[port_num].haptic) + SDL_HapticClose(sdl_pads[port_num].haptic); - if (sdl_pads[id].controller) + if (sdl_pads[port_num].controller) { - SDL_GameControllerClose(sdl_pads[id].controller); - input_autoconfigure_disconnect(id, sdl_joypad.ident); + SDL_GameControllerClose(sdl_pads[port_num].controller); + input_autoconfigure_disconnect(port_num, sdl_joypad.ident); } else #endif - if (sdl_pads[id].joypad) + if (sdl_pads[port_num].joypad) { - SDL_JoystickClose(sdl_pads[id].joypad); - input_autoconfigure_disconnect(id, sdl_joypad.ident); + SDL_JoystickClose(sdl_pads[port_num].joypad); + input_autoconfigure_disconnect(port_num, sdl_joypad.ident); } - memset(&sdl_pads[id], 0, sizeof(sdl_pads[id])); + memset(&sdl_pads[port_num], 0, sizeof(sdl_pads[port_num])); } static void sdl_joypad_destroy(void) @@ -447,10 +475,20 @@ static void sdl_joypad_poll(void) switch (event.type) { case SDL_JOYDEVICEADDED: + RARCH_WARN("[SDL_JOYPAD] hotplug added: %d\n", event.jdevice.which); sdl_pad_connect(event.jdevice.which); break; case SDL_JOYDEVICEREMOVED: - sdl_pad_disconnect(event.jdevice.which); + RARCH_WARN("[SDL_JOYPAD] hotplug removed: %d\n", event.jdevice.which); + + for (int i = 0 ; i < MAX_USERS ; i++) { + if (SDL_JoystickInstanceID(sdl_pads[i].joypad) == event.jdevice.which) { + RARCH_WARN("Found joystick: %d\n", i); + sdl_pad_disconnect(i); + break; + } + } + break; } } From 62cbb8b8ca418f37d99963ab027f484e12110dc6 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 29 Aug 2024 23:07:38 -0400 Subject: [PATCH 2/4] Update warnings for SDL_JOYPAD --- input/drivers_joypad/sdl_joypad.c | 41 ++++++++++++++----------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/input/drivers_joypad/sdl_joypad.c b/input/drivers_joypad/sdl_joypad.c index f7f1aabfc53..d1d2630c2f5 100644 --- a/input/drivers_joypad/sdl_joypad.c +++ b/input/drivers_joypad/sdl_joypad.c @@ -107,7 +107,7 @@ static void sdl_pad_connect(unsigned id) for (int i = 0; i < MAX_USERS; i++) { if (sdl_pads[i].joypad == NULL) { - RARCH_WARN("[SDL_JOYPAD]: using port: %d\n", i); + RARCH_LOG("[SDL_JOYPAD]: using port: %d\n", i); port_num = i; break; } @@ -124,7 +124,7 @@ static void sdl_pad_connect(unsigned id) if (SDL_IsGameController(id)) { - RARCH_WARN("[SDL_JOYSTICK]: opening #%d as GameController\n", id); + RARCH_LOG("[SDL_JOYPAD]: opening #%d as GameController\n", id); pad->controller = SDL_GameControllerOpen(id); pad->joypad = SDL_GameControllerGetJoystick(pad->controller); @@ -133,14 +133,14 @@ static void sdl_pad_connect(unsigned id) else #endif { - RARCH_WARN("[SDL_JOYSTICK]: opening #%d as Joystick\n", id); + RARCH_LOG("[SDL_JOYPAD]: opening #%d as Joystick\n", id); pad->joypad = SDL_JoystickOpen(id); success = pad->joypad != NULL; } if (!success) { - RARCH_ERR("[SDL]: Couldn't open joystick #%u: %s.\n", id, SDL_GetError()); + RARCH_WARN("[SDL_JOYPAD]: Couldn't open joystick #%u: %s.\n", id, SDL_GetError()); if (pad->joypad) SDL_JoystickClose(pad->joypad); @@ -162,7 +162,7 @@ static void sdl_pad_connect(unsigned id) product = guid_ptr[1]; #endif #ifdef WEBOS - RARCH_WARN("[SDL_JOYPAD] #%d: vendor: %04x; product: %04x\n", id, vendor, product); + RARCH_LOG("[SDL_JOYPAD] #%d: vendor: %04x; product: %04x\n", id, vendor, product); if (vendor == 0x9999 && product == 0x9999) { RARCH_WARN("[SDL_JOYPAD]: Ignoring pad #%d (vendor: %04x; product: %04x)\n", id, vendor, product); @@ -178,7 +178,7 @@ static void sdl_pad_connect(unsigned id) pad->sdl_id = id; - RARCH_WARN("[SDL_JOYPAD]: registering %d as port %d\n", id, port_num); + RARCH_LOG("[SDL_JOYPAD]: registering %d as port %d\n", id, port_num); input_autoconfigure_connect( sdl_joypad_name(port_num), @@ -224,7 +224,7 @@ static void sdl_pad_connect(unsigned id) pad->haptic = SDL_HapticOpenFromJoystick(pad->joypad); if (!pad->haptic) - RARCH_WARN("[SDL]: Couldn't open haptic device of the joypad #%u: %s\n", + RARCH_WARN("[SDL_JOYPAD]: Couldn't open haptic device of the joypad #%u: %s\n", id, SDL_GetError()); } @@ -241,13 +241,13 @@ static void sdl_pad_connect(unsigned id) if (SDL_HapticEffectSupported(pad->haptic, &efx) == SDL_FALSE) { pad->rumble_effect = -2; - RARCH_WARN("[SDL]: Device #%u does not support leftright haptic effect.\n", id); + RARCH_WARN("[SDL_JOYPAD]: Device #%u does not support leftright haptic effect.\n", id); } } #if SDL_VERSION_ATLEAST(2, 0, 9) if (!pad->haptic || pad->rumble_effect == -2) { pad->rumble_effect = -3; - RARCH_LOG("[SDL]: Falling back to joystick rumble\n"); + RARCH_LOG("[SDL_JOYPAD]: Falling back to joystick rumble\n"); } #endif #else @@ -317,14 +317,14 @@ static void *sdl_joypad_init(void *data) if ((sdl_subsystem_flags & SDL_INIT_HAPTIC) == 0) { if (SDL_InitSubSystem(SDL_INIT_HAPTIC) < 0) - RARCH_WARN("[SDL]: Failed to initialize haptic device support: %s\n", + RARCH_WARN("[SDL_JOYPAD]: Failed to initialize haptic device support: %s\n", SDL_GetError()); else g_has_haptic = true; } else g_has_haptic = true; - + #if SDL_VERSION_ATLEAST(2, 0, 9) /* enable extended hid reports to support ps4/ps5 rumble over bluetooth */ SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); @@ -417,7 +417,7 @@ static int16_t sdl_joypad_axis_state( if (val < 0) { /* Clamp - -0x8000 can cause trouble if we later abs() it. */ - if (val < -0x7fff) + if (val < -0x7fff) return -0x7fff; return val; } @@ -463,12 +463,12 @@ static int16_t sdl_joypad_state( const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; if ( - (uint16_t)joykey != NO_BTN + (uint16_t)joykey != NO_BTN && sdl_joypad_button_state(pad, port_idx, (uint16_t)joykey) ) ret |= ( 1 << i); else if (joyaxis != AXIS_NONE && - ((float)abs(sdl_joypad_axis_state(pad, port_idx, joyaxis)) + ((float)abs(sdl_joypad_axis_state(pad, port_idx, joyaxis)) / 0x8000) > joypad_info->axis_threshold) ret |= (1 << i); } @@ -489,20 +489,17 @@ static void sdl_joypad_poll(void) switch (event.type) { case SDL_JOYDEVICEADDED: - RARCH_WARN("[SDL_JOYPAD] hotplug added: %d\n", event.jdevice.which); + RARCH_LOG("[SDL_JOYPAD] Contoller added: %d\n", event.jdevice.which); sdl_pad_connect(event.jdevice.which); break; case SDL_JOYDEVICEREMOVED: - RARCH_WARN("[SDL_JOYPAD] hotplug removed: %d\n", event.jdevice.which); - + RARCH_LOG("[SDL_JOYPAD] Contoller removed: %d\n", event.jdevice.which); for (int i = 0 ; i < MAX_USERS ; i++) { if (SDL_JoystickInstanceID(sdl_pads[i].joypad) == event.jdevice.which) { - RARCH_WARN("Found joystick: %d\n", i); sdl_pad_disconnect(i); break; } } - break; } } @@ -545,7 +542,7 @@ static bool sdl_joypad_set_rumble(unsigned pad, enum retro_rumble_effect effect, { if (SDL_JoystickRumble(joypad->joypad, efx.leftright.large_magnitude, efx.leftright.small_magnitude, efx.leftright.length) == -1) { - RARCH_WARN("[SDL]: Failed to rumble joypad %u: %s\n", + RARCH_WARN("[SDL_JOYPAD]: Failed to rumble joypad %u: %s\n", pad, SDL_GetError()); joypad->rumble_effect = -2; return false; @@ -561,7 +558,7 @@ static bool sdl_joypad_set_rumble(unsigned pad, enum retro_rumble_effect effect, joypad->rumble_effect = SDL_HapticNewEffect(joypad->haptic, &efx); if (joypad->rumble_effect < 0) { - RARCH_WARN("[SDL]: Failed to create rumble effect for joypad %u: %s\n", + RARCH_WARN("[SDL_JOYPAD]: Failed to create rumble effect for joypad %u: %s\n", pad, SDL_GetError()); joypad->rumble_effect = -2; return false; @@ -575,7 +572,7 @@ static bool sdl_joypad_set_rumble(unsigned pad, enum retro_rumble_effect effect, if (SDL_HapticRunEffect(joypad->haptic, joypad->rumble_effect, 1) < 0) { - RARCH_WARN("[SDL]: Failed to set rumble effect on joypad %u: %s\n", + RARCH_WARN("[SDL_JOYPAD]: Failed to set rumble effect on joypad %u: %s\n", pad, SDL_GetError()); return false; } From 0d10ae11f0bcb6e10f4b206a67908d4bc03ffc4b Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 29 Aug 2024 23:12:23 -0400 Subject: [PATCH 3/4] Fix logic --- input/drivers_joypad/sdl_joypad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/drivers_joypad/sdl_joypad.c b/input/drivers_joypad/sdl_joypad.c index d1d2630c2f5..2d3fc668db8 100644 --- a/input/drivers_joypad/sdl_joypad.c +++ b/input/drivers_joypad/sdl_joypad.c @@ -57,7 +57,7 @@ static const char *sdl_joypad_name(unsigned pad) #ifdef HAVE_SDL2 if (sdl_pads[pad].controller) - return SDL_GameControllerNameForIndex(sdl_pads[pad].sdl_id); + return SDL_GameControllerName(sdl_pads[pad].controller); return SDL_JoystickNameForIndex(sdl_pads[pad].sdl_id); #else return SDL_JoystickName(sdl_pads[pad].sdl_id); From 7ca0939f86a5f5f270292df0d70a8e646adbfd71 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 29 Aug 2024 23:15:10 -0400 Subject: [PATCH 4/4] Only null out the controller if HAVE_SDL2 --- input/drivers_joypad/sdl_joypad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/input/drivers_joypad/sdl_joypad.c b/input/drivers_joypad/sdl_joypad.c index 2d3fc668db8..b448fccaec9 100644 --- a/input/drivers_joypad/sdl_joypad.c +++ b/input/drivers_joypad/sdl_joypad.c @@ -146,7 +146,9 @@ static void sdl_pad_connect(unsigned id) SDL_JoystickClose(pad->joypad); pad->joypad = NULL; +#ifdef HAVE_SDL2 pad->controller = NULL; +#endif return; }