# SDL: Allow switching licensed Nintendo Switch Pro controllers into gyro input mode

**URL:** <https://discourse.libsdl.org/t/sdl-allow-switching-licensed-nintendo-switch-pro-controllers-into-gyro-input-mode/44249>\
**Category:** SDL Commits\
**Created:** [June 14, 2023, 5:42am UTC](https://discourse.libsdl.org/t/sdl-allow-switching-licensed-nintendo-switch-pro-controllers-into-gyro-input-mode/44249 "2023-06-14T05:42:08Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![SDLPushPostBot](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/sdlpushpostbot/32/4370_2.png) [@SDLPushPostBot](https://discourse.libsdl.org/u/SDLPushPostBot)\
**Post date:** [June 14, 2023, 5:42am UTC](https://discourse.libsdl.org/t/sdl-allow-switching-licensed-nintendo-switch-pro-controllers-into-gyro-input-mode/44249/1 "2023-06-14T05:42:09Z")

</div>

> <https://github.com/libsdl-org/SDL/commit/8c95bd814bf1cf0ea1f12aa724938176a7dfd780>

```diff
From 8c95bd814bf1cf0ea1f12aa724938176a7dfd780 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 13 Jun 2023 22:40:51 -0700
Subject: [PATCH] Allow switching licensed Nintendo Switch Pro controllers into
 gyro input mode

---
 src/joystick/hidapi/SDL_hidapi_switch.c | 56 +++++++++++++++----------
 1 file changed, 34 insertions(+), 22 deletions(-)

diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 080f682b584f..e01f13dafa24 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -717,13 +717,35 @@ static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, c
     }
 }
 
+static Uint8 GetDefaultInputMode(SDL_DriverSwitch_Context *ctx)
+{
+ Uint8 input_mode;
+
+ /* Determine the desired input mode */
+ if (ctx->device->is_bluetooth) {
+ input_mode = k_eSwitchInputReportIDs_SimpleControllerState;
+ } else {
+ input_mode = k_eSwitchInputReportIDs_FullControllerState;
+ }
+
+ /* The official Nintendo Switch Pro Controller supports FullControllerState over Bluetooth
+ * just fine. We really should use that, or else the epowerlevel code in HandleFullControllerState
+ * is completely pointless. We need full state if we want battery level and we only care about
+ * battery level over Bluetooth anyway.
+ */
+ if (ctx->device->vendor_id == USB_VENDOR_NINTENDO) {
+ input_mode = k_eSwitchInputReportIDs_FullControllerState;
+ }
+ return input_mode;
+}
+
 static SDL_bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, SDL_bool enabled)
 {
     Uint8 imu_data = enabled ? 1 : 0;
     return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_EnableIMU, &imu_data, sizeof(imu_data), NULL);
 }
 
-static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_mode)
+static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
 {
     Uint8 *pLeftStickCal;
     Uint8 *pRightStickCal;
@@ -1296,7 +1318,6 @@ static void HIDAPI_DriverSwitch_SetDevicePlayerIndex(SDL_HIDAPI_Device *device,
 static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
 {
     SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
- Uint8 input_mode;
 
     SDL_AssertJoysticksLocked();
 
@@ -1316,24 +1337,7 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
             }
         }
 
- /* Determine the desired input mode (needed before loading stick calibration) */
- if (device->is_bluetooth) {
- input_mode = k_eSwitchInputReportIDs_SimpleControllerState;
- } else {
- input_mode = k_eSwitchInputReportIDs_FullControllerState;
- }
-
- /* The official Nintendo Switch Pro Controller supports FullControllerState over bluetooth
- * just fine. We really should use that, or else the epowerlevel code in
- * HandleFullControllerState is completely pointless. We need full state if we want battery
- * level and we only care about battery level over bluetooth anyway.
- */
- if (device->vendor_id == USB_VENDOR_NINTENDO) {
- input_mode = k_eSwitchInputReportIDs_FullControllerState;
- }
-
- if (input_mode == k_eSwitchInputReportIDs_FullControllerState &&
- ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft &&
+ if (ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft &&
             ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESRight &&
             ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_SNES &&
             ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_N64 &&
@@ -1356,7 +1360,7 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
             }
         }
 
- if (!LoadStickCalibration(ctx, input_mode)) {
+ if (!LoadStickCalibration(ctx)) {
             SDL_SetError("Couldn't load stick calibration");
             return SDL_FALSE;
         }
@@ -1372,7 +1376,7 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
         }
 
         /* Set desired input mode */
- if (!SetInputMode(ctx, input_mode)) {
+ if (!SetInputMode(ctx, GetDefaultInputMode(ctx))) {
             SDL_SetError("Couldn't set input mode");
             return SDL_FALSE;
         }
@@ -1604,6 +1608,14 @@ static int HIDAPI_DriverSwitch_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL
 static int HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
 {
     SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
+ Uint8 input_mode;
+
+ if (enabled) {
+ input_mode = k_eSwitchInputReportIDs_FullControllerState;
+ } else {
+ input_mode = GetDefaultInputMode(ctx);
+ }
+ SetInputMode(ctx, input_mode);
 
     SetIMUEnabled(ctx, enabled);
     ctx->m_bReportSensors = enabled;

```
