Handle hotplugging of Wii controller extensions
parent
396411c090
commit
8381e008ea
|
@ -254,7 +254,7 @@ static SDL_bool ReadRegister(SDL_DriverWii_Context *ctx, Uint32 address, int siz
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool ParseExtensionResponse(SDL_DriverWii_Context *ctx)
|
static SDL_bool ParseExtensionResponse(SDL_DriverWii_Context *ctx, EWiiExtensionControllerType *controller_type)
|
||||||
{
|
{
|
||||||
Uint64 type = 0;
|
Uint64 type = 0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -278,23 +278,23 @@ static SDL_bool ParseExtensionResponse(SDL_DriverWii_Context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == 0x0000A4200000) {
|
if (type == 0x0000A4200000) {
|
||||||
ctx->m_eExtensionControllerType = k_eWiiExtensionControllerType_Nunchuck;
|
*controller_type = k_eWiiExtensionControllerType_Nunchuck;
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
if (type == 0x0000A4200101) {
|
if (type == 0x0000A4200101) {
|
||||||
ctx->m_eExtensionControllerType = k_eWiiExtensionControllerType_ClassicController;
|
*controller_type = k_eWiiExtensionControllerType_ClassicController;
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
if (type == 0x0100A4200101) {
|
if (type == 0x0100A4200101) {
|
||||||
ctx->m_eExtensionControllerType = k_eWiiExtensionControllerType_ClassicControllerPro;
|
*controller_type = k_eWiiExtensionControllerType_ClassicControllerPro;
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
if (type == 0x0000A4200120) {
|
if (type == 0x0000A4200120) {
|
||||||
ctx->m_eExtensionControllerType = k_eWiiExtensionControllerType_WiiUPro;
|
*controller_type = k_eWiiExtensionControllerType_WiiUPro;
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->m_eExtensionControllerType = k_eWiiExtensionControllerType_Unknown;
|
*controller_type = k_eWiiExtensionControllerType_Unknown;
|
||||||
SDL_SetError("Unrecognized controller type: %012" SDL_PRIx64, type);
|
SDL_SetError("Unrecognized controller type: %012" SDL_PRIx64, type);
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -472,7 +472,7 @@ static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, c
|
||||||
static EWiiExtensionControllerType
|
static EWiiExtensionControllerType
|
||||||
ReadControllerType(SDL_HIDAPI_Device *device)
|
ReadControllerType(SDL_HIDAPI_Device *device)
|
||||||
{
|
{
|
||||||
EWiiExtensionControllerType eControllerType = k_eWiiExtensionControllerType_Unknown;
|
EWiiExtensionControllerType eExtensionControllerType = k_eWiiExtensionControllerType_Unknown;
|
||||||
|
|
||||||
/* Create enough of a context to read the controller type from the device */
|
/* Create enough of a context to read the controller type from the device */
|
||||||
SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)SDL_calloc(1, sizeof(*ctx));
|
SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)SDL_calloc(1, sizeof(*ctx));
|
||||||
|
@ -491,11 +491,11 @@ ReadControllerType(SDL_HIDAPI_Device *device)
|
||||||
Uint8 data_0x00 = 0x00;
|
Uint8 data_0x00 = 0x00;
|
||||||
if (WriteRegister(ctx, 0xA400F0, &data_0x55, sizeof(data_0x55), SDL_TRUE) &&
|
if (WriteRegister(ctx, 0xA400F0, &data_0x55, sizeof(data_0x55), SDL_TRUE) &&
|
||||||
WriteRegister(ctx, 0xA400FB, &data_0x00, sizeof(data_0x00), SDL_TRUE) &&
|
WriteRegister(ctx, 0xA400FB, &data_0x00, sizeof(data_0x00), SDL_TRUE) &&
|
||||||
ReadRegister(ctx, 0xA400FA, 6, SDL_TRUE) && ParseExtensionResponse(ctx)) {
|
ReadRegister(ctx, 0xA400FA, 6, SDL_TRUE)) {
|
||||||
eControllerType = ctx->m_eExtensionControllerType;
|
ParseExtensionResponse(ctx, &eExtensionControllerType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eControllerType = k_eWiiExtensionControllerType_None;
|
eExtensionControllerType = k_eWiiExtensionControllerType_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_hid_close(device->dev);
|
SDL_hid_close(device->dev);
|
||||||
|
@ -503,16 +503,16 @@ ReadControllerType(SDL_HIDAPI_Device *device)
|
||||||
}
|
}
|
||||||
SDL_free(ctx);
|
SDL_free(ctx);
|
||||||
}
|
}
|
||||||
return eControllerType;
|
return eExtensionControllerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
|
UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
|
||||||
{
|
{
|
||||||
EWiiExtensionControllerType eControllerType = (EWiiExtensionControllerType)device->guid.data[15];
|
EWiiExtensionControllerType eExtensionControllerType = (EWiiExtensionControllerType)device->guid.data[15];
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
|
|
||||||
switch (eControllerType) {
|
switch (eExtensionControllerType) {
|
||||||
case k_eWiiExtensionControllerType_None:
|
case k_eWiiExtensionControllerType_None:
|
||||||
name = "Nintendo Wii Remote";
|
name = "Nintendo Wii Remote";
|
||||||
break;
|
break;
|
||||||
|
@ -543,8 +543,8 @@ static SDL_bool
|
||||||
HIDAPI_DriverWii_InitDevice(SDL_HIDAPI_Device *device)
|
HIDAPI_DriverWii_InitDevice(SDL_HIDAPI_Device *device)
|
||||||
{
|
{
|
||||||
if (device->vendor_id == USB_VENDOR_NINTENDO) {
|
if (device->vendor_id == USB_VENDOR_NINTENDO) {
|
||||||
EWiiExtensionControllerType eControllerType = ReadControllerType(device);
|
EWiiExtensionControllerType eExtensionControllerType = ReadControllerType(device);
|
||||||
device->guid.data[15] = eControllerType;
|
device->guid.data[15] = eExtensionControllerType;
|
||||||
UpdateDeviceIdentity(device);
|
UpdateDeviceIdentity(device);
|
||||||
}
|
}
|
||||||
return HIDAPI_JoystickConnected(device, NULL);
|
return HIDAPI_JoystickConnected(device, NULL);
|
||||||
|
@ -593,6 +593,8 @@ HIDAPI_DriverWii_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||||
|
|
||||||
InitStickCalibrationData(ctx);
|
InitStickCalibrationData(ctx);
|
||||||
|
|
||||||
|
RequestButtonPacketType(ctx, GetButtonPacketType(ctx));
|
||||||
|
|
||||||
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
|
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
|
||||||
SDL_GameControllerButtonReportingHintChanged, ctx);
|
SDL_GameControllerButtonReportingHintChanged, ctx);
|
||||||
|
|
||||||
|
@ -613,8 +615,6 @@ HIDAPI_DriverWii_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||||
}
|
}
|
||||||
joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
|
joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
|
||||||
|
|
||||||
RequestButtonPacketType(ctx, GetButtonPacketType(ctx));
|
|
||||||
|
|
||||||
ctx->m_unLastInput = SDL_GetTicks();
|
ctx->m_unLastInput = SDL_GetTicks();
|
||||||
|
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
|
@ -861,7 +861,28 @@ static void HandleStatus(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick)
|
||||||
/* Wii U has separate battery level tracking */
|
/* Wii U has separate battery level tracking */
|
||||||
UpdatePowerLevelWii(joystick, ctx->m_rgucReadBuffer[6]);
|
UpdatePowerLevelWii(joystick, ctx->m_rgucReadBuffer[6]);
|
||||||
}
|
}
|
||||||
/* TODO: Check Extensions */
|
|
||||||
|
/* Check to see if extensions have changed */
|
||||||
|
{
|
||||||
|
EWiiExtensionControllerType eExtensionControllerType = k_eWiiExtensionControllerType_Unknown;
|
||||||
|
SDL_bool hasExtension = (ctx->m_rgucReadBuffer[3] & 2) ? SDL_TRUE : SDL_FALSE;
|
||||||
|
if (hasExtension) {
|
||||||
|
/* http://wiibrew.org/wiki/Wiimote/Extension_Controllers#The_New_Way */
|
||||||
|
Uint8 data_0x55 = 0x55;
|
||||||
|
Uint8 data_0x00 = 0x00;
|
||||||
|
if (WriteRegister(ctx, 0xA400F0, &data_0x55, sizeof(data_0x55), SDL_TRUE) &&
|
||||||
|
WriteRegister(ctx, 0xA400FB, &data_0x00, sizeof(data_0x00), SDL_TRUE) &&
|
||||||
|
ReadRegister(ctx, 0xA400FA, 6, SDL_TRUE)) {
|
||||||
|
ParseExtensionResponse(ctx, &eExtensionControllerType);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eExtensionControllerType = k_eWiiExtensionControllerType_None;
|
||||||
|
}
|
||||||
|
if (eExtensionControllerType != ctx->m_eExtensionControllerType) {
|
||||||
|
/* Mark this controller as disconnected so we re-connect with a new identity */
|
||||||
|
HIDAPI_JoystickDisconnected(ctx->device, joystick->instance_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleResponse(SDL_DriverWii_Context *ctx)
|
static void HandleResponse(SDL_DriverWii_Context *ctx)
|
||||||
|
|
|
@ -834,6 +834,9 @@ check_removed:
|
||||||
goto check_removed;
|
goto check_removed;
|
||||||
} else {
|
} else {
|
||||||
HIDAPI_DelDevice(device);
|
HIDAPI_DelDevice(device);
|
||||||
|
|
||||||
|
/* Update the device list again in case this device comes back */
|
||||||
|
SDL_HIDAPI_change_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
device = next;
|
device = next;
|
||||||
|
|
Loading…
Reference in New Issue