Added SDL_GameControllerSendEffect() and SDL_JoystickSendEffect() to allow applications to send custom effects to the PS4 and PS5 controllers

See testgamecontroller.c for an example of a custom PS5 trigger effect
This commit is contained in:
Sam Lantinga
2021-07-08 13:22:41 -07:00
parent 073cbc40cb
commit d135c0762f
36 changed files with 533 additions and 186 deletions

View File

@@ -476,6 +476,12 @@ HIDAPI_DriverGameCube_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo
return SDL_Unsupported();
}
static int
HIDAPI_DriverGameCube_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -528,6 +534,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
HIDAPI_DriverGameCube_RumbleJoystickTriggers,
HIDAPI_DriverGameCube_HasJoystickLED,
HIDAPI_DriverGameCube_SetJoystickLED,
HIDAPI_DriverGameCube_SendJoystickEffect,
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled,
HIDAPI_DriverGameCube_CloseJoystick,
HIDAPI_DriverGameCube_FreeDevice,

View File

@@ -148,6 +148,12 @@ HIDAPI_DriverLuna_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
return SDL_Unsupported();
}
static int
HIDAPI_DriverLuna_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverLuna_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -441,6 +447,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna =
HIDAPI_DriverLuna_RumbleJoystickTriggers,
HIDAPI_DriverLuna_HasJoystickLED,
HIDAPI_DriverLuna_SetJoystickLED,
HIDAPI_DriverLuna_SendJoystickEffect,
HIDAPI_DriverLuna_SetJoystickSensorsEnabled,
HIDAPI_DriverLuna_CloseJoystick,
HIDAPI_DriverLuna_FreeDevice,

View File

@@ -146,6 +146,8 @@ typedef struct {
} SDL_DriverPS4_Context;
static int HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size);
static SDL_bool
HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
@@ -385,61 +387,26 @@ static int
HIDAPI_DriverPS4_UpdateEffects(SDL_HIDAPI_Device *device)
{
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
DS4EffectsState_t *effects;
Uint8 data[78];
int report_size, offset;
if (!ctx->effects_supported) {
return SDL_Unsupported();
}
DS4EffectsState_t effects;
if (!ctx->enhanced_mode) {
return SDL_Unsupported();
}
SDL_zero(data);
SDL_zero(effects);
if (ctx->is_bluetooth) {
data[0] = k_EPS4ReportIdBluetoothEffects;
data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */
data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */
report_size = 78;
offset = 6;
} else {
data[0] = k_EPS4ReportIdUsbEffects;
data[1] = 0x07; /* Magic value */
report_size = 32;
offset = 4;
}
effects = (DS4EffectsState_t *)&data[offset];
effects->ucRumbleLeft = ctx->rumble_left;
effects->ucRumbleRight = ctx->rumble_right;
effects.ucRumbleLeft = ctx->rumble_left;
effects.ucRumbleRight = ctx->rumble_right;
/* Populate the LED state with the appropriate color from our lookup table */
if (ctx->color_set) {
effects->ucLedRed = ctx->led_red;
effects->ucLedGreen = ctx->led_green;
effects->ucLedBlue = ctx->led_blue;
effects.ucLedRed = ctx->led_red;
effects.ucLedGreen = ctx->led_green;
effects.ucLedBlue = ctx->led_blue;
} else {
SetLedsForPlayerIndex(effects, ctx->player_index);
SetLedsForPlayerIndex(&effects, ctx->player_index);
}
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) {
return SDL_SetError("Couldn't send rumble packet");
}
return 0;
return HIDAPI_DriverPS4_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects));
}
static void
@@ -650,6 +617,55 @@ HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
return HIDAPI_DriverPS4_UpdateEffects(device);
}
static int
HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size)
{
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
Uint8 data[78];
int report_size, offset;
if (!ctx->effects_supported) {
return SDL_Unsupported();
}
if (!ctx->enhanced_mode) {
HIDAPI_DriverPS4_SetEnhancedMode(device, joystick);
}
SDL_zero(data);
if (ctx->is_bluetooth) {
data[0] = k_EPS4ReportIdBluetoothEffects;
data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */
data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */
report_size = 78;
offset = 6;
} else {
data[0] = k_EPS4ReportIdUsbEffects;
data[1] = 0x07; /* Magic value */
report_size = 32;
offset = 4;
}
SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), size));
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) {
return SDL_SetError("Couldn't send rumble packet");
}
return 0;
}
static int
HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -921,6 +937,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
HIDAPI_DriverPS4_RumbleJoystickTriggers,
HIDAPI_DriverPS4_HasJoystickLED,
HIDAPI_DriverPS4_SetJoystickLED,
HIDAPI_DriverPS4_SendJoystickEffect,
HIDAPI_DriverPS4_SetJoystickSensorsEnabled,
HIDAPI_DriverPS4_CloseJoystick,
HIDAPI_DriverPS4_FreeDevice,

