From fe9799218555309867cc1b163c9cebdf2193ad3d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Mar 2020 17:35:14 -0700 Subject: [PATCH] Read the buttons on Nintendo Switch and GameCube controllers as they are labeled, and swap them if the applications wants positional button data instead. --- src/joystick/hidapi/SDL_hidapi_gamecube.c | 7 +-- src/joystick/hidapi/SDL_hidapi_switch.c | 53 ++++++++++++++--------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_gamecube.c b/src/joystick/hidapi/SDL_hidapi_gamecube.c index 6cd6659ba..7ef22b673 100644 --- a/src/joystick/hidapi/SDL_hidapi_gamecube.c +++ b/src/joystick/hidapi/SDL_hidapi_gamecube.c @@ -105,7 +105,8 @@ static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button) { - if (ctx->m_bUseButtonLabels) { + if (!ctx->m_bUseButtonLabels) { + /* Use button positions */ switch (button) { case SDL_CONTROLLER_BUTTON_B: return SDL_CONTROLLER_BUTTON_X; @@ -274,8 +275,8 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device) (curSlot[off] & flag) ? SDL_PRESSED : SDL_RELEASED \ ); READ_BUTTON(1, 0x01, 0) /* A */ - READ_BUTTON(1, 0x02, 1) /* B */ - READ_BUTTON(1, 0x04, 2) /* X */ + READ_BUTTON(1, 0x04, 1) /* B */ + READ_BUTTON(1, 0x02, 2) /* X */ READ_BUTTON(1, 0x08, 3) /* Y */ READ_BUTTON(1, 0x10, 4) /* DPAD_LEFT */ READ_BUTTON(1, 0x20, 5) /* DPAD_RIGHT */ diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 8e2565752..26f72271e 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -197,6 +197,7 @@ typedef struct { SDL_bool m_bInputOnly; SDL_bool m_bHasHomeLED; SDL_bool m_bUsingBluetooth; + SDL_bool m_bIsGameCube; SDL_bool m_bUseButtonLabels; Uint8 m_nCommandNumber; SwitchCommonOutputPacket_t m_RumblePacket; @@ -638,18 +639,30 @@ static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button) { - if (ctx->m_bUseButtonLabels) { - switch (button) { - case SDL_CONTROLLER_BUTTON_A: - return SDL_CONTROLLER_BUTTON_B; - case SDL_CONTROLLER_BUTTON_B: - return SDL_CONTROLLER_BUTTON_A; - case SDL_CONTROLLER_BUTTON_X: - return SDL_CONTROLLER_BUTTON_Y; - case SDL_CONTROLLER_BUTTON_Y: - return SDL_CONTROLLER_BUTTON_X; - default: - break; + if (!ctx->m_bUseButtonLabels) { + /* Use button positions */ + if (ctx->m_bIsGameCube) { + switch (button) { + case SDL_CONTROLLER_BUTTON_B: + return SDL_CONTROLLER_BUTTON_X; + case SDL_CONTROLLER_BUTTON_X: + return SDL_CONTROLLER_BUTTON_B; + default: + break; + } + } else { + switch (button) { + case SDL_CONTROLLER_BUTTON_A: + return SDL_CONTROLLER_BUTTON_B; + case SDL_CONTROLLER_BUTTON_B: + return SDL_CONTROLLER_BUTTON_A; + case SDL_CONTROLLER_BUTTON_X: + return SDL_CONTROLLER_BUTTON_Y; + case SDL_CONTROLLER_BUTTON_Y: + return SDL_CONTROLLER_BUTTON_X; + default: + break; + } } } return button; @@ -746,12 +759,12 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti if (IsGameCubeFormFactor(device->vendor_id, device->product_id)) { /* This is a controller shaped like a GameCube controller, with a large central A button */ - ctx->m_bUseButtonLabels = SDL_TRUE; - } else { - SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, - SDL_GameControllerButtonReportingHintChanged, ctx); + ctx->m_bIsGameCube = SDL_TRUE; } + SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + /* Initialize the joystick capabilities */ joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; @@ -814,10 +827,10 @@ static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwi if (packet->rgucButtons[0] != ctx->m_lastInputOnlyState.rgucButtons[0]) { Uint8 data = packet->rgucButtons[0]; - SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);