Skip to content

Commit 45b01d1

Browse files
committed
Fixed reliability of initializing Switch controllers on macOS
It looks like both macOS (15.1.1) and SDL are trying to talk to the controller at the same time, which can cause interleaved replies or even locking up the controller. Waiting a bit before talking to the controller seems to take care of this.
1 parent 433810c commit 45b01d1

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

src/joystick/hidapi/SDL_hidapi_switch.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,9 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
817817
SwitchSubcommandInputPacket_t *factory_reply = NULL;
818818
SwitchSPIOpData_t readUserParams;
819819
SwitchSPIOpData_t readFactoryParams;
820-
820+
const int MAX_ATTEMPTS = 3;
821+
int attempt;
822+
821823
/* Read User Calibration Info */
822824
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
823825
readUserParams.ucLength = k_unSPIStickUserCalibrationLength;
@@ -829,8 +831,19 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
829831
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
830832
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
831833

832-
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
833-
return SDL_FALSE;
834+
for (attempt = 0; ; ++attempt) {
835+
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
836+
return SDL_FALSE;
837+
}
838+
839+
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
840+
/* We successfully read the calibration data */
841+
break;
842+
}
843+
844+
if (attempt == MAX_ATTEMPTS) {
845+
return SDL_FALSE;
846+
}
834847
}
835848

836849
/* Automatically select the user calibration if magic bytes are set */
@@ -1426,6 +1439,10 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
14261439
ctx->m_bSyncWrite = SDL_TRUE;
14271440

14281441
if (!ctx->m_bInputOnly) {
1442+
#ifdef SDL_PLATFORM_MACOS
1443+
// Wait for the OS to finish its handshake with the controller
1444+
SDL_Delay(250);
1445+
#endif
14291446
GetInitialInputMode(ctx);
14301447
ctx->m_nCurrentInputMode = ctx->m_nInitialInputMode;
14311448

0 commit comments

Comments
 (0)