From 8397e1fcc0d59a02924bd554bd73f3c31008dc4b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 6 Feb 2025 09:21:52 -0800 Subject: [PATCH] Fix up SDL2 style mappings for HIDAPI controllers Fixes https://github.com/libsdl-org/sdl2-compat/issues/316 --- src/joystick/SDL_gamepad.c | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index d931ed23a3..2efa9c305e 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -1393,6 +1393,55 @@ static void SDL_UpdateGamepadFaceStyle(SDL_Gamepad *gamepad) } } +static void SDL_FixupHIDAPIMapping(SDL_Gamepad *gamepad) +{ + // Check to see if we need fixup + for (int i = 0; i < gamepad->num_bindings; ++i) { + SDL_GamepadBinding *binding = &gamepad->bindings[i]; + if (binding->output_type == SDL_GAMEPAD_BINDTYPE_BUTTON && + binding->output.button == SDL_GAMEPAD_BUTTON_DPAD_UP) { + if (binding->input_type != SDL_GAMEPAD_BINDTYPE_BUTTON || + binding->input.button != SDL_GAMEPAD_BUTTON_DPAD_UP) { + // New style binding + return; + } + } + } + + for (int i = 0; i < gamepad->num_bindings; ++i) { + SDL_GamepadBinding *binding = &gamepad->bindings[i]; + if (binding->input_type == SDL_GAMEPAD_BINDTYPE_BUTTON && + binding->output_type == SDL_GAMEPAD_BINDTYPE_BUTTON) { + switch (binding->output.button) { + case SDL_GAMEPAD_BUTTON_DPAD_UP: + binding->input_type = SDL_GAMEPAD_BINDTYPE_HAT; + binding->input.hat.hat = 0; + binding->input.hat.hat_mask = SDL_HAT_UP; + break; + case SDL_GAMEPAD_BUTTON_DPAD_DOWN: + binding->input_type = SDL_GAMEPAD_BINDTYPE_HAT; + binding->input.hat.hat = 0; + binding->input.hat.hat_mask = SDL_HAT_DOWN; + break; + case SDL_GAMEPAD_BUTTON_DPAD_LEFT: + binding->input_type = SDL_GAMEPAD_BINDTYPE_HAT; + binding->input.hat.hat = 0; + binding->input.hat.hat_mask = SDL_HAT_LEFT; + break; + case SDL_GAMEPAD_BUTTON_DPAD_RIGHT: + binding->input_type = SDL_GAMEPAD_BINDTYPE_HAT; + binding->input.hat.hat = 0; + binding->input.hat.hat_mask = SDL_HAT_RIGHT; + break; + default: + if (binding->output.button > SDL_GAMEPAD_BUTTON_DPAD_RIGHT) { + binding->input.button -= 4; + } + break; + } + } + } +} /* * Make a new button mapping struct @@ -1415,6 +1464,10 @@ static void SDL_PrivateLoadButtonMapping(SDL_Gamepad *gamepad, GamepadMapping_t SDL_PrivateParseGamepadConfigString(gamepad, pGamepadMapping->mapping); + if (SDL_IsJoystickHIDAPI(pGamepadMapping->guid)) { + SDL_FixupHIDAPIMapping(gamepad); + } + // Set the zero point for triggers for (i = 0; i < gamepad->num_bindings; ++i) { SDL_GamepadBinding *binding = &gamepad->bindings[i];