mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-16 11:06:49 +01:00
Get the serial number for the Nintendo Switch Pro controller
This commit is contained in:
parent
5fc743c4fd
commit
e3dbae5010
@ -90,6 +90,7 @@ typedef enum {
|
|||||||
} ESwitchSubcommandIDs;
|
} ESwitchSubcommandIDs;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
k_eSwitchProprietaryCommandIDs_Status = 0x01,
|
||||||
k_eSwitchProprietaryCommandIDs_Handshake = 0x02,
|
k_eSwitchProprietaryCommandIDs_Handshake = 0x02,
|
||||||
k_eSwitchProprietaryCommandIDs_HighSpeed = 0x03,
|
k_eSwitchProprietaryCommandIDs_HighSpeed = 0x03,
|
||||||
k_eSwitchProprietaryCommandIDs_ForceUSB = 0x04,
|
k_eSwitchProprietaryCommandIDs_ForceUSB = 0x04,
|
||||||
@ -98,6 +99,7 @@ typedef enum {
|
|||||||
} ESwitchProprietaryCommandIDs;
|
} ESwitchProprietaryCommandIDs;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
k_eSwitchDeviceInfoControllerType_Unknown = 0x0,
|
||||||
k_eSwitchDeviceInfoControllerType_JoyConLeft = 0x1,
|
k_eSwitchDeviceInfoControllerType_JoyConLeft = 0x1,
|
||||||
k_eSwitchDeviceInfoControllerType_JoyConRight = 0x2,
|
k_eSwitchDeviceInfoControllerType_JoyConRight = 0x2,
|
||||||
k_eSwitchDeviceInfoControllerType_ProController = 0x3,
|
k_eSwitchDeviceInfoControllerType_ProController = 0x3,
|
||||||
@ -187,6 +189,16 @@ typedef struct
|
|||||||
};
|
};
|
||||||
} SwitchSubcommandInputPacket_t;
|
} SwitchSubcommandInputPacket_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Uint8 ucPacketType;
|
||||||
|
Uint8 ucCommandID;
|
||||||
|
Uint8 ucFiller;
|
||||||
|
|
||||||
|
Uint8 ucDeviceType;
|
||||||
|
Uint8 rgucMACAddress[6];
|
||||||
|
} SwitchProprietaryStatusPacket_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Uint8 rgucData[4];
|
Uint8 rgucData[4];
|
||||||
@ -223,6 +235,8 @@ typedef struct {
|
|||||||
SDL_bool m_bUsingBluetooth;
|
SDL_bool m_bUsingBluetooth;
|
||||||
SDL_bool m_bIsGameCube;
|
SDL_bool m_bIsGameCube;
|
||||||
SDL_bool m_bUseButtonLabels;
|
SDL_bool m_bUseButtonLabels;
|
||||||
|
ESwitchDeviceInfoControllerType m_eControllerType;
|
||||||
|
Uint8 m_rgucMACAddress[6];
|
||||||
Uint8 m_nCommandNumber;
|
Uint8 m_nCommandNumber;
|
||||||
SwitchCommonOutputPacket_t m_RumblePacket;
|
SwitchCommonOutputPacket_t m_RumblePacket;
|
||||||
Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength];
|
Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength];
|
||||||
@ -298,7 +312,7 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t
|
|||||||
controller to continually attempt to reconnect is to filter it out by manufactuer/product string.
|
controller to continually attempt to reconnect is to filter it out by manufactuer/product string.
|
||||||
Note that the controller does have a different product string when connected over Bluetooth.
|
Note that the controller does have a different product string when connected over Bluetooth.
|
||||||
*/
|
*/
|
||||||
if (SDL_strcmp( name, "HORI Wireless Switch Pad" ) == 0) {
|
if (SDL_strcmp(name, "HORI Wireless Switch Pad") == 0) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ? SDL_TRUE : SDL_FALSE;
|
return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ? SDL_TRUE : SDL_FALSE;
|
||||||
@ -511,6 +525,39 @@ static SDL_bool WriteRumble(SDL_DriverSwitch_Context *ctx)
|
|||||||
return WritePacket(ctx, (Uint8 *)&ctx->m_RumblePacket, sizeof(ctx->m_RumblePacket));
|
return WritePacket(ctx, (Uint8 *)&ctx->m_RumblePacket, sizeof(ctx->m_RumblePacket));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_bool BReadDeviceInfo(SDL_DriverSwitch_Context *ctx)
|
||||||
|
{
|
||||||
|
SwitchSubcommandInputPacket_t *reply = NULL;
|
||||||
|
|
||||||
|
ctx->m_bUsingBluetooth = SDL_FALSE;
|
||||||
|
|
||||||
|
if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) {
|
||||||
|
SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0];
|
||||||
|
|
||||||
|
ctx->m_eControllerType = (ESwitchDeviceInfoControllerType)status->ucDeviceType;
|
||||||
|
for (size_t i = 0; i < sizeof (ctx->m_rgucMACAddress); ++i)
|
||||||
|
ctx->m_rgucMACAddress[i] = status->rgucMACAddress[ sizeof(ctx->m_rgucMACAddress) - i - 1 ];
|
||||||
|
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->m_bUsingBluetooth = SDL_TRUE;
|
||||||
|
|
||||||
|
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_RequestDeviceInfo, NULL, 0, &reply)) {
|
||||||
|
// Byte 2: Controller ID (1=LJC, 2=RJC, 3=Pro)
|
||||||
|
ctx->m_eControllerType = (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType;
|
||||||
|
|
||||||
|
// Bytes 4-9: MAC address (big-endian)
|
||||||
|
memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
|
||||||
|
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->m_bUsingBluetooth = SDL_FALSE;
|
||||||
|
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_bool BTrySetupUSB(SDL_DriverSwitch_Context *ctx)
|
static SDL_bool BTrySetupUSB(SDL_DriverSwitch_Context *ctx)
|
||||||
{
|
{
|
||||||
/* We have to send a connection handshake to the controller when communicating over USB
|
/* We have to send a connection handshake to the controller when communicating over USB
|
||||||
@ -528,6 +575,9 @@ static SDL_bool BTrySetupUSB(SDL_DriverSwitch_Context *ctx)
|
|||||||
if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Handshake, NULL, 0, SDL_TRUE)) {
|
if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Handshake, NULL, 0, SDL_TRUE)) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE)) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,9 +814,16 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
|||||||
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]);
|
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]);
|
||||||
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]);
|
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]);
|
||||||
|
|
||||||
/* Try setting up USB mode, and if that fails we're using Bluetooth */
|
if (!BReadDeviceInfo(ctx)) {
|
||||||
if (!BTrySetupUSB(ctx)) {
|
SDL_SetError("Couldn't read device info");
|
||||||
ctx->m_bUsingBluetooth = SDL_TRUE;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx->m_bUsingBluetooth) {
|
||||||
|
if (!BTrySetupUSB(ctx)) {
|
||||||
|
SDL_SetError("Couldn't setup USB mode");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine the desired input mode (needed before loading stick calibration) */
|
/* Determine the desired input mode (needed before loading stick calibration) */
|
||||||
@ -822,6 +879,20 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
|||||||
SetHomeLED(ctx, 100);
|
SetHomeLED(ctx, 100);
|
||||||
}
|
}
|
||||||
SetSlotLED(ctx, (joystick->instance_id % 4));
|
SetSlotLED(ctx, (joystick->instance_id % 4));
|
||||||
|
|
||||||
|
/* Set the serial number */
|
||||||
|
{
|
||||||
|
char serial[18];
|
||||||
|
|
||||||
|
SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
|
||||||
|
ctx->m_rgucMACAddress[0],
|
||||||
|
ctx->m_rgucMACAddress[1],
|
||||||
|
ctx->m_rgucMACAddress[2],
|
||||||
|
ctx->m_rgucMACAddress[3],
|
||||||
|
ctx->m_rgucMACAddress[4],
|
||||||
|
ctx->m_rgucMACAddress[5]);
|
||||||
|
joystick->serial = SDL_strdup(serial);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsGameCubeFormFactor(device->vendor_id, device->product_id)) {
|
if (IsGameCubeFormFactor(device->vendor_id, device->product_id)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user