mirror of https://github.com/encounter/SDL.git
Xbox One controller rumble doesn't need synchronization if you use a packet counter of 0
This commit is contained in:
parent
2cd88ddf99
commit
20d67446e0
|
@ -74,11 +74,6 @@ static const Uint8 xboxone_init6[] = {
|
||||||
0x00, 0x00, 0xFF, 0x00, 0xEB
|
0x00, 0x00, 0xFF, 0x00, 0xEB
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Uint8 xboxone_rumble_reset[] = {
|
|
||||||
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This specifies the selection of init packets that a gamepad
|
* This specifies the selection of init packets that a gamepad
|
||||||
* will be sent on init *and* the order in which they will be
|
* will be sent on init *and* the order in which they will be
|
||||||
|
@ -117,8 +112,6 @@ typedef struct {
|
||||||
SDL_bool initialized;
|
SDL_bool initialized;
|
||||||
Uint8 sequence;
|
Uint8 sequence;
|
||||||
Uint8 last_state[USB_PACKET_LENGTH];
|
Uint8 last_state[USB_PACKET_LENGTH];
|
||||||
SDL_bool rumble_synchronized;
|
|
||||||
SDL_bool rumble_synchronization_complete;
|
|
||||||
SDL_bool has_paddles;
|
SDL_bool has_paddles;
|
||||||
} SDL_DriverXboxOne_Context;
|
} SDL_DriverXboxOne_Context;
|
||||||
|
|
||||||
|
@ -168,47 +161,6 @@ ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
|
||||||
ControllerNeedsRumbleSequenceSynchronized(Uint16 vendor_id, Uint16 product_id)
|
|
||||||
{
|
|
||||||
if (vendor_id == USB_VENDOR_MICROSOFT) {
|
|
||||||
/* All Xbox One controllers, from model 1537 through Elite Series 2, appear to need this */
|
|
||||||
return SDL_TRUE;
|
|
||||||
}
|
|
||||||
return SDL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SDL_bool
|
|
||||||
SynchronizeRumbleSequence(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx)
|
|
||||||
{
|
|
||||||
Uint16 vendor_id = ctx->vendor_id;
|
|
||||||
Uint16 product_id = ctx->product_id;
|
|
||||||
|
|
||||||
if (ctx->rumble_synchronized) {
|
|
||||||
return SDL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ControllerNeedsRumbleSequenceSynchronized(vendor_id, product_id)) {
|
|
||||||
int i;
|
|
||||||
Uint8 init_packet[USB_PACKET_LENGTH];
|
|
||||||
|
|
||||||
SDL_memcpy(init_packet, xboxone_rumble_reset, sizeof(xboxone_rumble_reset));
|
|
||||||
for (i = 0; i < 255; ++i) {
|
|
||||||
init_packet[2] = ((ctx->sequence + i) % 255);
|
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
|
||||||
return SDL_FALSE;
|
|
||||||
}
|
|
||||||
if (SDL_HIDAPI_SendRumbleAndUnlock(device, init_packet, sizeof(xboxone_rumble_reset)) != sizeof(xboxone_rumble_reset)) {
|
|
||||||
SDL_SetError("Couldn't write Xbox One initialization packet");
|
|
||||||
return SDL_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx->rumble_synchronized = SDL_TRUE;
|
|
||||||
|
|
||||||
return SDL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true if this controller sends the 0x02 "waiting for init" packet */
|
/* Return true if this controller sends the 0x02 "waiting for init" packet */
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
ControllerSendsWaitingForInit(Uint16 vendor_id, Uint16 product_id)
|
ControllerSendsWaitingForInit(Uint16 vendor_id, Uint16 product_id)
|
||||||
|
@ -293,8 +245,6 @@ SendControllerInit(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SynchronizeRumbleSequence(device, ctx);
|
|
||||||
|
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,41 +323,14 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||||
static int
|
static int
|
||||||
HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||||
{
|
{
|
||||||
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
|
||||||
Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
|
Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
|
||||||
Uint8 *pending_rumble;
|
|
||||||
int *pending_size;
|
|
||||||
int maximum_size;
|
|
||||||
|
|
||||||
SynchronizeRumbleSequence(device, ctx);
|
/* Magnitude is 1..100 so scale the 16-bit input here */
|
||||||
|
rumble_packet[8] = low_frequency_rumble / 655;
|
||||||
|
rumble_packet[9] = high_frequency_rumble / 655;
|
||||||
|
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
|
||||||
return -1;
|
return SDL_SetError("Couldn't send rumble packet");
|
||||||
}
|
|
||||||
|
|
||||||
if (!ctx->rumble_synchronization_complete) {
|
|
||||||
if (!SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_rumble, &pending_size, &maximum_size)) {
|
|
||||||
/* Rumble synchronization has drained */
|
|
||||||
ctx->rumble_synchronization_complete = SDL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to overwrite any pending rumble with the new value */
|
|
||||||
if (ctx->rumble_synchronization_complete &&
|
|
||||||
SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_rumble, &pending_size, &maximum_size)) {
|
|
||||||
/* Magnitude is 1..100 so scale the 16-bit input here */
|
|
||||||
pending_rumble[8] = low_frequency_rumble / 655;
|
|
||||||
pending_rumble[9] = high_frequency_rumble / 655;
|
|
||||||
SDL_HIDAPI_UnlockRumble();
|
|
||||||
} else {
|
|
||||||
/* Magnitude is 1..100 so scale the 16-bit input here */
|
|
||||||
rumble_packet[2] = ctx->sequence++;
|
|
||||||
rumble_packet[8] = low_frequency_rumble / 655;
|
|
||||||
rumble_packet[9] = high_frequency_rumble / 655;
|
|
||||||
|
|
||||||
if (SDL_HIDAPI_SendRumbleAndUnlock(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
|
|
||||||
return SDL_SetError("Couldn't send rumble packet");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue