diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 60a82c967..c1e47beb0 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1005,6 +1005,10 @@ SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h result = 0; } else { result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble); + joystick->rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS; + if (!joystick->rumble_resend) { + joystick->rumble_resend = 1; + } } if (result == 0) { @@ -1018,6 +1022,7 @@ SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h } } else { joystick->rumble_expiration = 0; + joystick->rumble_resend = 0; } } SDL_UnlockJoysticks(); @@ -1713,6 +1718,7 @@ void SDL_JoystickUpdate(void) { int i; + Uint32 now; SDL_Joystick *joystick; if (!SDL_WasInit(SDL_INIT_JOYSTICK)) { @@ -1735,13 +1741,24 @@ SDL_JoystickUpdate(void) } } + now = SDL_GetTicks(); if (joystick->rumble_expiration && - SDL_TICKS_PASSED(SDL_GetTicks(), joystick->rumble_expiration)) { + SDL_TICKS_PASSED(now, joystick->rumble_expiration)) { SDL_JoystickRumble(joystick, 0, 0, 0); + joystick->rumble_resend = 0; + } + + if (joystick->rumble_resend && + SDL_TICKS_PASSED(now, joystick->rumble_resend)) { + joystick->driver->Rumble(joystick, joystick->low_frequency_rumble, joystick->high_frequency_rumble); + joystick->rumble_resend = now + SDL_RUMBLE_RESEND_MS; + if (joystick->rumble_resend == 0) { + joystick->rumble_resend = 1; + } } if (joystick->trigger_rumble_expiration && - SDL_TICKS_PASSED(SDL_GetTicks(), joystick->trigger_rumble_expiration)) { + SDL_TICKS_PASSED(now, joystick->trigger_rumble_expiration)) { SDL_JoystickRumbleTriggers(joystick, 0, 0, 0); } } diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 707ab4ae3..015007c59 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -103,6 +103,7 @@ struct _SDL_Joystick Uint16 low_frequency_rumble; Uint16 high_frequency_rumble; Uint32 rumble_expiration; + Uint32 rumble_resend; Uint16 left_trigger_rumble; Uint16 right_trigger_rumble; @@ -217,6 +218,10 @@ typedef struct _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 +/* Dualshock4 only rumbles for about 5 seconds max, resend rumble command every 2 seconds + * to make long rumble work. */ +#define SDL_RUMBLE_RESEND_MS 2000 + #define SDL_LED_MIN_REPEAT_MS 5000 /* The available joystick drivers */