Read the buttons on Nintendo Switch and GameCube controllers as they are labeled, and swap them if the applications wants positional button data instead.
authorSam Lantinga <slouken@libsdl.org>
Tue, 10 Mar 2020 17:35:14 -0700
changeset 1360378d0bb6f3b8f
parent 13602 e6a2558ec791
child 13604 9ef2846f0c73
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
src/joystick/hidapi/SDL_hidapi_switch.c
     1.1 --- a/src/joystick/hidapi/SDL_hidapi_gamecube.c	Tue Mar 10 16:41:42 2020 -0700
     1.2 +++ b/src/joystick/hidapi/SDL_hidapi_gamecube.c	Tue Mar 10 17:35:14 2020 -0700
     1.3 @@ -105,7 +105,8 @@
     1.4  
     1.5  static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button)
     1.6  {
     1.7 -    if (ctx->m_bUseButtonLabels) {
     1.8 +    if (!ctx->m_bUseButtonLabels) {
     1.9 +        /* Use button positions */
    1.10          switch (button) {
    1.11          case SDL_CONTROLLER_BUTTON_B:
    1.12              return SDL_CONTROLLER_BUTTON_X;
    1.13 @@ -274,8 +275,8 @@
    1.14                      (curSlot[off] & flag) ? SDL_PRESSED : SDL_RELEASED \
    1.15                  );
    1.16              READ_BUTTON(1, 0x01, 0) /* A */
    1.17 -            READ_BUTTON(1, 0x02, 1) /* B */
    1.18 -            READ_BUTTON(1, 0x04, 2) /* X */
    1.19 +            READ_BUTTON(1, 0x04, 1) /* B */
    1.20 +            READ_BUTTON(1, 0x02, 2) /* X */
    1.21              READ_BUTTON(1, 0x08, 3) /* Y */
    1.22              READ_BUTTON(1, 0x10, 4) /* DPAD_LEFT */
    1.23              READ_BUTTON(1, 0x20, 5) /* DPAD_RIGHT */
     2.1 --- a/src/joystick/hidapi/SDL_hidapi_switch.c	Tue Mar 10 16:41:42 2020 -0700
     2.2 +++ b/src/joystick/hidapi/SDL_hidapi_switch.c	Tue Mar 10 17:35:14 2020 -0700
     2.3 @@ -197,6 +197,7 @@
     2.4      SDL_bool m_bInputOnly;
     2.5      SDL_bool m_bHasHomeLED;
     2.6      SDL_bool m_bUsingBluetooth;
     2.7 +    SDL_bool m_bIsGameCube;
     2.8      SDL_bool m_bUseButtonLabels;
     2.9      Uint8 m_nCommandNumber;
    2.10      SwitchCommonOutputPacket_t m_RumblePacket;
    2.11 @@ -638,18 +639,30 @@
    2.12  
    2.13  static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)
    2.14  {
    2.15 -    if (ctx->m_bUseButtonLabels) {
    2.16 -        switch (button) {
    2.17 -        case SDL_CONTROLLER_BUTTON_A:
    2.18 -            return SDL_CONTROLLER_BUTTON_B;
    2.19 -        case SDL_CONTROLLER_BUTTON_B:
    2.20 -            return SDL_CONTROLLER_BUTTON_A;
    2.21 -        case SDL_CONTROLLER_BUTTON_X:
    2.22 -            return SDL_CONTROLLER_BUTTON_Y;
    2.23 -        case SDL_CONTROLLER_BUTTON_Y:
    2.24 -            return SDL_CONTROLLER_BUTTON_X;
    2.25 -        default:
    2.26 -            break;
    2.27 +    if (!ctx->m_bUseButtonLabels) {
    2.28 +        /* Use button positions */
    2.29 +        if (ctx->m_bIsGameCube) {
    2.30 +            switch (button) {
    2.31 +            case SDL_CONTROLLER_BUTTON_B:
    2.32 +                return SDL_CONTROLLER_BUTTON_X;
    2.33 +            case SDL_CONTROLLER_BUTTON_X:
    2.34 +                return SDL_CONTROLLER_BUTTON_B;
    2.35 +            default:
    2.36 +                break;
    2.37 +            }
    2.38 +        } else {
    2.39 +            switch (button) {
    2.40 +            case SDL_CONTROLLER_BUTTON_A:
    2.41 +                return SDL_CONTROLLER_BUTTON_B;
    2.42 +            case SDL_CONTROLLER_BUTTON_B:
    2.43 +                return SDL_CONTROLLER_BUTTON_A;
    2.44 +            case SDL_CONTROLLER_BUTTON_X:
    2.45 +                return SDL_CONTROLLER_BUTTON_Y;
    2.46 +            case SDL_CONTROLLER_BUTTON_Y:
    2.47 +                return SDL_CONTROLLER_BUTTON_X;
    2.48 +            default:
    2.49 +                break;
    2.50 +            }
    2.51          }
    2.52      }
    2.53      return button;
    2.54 @@ -746,12 +759,12 @@
    2.55  
    2.56      if (IsGameCubeFormFactor(device->vendor_id, device->product_id)) {
    2.57          /* This is a controller shaped like a GameCube controller, with a large central A button */
    2.58 -        ctx->m_bUseButtonLabels = SDL_TRUE;
    2.59 -    } else {
    2.60 -        SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
    2.61 -                            SDL_GameControllerButtonReportingHintChanged, ctx);
    2.62 +        ctx->m_bIsGameCube = SDL_TRUE;
    2.63      }
    2.64  
    2.65 +    SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
    2.66 +                        SDL_GameControllerButtonReportingHintChanged, ctx);
    2.67 +
    2.68      /* Initialize the joystick capabilities */
    2.69      joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
    2.70      joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
    2.71 @@ -814,10 +827,10 @@
    2.72  
    2.73      if (packet->rgucButtons[0] != ctx->m_lastInputOnlyState.rgucButtons[0]) {
    2.74          Uint8 data = packet->rgucButtons[0];
    2.75 -        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    2.76 -        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
    2.77 -        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
    2.78 -        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
    2.79 +        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
    2.80 +        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
    2.81 +        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
    2.82 +        SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
    2.83          SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
    2.84          SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
    2.85