Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Turn off rumble on drivers which don't respect the replay.length value
  • Loading branch information
slouken committed Jan 23, 2020
1 parent 30ff5fc commit 6dc172d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/joystick/linux/SDL_sysjoystick.c
Expand Up @@ -803,16 +803,30 @@ LINUX_JoystickOpen(SDL_Joystick * joystick, int device_index)
return (0);
}

#define MAX_KERNEL_RUMBLE_DURATION_MS 0xFFFF

static int
LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
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 {
joystick->hwdata->effect_expiration = 0;
}

if (joystick->hwdata->ff_rumble) {
struct ff_effect *effect = &joystick->hwdata->effect;

effect->type = FF_RUMBLE;
effect->replay.length = SDL_min(duration_ms, 32767);
effect->replay.length = duration_ms;
effect->u.rumble.strong_magnitude = low_frequency_rumble;
effect->u.rumble.weak_magnitude = high_frequency_rumble;
} else if (joystick->hwdata->ff_sine) {
Expand All @@ -821,7 +835,7 @@ LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint1
struct ff_effect *effect = &joystick->hwdata->effect;

effect->type = FF_PERIODIC;
effect->replay.length = SDL_min(duration_ms, 32767);
effect->replay.length = duration_ms;
effect->u.periodic.waveform = FF_SINE;
effect->u.periodic.magnitude = magnitude;
} else {
Expand Down Expand Up @@ -1038,13 +1052,23 @@ LINUX_JoystickUpdate(SDL_Joystick * joystick)
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 */
static void
LINUX_JoystickClose(SDL_Joystick * joystick)
{
if (joystick->hwdata) {
if (joystick->hwdata->effect_expiration) {
LINUX_JoystickRumble(joystick, 0, 0, 0);
}
if (joystick->hwdata->effect.id >= 0) {
ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
joystick->hwdata->effect.id = -1;
Expand Down
1 change: 1 addition & 0 deletions src/joystick/linux/SDL_sysjoystick_c.h
Expand Up @@ -37,6 +37,7 @@ struct joystick_hwdata
SDL_bool ff_rumble;
SDL_bool ff_sine;
struct ff_effect effect;
Uint32 effect_expiration;

/* The current Linux joystick driver maps hats to two axes */
struct hwdata_hat
Expand Down

0 comments on commit 6dc172d

Please sign in to comment.