View File

@@ -175,6 +175,8 @@ typedef struct {
} SDL_DriverPS5_Context;
static int HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size);
static SDL_bool
HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
@@ -375,32 +377,13 @@ static int
HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, int effect_mask)
{
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
DS5EffectsState_t *effects;
Uint8 data[78];
int report_size, offset;
Uint8 *pending_data;
int *pending_size;
int maximum_size;
DS5EffectsState_t effects;
if (!ctx->enhanced_mode) {
return SDL_Unsupported();
}
SDL_zero(data);
if (ctx->is_bluetooth) {
data[0] = k_EPS5ReportIdBluetoothEffects;
data[1] = 0x02; /* Magic value */
report_size = 78;
offset = 2;
} else {
data[0] = k_EPS5ReportIdUsbEffects;
report_size = 48;
offset = 1;
}
effects = (DS5EffectsState_t *)&data[offset];
SDL_zero(effects);
/* Make sure the Bluetooth connection sequence has completed before sending LED color change */
if (ctx->is_bluetooth &&
@@ -412,79 +395,53 @@ HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, int effect_mask)
}
if (ctx->rumble_left || ctx->rumble_right) {
effects->ucEnableBits1 |= 0x01; /* Enable rumble emulation */
effects->ucEnableBits1 |= 0x02; /* Disable audio haptics */
effects.ucEnableBits1 |= 0x01; /* Enable rumble emulation */
effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */
/* Shift to reduce effective rumble strength to match Xbox controllers */
effects->ucRumbleLeft = ctx->rumble_left >> 1;
effects->ucRumbleRight = ctx->rumble_right >> 1;
effects.ucRumbleLeft = ctx->rumble_left >> 1;
effects.ucRumbleRight = ctx->rumble_right >> 1;
} else {
/* Leaving emulated rumble bits off will restore audio haptics */
}
if ((effect_mask & k_EDS5EffectRumbleStart) != 0) {
effects->ucEnableBits1 |= 0x02; /* Disable audio haptics */
effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */
}
if ((effect_mask & k_EDS5EffectRumble) != 0) {
/* Already handled above */
}
if ((effect_mask & k_EDS5EffectLEDReset) != 0) {
effects->ucEnableBits2 |= 0x08; /* Reset LED state */
effects.ucEnableBits2 |= 0x08; /* Reset LED state */
}
if ((effect_mask & k_EDS5EffectLED) != 0) {
effects->ucEnableBits2 |= 0x04; /* Enable LED color */
effects.ucEnableBits2 |= 0x04; /* Enable LED color */
/* Populate the LED state with the appropriate color from our lookup table */
if (ctx->color_set) {
effects->ucLedRed = ctx->led_red;
effects->ucLedGreen = ctx->led_green;
effects->ucLedBlue = ctx->led_blue;
effects.ucLedRed = ctx->led_red;
effects.ucLedGreen = ctx->led_green;
effects.ucLedBlue = ctx->led_blue;
} else {
SetLedsForPlayerIndex(effects, ctx->player_index);
SetLedsForPlayerIndex(&effects, ctx->player_index);
}
}
if ((effect_mask & k_EDS5EffectPadLights) != 0) {
effects->ucEnableBits2 |= 0x10; /* Enable touchpad lights */
effects.ucEnableBits2 |= 0x10; /* Enable touchpad lights */
if (ctx->player_lights) {
SetLightsForPlayerIndex(effects, ctx->player_index);
SetLightsForPlayerIndex(&effects, ctx->player_index);
} else {
effects->ucPadLights = 0x00;
effects.ucPadLights = 0x00;
}
}
if ((effect_mask & k_EDS5EffectMicLight) != 0) {
effects->ucEnableBits2 |= 0x01; /* Enable microphone light */
effects.ucEnableBits2 |= 0x01; /* Enable microphone light */
effects->ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */
effects.ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */
}
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_LockRumble() < 0) {
return -1;
}
/* See if we can update an existing pending request */
if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) {
DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset];
if (report_size == *pending_size &&
effects->ucEnableBits1 == pending_effects->ucEnableBits1 &&
effects->ucEnableBits2 == pending_effects->ucEnableBits2) {
/* We're simply updating the data for this request */
SDL_memcpy(pending_data, data, report_size);
SDL_HIDAPI_UnlockRumble();
return 0;
}
}
return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
return HIDAPI_DriverPS5_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects));
}
static void
@@ -725,6 +682,67 @@ HIDAPI_DriverPS5_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
return HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED);
}
static int
HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size)
{
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
Uint8 data[78];
int report_size, offset;
Uint8 *pending_data;
int *pending_size;
int maximum_size;
if (!ctx->enhanced_mode) {
HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
}
SDL_zero(data);
if (ctx->is_bluetooth) {
data[0] = k_EPS5ReportIdBluetoothEffects;
data[1] = 0x02; /* Magic value */
report_size = 78;
offset = 2;
} else {
data[0] = k_EPS5ReportIdUsbEffects;
report_size = 48;
offset = 1;
}
SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), size));
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_LockRumble() < 0) {
return -1;
}
/* See if we can update an existing pending request */
if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) {
DS5EffectsState_t *effects = (DS5EffectsState_t *)&data[offset];
DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset];
if (report_size == *pending_size &&
effects->ucEnableBits1 == pending_effects->ucEnableBits1 &&
effects->ucEnableBits2 == pending_effects->ucEnableBits2) {
/* We're simply updating the data for this request */
SDL_memcpy(pending_data, data, report_size);
SDL_HIDAPI_UnlockRumble();
return 0;
}
}
return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
}
static int
HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1082,6 +1100,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
HIDAPI_DriverPS5_RumbleJoystickTriggers,
HIDAPI_DriverPS5_HasJoystickLED,
HIDAPI_DriverPS5_SetJoystickLED,
HIDAPI_DriverPS5_SendJoystickEffect,
HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
HIDAPI_DriverPS5_CloseJoystick,
HIDAPI_DriverPS5_FreeDevice,

