Moved rumble expiration to the main joystick handling level, and prevent sending the driver layer duplicate rumble requests.

Sam Lantinga 2020-02-04 12:48:53 -08:00
parent 976eee77cc
commit 6efebf1768
25 changed files with 94 additions and 237 deletions

View File

@ -758,7 +758,26 @@ SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16
} }
SDL_LockJoysticks(); SDL_LockJoysticks();
result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms); if (low_frequency_rumble == joystick->low_frequency_rumble &&
high_frequency_rumble == joystick->high_frequency_rumble) {
/* Just update the expiration */
result = 0;
} else {
result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
}
/* Save the rumble value regardless of success, so we don't spam the driver */
joystick->low_frequency_rumble = low_frequency_rumble;
joystick->high_frequency_rumble = high_frequency_rumble;
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->rumble_expiration) {
joystick->rumble_expiration = 1;
}
} else {
joystick->rumble_expiration = 0;
}
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
return result; return result;
@ -790,6 +809,10 @@ SDL_JoystickClose(SDL_Joystick * joystick)
return; return;
} }
if (joystick->rumble_expiration) {
SDL_JoystickRumble(joystick, 0, 0, 0);
}
joystick->driver->Close(joystick); joystick->driver->Close(joystick);
joystick->hwdata = NULL; joystick->hwdata = NULL;
@ -1217,6 +1240,16 @@ SDL_JoystickUpdate(void)
} }
} }
if (joystick->rumble_expiration) {
SDL_LockJoysticks();
/* Double check now that the lock is held */
if (joystick->rumble_expiration &&
SDL_TICKS_PASSED(SDL_GetTicks(), joystick->rumble_expiration)) {
SDL_JoystickRumble(joystick, 0, 0, 0);
}
SDL_UnlockJoysticks();
}
if (joystick->force_recentering) { if (joystick->force_recentering) {
/* Tell the app that everything is centered/unpressed... */ /* Tell the app that everything is centered/unpressed... */
for (i = 0; i < joystick->naxes; i++) { for (i = 0; i < joystick->naxes; i++) {

View File

@ -60,6 +60,10 @@ struct _SDL_Joystick
int nbuttons; /* Number of buttons on the joystick */ int nbuttons; /* Number of buttons on the joystick */
Uint8 *buttons; /* Current button states */ Uint8 *buttons; /* Current button states */
Uint16 low_frequency_rumble;
Uint16 high_frequency_rumble;
Uint32 rumble_expiration;
SDL_bool attached; SDL_bool attached;
SDL_bool is_game_controller; SDL_bool is_game_controller;
SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */ SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */
@ -118,7 +122,7 @@ typedef struct _SDL_JoystickDriver
int (*Open)(SDL_Joystick * joystick, int device_index); int (*Open)(SDL_Joystick * joystick, int device_index);
/* Rumble functionality */ /* Rumble functionality */
int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
/* Function to update the state of a joystick - called as a device poll. /* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly, * This function shouldn't update the joystick structure directly,
@ -135,6 +139,9 @@ typedef struct _SDL_JoystickDriver
} SDL_JoystickDriver; } SDL_JoystickDriver;
/* Windows and Mac OSX has a limit of MAX_DWORD / 1000, Linux kernel has a limit of 0xFFFF */
#define SDL_MAX_RUMBLE_DURATION_MS 0xFFFF
/* The available joystick drivers */ /* The available joystick drivers */
extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver; extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver;
extern SDL_JoystickDriver SDL_BSD_JoystickDriver; extern SDL_JoystickDriver SDL_BSD_JoystickDriver;

View File

@ -629,7 +629,7 @@ ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index)
} }
static int static int
ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -757,7 +757,7 @@ report_free(struct report *r)
} }
static int static int
BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -52,7 +52,7 @@ void FreeRumbleEffectData(FFEFFECT *effect)
SDL_free(effect); SDL_free(effect);
} }
FFEFFECT *CreateRumbleEffectData(Sint16 magnitude, Uint32 duration_ms) FFEFFECT *CreateRumbleEffectData(Sint16 magnitude)
{ {
FFEFFECT *effect; FFEFFECT *effect;
FFPERIODIC *periodic; FFPERIODIC *periodic;
@ -65,7 +65,7 @@ FFEFFECT *CreateRumbleEffectData(Sint16 magnitude, Uint32 duration_ms)
effect->dwSize = sizeof(*effect); effect->dwSize = sizeof(*effect);
effect->dwGain = 10000; effect->dwGain = 10000;
effect->dwFlags = FFEFF_OBJECTOFFSETS; effect->dwFlags = FFEFF_OBJECTOFFSETS;
effect->dwDuration = duration_ms * 1000; /* In microseconds. */ effect->dwDuration = SDL_MAX_RUMBLE_DURATION_MS * 1000; /* In microseconds. */
effect->dwTriggerButton = FFEB_NOTRIGGER; effect->dwTriggerButton = FFEB_NOTRIGGER;
effect->cAxes = 2; effect->cAxes = 2;
@ -832,7 +832,7 @@ FFStrError(unsigned int err)
} }
static int static int
DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude, Uint32 duration_ms) DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude)
{ {
HRESULT result; HRESULT result;
@ -855,7 +855,7 @@ DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude, Uint32 duration_m
} }
/* Create the effect */ /* Create the effect */
device->ffeffect = CreateRumbleEffectData(magnitude, duration_ms); device->ffeffect = CreateRumbleEffectData(magnitude);
if (!device->ffeffect) { if (!device->ffeffect) {
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
@ -869,7 +869,7 @@ DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude, Uint32 duration_m
} }
static int static int
DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
HRESULT result; HRESULT result;
recDevice *device = joystick->hwdata; recDevice *device = joystick->hwdata;
@ -883,7 +883,6 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
if (device->ff_initialized) { if (device->ff_initialized) {
FFPERIODIC *periodic = ((FFPERIODIC *)device->ffeffect->lpvTypeSpecificParams); FFPERIODIC *periodic = ((FFPERIODIC *)device->ffeffect->lpvTypeSpecificParams);
device->ffeffect->dwDuration = duration_ms * 1000; /* In microseconds. */
periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude); periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude);
result = FFEffectSetParameters(device->ffeffect_ref, device->ffeffect, result = FFEffectSetParameters(device->ffeffect_ref, device->ffeffect,
@ -892,7 +891,7 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
return SDL_SetError("Unable to update rumble effect: %s", FFStrError(result)); return SDL_SetError("Unable to update rumble effect: %s", FFStrError(result));
} }
} else { } else {
if (DARWIN_JoystickInitRumble(device, magnitude, duration_ms) < 0) { if (DARWIN_JoystickInitRumble(device, magnitude) < 0) {
return -1; return -1;
} }
device->ff_initialized = SDL_TRUE; device->ff_initialized = SDL_TRUE;

View File

@ -84,7 +84,7 @@ DUMMY_JoystickOpen(SDL_Joystick * joystick, int device_index)
} }
static int static int
DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -399,7 +399,7 @@ EMSCRIPTEN_JoystickGetDeviceGUID(int device_index)
} }
static int static int
EMSCRIPTEN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) EMSCRIPTEN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -254,7 +254,7 @@ extern "C"
return guid; return guid;
} }
static int HAIKU_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) static int HAIKU_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -44,7 +44,6 @@ typedef struct {
Uint8 max_axis[MAX_CONTROLLERS*SDL_CONTROLLER_AXIS_MAX]; Uint8 max_axis[MAX_CONTROLLERS*SDL_CONTROLLER_AXIS_MAX];
Uint8 rumbleAllowed[MAX_CONTROLLERS]; Uint8 rumbleAllowed[MAX_CONTROLLERS];
Uint8 rumble[1+MAX_CONTROLLERS]; Uint8 rumble[1+MAX_CONTROLLERS];
Uint32 rumbleExpiration[MAX_CONTROLLERS];
/* Without this variable, hid_write starts to lag a TON */ /* Without this variable, hid_write starts to lag a TON */
SDL_bool rumbleUpdate; SDL_bool rumbleUpdate;
} SDL_DriverGameCube_Context; } SDL_DriverGameCube_Context;
@ -285,16 +284,6 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
} }
/* Write rumble packet */ /* Write rumble packet */
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
if (ctx->rumbleExpiration[i] || (ctx->rumble[1 + i] && !ctx->rumbleAllowed[i])) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, ctx->rumbleExpiration[i]) || !ctx->rumbleAllowed[i]) {
ctx->rumble[1 + i] = 0;
ctx->rumbleExpiration[i] = 0;
ctx->rumbleUpdate = SDL_TRUE;
}
}
}
if (ctx->rumbleUpdate) { if (ctx->rumbleUpdate) {
hid_write(device->dev, ctx->rumble, sizeof(ctx->rumble)); hid_write(device->dev, ctx->rumble, sizeof(ctx->rumble));
ctx->rumbleUpdate = SDL_FALSE; ctx->rumbleUpdate = SDL_FALSE;
@ -321,7 +310,7 @@ HIDAPI_DriverGameCube_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
} }
static int static int
HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
Uint8 i, val; Uint8 i, val;
@ -338,14 +327,6 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
ctx->rumble[i + 1] = val; ctx->rumble[i + 1] = val;
ctx->rumbleUpdate = SDL_TRUE; ctx->rumbleUpdate = SDL_TRUE;
} }
if (val && duration_ms) {
ctx->rumbleExpiration[i] = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!ctx->rumbleExpiration[i]) {
ctx->rumbleExpiration[i] = 1;
}
} else {
ctx->rumbleExpiration[i] = 0;
}
return 0; return 0;
} }
} }
@ -359,18 +340,11 @@ static void
HIDAPI_DriverGameCube_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) HIDAPI_DriverGameCube_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{ {
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
Uint8 i;
/* Stop rumble activity */ /* Stop rumble activity */
for (i = 0; i < MAX_CONTROLLERS; i += 1) { if (ctx->rumbleUpdate) {
if (joystick->instance_id == ctx->joysticks[i]) {
if (!ctx->wireless[i] && ctx->rumbleAllowed[i] && ctx->rumble[1 + i] != 0) {
ctx->rumble[1 + i] = 0;
ctx->rumbleExpiration[i] = 0;
hid_write(device->dev, ctx->rumble, sizeof(ctx->rumble)); hid_write(device->dev, ctx->rumble, sizeof(ctx->rumble));
} ctx->rumbleUpdate = SDL_FALSE;
break;
}
} }
} }

