Simplified the HIDAPI Xbox One controller initialization
parent
25cd749adb
commit
6eb4ebb502
|
@ -44,33 +44,23 @@
|
||||||
#define CONTROLLER_PREPARE_INPUT_TIMEOUT_MS 50
|
#define CONTROLLER_PREPARE_INPUT_TIMEOUT_MS 50
|
||||||
|
|
||||||
|
|
||||||
/* Connect controller */
|
/* Start controller */
|
||||||
static const Uint8 xboxone_init0[] = {
|
static const Uint8 xboxone_init0[] = {
|
||||||
0x04, 0x20, 0x00, 0x00
|
|
||||||
};
|
|
||||||
/* Start controller - extended? */
|
|
||||||
static const Uint8 xboxone_init1[] = {
|
|
||||||
0x05, 0x20, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
/* Start controller with input */
|
|
||||||
static const Uint8 xboxone_init2[] = {
|
|
||||||
0x05, 0x20, 0x03, 0x01, 0x00
|
0x05, 0x20, 0x03, 0x01, 0x00
|
||||||
};
|
};
|
||||||
/* Enable LED */
|
/* Enable LED */
|
||||||
static const Uint8 xboxone_init3[] = {
|
static const Uint8 xboxone_init1[] = {
|
||||||
0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
|
0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
|
||||||
};
|
};
|
||||||
/* Start input reports? */
|
/* Setup rumble (not needed for Microsoft controllers, but it doesn't hurt) */
|
||||||
static const Uint8 xboxone_init4[] = {
|
static const Uint8 xboxone_init2[] = {
|
||||||
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
|
|
||||||
};
|
|
||||||
/* Start rumble? */
|
|
||||||
static const Uint8 xboxone_init5[] = {
|
|
||||||
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
|
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
|
||||||
0x00, 0x00, 0xFF, 0x00, 0xEB
|
0x00, 0x00, 0xFF, 0x00, 0xEB
|
||||||
};
|
};
|
||||||
|
/* This controller passed security check */
|
||||||
|
static const Uint8 security_passed_packet[] = {
|
||||||
|
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This specifies the selection of init packets that a gamepad
|
* This specifies the selection of init packets that a gamepad
|
||||||
|
@ -90,16 +80,11 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
|
static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
|
||||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x04, 0xb0 } },
|
/* The PDP Rock Candy controller doesn't start sending input until it gets this packet */
|
||||||
|
{ 0x0e6f, 0x0246, 0x0000, 0x0000, security_passed_packet, sizeof(security_passed_packet), { 0x00, 0x00 } },
|
||||||
|
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x00, 0x00 } },
|
||||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x00, 0x00 } },
|
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x00, 0x00 } },
|
||||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } },
|
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } },
|
||||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init3, sizeof(xboxone_init3), { 0x00, 0x00 } },
|
|
||||||
|
|
||||||
/* These next packets are required for third party controllers (PowerA, PDP, HORI),
|
|
||||||
but aren't the correct protocol for Microsoft Xbox controllers.
|
|
||||||
*/
|
|
||||||
{ 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init4, sizeof(xboxone_init4), { 0x00, 0x00 } },
|
|
||||||
{ 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init5, sizeof(xboxone_init5), { 0x00, 0x00 } },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -185,7 +170,10 @@ SendAckIfNeeded(SDL_HIDAPI_Device *device, Uint8 *data, int size)
|
||||||
#ifdef DEBUG_XBOX_PROTOCOL
|
#ifdef DEBUG_XBOX_PROTOCOL
|
||||||
HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet));
|
HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet));
|
||||||
#endif
|
#endif
|
||||||
hid_write(device->dev, ack_packet, sizeof(ack_packet));
|
if (SDL_HIDAPI_LockRumble() < 0 ||
|
||||||
|
SDL_HIDAPI_SendRumbleAndUnlock(device, ack_packet, sizeof(ack_packet)) != sizeof(ack_packet)) {
|
||||||
|
SDL_SetError("Couldn't send ack packet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* __WIN32__ */
|
#endif /* __WIN32__ */
|
||||||
}
|
}
|
||||||
|
@ -633,6 +621,14 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||||
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
|
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
HIDAPI_DriverXboxOne_HandleStatusPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
||||||
|
{
|
||||||
|
if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
|
||||||
|
SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
||||||
{
|
{
|
||||||
|
@ -1000,16 +996,18 @@ HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||||
is firmware version 5.5.2641.0, and product version 0x0505 = 1285
|
is firmware version 5.5.2641.0, and product version 0x0505 = 1285
|
||||||
then 8 bytes of unknown data
|
then 8 bytes of unknown data
|
||||||
*/
|
*/
|
||||||
|
if (data[1] == 0x20) {
|
||||||
#ifdef DEBUG_JOYSTICK
|
#ifdef DEBUG_JOYSTICK
|
||||||
SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time));
|
SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time));
|
||||||
#endif
|
#endif
|
||||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING);
|
SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING);
|
||||||
|
} else {
|
||||||
|
/* Possibly an announce from a device plugged into the controller */
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
/* Controller heartbeat */
|
/* Controller status update */
|
||||||
if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
|
HIDAPI_DriverXboxOne_HandleStatusPacket(joystick, ctx, data, size);
|
||||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
/* Unknown chatty controller information, sent by both sides */
|
/* Unknown chatty controller information, sent by both sides */
|
||||||
|
|
Loading…
Reference in New Issue