View File

@@ -141,6 +141,12 @@ HIDAPI_DriverStadia_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joys
return SDL_Unsupported();
}
static int
HIDAPI_DriverStadia_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverStadia_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -314,6 +320,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia =
HIDAPI_DriverStadia_RumbleJoystickTriggers,
HIDAPI_DriverStadia_HasJoystickLED,
HIDAPI_DriverStadia_SetJoystickLED,
HIDAPI_DriverStadia_SendJoystickEffect,
HIDAPI_DriverStadia_SetJoystickSensorsEnabled,
HIDAPI_DriverStadia_CloseJoystick,
HIDAPI_DriverStadia_FreeDevice,

View File

@@ -1058,6 +1058,12 @@ HIDAPI_DriverSteam_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
return SDL_Unsupported();
}
static int
HIDAPI_DriverSteam_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverSteam_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1207,6 +1213,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
HIDAPI_DriverSteam_RumbleJoystickTriggers,
HIDAPI_DriverSteam_HasJoystickLED,
HIDAPI_DriverSteam_SetJoystickLED,
HIDAPI_DriverSteam_SendJoystickEffect,
HIDAPI_DriverSteam_SetSensorsEnabled,
HIDAPI_DriverSteam_CloseJoystick,
HIDAPI_DriverSteam_FreeDevice,

View File

@@ -1052,6 +1052,12 @@ HIDAPI_DriverSwitch_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joys
return SDL_Unsupported();
}
static int
HIDAPI_DriverSwitch_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1497,6 +1503,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
HIDAPI_DriverSwitch_RumbleJoystickTriggers,
HIDAPI_DriverSwitch_HasJoystickLED,
HIDAPI_DriverSwitch_SetJoystickLED,
HIDAPI_DriverSwitch_SendJoystickEffect,
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled,
HIDAPI_DriverSwitch_CloseJoystick,
HIDAPI_DriverSwitch_FreeDevice,

