Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the SDL Joypad Input Drivery #16941

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 70 additions & 33 deletions input/drivers_joypad/sdl_joypad.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ typedef struct _sdl_joypad
#ifdef HAVE_SDL2
unsigned num_balls;
#endif
int sdl_id;
} sdl_joypad_t;

/* TODO/FIXME - static globals */
Expand All @@ -56,10 +57,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_GameControllerName(sdl_pads[pad].controller);
return SDL_JoystickNameForIndex(sdl_pads[pad].sdl_id);
#else
return SDL_JoystickName(pad);
return SDL_JoystickName(sdl_pads[pad].sdl_id);
#endif
}

Expand Down Expand Up @@ -92,9 +93,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_LOG("[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;
Expand All @@ -105,6 +124,7 @@ static void sdl_pad_connect(unsigned id)

if (SDL_IsGameController(id))
{
RARCH_LOG("[SDL_JOYPAD]: opening #%d as GameController\n", id);
pad->controller = SDL_GameControllerOpen(id);
pad->joypad = SDL_GameControllerGetJoystick(pad->controller);

Expand All @@ -113,18 +133,22 @@ static void sdl_pad_connect(unsigned id)
else
#endif
{
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);

pad->joypad = NULL;
#ifdef HAVE_SDL2
pad->controller = NULL;
#endif

return;
}
Expand All @@ -140,23 +164,29 @@ static void sdl_pad_connect(unsigned id)
product = guid_ptr[1];
#endif
#ifdef WEBOS
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: %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_LOG("[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);

Expand Down Expand Up @@ -190,13 +220,13 @@ static void sdl_pad_connect(unsigned id)
}

pad->haptic = NULL;

if (g_has_haptic)
{
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());
}

Expand All @@ -213,13 +243,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
Expand All @@ -229,26 +259,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)
Expand Down Expand Up @@ -289,14 +319,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");
Expand Down Expand Up @@ -389,7 +419,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;
}
Expand Down Expand Up @@ -435,12 +465,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);
}
Expand All @@ -461,10 +491,17 @@ static void sdl_joypad_poll(void)
switch (event.type)
{
case SDL_JOYDEVICEADDED:
RARCH_LOG("[SDL_JOYPAD] Contoller added: %d\n", event.jdevice.which);
sdl_pad_connect(event.jdevice.which);
break;
case SDL_JOYDEVICEREMOVED:
sdl_pad_disconnect(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) {
sdl_pad_disconnect(i);
break;
}
}
break;
}
}
Expand Down Expand Up @@ -507,7 +544,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;
Expand All @@ -523,7 +560,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;
Expand All @@ -537,7 +574,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;
}
Expand Down
Loading