View File

@ -37,8 +37,6 @@
#ifdef SDL_JOYSTICK_HIDAPI_PS4 #ifdef SDL_JOYSTICK_HIDAPI_PS4
#define USB_PACKET_LENGTH 64
typedef enum typedef enum
{ {
k_EPS4ReportIdUsbState = 1, k_EPS4ReportIdUsbState = 1,
@ -103,7 +101,6 @@ typedef struct {
SDL_bool rumble_supported; SDL_bool rumble_supported;
Uint8 volume; Uint8 volume;
Uint32 last_volume_check; Uint32 last_volume_check;
Uint32 rumble_expiration;
PS4StatePacket_t last_state; PS4StatePacket_t last_state;
} SDL_DriverPS4_Context; } SDL_DriverPS4_Context;
@ -201,7 +198,7 @@ HIDAPI_DriverPS4_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID
{ {
} }
static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
static SDL_bool static SDL_bool
HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
@ -251,7 +248,7 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
} }
/* Initialize LED and effect state */ /* Initialize LED and effect state */
HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0, 0); HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0);
/* Initialize the joystick capabilities */ /* Initialize the joystick capabilities */
joystick->nbuttons = 16; joystick->nbuttons = 16;
@ -262,7 +259,7 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
} }
static int static int
HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
DS4EffectsState_t *effects; DS4EffectsState_t *effects;
@ -311,15 +308,6 @@ HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
if (hid_write(device->dev, data, report_size) != report_size) { if (hid_write(device->dev, data, report_size) != report_size) {
return SDL_SetError("Couldn't send rumble packet"); return SDL_SetError("Couldn't send rumble packet");
} }
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!ctx->rumble_expiration) {
ctx->rumble_expiration = 1;
}
} else {
ctx->rumble_expiration = 0;
}
return 0; return 0;
} }
@ -465,13 +453,6 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
} }
} }
if (ctx->rumble_expiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0, 0);
}
}
if (size < 0) { if (size < 0) {
/* Read error, device is disconnected */ /* Read error, device is disconnected */
HIDAPI_JoystickDisconnected(device, joystick->instance_id); HIDAPI_JoystickDisconnected(device, joystick->instance_id);
@ -482,12 +463,6 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
static void static void
HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{ {
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
if (ctx->rumble_expiration) {
HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0, 0);
}
hid_close(device->dev); hid_close(device->dev);
device->dev = NULL; device->dev = NULL;

View File

@ -1029,7 +1029,7 @@ error:
} }
static int static int
HIDAPI_DriverSteam_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) HIDAPI_DriverSteam_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
/* You should use the full Steam Input API for rumble support */ /* You should use the full Steam Input API for rumble support */
return SDL_Unsupported(); return SDL_Unsupported();

View File

@ -199,7 +199,6 @@ typedef struct {
SDL_bool m_bUseButtonLabels; SDL_bool m_bUseButtonLabels;
Uint8 m_nCommandNumber; Uint8 m_nCommandNumber;
SwitchCommonOutputPacket_t m_RumblePacket; SwitchCommonOutputPacket_t m_RumblePacket;
Uint32 m_nRumbleExpiration;
Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength]; Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength];
SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState; SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState;
@ -739,7 +738,7 @@ error:
} }
static int static int
HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
@ -770,15 +769,6 @@ HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
SDL_SetError("Couldn't send rumble packet"); SDL_SetError("Couldn't send rumble packet");
return -1; return -1;
} }
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
ctx->m_nRumbleExpiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!ctx->m_nRumbleExpiration) {
ctx->m_nRumbleExpiration = 1;
}
} else {
ctx->m_nRumbleExpiration = 0;
}
return 0; return 0;
} }
@ -1075,13 +1065,6 @@ HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
} }
} }
if (ctx->m_nRumbleExpiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, ctx->m_nRumbleExpiration)) {
HIDAPI_DriverSwitch_RumbleJoystick(device, joystick, 0, 0, 0);
}
}
if (size < 0) { if (size < 0) {
/* Read error, device is disconnected */ /* Read error, device is disconnected */
HIDAPI_JoystickDisconnected(device, joystick->instance_id); HIDAPI_JoystickDisconnected(device, joystick->instance_id);
@ -1094,10 +1077,6 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
{ {
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
if (ctx->m_nRumbleExpiration) {
HIDAPI_DriverSwitch_RumbleJoystick(device, joystick, 0, 0, 0);
}
if (!ctx->m_bInputOnly) { if (!ctx->m_bInputOnly) {
/* Restore simple input mode for other applications */ /* Restore simple input mode for other applications */
SetInputMode(ctx, k_eSwitchInputReportIDs_SimpleControllerState); SetInputMode(ctx, k_eSwitchInputReportIDs_SimpleControllerState);

View File

@ -50,12 +50,9 @@
#include "windows.gaming.input.h" #include "windows.gaming.input.h"
#endif #endif
#define USB_PACKET_LENGTH 64
typedef struct { typedef struct {
Uint8 last_state[USB_PACKET_LENGTH]; Uint8 last_state[USB_PACKET_LENGTH];
Uint32 rumble_expiration;
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT #ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
SDL_bool xinput_enabled; SDL_bool xinput_enabled;
Uint8 xinput_slot; Uint8 xinput_slot;
@ -362,9 +359,11 @@ HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
} }
static int static int
HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
#if defined(SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT) || defined(SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT)
SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context; SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context;
#endif
#ifdef __WIN32__ #ifdef __WIN32__
SDL_bool rumbled = SDL_FALSE; SDL_bool rumbled = SDL_FALSE;
@ -422,14 +421,6 @@ HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
} }
#endif /* __WIN32__ */ #endif /* __WIN32__ */
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!ctx->rumble_expiration) {
ctx->rumble_expiration = 1;
}
} else {
ctx->rumble_expiration = 0;
}
return 0; return 0;
} }
@ -802,13 +793,6 @@ HIDAPI_DriverXbox360_UpdateDevice(SDL_HIDAPI_Device *device)
#endif /* __WIN32__ */ #endif /* __WIN32__ */
} }
if (ctx->rumble_expiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
HIDAPI_DriverXbox360_RumbleJoystick(device, joystick, 0, 0, 0);
}
}
if (size < 0) { if (size < 0) {
/* Read error, device is disconnected */ /* Read error, device is disconnected */
HIDAPI_JoystickDisconnected(device, joystick->instance_id); HIDAPI_JoystickDisconnected(device, joystick->instance_id);
@ -819,11 +803,9 @@ HIDAPI_DriverXbox360_UpdateDevice(SDL_HIDAPI_Device *device)
static void static void
HIDAPI_DriverXbox360_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) HIDAPI_DriverXbox360_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{ {
#if defined(SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT) || defined(SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT)
SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context; SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context;
#endif
if (ctx->rumble_expiration) {
HIDAPI_DriverXbox360_RumbleJoystick(device, joystick, 0, 0, 0);
}
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT #ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
if (ctx->xinput_enabled) { if (ctx->xinput_enabled) {

View File

@ -34,13 +34,10 @@
#ifdef SDL_JOYSTICK_HIDAPI_XBOX360 #ifdef SDL_JOYSTICK_HIDAPI_XBOX360
#define USB_PACKET_LENGTH 64
typedef struct { typedef struct {
SDL_bool connected; SDL_bool connected;
Uint8 last_state[USB_PACKET_LENGTH]; Uint8 last_state[USB_PACKET_LENGTH];
Uint32 rumble_expiration;
} SDL_DriverXbox360W_Context; } SDL_DriverXbox360W_Context;
@ -147,10 +144,8 @@ HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
} }
static int static int
HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context;
Uint8 rumble_packet[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; Uint8 rumble_packet[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
rumble_packet[5] = (low_frequency_rumble >> 8); rumble_packet[5] = (low_frequency_rumble >> 8);
@ -159,15 +154,6 @@ HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
if (hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { if (hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
return SDL_SetError("Couldn't send rumble packet"); return SDL_SetError("Couldn't send rumble packet");
} }
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!ctx->rumble_expiration) {
ctx->rumble_expiration = 1;
}
} else {
ctx->rumble_expiration = 0;
}
return 0; return 0;
} }
@ -273,13 +259,6 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
} }
if (joystick) { if (joystick) {
if (ctx->rumble_expiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
HIDAPI_DriverXbox360W_RumbleJoystick(device, joystick, 0, 0, 0);
}
}
if (size < 0) { if (size < 0) {
/* Read error, device is disconnected */ /* Read error, device is disconnected */
HIDAPI_JoystickDisconnected(device, joystick->instance_id); HIDAPI_JoystickDisconnected(device, joystick->instance_id);
@ -291,11 +270,6 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
static void static void
HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{ {
SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context;
if (ctx->rumble_expiration) {
HIDAPI_DriverXbox360W_RumbleJoystick(device, joystick, 0, 0, 0);
}
} }
static void static void

View File

@ -37,8 +37,6 @@
/* Define this if you want to log all packets from the controller */ /* Define this if you want to log all packets from the controller */
/*#define DEBUG_XBOX_PROTOCOL*/ /*#define DEBUG_XBOX_PROTOCOL*/
#define USB_PACKET_LENGTH 64
/* The amount of time to wait after hotplug to send controller init sequence */ /* The amount of time to wait after hotplug to send controller init sequence */
#define CONTROLLER_INIT_DELAY_MS 1500 /* 475 for Xbox One S, 1275 for the PDP Battlefield 1 */ #define CONTROLLER_INIT_DELAY_MS 1500 /* 475 for Xbox One S, 1275 for the PDP Battlefield 1 */
@ -119,7 +117,6 @@ typedef struct {
Uint8 sequence; Uint8 sequence;
Uint8 last_state[USB_PACKET_LENGTH]; Uint8 last_state[USB_PACKET_LENGTH];
SDL_bool rumble_synchronized; SDL_bool rumble_synchronized;
Uint32 rumble_expiration;
SDL_bool has_paddles; SDL_bool has_paddles;
} SDL_DriverXboxOne_Context; } SDL_DriverXboxOne_Context;
@ -369,7 +366,7 @@ 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, Uint32 duration_ms) 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; 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 };
@ -384,15 +381,6 @@ HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
if (hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { if (hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
return SDL_SetError("Couldn't send rumble packet"); return SDL_SetError("Couldn't send rumble packet");
} }
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!ctx->rumble_expiration) {
ctx->rumble_expiration = 1;
}
} else {
ctx->rumble_expiration = 0;
}
return 0; return 0;
} }
@ -578,13 +566,6 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
} }
} }
if (ctx->rumble_expiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
HIDAPI_DriverXboxOne_RumbleJoystick(device, joystick, 0, 0, 0);
}
}
if (size < 0) { if (size < 0) {
/* Read error, device is disconnected */ /* Read error, device is disconnected */
HIDAPI_JoystickDisconnected(device, joystick->instance_id); HIDAPI_JoystickDisconnected(device, joystick->instance_id);
@ -595,12 +576,6 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
static void static void
HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{ {
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
if (ctx->rumble_expiration) {
HIDAPI_DriverXboxOne_RumbleJoystick(device, joystick, 0, 0, 0);
}
hid_close(device->dev); hid_close(device->dev);
device->dev = NULL; device->dev = NULL;

View File

@ -1001,14 +1001,14 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
} }
static int static int
HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
int result; int result;
if (joystick->hwdata) { if (joystick->hwdata) {
SDL_HIDAPI_Device *device = joystick->hwdata->device; SDL_HIDAPI_Device *device = joystick->hwdata->device;
result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble, duration_ms); result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble);
} else { } else {
SDL_SetError("Rumble failed, device disconnected"); SDL_SetError("Rumble failed, device disconnected");
result = -1; result = -1;

View File

@ -50,9 +50,6 @@
#define SDL_JOYSTICK_HIDAPI_STEAM #define SDL_JOYSTICK_HIDAPI_STEAM
#endif #endif
/* Prevent rumble duration overflow */
#define SDL_MAX_RUMBLE_DURATION_MS 0x0fffffff
/* Forward declaration */ /* Forward declaration */
struct _SDL_HIDAPI_DeviceDriver; struct _SDL_HIDAPI_DeviceDriver;
@ -94,12 +91,16 @@ typedef struct _SDL_HIDAPI_DeviceDriver
void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index); void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index);
SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device); SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device);
SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
void (*FreeDevice)(SDL_HIDAPI_Device *device); void (*FreeDevice)(SDL_HIDAPI_Device *device);
} SDL_HIDAPI_DeviceDriver; } SDL_HIDAPI_DeviceDriver;
/* The maximum size of a USB packet for HID devices */
#define USB_PACKET_LENGTH 64
/* HIDAPI device support */ /* HIDAPI device support */
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam;

View File

@ -758,7 +758,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
} }
static int static int
IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -822,33 +822,16 @@ LINUX_JoystickOpen(SDL_Joystick * joystick, int device_index)
return (0); return (0);
} }
#define MAX_KERNEL_RUMBLE_DURATION_MS 0xFFFF
static int static int
LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
struct input_event event; struct input_event event;
if (duration_ms > MAX_KERNEL_RUMBLE_DURATION_MS) {
duration_ms = MAX_KERNEL_RUMBLE_DURATION_MS;
}
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->hwdata->effect_expiration = SDL_GetTicks() + duration_ms;
if (!joystick->hwdata->effect_expiration) {
joystick->hwdata->effect_expiration = 1;
}
} else {
if (!joystick->hwdata->effect_expiration) {
return 0;
}
joystick->hwdata->effect_expiration = 0;
}
if (joystick->hwdata->ff_rumble) { if (joystick->hwdata->ff_rumble) {
struct ff_effect *effect = &joystick->hwdata->effect; struct ff_effect *effect = &joystick->hwdata->effect;
effect->type = FF_RUMBLE; effect->type = FF_RUMBLE;
effect->replay.length = duration_ms; effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
effect->u.rumble.strong_magnitude = low_frequency_rumble; effect->u.rumble.strong_magnitude = low_frequency_rumble;
effect->u.rumble.weak_magnitude = high_frequency_rumble; effect->u.rumble.weak_magnitude = high_frequency_rumble;
} else if (joystick->hwdata->ff_sine) { } else if (joystick->hwdata->ff_sine) {
@ -857,7 +840,7 @@ LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint1
struct ff_effect *effect = &joystick->hwdata->effect; struct ff_effect *effect = &joystick->hwdata->effect;
effect->type = FF_PERIODIC; effect->type = FF_PERIODIC;
effect->replay.length = duration_ms; effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
effect->u.periodic.waveform = FF_SINE; effect->u.periodic.waveform = FF_SINE;
effect->u.periodic.magnitude = magnitude; effect->u.periodic.magnitude = magnitude;
} else { } else {
@ -1074,13 +1057,6 @@ LINUX_JoystickUpdate(SDL_Joystick * joystick)
SDL_PrivateJoystickBall(joystick, (Uint8) i, xrel, yrel); SDL_PrivateJoystickBall(joystick, (Uint8) i, xrel, yrel);
} }
} }
if (joystick->hwdata->effect_expiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, joystick->hwdata->effect_expiration)) {
LINUX_JoystickRumble(joystick, 0, 0, 0);
}
}
} }
/* Function to close a joystick after use */ /* Function to close a joystick after use */
@ -1088,9 +1064,6 @@ static void
LINUX_JoystickClose(SDL_Joystick * joystick) LINUX_JoystickClose(SDL_Joystick * joystick)
{ {
if (joystick->hwdata) { if (joystick->hwdata) {
if (joystick->hwdata->effect_expiration) {
LINUX_JoystickRumble(joystick, 0, 0, 0);
}
if (joystick->hwdata->effect.id >= 0) { if (joystick->hwdata->effect.id >= 0) {
ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id); ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
joystick->hwdata->effect.id = -1; joystick->hwdata->effect.id = -1;

View File

@ -432,7 +432,7 @@ void FreeRumbleEffectData(DIEFFECT *effect)
SDL_free(effect); SDL_free(effect);
} }
DIEFFECT *CreateRumbleEffectData(Sint16 magnitude, Uint32 duration_ms) DIEFFECT *CreateRumbleEffectData(Sint16 magnitude)
{ {
DIEFFECT *effect; DIEFFECT *effect;
DIPERIODIC *periodic; DIPERIODIC *periodic;
@ -445,7 +445,7 @@ DIEFFECT *CreateRumbleEffectData(Sint16 magnitude, Uint32 duration_ms)
effect->dwSize = sizeof(*effect); effect->dwSize = sizeof(*effect);
effect->dwGain = 10000; effect->dwGain = 10000;
effect->dwFlags = DIEFF_OBJECTOFFSETS; effect->dwFlags = DIEFF_OBJECTOFFSETS;
effect->dwDuration = duration_ms * 1000; /* In microseconds. */ effect->dwDuration = SDL_MAX_RUMBLE_DURATION_MS * 1000; /* In microseconds. */
effect->dwTriggerButton = DIEB_NOTRIGGER; effect->dwTriggerButton = DIEB_NOTRIGGER;
effect->cAxes = 2; effect->cAxes = 2;
@ -944,7 +944,7 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde
} }
static int static int
SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude, Uint32 duration_ms) SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude)
{ {
HRESULT result; HRESULT result;
@ -966,7 +966,7 @@ SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude, Uint32
} }
/* Create the effect */ /* Create the effect */
joystick->hwdata->ffeffect = CreateRumbleEffectData(magnitude, duration_ms); joystick->hwdata->ffeffect = CreateRumbleEffectData(magnitude);
if (!joystick->hwdata->ffeffect) { if (!joystick->hwdata->ffeffect) {
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
@ -980,7 +980,7 @@ SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude, Uint32
} }
int int
SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
HRESULT result; HRESULT result;
@ -993,7 +993,6 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
if (joystick->hwdata->ff_initialized) { if (joystick->hwdata->ff_initialized) {
DIPERIODIC *periodic = ((DIPERIODIC *)joystick->hwdata->ffeffect->lpvTypeSpecificParams); DIPERIODIC *periodic = ((DIPERIODIC *)joystick->hwdata->ffeffect->lpvTypeSpecificParams);
joystick->hwdata->ffeffect->dwDuration = duration_ms * 1000; /* In microseconds. */
periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude); periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude);
result = IDirectInputEffect_SetParameters(joystick->hwdata->ffeffect_ref, joystick->hwdata->ffeffect, (DIEP_DURATION | DIEP_TYPESPECIFICPARAMS)); result = IDirectInputEffect_SetParameters(joystick->hwdata->ffeffect_ref, joystick->hwdata->ffeffect, (DIEP_DURATION | DIEP_TYPESPECIFICPARAMS));
@ -1007,7 +1006,7 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
return SetDIerror("IDirectInputDevice8::SetParameters", result); return SetDIerror("IDirectInputDevice8::SetParameters", result);
} }
} else { } else {
if (SDL_DINPUT_JoystickInitRumble(joystick, magnitude, duration_ms) < 0) { if (SDL_DINPUT_JoystickInitRumble(joystick, magnitude) < 0) {
return -1; return -1;
} }
joystick->hwdata->ff_initialized = SDL_TRUE; joystick->hwdata->ff_initialized = SDL_TRUE;
@ -1252,7 +1251,7 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde
} }
int int
SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -23,7 +23,7 @@
extern int SDL_DINPUT_JoystickInit(void); extern int SDL_DINPUT_JoystickInit(void);
extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext); extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice); extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice);
extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick); extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick);
extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick); extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick);
extern void SDL_DINPUT_JoystickQuit(void); extern void SDL_DINPUT_JoystickQuit(void);

