SDL: switch2: Use report ID 5 for all controllers

From 82374b47784d73d705bd2398ee38ed3b1ac4c22f Mon Sep 17 00:00:00 2001
From: Vicki Pfau <[EMAIL REDACTED]>
Date: Tue, 14 Oct 2025 19:46:00 -0700
Subject: [PATCH] switch2: Use report ID 5 for all controllers

---
 src/joystick/SDL_gamepad.c               |   6 +-
 src/joystick/hidapi/SDL_hidapi_switch2.c | 249 ++++++++++++-----------
 2 files changed, 132 insertions(+), 123 deletions(-)

diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c
index 4f56cf752d182..826d0020f4043 100644
--- a/src/joystick/SDL_gamepad.c
+++ b/src/joystick/SDL_gamepad.c
@@ -1128,7 +1128,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
         SDL_strlcat(mapping_string, "a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,misc3:b11,misc4:b10,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
     } else if (vendor == USB_VENDOR_NINTENDO &&
                product == USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER) {
-        SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,rightx:a2,righty:a3,start:b5,x:b2,y:b3,misc1:b8,misc2:b9,misc3:b10,misc4:b11,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
+        SDL_strlcat(mapping_string, "a:b1,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,rightx:a2,righty:a3,start:b5,x:b0,y:b2,misc1:b8,misc2:b9,misc3:b10,misc4:b11,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
     } else if (vendor == USB_VENDOR_NINTENDO &&
                product == USB_PRODUCT_NINTENDO_SWITCH2_PRO) {
         SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,misc1:b11,misc2:b12,paddle1:b13,paddle2:b14,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
@@ -1139,7 +1139,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
             SDL_strlcat(mapping_string, "back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle2:b14,paddle4:b16,", sizeof(mapping_string));
         } else {
             // Mini gamepad mode
-            SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,paddle2:b14,paddle4:b16,", sizeof(mapping_string));
+            SDL_strlcat(mapping_string, "a:b1,b:b2,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b0,paddle2:b14,paddle4:b16,", sizeof(mapping_string));
         }
     } else if (vendor == USB_VENDOR_NINTENDO &&
                product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT) {
@@ -1148,7 +1148,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
             SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,misc2:b12,paddle1:b13,paddle3:b15,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
         } else {
             // Mini gamepad mode
-            SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,misc2:b12,paddle1:b13,paddle3:b15,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
+            SDL_strlcat(mapping_string, "a:b1,b:b3,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b0,y:b2,misc2:b12,paddle1:b13,paddle3:b15,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
         }
     } else if (vendor == USB_VENDOR_NINTENDO &&
                product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_PAIR) {
diff --git a/src/joystick/hidapi/SDL_hidapi_switch2.c b/src/joystick/hidapi/SDL_hidapi_switch2.c
index f978e3e119cd7..99e5f9fe48362 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch2.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch2.c
@@ -372,6 +372,10 @@ static bool HIDAPI_DriverSwitch2_InitUSB(SDL_HIDAPI_Device *device)
         (Uint8[]) { // Enable rumble
             0x01, 0x91, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,
         },
+        (Uint8[]) { // Set report format
+            0x03, 0x91, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00,
+            0x05, 0x00, 0x00, 0x00
+        },
         (Uint8[]) { // Start output
             0x03, 0x91, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00,
             0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -604,41 +608,42 @@ static bool HIDAPI_DriverSwitch2_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *de
 
 static void HandleGameCubeState(Uint64 timestamp, SDL_Joystick *joystick, SDL_DriverSwitch2_Context *ctx, Uint8 *data, int size)
 {
-    if (data[3] != ctx->last_state[3]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[3] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[3] & 0x02) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[3] & 0x04) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[3] & 0x08) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_TRIGGER, ((data[3] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_SHOULDER, ((data[3] & 0x20) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_START, ((data[3] & 0x40) != 0));
+
+    if (data[5] != ctx->last_state[5]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_TRIGGER, ((data[5] & 0x40) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_RIGHT_SHOULDER, ((data[5] & 0x80) != 0));
+    }
+
+    if (data[6] != ctx->last_state[6]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_START, ((data[6] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_GUIDE, ((data[6] & 0x10) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_SHARE, ((data[6] & 0x20) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_C, ((data[6] & 0x40) != 0));
     }
 
-    if (data[4] != ctx->last_state[4]) {
+    if (data[7] != ctx->last_state[7]) {
         Uint8 hat = 0;
 
-        if (data[4] & 0x01) {
+        if (data[7] & 0x01) {
             hat |= SDL_HAT_DOWN;
         }
-        if (data[4] & 0x02) {
+        if (data[7] & 0x02) {
+            hat |= SDL_HAT_UP;
+        }
+        if (data[7] & 0x04) {
             hat |= SDL_HAT_RIGHT;
         }
-        if (data[4] & 0x04) {
+        if (data[7] & 0x08) {
             hat |= SDL_HAT_LEFT;
         }
-        if (data[4] & 0x08) {
-            hat |= SDL_HAT_UP;
-        }
         SDL_SendJoystickHat(timestamp, joystick, 0, hat);
 
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_TRIGGER, ((data[4] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_SHOULDER, ((data[4] & 0x20) != 0));
-    }
-
-    if (data[5] != ctx->last_state[5]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_GUIDE, ((data[5] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_SHARE, ((data[5] & 0x02) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_C, ((data[5] & 0x10) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_TRIGGER, ((data[7] & 0x40) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_GAMECUBE_LEFT_SHOULDER, ((data[7] & 0x80) != 0));
     }
 
     MapTriggerAxis(
@@ -646,14 +651,14 @@ static void HandleGameCubeState(Uint64 timestamp, SDL_Joystick *joystick, SDL_Dr
         joystick,
         SDL_GAMEPAD_AXIS_LEFT_TRIGGER,
         ctx->left_trigger_zero,
-        data[13]
+        data[61]
     );
     MapTriggerAxis(
         timestamp,
         joystick,
         SDL_GAMEPAD_AXIS_RIGHT_TRIGGER,
         ctx->right_trigger_zero,
-        data[14]
+        data[62]
     );
 
     MapJoystickAxis(
@@ -661,7 +666,7 @@ static void HandleGameCubeState(Uint64 timestamp, SDL_Joystick *joystick, SDL_Dr
         joystick,
         SDL_GAMEPAD_AXIS_LEFTX,
         &ctx->left_stick.x,
-        (float) (data[6] | ((data[7] & 0x0F) << 8)),
+        (float) (data[11] | ((data[12] & 0x0F) << 8)),
         false
     );
     MapJoystickAxis(
@@ -669,7 +674,7 @@ static void HandleGameCubeState(Uint64 timestamp, SDL_Joystick *joystick, SDL_Dr
         joystick,
         SDL_GAMEPAD_AXIS_LEFTY,
         &ctx->left_stick.y,
-        (float) ((data[7] >> 4) | (data[8] << 4)),
+        (float) ((data[12] >> 4) | (data[13] << 4)),
         true
     );
     MapJoystickAxis(
@@ -677,7 +682,7 @@ static void HandleGameCubeState(Uint64 timestamp, SDL_Joystick *joystick, SDL_Dr
         joystick,
         SDL_GAMEPAD_AXIS_RIGHTX,
         &ctx->right_stick.x,
-        (float) (data[9] | ((data[10] & 0x0F) << 8)),
+        (float) (data[14] | ((data[15] & 0x0F) << 8)),
         false
     );
     MapJoystickAxis(
@@ -685,7 +690,7 @@ static void HandleGameCubeState(Uint64 timestamp, SDL_Joystick *joystick, SDL_Dr
         joystick,
         SDL_GAMEPAD_AXIS_RIGHTY,
         &ctx->right_stick.y,
-        (float)((data[10] >> 4) | (data[11] << 4)),
+        (float)((data[15] >> 4) | (data[16] << 4)),
         true
     );
 }
@@ -694,33 +699,33 @@ static void HandleCombinedControllerStateL(Uint64 timestamp, SDL_Joystick *joyst
 {
     // FIXME: When we find out what the SL and SR buttons are, map them to paddles
 
-    if (data[3] != ctx->last_state[3]) {
+    if (data[6] != ctx->last_state[6]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[6] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_SHARE, ((data[6] & 0x20) != 0));
+    }
+
+    if (data[7] != ctx->last_state[7]) {
         Uint8 hat = 0;
 
-        if (data[3] & 0x01) {
+        if (data[7] & 0x01) {
             hat |= SDL_HAT_DOWN;
         }
-        if (data[3] & 0x02) {
+        if (data[7] & 0x02) {
+            hat |= SDL_HAT_UP;
+        }
+        if (data[7] & 0x04) {
             hat |= SDL_HAT_RIGHT;
         }
-        if (data[3] & 0x04) {
+        if (data[7] & 0x08) {
             hat |= SDL_HAT_LEFT;
         }
-        if (data[3] & 0x08) {
-            hat |= SDL_HAT_UP;
-        }
         SDL_SendJoystickHat(timestamp, joystick, 0, hat);
 
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[3] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[3] & 0x40) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[3] & 0x80) != 0));
-    }
-
-    if (data[4] != ctx->last_state[4]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_SHARE, ((data[4] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[7] & 0x40) != 0));
     }
 
-    Sint16 axis = (data[3] & 0x20) ? 32767 : -32768;
+    Sint16 axis = (data[7] & 0x80) ? 32767 : -32768;
     SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
 
     MapJoystickAxis(
@@ -728,7 +733,7 @@ static void HandleCombinedControllerStateL(Uint64 timestamp, SDL_Joystick *joyst
         joystick,
         SDL_GAMEPAD_AXIS_LEFTX,
         &ctx->left_stick.x,
-        (float) (data[6] | ((data[7] & 0x0F) << 8)),
+        (float) (data[11] | ((data[12] & 0x0F) << 8)),
         false
     );
     MapJoystickAxis(
@@ -736,7 +741,7 @@ static void HandleCombinedControllerStateL(Uint64 timestamp, SDL_Joystick *joyst
         joystick,
         SDL_GAMEPAD_AXIS_LEFTY,
         &ctx->left_stick.y,
-        (float) ((data[7] >> 4) | (data[8] << 4)),
+        (float) ((data[12] >> 4) | (data[13] << 4)),
         true
     );
 }
@@ -745,19 +750,20 @@ static void HandleMiniControllerStateL(Uint64 timestamp, SDL_Joystick *joystick,
 {
     // FIXME: When we find out what the SL and SR buttons are, map them to shoulder buttons
 
-    if (data[3] != ctx->last_state[3]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[3] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[3] & 0x02) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[3] & 0x04) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[3] & 0x08) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[3] & 0x40) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE1, ((data[3] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE2, ((data[3] & 0x20) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[3] & 0x80) != 0));
+    if (data[6] != ctx->last_state[6]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x20) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_SHARE, ((data[6] & 0x10) != 0));
     }
 
-    if (data[4] != ctx->last_state[4]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[4] & 0x01) != 0));
+    if (data[7] != ctx->last_state[7]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[7] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[7] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[7] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[7] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE1, ((data[7] & 0x40) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_LEFT_PADDLE2, ((data[7] & 0x80) != 0));
     }
 
     MapJoystickAxis(
@@ -765,7 +771,7 @@ static void HandleMiniControllerStateL(Uint64 timestamp, SDL_Joystick *joystick,
         joystick,
         SDL_GAMEPAD_AXIS_LEFTX,
         &ctx->left_stick.y,
-        (float) ((data[7] >> 4) | (data[8] << 4)),
+        (float) ((data[12] >> 4) | (data[13] << 4)),
         true
     );
     MapJoystickAxis(
@@ -773,7 +779,7 @@ static void HandleMiniControllerStateL(Uint64 timestamp, SDL_Joystick *joystick,
         joystick,
         SDL_GAMEPAD_AXIS_LEFTY,
         &ctx->left_stick.x,
-        (float) (data[6] | ((data[7] & 0x0F) << 8)),
+        (float) (data[11] | ((data[12] & 0x0F) << 8)),
         true
     );
 }
@@ -782,22 +788,22 @@ static void HandleCombinedControllerStateR(Uint64 timestamp, SDL_Joystick *joyst
 {
     // FIXME: When we find out what the SL and SR buttons are, map them to paddles
 
-    if (data[3] != ctx->last_state[3]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[3] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[3] & 0x02) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[3] & 0x04) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[3] & 0x08) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[3] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[3] & 0x40) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[3] & 0x80) != 0));
+    if (data[5] != ctx->last_state[5]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[5] & 0x40) != 0));
     }
 
-    if (data[4] != ctx->last_state[4]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[4] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_C, ((data[4] & 0x10) != 0));
+    if (data[6] != ctx->last_state[6]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[6] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x10) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_C, ((data[6] & 0x40) != 0));
     }
 
-    Sint16 axis = (data[3] & 0x20) ? 32767 : -32768;
+    Sint16 axis = (data[5] & 0x80) ? 32767 : -32768;
     SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis);
 
     MapJoystickAxis(
@@ -805,7 +811,7 @@ static void HandleCombinedControllerStateR(Uint64 timestamp, SDL_Joystick *joyst
         joystick,
         SDL_GAMEPAD_AXIS_RIGHTX,
         &ctx->left_stick.x,
-        (float) (data[6] | ((data[7] & 0x0F) << 8)),
+        (float) (data[14] | ((data[15] & 0x0F) << 8)),
         false
     );
     MapJoystickAxis(
@@ -813,7 +819,7 @@ static void HandleCombinedControllerStateR(Uint64 timestamp, SDL_Joystick *joyst
         joystick,
         SDL_GAMEPAD_AXIS_RIGHTY,
         &ctx->left_stick.y,
-        (float) ((data[7] >> 4) | (data[8] << 4)),
+        (float)((data[15] >> 4) | (data[16] << 4)),
         true
     );
 }
@@ -822,20 +828,20 @@ static void HandleMiniControllerStateR(Uint64 timestamp, SDL_Joystick *joystick,
 {
     // FIXME: When we find out what the SL and SR buttons are, map them to shoulder buttons
 
-    if (data[3] != ctx->last_state[3]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[3] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[3] & 0x02) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[3] & 0x04) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[3] & 0x08) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE1, ((data[3] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE2, ((data[3] & 0x20) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[3] & 0x40) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[3] & 0x80) != 0));
+    if (data[5] != ctx->last_state[5]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE1, ((data[5] & 0x40) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_RIGHT_PADDLE2, ((data[5] & 0x80) != 0));
     }
 
-    if (data[4] != ctx->last_state[4]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[4] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_C, ((data[4] & 0x10) != 0));
+    if (data[6] != ctx->last_state[6]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x10) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_JOYCON_C, ((data[6] & 0x40) != 0));
     }
 
     MapJoystickAxis(
@@ -843,7 +849,7 @@ static void HandleMiniControllerStateR(Uint64 timestamp, SDL_Joystick *joystick,
         joystick,
         SDL_GAMEPAD_AXIS_LEFTX,
         &ctx->left_stick.y,
-        (float) ((data[7] >> 4) | (data[8] << 4)),
+        (float)((data[15] >> 4) | (data[16] << 4)),
         false
     );
     MapJoystickAxis(
@@ -851,7 +857,7 @@ static void HandleMiniControllerStateR(Uint64 timestamp, SDL_Joystick *joystick,
         joystick,
         SDL_GAMEPAD_AXIS_LEFTY,
         &ctx->left_stick.x,
-        (float) (data[6] | ((data[7] & 0x0F) << 8)),
+        (float) (data[14] | ((data[15] & 0x0F) << 8)),
         false
     );
 }
@@ -860,58 +866,61 @@ static void HandleSwitchProState(Uint64 timestamp, SDL_Joystick *joystick, SDL_D
 {
     Sint16 axis;
 
-    if (data[3] != ctx->last_state[3]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[3] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[3] & 0x02) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[3] & 0x04) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[3] & 0x08) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[3] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[3] & 0x40) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[3] & 0x80) != 0));
+    if (data[5] != ctx->last_state[5]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data[5] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data[5] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data[5] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data[5] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, ((data[5] & 0x40) != 0));
+    }
+
+    if (data[6] != ctx->last_state[6]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[6] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[6] & 0x02) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, ((data[6] & 0x04) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[6] & 0x08) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[6] & 0x10) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_SHARE, ((data[6] & 0x20) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_C, ((data[6] & 0x40) != 0));
     }
 
