Added support for the older Xbox One S Bluetooth controller report format

This commit is contained in:
Sam Lantinga 2020-03-13 19:00:24 -07:00
parent d662a65964
commit 879f137aec
1 changed files with 100 additions and 2 deletions

View File

@ -478,7 +478,96 @@ HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, hid_device *dev, S
} }
static void static void
HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV1(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
{
Sint16 axis;
if (ctx->last_state[14] != data[14]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->last_state[15] != data[15]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->last_state[13] != data[13]) {
SDL_bool dpad_up = SDL_FALSE;
SDL_bool dpad_down = SDL_FALSE;
SDL_bool dpad_left = SDL_FALSE;
SDL_bool dpad_right = SDL_FALSE;
switch (data[13]) {
case 1:
dpad_up = SDL_TRUE;
break;
case 2:
dpad_up = SDL_TRUE;
dpad_right = SDL_TRUE;
break;
case 3:
dpad_right = SDL_TRUE;
break;
case 4:
dpad_right = SDL_TRUE;
dpad_down = SDL_TRUE;
break;
case 5:
dpad_down = SDL_TRUE;
break;
case 6:
dpad_left = SDL_TRUE;
dpad_down = SDL_TRUE;
break;
case 7:
dpad_left = SDL_TRUE;
break;
case 8:
dpad_up = SDL_TRUE;
dpad_left = SDL_TRUE;
break;
default:
break;
}
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
}
axis = (int)*(Uint16*)(&data[1]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
axis = (int)*(Uint16*)(&data[3]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
axis = (int)*(Uint16*)(&data[5]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
axis = (int)*(Uint16*)(&data[7]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
axis = ((int)*(Sint16*)(&data[9]) * 64) - 32768;
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
axis = ((int)*(Sint16*)(&data[11]) * 64) - 32768;
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}
static void
HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV2(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
{ {
Sint16 axis; Sint16 axis;
@ -619,7 +708,16 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
if (ctx->bluetooth) { if (ctx->bluetooth) {
switch (data[0]) { switch (data[0]) {
case 0x01: case 0x01:
HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(joystick, device->dev, ctx, data, size); switch (size) {
case 16:
HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV1(joystick, device->dev, ctx, data, size);
break;
case 17:
HIDAPI_DriverXboxOneBluetooth_HandleStatePacketV2(joystick, device->dev, ctx, data, size);
break;
default:
break;
}
break; break;
case 0x02: case 0x02:
HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(joystick, device->dev, ctx, data, size); HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(joystick, device->dev, ctx, data, size);