View File

@@ -216,6 +216,12 @@ HIDAPI_DriverXbox360_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joy
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -342,6 +348,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
HIDAPI_DriverXbox360_RumbleJoystickTriggers,
HIDAPI_DriverXbox360_HasJoystickLED,
HIDAPI_DriverXbox360_SetJoystickLED,
HIDAPI_DriverXbox360_SendJoystickEffect,
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled,
HIDAPI_DriverXbox360_CloseJoystick,
HIDAPI_DriverXbox360_FreeDevice,

View File

@@ -186,6 +186,12 @@ HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360W_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -339,6 +345,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
HIDAPI_DriverXbox360W_RumbleJoystickTriggers,
HIDAPI_DriverXbox360W_HasJoystickLED,
HIDAPI_DriverXbox360W_SetJoystickLED,
HIDAPI_DriverXbox360W_SendJoystickEffect,
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled,
HIDAPI_DriverXbox360W_CloseJoystick,
HIDAPI_DriverXbox360W_FreeDevice,

View File

@@ -439,6 +439,12 @@ HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joy
return SDL_Unsupported();
}
static int
HIDAPI_DriverXboxOne_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1078,6 +1084,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
HIDAPI_DriverXboxOne_RumbleJoystickTriggers,
HIDAPI_DriverXboxOne_HasJoystickLED,
HIDAPI_DriverXboxOne_SetJoystickLED,
HIDAPI_DriverXboxOne_SendJoystickEffect,
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled,
HIDAPI_DriverXboxOne_CloseJoystick,
HIDAPI_DriverXboxOne_FreeDevice,

View File

@@ -565,7 +565,7 @@ HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float
}
static void HIDAPI_JoystickDetect(void);
static void HIDAPI_JoystickClose(SDL_Joystick * joystick);
static void HIDAPI_JoystickClose(SDL_Joystick *joystick);
static SDL_bool
HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
@@ -1269,7 +1269,7 @@ HIDAPI_JoystickGetDeviceInstanceID(int device_index)
}
static int
HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
SDL_JoystickID joystickID;
SDL_HIDAPI_Device *device = HIDAPI_GetDeviceByIndex(device_index, &joystickID);
@@ -1295,7 +1295,7 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
}
static int
HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
int result;
@@ -1312,7 +1312,7 @@ HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
}
static int
HIDAPI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
int result;
@@ -1329,7 +1329,7 @@ HIDAPI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint1
}
static SDL_bool
HIDAPI_JoystickHasLED(SDL_Joystick * joystick)
HIDAPI_JoystickHasLED(SDL_Joystick *joystick)
{
SDL_bool result = SDL_FALSE;
@@ -1343,7 +1343,7 @@ HIDAPI_JoystickHasLED(SDL_Joystick * joystick)
}
static int
HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
int result;
@@ -1360,7 +1360,24 @@ HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blu
}
static int
HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled)
HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
int result;
if (joystick->hwdata) {
SDL_HIDAPI_Device *device = joystick->hwdata->device;
result = device->driver->SendJoystickEffect(device, joystick, data, size);
} else {
SDL_SetError("SendEffect failed, device disconnected");
result = -1;
}
return result;
}
static int
HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
int result;
@@ -1377,13 +1394,13 @@ HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled)
}
static void
HIDAPI_JoystickUpdate(SDL_Joystick * joystick)
HIDAPI_JoystickUpdate(SDL_Joystick *joystick)
{
/* This is handled in SDL_HIDAPI_UpdateDevices() */
}
static void
HIDAPI_JoystickClose(SDL_Joystick * joystick)
HIDAPI_JoystickClose(SDL_Joystick *joystick)
{
if (joystick->hwdata) {
SDL_HIDAPI_Device *device = joystick->hwdata->device;
@@ -1470,6 +1487,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickRumbleTriggers,
HIDAPI_JoystickHasLED,
HIDAPI_JoystickSetLED,
HIDAPI_JoystickSendEffect,
HIDAPI_JoystickSetSensorsEnabled,
HIDAPI_JoystickUpdate,
HIDAPI_JoystickClose,

View File

@@ -99,6 +99,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble);
SDL_bool (*HasJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
int (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size);
int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled);
void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
void (*FreeDevice)(SDL_HIDAPI_Device *device);