-    if (data[4] != ctx->last_state[4]) {
+    if (data[7] != ctx->last_state[7]) {
         Uint8 hat = 0;
 
-        if (data[4] & 0x01) {
+        if (data[7] & 0x01) {
             hat |= SDL_HAT_DOWN;
         }
-        if (data[4] & 0x02) {
+        if (data[7] & 0x02) {
+            hat |= SDL_HAT_UP;
+        }
+        if (data[7] & 0x04) {
             hat |= SDL_HAT_RIGHT;
         }
-        if (data[4] & 0x04) {
+        if (data[7] & 0x08) {
             hat |= SDL_HAT_LEFT;
         }
-        if (data[4] & 0x08) {
-            hat |= SDL_HAT_UP;
-        }
         SDL_SendJoystickHat(timestamp, joystick, 0, hat);
 
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[4] & 0x10) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, ((data[4] & 0x40) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, ((data[4] & 0x80) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, ((data[7] & 0x40) != 0));
     }
 
-    if (data[5] != ctx->last_state[5]) {
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[5] & 0x01) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_SHARE, ((data[5] & 0x02) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_RIGHT_PADDLE, ((data[5] & 0x04) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_LEFT_PADDLE, ((data[5] & 0x08) != 0));
-        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_C, ((data[5] & 0x10) != 0));
+    if (data[8] != ctx->last_state[8]) {
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_RIGHT_PADDLE, ((data[8] & 0x01) != 0));
+        SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH2_PRO_LEFT_PADDLE, ((data[8] & 0x02) != 0));
     }
 
-    axis = (data[4] & 0x20) ? 32767 : -32768;
-    SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
-
-    axis = (data[3] & 0x20) ? 32767 : -32768;
+    axis = (data[5] & 0x80) ? 32767 : -32768;
     SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis);
 
+    axis = (data[7] & 0x80) ? 32767 : -32768;
+    SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
+
     MapJoystickAxis(
         timestamp,
         joystick,
         SDL_GAMEPAD_AXIS_LEFTX,
         &ctx->left_stick.x,
-        (float) (data[6] | ((data[7] & 0x0F) << 8)),
+        (float) (data[11] | ((data[12] & 0x0F) << 8)),
         false
     );
     MapJoystickAxis(
@@ -919,7 +928,7 @@ static void HandleSwitchProState(Uint64 timestamp, SDL_Joystick *joystick, SDL_D
         joystick,
         SDL_GAMEPAD_AXIS_LEFTY,
         &ctx->left_stick.y,
-        (float) ((data[7] >> 4) | (data[8] << 4)),
+        (float) ((data[12] >> 4) | (data[13] << 4)),
         true
     );
     MapJoystickAxis(
@@ -927,7 +936,7 @@ static void HandleSwitchProState(Uint64 timestamp, SDL_Joystick *joystick, SDL_D
         joystick,
         SDL_GAMEPAD_AXIS_RIGHTX,
         &ctx->right_stick.x,
-        (float) (data[9] | ((data[10] & 0x0F) << 8)),
+        (float) (data[14] | ((data[15] & 0x0F) << 8)),
         false
     );
     MapJoystickAxis(
@@ -935,7 +944,7 @@ static void HandleSwitchProState(Uint64 timestamp, SDL_Joystick *joystick, SDL_D
         joystick,
         SDL_GAMEPAD_AXIS_RIGHTY,
         &ctx->right_stick.y,
-        (float)((data[10] >> 4) | (data[11] << 4)),
+        (float)((data[15] >> 4) | (data[16] << 4)),
         true
     );
 }
@@ -1021,7 +1030,7 @@ static void HIDAPI_DriverSwitch2_HandleStatePacket(SDL_HIDAPI_Device *device, SD
 {
     Uint64 timestamp = SDL_GetTicksNS();
 
-    if (size < 15) {
+    if (size < 64) {
         // We don't know how to handle this report
         return;
     }