diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 5a4b109df..b4f2d9a9c 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -269,6 +269,8 @@ typedef struct SDL_bool m_bSyncWrite; int m_nMaxWriteAttempts; ESwitchDeviceInfoControllerType m_eControllerType; + Uint8 m_nInitialInputMode; + Uint8 m_nCurrentInputMode; Uint8 m_rgucMACAddress[6]; Uint8 m_nCommandNumber; SwitchCommonOutputPacket_t m_RumblePacket; @@ -643,7 +645,13 @@ static SDL_bool SetVibrationEnabled(SDL_DriverSwitch_Context *ctx, Uint8 enabled } static SDL_bool SetInputMode(SDL_DriverSwitch_Context *ctx, Uint8 input_mode) { - return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SetInputReportMode, &input_mode, sizeof(input_mode), NULL); + if (input_mode == ctx->m_nCurrentInputMode) { + return SDL_TRUE; + } else { + ctx->m_nCurrentInputMode = input_mode; + + return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SetInputReportMode, &input_mode, sizeof(input_mode), NULL); + } } static SDL_bool SetHomeLED(SDL_DriverSwitch_Context *ctx, Uint8 brightness) @@ -712,15 +720,29 @@ static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, c } } +static Uint8 GetInitialInputMode(SDL_DriverSwitch_Context *ctx) +{ + Uint8 input_mode = 0; + + if (ReadInput(ctx) > 0) { + input_mode = ctx->m_rgucReadBuffer[0]; + } + return input_mode; +} + 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; + if (ctx->m_nInitialInputMode) { + input_mode = ctx->m_nInitialInputMode; } else { - input_mode = k_eSwitchInputReportIDs_FullControllerState; + 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 @@ -734,6 +756,20 @@ static Uint8 GetDefaultInputMode(SDL_DriverSwitch_Context *ctx) return input_mode; } +static Uint8 GetSensorInputMode(SDL_DriverSwitch_Context *ctx) +{ + Uint8 input_mode; + + /* Determine the desired input mode */ + if (!ctx->m_nInitialInputMode || + ctx->m_nInitialInputMode == k_eSwitchInputReportIDs_SimpleControllerState) { + input_mode = k_eSwitchInputReportIDs_FullControllerState; + } else { + input_mode = ctx->m_nInitialInputMode; + } + return input_mode; +} + static SDL_bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, SDL_bool enabled) { Uint8 imu_data = enabled ? 1 : 0; @@ -1305,6 +1341,9 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_ ctx->m_bSyncWrite = SDL_TRUE; if (!ctx->m_bInputOnly) { + ctx->m_nInitialInputMode = GetInitialInputMode(ctx); + ctx->m_nCurrentInputMode = ctx->m_nInitialInputMode; + /* Initialize rumble data */ SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]); SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]); @@ -1590,7 +1629,7 @@ static int HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *devi Uint8 input_mode; if (enabled) { - input_mode = k_eSwitchInputReportIDs_FullControllerState; + input_mode = GetSensorInputMode(ctx); } else { input_mode = GetDefaultInputMode(ctx); } @@ -2176,6 +2215,8 @@ static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device) if (ctx->m_bInputOnly) { HandleInputOnlyControllerState(joystick, ctx, (SwitchInputOnlyControllerStatePacket_t *)&ctx->m_rgucReadBuffer[0]); } else { + ctx->m_nCurrentInputMode = ctx->m_rgucReadBuffer[0]; + switch (ctx->m_rgucReadBuffer[0]) { case k_eSwitchInputReportIDs_SimpleControllerState: HandleSimpleControllerState(joystick, ctx, (SwitchSimpleStatePacket_t *)&ctx->m_rgucReadBuffer[1]); @@ -2242,7 +2283,10 @@ static void HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joy if (!ctx->m_bInputOnly) { /* Restore simple input mode for other applications */ - SetInputMode(ctx, k_eSwitchInputReportIDs_SimpleControllerState); + if (!ctx->m_nInitialInputMode || + ctx->m_nInitialInputMode == k_eSwitchInputReportIDs_SimpleControllerState) { + SetInputMode(ctx, k_eSwitchInputReportIDs_SimpleControllerState); + } } if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft ||