mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 10:44:59 +00:00 
			
		
		
		
	hidapi: switch: Add user calibration support
(cherry picked from commit 9fa55d9cabc93532cd5cf44105ec589a4db1d097)
This commit is contained in:
		
							parent
							
								
									6a52017724
								
							
						
					
					
						commit
						fa934dd4df
					
				| 
						 | 
				
			
			@ -111,9 +111,13 @@ typedef enum
 | 
			
		|||
#define k_unSwitchBluetoothPacketLength  k_unSwitchOutputPacketDataLength
 | 
			
		||||
#define k_unSwitchUSBPacketLength        k_unSwitchMaxOutputPacketLength
 | 
			
		||||
 | 
			
		||||
#define k_unSPIStickCalibrationStartOffset 0x603D
 | 
			
		||||
#define k_unSPIStickCalibrationEndOffset   0x604E
 | 
			
		||||
#define k_unSPIStickCalibrationLength      (k_unSPIStickCalibrationEndOffset - k_unSPIStickCalibrationStartOffset + 1)
 | 
			
		||||
#define k_unSPIStickFactoryCalibrationStartOffset 0x603D
 | 
			
		||||
#define k_unSPIStickFactoryCalibrationEndOffset   0x604E
 | 
			
		||||
#define k_unSPIStickFactoryCalibrationLength      (k_unSPIStickFactoryCalibrationEndOffset - k_unSPIStickFactoryCalibrationStartOffset + 1)
 | 
			
		||||
 | 
			
		||||
#define k_unSPIStickUserCalibrationStartOffset 0x8010
 | 
			
		||||
#define k_unSPIStickUserCalibrationEndOffset   0x8025
 | 
			
		||||
#define k_unSPIStickUserCalibrationLength      (k_unSPIStickUserCalibrationEndOffset - k_unSPIStickUserCalibrationStartOffset + 1)
 | 
			
		||||
 | 
			
		||||
#define k_unSPIIMUScaleStartOffset 0x6020
 | 
			
		||||
#define k_unSPIIMUScaleEndOffset   0x6037
 | 
			
		||||
| 
						 | 
				
			
			@ -199,6 +203,22 @@ typedef struct
 | 
			
		|||
            Uint8 ucFiller2;
 | 
			
		||||
            Uint8 ucColorLocation;
 | 
			
		||||
        } deviceInfo;
 | 
			
		||||
 | 
			
		||||
        struct
 | 
			
		||||
        {
 | 
			
		||||
            SwitchSPIOpData_t opData;
 | 
			
		||||
            Uint8 rgucLeftCalibration[9];
 | 
			
		||||
            Uint8 rgucRightCalibration[9];
 | 
			
		||||
        } stickFactoryCalibration;
 | 
			
		||||
 | 
			
		||||
        struct
 | 
			
		||||
        {
 | 
			
		||||
            SwitchSPIOpData_t opData;
 | 
			
		||||
            Uint8 rgucLeftMagic[2];
 | 
			
		||||
            Uint8 rgucLeftCalibration[9];
 | 
			
		||||
            Uint8 rgucRightMagic[2];
 | 
			
		||||
            Uint8 rgucRightCalibration[9];
 | 
			
		||||
        } stickUserCalibration;
 | 
			
		||||
    };
 | 
			
		||||
} SwitchSubcommandInputPacket_t;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -708,41 +728,64 @@ static SDL_bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, SDL_bool enabled)
 | 
			
		|||
 | 
			
		||||
static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_mode)
 | 
			
		||||
{
 | 
			
		||||
    Uint8 *pStickCal;
 | 
			
		||||
    Uint8 *pLeftStickCal;
 | 
			
		||||
    Uint8 *pRightStickCal;
 | 
			
		||||
    size_t stick, axis;
 | 
			
		||||
    SwitchSubcommandInputPacket_t *reply = NULL;
 | 
			
		||||
    SwitchSubcommandInputPacket_t *user_reply = NULL;
 | 
			
		||||
    SwitchSubcommandInputPacket_t *factory_reply = NULL;
 | 
			
		||||
    SwitchSPIOpData_t readUserParams;
 | 
			
		||||
    SwitchSPIOpData_t readFactoryParams;
 | 
			
		||||
 | 
			
		||||
    /* Read Calibration Info */
 | 
			
		||||
    SwitchSPIOpData_t readParams;
 | 
			
		||||
    readParams.unAddress = k_unSPIStickCalibrationStartOffset;
 | 
			
		||||
    readParams.ucLength = k_unSPIStickCalibrationLength;
 | 
			
		||||
    /* Read User Calibration Info */
 | 
			
		||||
    readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
 | 
			
		||||
    readUserParams.ucLength = k_unSPIStickUserCalibrationLength;
 | 
			
		||||
 | 
			
		||||
    if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply)) {
 | 
			
		||||
    if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readUserParams, sizeof(readUserParams), &user_reply)) {
 | 
			
		||||
        return SDL_FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Read Factory Calibration Info */
 | 
			
		||||
    readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
 | 
			
		||||
    readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
 | 
			
		||||
 | 
			
		||||
    if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
 | 
			
		||||
        return SDL_FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Automatically select the user calibration if magic bytes are set */
 | 
			
		||||
    if (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->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
 | 
			
		||||
        pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
 | 
			
		||||
    } else {
 | 
			
		||||
        pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Stick calibration values are 12-bits each and are packed by bit
 | 
			
		||||
     * For whatever reason the fields are in a different order for each stick
 | 
			
		||||
     * Left:  X-Max, Y-Max, X-Center, Y-Center, X-Min, Y-Min
 | 
			
		||||
     * Right: X-Center, Y-Center, X-Min, Y-Min, X-Max, Y-Max
 | 
			
		||||
     */
 | 
			
		||||
    pStickCal = reply->spiReadData.rgucReadData;
 | 
			
		||||
 | 
			
		||||
    /* Left stick */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[0].sMax = ((pStickCal[1] << 8) & 0xF00) | pStickCal[0];    /* X Axis max above center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[1].sMax = (pStickCal[2] << 4) | (pStickCal[1] >> 4);       /* Y Axis max above center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[0].sCenter = ((pStickCal[4] << 8) & 0xF00) | pStickCal[3]; /* X Axis center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[1].sCenter = (pStickCal[5] << 4) | (pStickCal[4] >> 4);    /* Y Axis center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[0].sMin = ((pStickCal[7] << 8) & 0xF00) | pStickCal[6];    /* X Axis min below center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[1].sMin = (pStickCal[8] << 4) | (pStickCal[7] >> 4);       /* Y Axis min below center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[0].sMax = ((pLeftStickCal[1] << 8) & 0xF00) | pLeftStickCal[0];    /* X Axis max above center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[1].sMax = (pLeftStickCal[2] << 4) | (pLeftStickCal[1] >> 4);       /* Y Axis max above center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[0].sCenter = ((pLeftStickCal[4] << 8) & 0xF00) | pLeftStickCal[3]; /* X Axis center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[1].sCenter = (pLeftStickCal[5] << 4) | (pLeftStickCal[4] >> 4);    /* Y Axis center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[0].sMin = ((pLeftStickCal[7] << 8) & 0xF00) | pLeftStickCal[6];    /* X Axis min below center */
 | 
			
		||||
    ctx->m_StickCalData[0].axis[1].sMin = (pLeftStickCal[8] << 4) | (pLeftStickCal[7] >> 4);       /* Y Axis min below center */
 | 
			
		||||
 | 
			
		||||
    /* Right stick */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[0].sCenter = ((pStickCal[10] << 8) & 0xF00) | pStickCal[9]; /* X Axis center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[1].sCenter = (pStickCal[11] << 4) | (pStickCal[10] >> 4);   /* Y Axis center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[0].sMin = ((pStickCal[13] << 8) & 0xF00) | pStickCal[12];   /* X Axis min below center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[1].sMin = (pStickCal[14] << 4) | (pStickCal[13] >> 4);      /* Y Axis min below center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[0].sMax = ((pStickCal[16] << 8) & 0xF00) | pStickCal[15];   /* X Axis max above center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[1].sMax = (pStickCal[17] << 4) | (pStickCal[16] >> 4);      /* Y Axis max above center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[0].sCenter = ((pRightStickCal[1] << 8) & 0xF00) | pRightStickCal[0]; /* X Axis center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[1].sCenter = (pRightStickCal[2] << 4) | (pRightStickCal[1] >> 4);    /* Y Axis center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[0].sMin = ((pRightStickCal[4] << 8) & 0xF00) | pRightStickCal[3];    /* X Axis min below center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[1].sMin = (pRightStickCal[5] << 4) | (pRightStickCal[4] >> 4);       /* Y Axis min below center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[0].sMax = ((pRightStickCal[7] << 8) & 0xF00) | pRightStickCal[6];    /* X Axis max above center */
 | 
			
		||||
    ctx->m_StickCalData[1].axis[1].sMax = (pRightStickCal[8] << 4) | (pRightStickCal[7] >> 4);       /* Y Axis max above center */
 | 
			
		||||
 | 
			
		||||
    /* Filter out any values that were uninitialized (0xFFF) in the SPI read */
 | 
			
		||||
    for (stick = 0; stick < 2; ++stick) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue