Fix Dualshock 4 rumble stopping too early Dualshock 4 controller only rumbles for 5 seconds maximum. Resend rumble command every 2 seconds to make long rumble work.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 60a82c9..c1e47be 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 707ab4a..015007c 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 */