View File

@ -481,12 +481,12 @@ WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
} }
static int static int
WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
if (joystick->hwdata->bXInputDevice) { if (joystick->hwdata->bXInputDevice) {
return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms); return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
} else { } else {
return SDL_DINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms); return SDL_DINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
} }
} }

View File

@ -66,7 +66,6 @@ typedef struct input_t
struct joystick_hwdata struct joystick_hwdata
{ {
SDL_JoystickGUID guid; SDL_JoystickGUID guid;
Uint32 rumble_expiration;
#if SDL_JOYSTICK_DINPUT #if SDL_JOYSTICK_DINPUT
LPDIRECTINPUTDEVICE8 InputDevice; LPDIRECTINPUTDEVICE8 InputDevice;

View File

@ -465,7 +465,7 @@ UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState
} }
int int
SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
XINPUT_VIBRATION XVibration; XINPUT_VIBRATION XVibration;
@ -478,12 +478,6 @@ SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
if (XINPUTSETSTATE(joystick->hwdata->userid, &XVibration) != ERROR_SUCCESS) { if (XINPUTSETSTATE(joystick->hwdata->userid, &XVibration) != ERROR_SUCCESS) {
return SDL_SetError("XInputSetState() failed"); return SDL_SetError("XInputSetState() failed");
} }
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->hwdata->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
} else {
joystick->hwdata->rumble_expiration = 0;
}
return 0; return 0;
} }
@ -516,13 +510,6 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
} }
joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber; joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
} }
if (joystick->hwdata->rumble_expiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, joystick->hwdata->rumble_expiration)) {
SDL_XINPUT_JoystickRumble(joystick, 0, 0, 0);
}
}
} }
void void
@ -565,7 +552,7 @@ SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde
} }
int int
SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
} }

View File

@ -26,7 +26,7 @@ extern SDL_bool SDL_XINPUT_Enabled(void);
extern int SDL_XINPUT_JoystickInit(void); extern int SDL_XINPUT_JoystickInit(void);
extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext); extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
extern int SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice); extern int SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice);
extern int SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); extern int SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick); extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick);
extern void SDL_XINPUT_JoystickClose(SDL_Joystick * joystick); extern void SDL_XINPUT_JoystickClose(SDL_Joystick * joystick);
extern void SDL_XINPUT_JoystickQuit(void); extern void SDL_XINPUT_JoystickQuit(void);