Record the initial input report mode and only restore simple mode if that's what we started with

Fixes https://github.com/libsdl-org/SDL/issues/8108
Closes https://github.com/libsdl-org/SDL/pull/8115

(cherry picked from commit c3d84c3342f61b808462c7437784af5df4906273)
This commit is contained in:
Sam Lantinga 2023-12-24 08:12:14 -08:00
parent fe76c40716
commit aeda6a8e6f

View file

@ -274,6 +274,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;
@ -653,7 +655,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, 1, 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)
@ -719,15 +727,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
@ -741,6 +763,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;
@ -1344,6 +1380,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]);
@ -1595,7 +1634,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);
}
@ -2175,6 +2214,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]);
@ -2241,7 +2282,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);
}
}
SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,