Resolve bug for calibration Nintendo Switch Pro Controller (#13260)

Resolves a bug which prevents the stored calibration data from loading, only allowing loading of factory-installed calibration data
This commit is contained in:
mitchellcairns
2025-06-22 20:59:15 -07:00
committed by GitHub
parent 3a6f9e01f8
commit 796961acec

View File

@@ -928,13 +928,14 @@ static bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, bool enabled)
static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx) static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
{ {
Uint8 *pLeftStickCal; Uint8 *pLeftStickCal = NULL;
Uint8 *pRightStickCal; Uint8 *pRightStickCal = NULL;
size_t stick, axis; size_t stick, axis;
SwitchSubcommandInputPacket_t *user_reply = NULL; SwitchSubcommandInputPacket_t *user_reply = NULL;
SwitchSubcommandInputPacket_t *factory_reply = NULL; SwitchSubcommandInputPacket_t *factory_reply = NULL;
SwitchSPIOpData_t readUserParams; SwitchSPIOpData_t readUserParams;
SwitchSPIOpData_t readFactoryParams; SwitchSPIOpData_t readFactoryParams;
Uint8 userParamsReadSuccessCount = 0;
// Read User Calibration Info // Read User Calibration Info
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset; readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
@@ -947,14 +948,33 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset; readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength; readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
// Automatically select the user calibration if magic bytes are set
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
userParamsReadSuccessCount += 1;
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
}
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
userParamsReadSuccessCount += 1;
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
}
// Only read the factory calibration info if we failed to receive the correct magic bytes
if (userParamsReadSuccessCount < 2) {
// Read Factory Calibration Info
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
const int MAX_ATTEMPTS = 3; const int MAX_ATTEMPTS = 3;
for (int attempt = 0; ; ++attempt) { for (int attempt = 0;; ++attempt) {
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) { if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
return false; return false;
} }
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) { if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
// We successfully read the calibration data // We successfully read the calibration data
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
break; break;
} }
@@ -962,18 +982,12 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
return false; return false;
} }
} }
// Automatically select the user calibration if magic bytes are set
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
} else {
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
} }
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) { // If we still don't have calibration data, return false
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration; if (pLeftStickCal == NULL || pRightStickCal == NULL)
} else { {
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration; return false;
} }
/* Stick calibration values are 12-bits each and are packed by bit /* Stick calibration values are 12-bits each and are packed by bit