Moved rumble expiration to the main joystick handling level, and prevent sending the driver layer duplicate rumble requests.
authorSam Lantinga
Tue, 04 Feb 2020 12:48:53 -0800
changeset 134806a144eb5e1f1
parent 13479 26fa8708d147
child 13481 2f70560af6d4
Moved rumble expiration to the main joystick handling level, and prevent sending the driver layer duplicate rumble requests.
src/joystick/SDL_joystick.c
src/joystick/SDL_sysjoystick.h
src/joystick/android/SDL_sysjoystick.c
src/joystick/bsd/SDL_sysjoystick.c
src/joystick/darwin/SDL_sysjoystick.c
src/joystick/dummy/SDL_sysjoystick.c
src/joystick/emscripten/SDL_sysjoystick.c
src/joystick/haiku/SDL_haikujoystick.cc
src/joystick/hidapi/SDL_hidapi_gamecube.c
src/joystick/hidapi/SDL_hidapi_ps4.c
src/joystick/hidapi/SDL_hidapi_steam.c
src/joystick/hidapi/SDL_hidapi_switch.c
src/joystick/hidapi/SDL_hidapi_xbox360.c
src/joystick/hidapi/SDL_hidapi_xbox360w.c
src/joystick/hidapi/SDL_hidapi_xboxone.c
src/joystick/hidapi/SDL_hidapijoystick.c
src/joystick/hidapi/SDL_hidapijoystick_c.h
src/joystick/iphoneos/SDL_sysjoystick.m
src/joystick/linux/SDL_sysjoystick.c
src/joystick/windows/SDL_dinputjoystick.c
src/joystick/windows/SDL_dinputjoystick_c.h
src/joystick/windows/SDL_windowsjoystick.c
src/joystick/windows/SDL_windowsjoystick_c.h
src/joystick/windows/SDL_xinputjoystick.c
src/joystick/windows/SDL_xinputjoystick_c.h
     1.1 --- a/src/joystick/SDL_joystick.c	Tue Feb 04 07:23:44 2020 -0800
     1.2 +++ b/src/joystick/SDL_joystick.c	Tue Feb 04 12:48:53 2020 -0800
     1.3 @@ -758,7 +758,26 @@
     1.4      }
     1.5  
     1.6      SDL_LockJoysticks();
     1.7 -    result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms);
     1.8 +    if (low_frequency_rumble == joystick->low_frequency_rumble &&
     1.9 +        high_frequency_rumble == joystick->high_frequency_rumble) {
    1.10 +        /* Just update the expiration */
    1.11 +        result = 0;
    1.12 +    } else {
    1.13 +        result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
    1.14 +    }
    1.15 +
    1.16 +    /* Save the rumble value regardless of success, so we don't spam the driver */
    1.17 +    joystick->low_frequency_rumble = low_frequency_rumble;
    1.18 +    joystick->high_frequency_rumble = high_frequency_rumble;
    1.19 +
    1.20 +    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
    1.21 +        joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
    1.22 +        if (!joystick->rumble_expiration) {
    1.23 +            joystick->rumble_expiration = 1;
    1.24 +        }
    1.25 +    } else {
    1.26 +        joystick->rumble_expiration = 0;
    1.27 +    }
    1.28      SDL_UnlockJoysticks();
    1.29  
    1.30      return result;
    1.31 @@ -790,6 +809,10 @@
    1.32          return;
    1.33      }
    1.34  
    1.35 +    if (joystick->rumble_expiration) {
    1.36 +        SDL_JoystickRumble(joystick, 0, 0, 0);
    1.37 +    }
    1.38 +
    1.39      joystick->driver->Close(joystick);
    1.40      joystick->hwdata = NULL;
    1.41  
    1.42 @@ -1217,6 +1240,16 @@
    1.43              }
    1.44          }
    1.45  
    1.46 +        if (joystick->rumble_expiration) {
    1.47 +            SDL_LockJoysticks();
    1.48 +            /* Double check now that the lock is held */
    1.49 +            if (joystick->rumble_expiration &&
    1.50 +                SDL_TICKS_PASSED(SDL_GetTicks(), joystick->rumble_expiration)) {
    1.51 +                SDL_JoystickRumble(joystick, 0, 0, 0);
    1.52 +            }
    1.53 +            SDL_UnlockJoysticks();
    1.54 +        }
    1.55 +
    1.56          if (joystick->force_recentering) {
    1.57              /* Tell the app that everything is centered/unpressed... */
    1.58              for (i = 0; i < joystick->naxes; i++) {
     2.1 --- a/src/joystick/SDL_sysjoystick.h	Tue Feb 04 07:23:44 2020 -0800
     2.2 +++ b/src/joystick/SDL_sysjoystick.h	Tue Feb 04 12:48:53 2020 -0800
     2.3 @@ -60,6 +60,10 @@
     2.4      int nbuttons;               /* Number of buttons on the joystick */
     2.5      Uint8 *buttons;             /* Current button states */
     2.6  
     2.7 +    Uint16 low_frequency_rumble;
     2.8 +    Uint16 high_frequency_rumble;
     2.9 +    Uint32 rumble_expiration;
    2.10 +
    2.11      SDL_bool attached;
    2.12      SDL_bool is_game_controller;
    2.13      SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */
    2.14 @@ -118,7 +122,7 @@
    2.15      int (*Open)(SDL_Joystick * joystick, int device_index);
    2.16  
    2.17      /* Rumble functionality */
    2.18 -    int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
    2.19 +    int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
    2.20  
    2.21      /* Function to update the state of a joystick - called as a device poll.
    2.22       * This function shouldn't update the joystick structure directly,
    2.23 @@ -135,6 +139,9 @@
    2.24  
    2.25  } SDL_JoystickDriver;
    2.26  
    2.27 +/* Windows and Mac OSX has a limit of MAX_DWORD / 1000, Linux kernel has a limit of 0xFFFF */
    2.28 +#define SDL_MAX_RUMBLE_DURATION_MS  0xFFFF
    2.29 +
    2.30  /* The available joystick drivers */
    2.31  extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver;
    2.32  extern SDL_JoystickDriver SDL_BSD_JoystickDriver;
     3.1 --- a/src/joystick/android/SDL_sysjoystick.c	Tue Feb 04 07:23:44 2020 -0800
     3.2 +++ b/src/joystick/android/SDL_sysjoystick.c	Tue Feb 04 12:48:53 2020 -0800
     3.3 @@ -629,7 +629,7 @@
     3.4  }
     3.5  
     3.6  static int
     3.7 -ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
     3.8 +ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
     3.9  {
    3.10      return SDL_Unsupported();
    3.11  }
     4.1 --- a/src/joystick/bsd/SDL_sysjoystick.c	Tue Feb 04 07:23:44 2020 -0800
     4.2 +++ b/src/joystick/bsd/SDL_sysjoystick.c	Tue Feb 04 12:48:53 2020 -0800
     4.3 @@ -757,7 +757,7 @@
     4.4  }
     4.5  
     4.6  static int
     4.7 -BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
     4.8 +BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
     4.9  {
    4.10      return SDL_Unsupported();
    4.11  }
     5.1 --- a/src/joystick/darwin/SDL_sysjoystick.c	Tue Feb 04 07:23:44 2020 -0800
     5.2 +++ b/src/joystick/darwin/SDL_sysjoystick.c	Tue Feb 04 12:48:53 2020 -0800
     5.3 @@ -52,7 +52,7 @@
     5.4      SDL_free(effect);
     5.5  }
     5.6  
     5.7 -FFEFFECT *CreateRumbleEffectData(Sint16 magnitude, Uint32 duration_ms)
     5.8 +FFEFFECT *CreateRumbleEffectData(Sint16 magnitude)
     5.9  {
    5.10      FFEFFECT *effect;
    5.11      FFPERIODIC *periodic;
    5.12 @@ -65,7 +65,7 @@
    5.13      effect->dwSize = sizeof(*effect);
    5.14      effect->dwGain = 10000;
    5.15      effect->dwFlags = FFEFF_OBJECTOFFSETS;
    5.16 -    effect->dwDuration = duration_ms * 1000; /* In microseconds. */
    5.17 +    effect->dwDuration = SDL_MAX_RUMBLE_DURATION_MS * 1000; /* In microseconds. */
    5.18      effect->dwTriggerButton = FFEB_NOTRIGGER;
    5.19  
    5.20      effect->cAxes = 2;
    5.21 @@ -832,7 +832,7 @@
    5.22  }
    5.23  
    5.24  static int
    5.25 -DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude, Uint32 duration_ms)
    5.26 +DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude)
    5.27  {
    5.28      HRESULT result;
    5.29  
    5.30 @@ -855,7 +855,7 @@
    5.31      }
    5.32  
    5.33      /* Create the effect */
    5.34 -    device->ffeffect = CreateRumbleEffectData(magnitude, duration_ms);
    5.35 +    device->ffeffect = CreateRumbleEffectData(magnitude);
    5.36      if (!device->ffeffect) {
    5.37          return SDL_OutOfMemory();
    5.38      }
    5.39 @@ -869,7 +869,7 @@
    5.40  }
    5.41  
    5.42  static int
    5.43 -DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    5.44 +DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    5.45  {
    5.46      HRESULT result;
    5.47      recDevice *device = joystick->hwdata;
    5.48 @@ -883,7 +883,6 @@
    5.49  
    5.50      if (device->ff_initialized) {
    5.51          FFPERIODIC *periodic = ((FFPERIODIC *)device->ffeffect->lpvTypeSpecificParams);
    5.52 -        device->ffeffect->dwDuration = duration_ms * 1000; /* In microseconds. */
    5.53          periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude);
    5.54  
    5.55          result = FFEffectSetParameters(device->ffeffect_ref, device->ffeffect,
    5.56 @@ -892,7 +891,7 @@
    5.57              return SDL_SetError("Unable to update rumble effect: %s", FFStrError(result));
    5.58          }
    5.59      } else {
    5.60 -        if (DARWIN_JoystickInitRumble(device, magnitude, duration_ms) < 0) {
    5.61 +        if (DARWIN_JoystickInitRumble(device, magnitude) < 0) {
    5.62              return -1;
    5.63          }
    5.64          device->ff_initialized = SDL_TRUE;
     6.1 --- a/src/joystick/dummy/SDL_sysjoystick.c	Tue Feb 04 07:23:44 2020 -0800
     6.2 +++ b/src/joystick/dummy/SDL_sysjoystick.c	Tue Feb 04 12:48:53 2020 -0800
     6.3 @@ -84,7 +84,7 @@
     6.4  }
     6.5  
     6.6  static int
     6.7 -DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
     6.8 +DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
     6.9  {
    6.10      return SDL_Unsupported();
    6.11  }
     7.1 --- a/src/joystick/emscripten/SDL_sysjoystick.c	Tue Feb 04 07:23:44 2020 -0800
     7.2 +++ b/src/joystick/emscripten/SDL_sysjoystick.c	Tue Feb 04 12:48:53 2020 -0800
     7.3 @@ -399,7 +399,7 @@
     7.4  }
     7.5  
     7.6  static int
     7.7 -EMSCRIPTEN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
     7.8 +EMSCRIPTEN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
     7.9  {
    7.10      return SDL_Unsupported();
    7.11  }
     8.1 --- a/src/joystick/haiku/SDL_haikujoystick.cc	Tue Feb 04 07:23:44 2020 -0800
     8.2 +++ b/src/joystick/haiku/SDL_haikujoystick.cc	Tue Feb 04 12:48:53 2020 -0800
     8.3 @@ -254,7 +254,7 @@
     8.4          return guid;
     8.5      }
     8.6  
     8.7 -    static int HAIKU_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
     8.8 +    static int HAIKU_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
     8.9      {
    8.10          return SDL_Unsupported();
    8.11      }
     9.1 --- a/src/joystick/hidapi/SDL_hidapi_gamecube.c	Tue Feb 04 07:23:44 2020 -0800
     9.2 +++ b/src/joystick/hidapi/SDL_hidapi_gamecube.c	Tue Feb 04 12:48:53 2020 -0800
     9.3 @@ -44,7 +44,6 @@
     9.4      Uint8 max_axis[MAX_CONTROLLERS*SDL_CONTROLLER_AXIS_MAX];
     9.5      Uint8 rumbleAllowed[MAX_CONTROLLERS];
     9.6      Uint8 rumble[1+MAX_CONTROLLERS];
     9.7 -    Uint32 rumbleExpiration[MAX_CONTROLLERS];
     9.8      /* Without this variable, hid_write starts to lag a TON */
     9.9      SDL_bool rumbleUpdate;
    9.10  } SDL_DriverGameCube_Context;
    9.11 @@ -285,16 +284,6 @@
    9.12      }
    9.13  
    9.14      /* Write rumble packet */
    9.15 -    for (i = 0; i < MAX_CONTROLLERS; i += 1) {
    9.16 -        if (ctx->rumbleExpiration[i] || (ctx->rumble[1 + i] && !ctx->rumbleAllowed[i])) {
    9.17 -            Uint32 now = SDL_GetTicks();
    9.18 -            if (SDL_TICKS_PASSED(now, ctx->rumbleExpiration[i]) || !ctx->rumbleAllowed[i]) {
    9.19 -                ctx->rumble[1 + i] = 0;
    9.20 -                ctx->rumbleExpiration[i] = 0;
    9.21 -                ctx->rumbleUpdate = SDL_TRUE;
    9.22 -            }
    9.23 -        }
    9.24 -    }
    9.25      if (ctx->rumbleUpdate) {
    9.26          hid_write(device->dev, ctx->rumble, sizeof(ctx->rumble));
    9.27          ctx->rumbleUpdate = SDL_FALSE;
    9.28 @@ -321,7 +310,7 @@
    9.29  }
    9.30  
    9.31  static int
    9.32 -HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    9.33 +HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    9.34  {
    9.35      SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
    9.36      Uint8 i, val;
    9.37 @@ -338,14 +327,6 @@
    9.38                  ctx->rumble[i + 1] = val;
    9.39                  ctx->rumbleUpdate = SDL_TRUE;
    9.40              }
    9.41 -            if (val && duration_ms) {
    9.42 -                ctx->rumbleExpiration[i] = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
    9.43 -                if (!ctx->rumbleExpiration[i]) {
    9.44 -                    ctx->rumbleExpiration[i] = 1;
    9.45 -                }
    9.46 -            } else {
    9.47 -                ctx->rumbleExpiration[i] = 0;
    9.48 -            }
    9.49              return 0;
    9.50          }
    9.51      }
    9.52 @@ -359,18 +340,11 @@
    9.53  HIDAPI_DriverGameCube_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
    9.54  {
    9.55      SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
    9.56 -    Uint8 i;
    9.57  
    9.58      /* Stop rumble activity */
    9.59 -    for (i = 0; i < MAX_CONTROLLERS; i += 1) {
    9.60 -        if (joystick->instance_id == ctx->joysticks[i]) {
    9.61 -            if (!ctx->wireless[i] && ctx->rumbleAllowed[i] && ctx->rumble[1 + i] != 0) {
    9.62 -                ctx->rumble[1 + i] = 0;
    9.63 -                ctx->rumbleExpiration[i] = 0;
    9.64 -                hid_write(device->dev, ctx->rumble, sizeof(ctx->rumble));
    9.65 -            }
    9.66 -            break;
    9.67 -        }
    9.68 +    if (ctx->rumbleUpdate) {
    9.69 +        hid_write(device->dev, ctx->rumble, sizeof(ctx->rumble));
    9.70 +        ctx->rumbleUpdate = SDL_FALSE;
    9.71      }
    9.72  }
    9.73  
    10.1 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c	Tue Feb 04 07:23:44 2020 -0800
    10.2 +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c	Tue Feb 04 12:48:53 2020 -0800
    10.3 @@ -37,8 +37,6 @@
    10.4  
    10.5  #ifdef SDL_JOYSTICK_HIDAPI_PS4
    10.6  
    10.7 -#define USB_PACKET_LENGTH   64
    10.8 -
    10.9  typedef enum
   10.10  {
   10.11      k_EPS4ReportIdUsbState = 1,
   10.12 @@ -103,7 +101,6 @@
   10.13      SDL_bool rumble_supported;
   10.14      Uint8 volume;
   10.15      Uint32 last_volume_check;
   10.16 -    Uint32 rumble_expiration;
   10.17      PS4StatePacket_t last_state;
   10.18  } SDL_DriverPS4_Context;
   10.19  
   10.20 @@ -201,7 +198,7 @@
   10.21  {
   10.22  }
   10.23  
   10.24 -static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
   10.25 +static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
   10.26  
   10.27  static SDL_bool
   10.28  HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   10.29 @@ -251,7 +248,7 @@
   10.30      }
   10.31  
   10.32      /* Initialize LED and effect state */
   10.33 -    HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0, 0);
   10.34 +    HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0);
   10.35  
   10.36      /* Initialize the joystick capabilities */
   10.37      joystick->nbuttons = 16;
   10.38 @@ -262,7 +259,7 @@
   10.39  }
   10.40  
   10.41  static int
   10.42 -HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   10.43 +HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   10.44  {
   10.45      SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
   10.46      DS4EffectsState_t *effects;
   10.47 @@ -311,15 +308,6 @@
   10.48      if (hid_write(device->dev, data, report_size) != report_size) {
   10.49          return SDL_SetError("Couldn't send rumble packet");
   10.50      }
   10.51 -
   10.52 -    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   10.53 -        ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
   10.54 -        if (!ctx->rumble_expiration) {
   10.55 -            ctx->rumble_expiration = 1;
   10.56 -        }
   10.57 -    } else {
   10.58 -        ctx->rumble_expiration = 0;
   10.59 -    }
   10.60      return 0;
   10.61  }
   10.62  
   10.63 @@ -465,13 +453,6 @@
   10.64          }
   10.65      }
   10.66  
   10.67 -    if (ctx->rumble_expiration) {
   10.68 -        Uint32 now = SDL_GetTicks();
   10.69 -        if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   10.70 -            HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0, 0);
   10.71 -        }
   10.72 -    }
   10.73 -
   10.74      if (size < 0) {
   10.75          /* Read error, device is disconnected */
   10.76          HIDAPI_JoystickDisconnected(device, joystick->instance_id);
   10.77 @@ -482,12 +463,6 @@
   10.78  static void
   10.79  HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   10.80  {
   10.81 -    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
   10.82 -
   10.83 -    if (ctx->rumble_expiration) {
   10.84 -        HIDAPI_DriverPS4_RumbleJoystick(device, joystick, 0, 0, 0);
   10.85 -    }
   10.86 -
   10.87      hid_close(device->dev);
   10.88      device->dev = NULL;
   10.89  
    11.1 --- a/src/joystick/hidapi/SDL_hidapi_steam.c	Tue Feb 04 07:23:44 2020 -0800
    11.2 +++ b/src/joystick/hidapi/SDL_hidapi_steam.c	Tue Feb 04 12:48:53 2020 -0800
    11.3 @@ -1029,7 +1029,7 @@
    11.4  }
    11.5  
    11.6  static int
    11.7 -HIDAPI_DriverSteam_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    11.8 +HIDAPI_DriverSteam_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    11.9  {
   11.10      /* You should use the full Steam Input API for rumble support */
   11.11      return SDL_Unsupported();
    12.1 --- a/src/joystick/hidapi/SDL_hidapi_switch.c	Tue Feb 04 07:23:44 2020 -0800
    12.2 +++ b/src/joystick/hidapi/SDL_hidapi_switch.c	Tue Feb 04 12:48:53 2020 -0800
    12.3 @@ -199,7 +199,6 @@
    12.4      SDL_bool m_bUseButtonLabels;
    12.5      Uint8 m_nCommandNumber;
    12.6      SwitchCommonOutputPacket_t m_RumblePacket;
    12.7 -    Uint32 m_nRumbleExpiration;
    12.8      Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength];
    12.9  
   12.10      SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState;
   12.11 @@ -739,7 +738,7 @@
   12.12  }
   12.13  
   12.14  static int
   12.15 -HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   12.16 +HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   12.17  {
   12.18      SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
   12.19  
   12.20 @@ -770,15 +769,6 @@
   12.21          SDL_SetError("Couldn't send rumble packet");
   12.22          return -1;
   12.23      }
   12.24 -
   12.25 -    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   12.26 -        ctx->m_nRumbleExpiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
   12.27 -        if (!ctx->m_nRumbleExpiration) {
   12.28 -            ctx->m_nRumbleExpiration = 1;
   12.29 -        }
   12.30 -    } else {
   12.31 -        ctx->m_nRumbleExpiration = 0;
   12.32 -    }
   12.33      return 0;
   12.34  }
   12.35  
   12.36 @@ -1075,13 +1065,6 @@
   12.37          }
   12.38      }
   12.39  
   12.40 -    if (ctx->m_nRumbleExpiration) {
   12.41 -        Uint32 now = SDL_GetTicks();
   12.42 -        if (SDL_TICKS_PASSED(now, ctx->m_nRumbleExpiration)) {
   12.43 -            HIDAPI_DriverSwitch_RumbleJoystick(device, joystick, 0, 0, 0);
   12.44 -        }
   12.45 -    }
   12.46 -
   12.47      if (size < 0) {
   12.48          /* Read error, device is disconnected */
   12.49          HIDAPI_JoystickDisconnected(device, joystick->instance_id);
   12.50 @@ -1094,10 +1077,6 @@
   12.51  {
   12.52      SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
   12.53  
   12.54 -    if (ctx->m_nRumbleExpiration) {
   12.55 -        HIDAPI_DriverSwitch_RumbleJoystick(device, joystick, 0, 0, 0);
   12.56 -    }
   12.57 -
   12.58      if (!ctx->m_bInputOnly) {
   12.59          /* Restore simple input mode for other applications */
   12.60          SetInputMode(ctx, k_eSwitchInputReportIDs_SimpleControllerState);
    13.1 --- a/src/joystick/hidapi/SDL_hidapi_xbox360.c	Tue Feb 04 07:23:44 2020 -0800
    13.2 +++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c	Tue Feb 04 12:48:53 2020 -0800
    13.3 @@ -50,12 +50,9 @@
    13.4  #include "windows.gaming.input.h"
    13.5  #endif
    13.6  
    13.7 -#define USB_PACKET_LENGTH   64
    13.8 -
    13.9  
   13.10  typedef struct {
   13.11      Uint8 last_state[USB_PACKET_LENGTH];
   13.12 -    Uint32 rumble_expiration;
   13.13  #ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
   13.14      SDL_bool xinput_enabled;
   13.15      Uint8 xinput_slot;
   13.16 @@ -362,9 +359,11 @@
   13.17  }
   13.18  
   13.19  static int
   13.20 -HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   13.21 +HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   13.22  {
   13.23 +#if defined(SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT) || defined(SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT)
   13.24      SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context;
   13.25 +#endif
   13.26  
   13.27  #ifdef __WIN32__
   13.28      SDL_bool rumbled = SDL_FALSE;
   13.29 @@ -422,14 +421,6 @@
   13.30      }
   13.31  #endif /* __WIN32__ */
   13.32  
   13.33 -    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   13.34 -        ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
   13.35 -        if (!ctx->rumble_expiration) {
   13.36 -            ctx->rumble_expiration = 1;
   13.37 -        }
   13.38 -    } else {
   13.39 -        ctx->rumble_expiration = 0;
   13.40 -    }
   13.41      return 0;
   13.42  }
   13.43  
   13.44 @@ -802,13 +793,6 @@
   13.45  #endif /* __WIN32__ */
   13.46      }
   13.47  
   13.48 -    if (ctx->rumble_expiration) {
   13.49 -        Uint32 now = SDL_GetTicks();
   13.50 -        if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   13.51 -            HIDAPI_DriverXbox360_RumbleJoystick(device, joystick, 0, 0, 0);
   13.52 -        }
   13.53 -    }
   13.54 -
   13.55      if (size < 0) {
   13.56          /* Read error, device is disconnected */
   13.57          HIDAPI_JoystickDisconnected(device, joystick->instance_id);
   13.58 @@ -819,11 +803,9 @@
   13.59  static void
   13.60  HIDAPI_DriverXbox360_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   13.61  {
   13.62 +#if defined(SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT) || defined(SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT)
   13.63      SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context;
   13.64 -
   13.65 -    if (ctx->rumble_expiration) {
   13.66 -        HIDAPI_DriverXbox360_RumbleJoystick(device, joystick, 0, 0, 0);
   13.67 -    }
   13.68 +#endif
   13.69  
   13.70  #ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
   13.71      if (ctx->xinput_enabled) {
    14.1 --- a/src/joystick/hidapi/SDL_hidapi_xbox360w.c	Tue Feb 04 07:23:44 2020 -0800
    14.2 +++ b/src/joystick/hidapi/SDL_hidapi_xbox360w.c	Tue Feb 04 12:48:53 2020 -0800
    14.3 @@ -34,13 +34,10 @@
    14.4  
    14.5  #ifdef SDL_JOYSTICK_HIDAPI_XBOX360
    14.6  
    14.7 -#define USB_PACKET_LENGTH   64
    14.8 -
    14.9  
   14.10  typedef struct {
   14.11      SDL_bool connected;
   14.12      Uint8 last_state[USB_PACKET_LENGTH];
   14.13 -    Uint32 rumble_expiration;
   14.14  } SDL_DriverXbox360W_Context;
   14.15  
   14.16  
   14.17 @@ -147,10 +144,8 @@
   14.18  }
   14.19  
   14.20  static int
   14.21 -HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   14.22 +HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   14.23  {
   14.24 -    SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context;
   14.25 -
   14.26      Uint8 rumble_packet[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
   14.27  
   14.28      rumble_packet[5] = (low_frequency_rumble >> 8);
   14.29 @@ -159,15 +154,6 @@
   14.30      if (hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
   14.31          return SDL_SetError("Couldn't send rumble packet");
   14.32      }
   14.33 -
   14.34 -    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   14.35 -        ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
   14.36 -        if (!ctx->rumble_expiration) {
   14.37 -            ctx->rumble_expiration = 1;
   14.38 -        }
   14.39 -    } else {
   14.40 -        ctx->rumble_expiration = 0;
   14.41 -    }
   14.42      return 0;
   14.43  }
   14.44  
   14.45 @@ -273,13 +259,6 @@
   14.46      }
   14.47  
   14.48      if (joystick) {
   14.49 -        if (ctx->rumble_expiration) {
   14.50 -            Uint32 now = SDL_GetTicks();
   14.51 -            if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   14.52 -                HIDAPI_DriverXbox360W_RumbleJoystick(device, joystick, 0, 0, 0);
   14.53 -            }
   14.54 -        }
   14.55 -
   14.56          if (size < 0) {
   14.57              /* Read error, device is disconnected */
   14.58              HIDAPI_JoystickDisconnected(device, joystick->instance_id);
   14.59 @@ -291,11 +270,6 @@
   14.60  static void
   14.61  HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   14.62  {
   14.63 -    SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context;
   14.64 -
   14.65 -    if (ctx->rumble_expiration) {
   14.66 -        HIDAPI_DriverXbox360W_RumbleJoystick(device, joystick, 0, 0, 0);
   14.67 -    }
   14.68  }
   14.69  
   14.70  static void
    15.1 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c	Tue Feb 04 07:23:44 2020 -0800
    15.2 +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c	Tue Feb 04 12:48:53 2020 -0800
    15.3 @@ -37,8 +37,6 @@
    15.4  /* Define this if you want to log all packets from the controller */
    15.5  /*#define DEBUG_XBOX_PROTOCOL*/
    15.6  
    15.7 -#define USB_PACKET_LENGTH   64
    15.8 -
    15.9  /* The amount of time to wait after hotplug to send controller init sequence */
   15.10  #define CONTROLLER_INIT_DELAY_MS    1500 /* 475 for Xbox One S, 1275 for the PDP Battlefield 1 */
   15.11  
   15.12 @@ -119,7 +117,6 @@
   15.13      Uint8 sequence;
   15.14      Uint8 last_state[USB_PACKET_LENGTH];
   15.15      SDL_bool rumble_synchronized;
   15.16 -    Uint32 rumble_expiration;
   15.17      SDL_bool has_paddles;
   15.18  } SDL_DriverXboxOne_Context;
   15.19  
   15.20 @@ -369,7 +366,7 @@
   15.21  }
   15.22  
   15.23  static int
   15.24 -HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   15.25 +HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   15.26  {
   15.27      SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
   15.28      Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
   15.29 @@ -384,15 +381,6 @@
   15.30      if (hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
   15.31          return SDL_SetError("Couldn't send rumble packet");
   15.32      }
   15.33 -
   15.34 -    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   15.35 -        ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
   15.36 -        if (!ctx->rumble_expiration) {
   15.37 -            ctx->rumble_expiration = 1;
   15.38 -        }
   15.39 -    } else {
   15.40 -        ctx->rumble_expiration = 0;
   15.41 -    }
   15.42      return 0;
   15.43  }
   15.44  
   15.45 @@ -578,13 +566,6 @@
   15.46          }
   15.47      }
   15.48  
   15.49 -    if (ctx->rumble_expiration) {
   15.50 -        Uint32 now = SDL_GetTicks();
   15.51 -        if (SDL_TICKS_PASSED(now, ctx->rumble_expiration)) {
   15.52 -            HIDAPI_DriverXboxOne_RumbleJoystick(device, joystick, 0, 0, 0);
   15.53 -        }
   15.54 -    }
   15.55 -
   15.56      if (size < 0) {
   15.57          /* Read error, device is disconnected */
   15.58          HIDAPI_JoystickDisconnected(device, joystick->instance_id);
   15.59 @@ -595,12 +576,6 @@
   15.60  static void
   15.61  HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
   15.62  {
   15.63 -    SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
   15.64 -
   15.65 -    if (ctx->rumble_expiration) {
   15.66 -        HIDAPI_DriverXboxOne_RumbleJoystick(device, joystick, 0, 0, 0);
   15.67 -    }
   15.68 -
   15.69      hid_close(device->dev);
   15.70      device->dev = NULL;
   15.71  
    16.1 --- a/src/joystick/hidapi/SDL_hidapijoystick.c	Tue Feb 04 07:23:44 2020 -0800
    16.2 +++ b/src/joystick/hidapi/SDL_hidapijoystick.c	Tue Feb 04 12:48:53 2020 -0800
    16.3 @@ -1001,14 +1001,14 @@
    16.4  }
    16.5  
    16.6  static int
    16.7 -HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    16.8 +HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    16.9  {
   16.10      int result;
   16.11  
   16.12      if (joystick->hwdata) {
   16.13          SDL_HIDAPI_Device *device = joystick->hwdata->device;
   16.14  
   16.15 -        result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble, duration_ms);
   16.16 +        result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble);
   16.17      } else {
   16.18          SDL_SetError("Rumble failed, device disconnected");
   16.19          result = -1;
    17.1 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h	Tue Feb 04 07:23:44 2020 -0800
    17.2 +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h	Tue Feb 04 12:48:53 2020 -0800
    17.3 @@ -50,9 +50,6 @@
    17.4  #define SDL_JOYSTICK_HIDAPI_STEAM
    17.5  #endif
    17.6  
    17.7 -/* Prevent rumble duration overflow */
    17.8 -#define SDL_MAX_RUMBLE_DURATION_MS  0x0fffffff
    17.9 -
   17.10  /* Forward declaration */
   17.11  struct _SDL_HIDAPI_DeviceDriver;
   17.12  
   17.13 @@ -94,12 +91,16 @@
   17.14      void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index);
   17.15      SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device);
   17.16      SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
   17.17 -    int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
   17.18 +    int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
   17.19      void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
   17.20      void (*FreeDevice)(SDL_HIDAPI_Device *device);
   17.21  
   17.22  } SDL_HIDAPI_DeviceDriver;
   17.23  
   17.24 +
   17.25 +/* The maximum size of a USB packet for HID devices */
   17.26 +#define USB_PACKET_LENGTH   64
   17.27 +
   17.28  /* HIDAPI device support */
   17.29  extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4;
   17.30  extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam;
    18.1 --- a/src/joystick/iphoneos/SDL_sysjoystick.m	Tue Feb 04 07:23:44 2020 -0800
    18.2 +++ b/src/joystick/iphoneos/SDL_sysjoystick.m	Tue Feb 04 12:48:53 2020 -0800
    18.3 @@ -758,7 +758,7 @@
    18.4  }
    18.5  
    18.6  static int
    18.7 -IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    18.8 +IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    18.9  {
   18.10      return SDL_Unsupported();
   18.11  }
    19.1 --- a/src/joystick/linux/SDL_sysjoystick.c	Tue Feb 04 07:23:44 2020 -0800
    19.2 +++ b/src/joystick/linux/SDL_sysjoystick.c	Tue Feb 04 12:48:53 2020 -0800
    19.3 @@ -822,33 +822,16 @@
    19.4      return (0);
    19.5  }
    19.6  
    19.7 -#define MAX_KERNEL_RUMBLE_DURATION_MS  0xFFFF
    19.8 -
    19.9  static int
   19.10 -LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   19.11 +LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   19.12  {
   19.13      struct input_event event;
   19.14  
   19.15 -    if (duration_ms > MAX_KERNEL_RUMBLE_DURATION_MS) {
   19.16 -        duration_ms = MAX_KERNEL_RUMBLE_DURATION_MS;
   19.17 -    }
   19.18 -    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   19.19 -        joystick->hwdata->effect_expiration = SDL_GetTicks() + duration_ms;
   19.20 -        if (!joystick->hwdata->effect_expiration) {
   19.21 -            joystick->hwdata->effect_expiration = 1;
   19.22 -        }
   19.23 -    } else {
   19.24 -        if (!joystick->hwdata->effect_expiration) {
   19.25 -            return 0;
   19.26 -        }
   19.27 -        joystick->hwdata->effect_expiration = 0;
   19.28 -    }
   19.29 -
   19.30      if (joystick->hwdata->ff_rumble) {
   19.31          struct ff_effect *effect = &joystick->hwdata->effect;
   19.32  
   19.33          effect->type = FF_RUMBLE;
   19.34 -        effect->replay.length = duration_ms;
   19.35 +        effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
   19.36          effect->u.rumble.strong_magnitude = low_frequency_rumble;
   19.37          effect->u.rumble.weak_magnitude = high_frequency_rumble;
   19.38      } else if (joystick->hwdata->ff_sine) {
   19.39 @@ -857,7 +840,7 @@
   19.40          struct ff_effect *effect = &joystick->hwdata->effect;
   19.41  
   19.42          effect->type = FF_PERIODIC;
   19.43 -        effect->replay.length = duration_ms;
   19.44 +        effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS;
   19.45          effect->u.periodic.waveform = FF_SINE;
   19.46          effect->u.periodic.magnitude = magnitude;
   19.47      } else {
   19.48 @@ -1074,13 +1057,6 @@
   19.49              SDL_PrivateJoystickBall(joystick, (Uint8) i, xrel, yrel);
   19.50          }
   19.51      }
   19.52 -
   19.53 -    if (joystick->hwdata->effect_expiration) {
   19.54 -        Uint32 now = SDL_GetTicks();
   19.55 -        if (SDL_TICKS_PASSED(now, joystick->hwdata->effect_expiration)) {
   19.56 -            LINUX_JoystickRumble(joystick, 0, 0, 0);
   19.57 -        }
   19.58 -    }
   19.59  }
   19.60  
   19.61  /* Function to close a joystick after use */
   19.62 @@ -1088,9 +1064,6 @@
   19.63  LINUX_JoystickClose(SDL_Joystick * joystick)
   19.64  {
   19.65      if (joystick->hwdata) {
   19.66 -        if (joystick->hwdata->effect_expiration) {
   19.67 -            LINUX_JoystickRumble(joystick, 0, 0, 0);
   19.68 -        }
   19.69          if (joystick->hwdata->effect.id >= 0) {
   19.70              ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
   19.71              joystick->hwdata->effect.id = -1;
    20.1 --- a/src/joystick/windows/SDL_dinputjoystick.c	Tue Feb 04 07:23:44 2020 -0800
    20.2 +++ b/src/joystick/windows/SDL_dinputjoystick.c	Tue Feb 04 12:48:53 2020 -0800
    20.3 @@ -432,7 +432,7 @@
    20.4      SDL_free(effect);
    20.5  }
    20.6  
    20.7 -DIEFFECT *CreateRumbleEffectData(Sint16 magnitude, Uint32 duration_ms)
    20.8 +DIEFFECT *CreateRumbleEffectData(Sint16 magnitude)
    20.9  {
   20.10      DIEFFECT *effect;
   20.11      DIPERIODIC *periodic;
   20.12 @@ -445,7 +445,7 @@
   20.13      effect->dwSize = sizeof(*effect);
   20.14      effect->dwGain = 10000;
   20.15      effect->dwFlags = DIEFF_OBJECTOFFSETS;
   20.16 -    effect->dwDuration = duration_ms * 1000; /* In microseconds. */
   20.17 +    effect->dwDuration = SDL_MAX_RUMBLE_DURATION_MS * 1000; /* In microseconds. */
   20.18      effect->dwTriggerButton = DIEB_NOTRIGGER;
   20.19  
   20.20      effect->cAxes = 2;
   20.21 @@ -944,7 +944,7 @@
   20.22  }
   20.23  
   20.24  static int
   20.25 -SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude, Uint32 duration_ms)
   20.26 +SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude)
   20.27  {
   20.28      HRESULT result;
   20.29  
   20.30 @@ -966,7 +966,7 @@
   20.31      }
   20.32  
   20.33      /* Create the effect */
   20.34 -    joystick->hwdata->ffeffect = CreateRumbleEffectData(magnitude, duration_ms);
   20.35 +    joystick->hwdata->ffeffect = CreateRumbleEffectData(magnitude);
   20.36      if (!joystick->hwdata->ffeffect) {
   20.37          return SDL_OutOfMemory();
   20.38      }
   20.39 @@ -980,7 +980,7 @@
   20.40  }
   20.41  
   20.42  int
   20.43 -SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   20.44 +SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   20.45  {
   20.46      HRESULT result;
   20.47  
   20.48 @@ -993,7 +993,6 @@
   20.49  
   20.50      if (joystick->hwdata->ff_initialized) {
   20.51          DIPERIODIC *periodic = ((DIPERIODIC *)joystick->hwdata->ffeffect->lpvTypeSpecificParams);
   20.52 -        joystick->hwdata->ffeffect->dwDuration = duration_ms * 1000; /* In microseconds. */
   20.53          periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude);
   20.54  
   20.55          result = IDirectInputEffect_SetParameters(joystick->hwdata->ffeffect_ref, joystick->hwdata->ffeffect, (DIEP_DURATION | DIEP_TYPESPECIFICPARAMS));
   20.56 @@ -1007,7 +1006,7 @@
   20.57              return SetDIerror("IDirectInputDevice8::SetParameters", result);
   20.58          }
   20.59      } else {
   20.60 -        if (SDL_DINPUT_JoystickInitRumble(joystick, magnitude, duration_ms) < 0) {
   20.61 +        if (SDL_DINPUT_JoystickInitRumble(joystick, magnitude) < 0) {
   20.62              return -1;
   20.63          }
   20.64          joystick->hwdata->ff_initialized = SDL_TRUE;
   20.65 @@ -1252,7 +1251,7 @@
   20.66  }
   20.67  
   20.68  int
   20.69 -SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   20.70 +SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   20.71  {
   20.72      return SDL_Unsupported();
   20.73  }
    21.1 --- a/src/joystick/windows/SDL_dinputjoystick_c.h	Tue Feb 04 07:23:44 2020 -0800
    21.2 +++ b/src/joystick/windows/SDL_dinputjoystick_c.h	Tue Feb 04 12:48:53 2020 -0800
    21.3 @@ -23,7 +23,7 @@
    21.4  extern int SDL_DINPUT_JoystickInit(void);
    21.5  extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
    21.6  extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice);
    21.7 -extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
    21.8 +extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
    21.9  extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick);
   21.10  extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick);
   21.11  extern void SDL_DINPUT_JoystickQuit(void);
    22.1 --- a/src/joystick/windows/SDL_windowsjoystick.c	Tue Feb 04 07:23:44 2020 -0800
    22.2 +++ b/src/joystick/windows/SDL_windowsjoystick.c	Tue Feb 04 12:48:53 2020 -0800
    22.3 @@ -481,12 +481,12 @@
    22.4  }
    22.5  
    22.6  static int
    22.7 -WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    22.8 +WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    22.9  {
   22.10      if (joystick->hwdata->bXInputDevice) {
   22.11 -        return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms);
   22.12 +        return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
   22.13      } else {
   22.14 -        return SDL_DINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms);
   22.15 +        return SDL_DINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
   22.16      }
   22.17  }
   22.18  
    23.1 --- a/src/joystick/windows/SDL_windowsjoystick_c.h	Tue Feb 04 07:23:44 2020 -0800
    23.2 +++ b/src/joystick/windows/SDL_windowsjoystick_c.h	Tue Feb 04 12:48:53 2020 -0800
    23.3 @@ -66,7 +66,6 @@
    23.4  struct joystick_hwdata
    23.5  {
    23.6      SDL_JoystickGUID guid;
    23.7 -    Uint32 rumble_expiration;
    23.8  
    23.9  #if SDL_JOYSTICK_DINPUT
   23.10      LPDIRECTINPUTDEVICE8 InputDevice;
    24.1 --- a/src/joystick/windows/SDL_xinputjoystick.c	Tue Feb 04 07:23:44 2020 -0800
    24.2 +++ b/src/joystick/windows/SDL_xinputjoystick.c	Tue Feb 04 12:48:53 2020 -0800
    24.3 @@ -465,7 +465,7 @@
    24.4  }
    24.5  
    24.6  int
    24.7 -SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
    24.8 +SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
    24.9  {
   24.10      XINPUT_VIBRATION XVibration;
   24.11  
   24.12 @@ -478,12 +478,6 @@
   24.13      if (XINPUTSETSTATE(joystick->hwdata->userid, &XVibration) != ERROR_SUCCESS) {
   24.14          return SDL_SetError("XInputSetState() failed");
   24.15      }
   24.16 -
   24.17 -    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
   24.18 -        joystick->hwdata->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
   24.19 -    } else {
   24.20 -        joystick->hwdata->rumble_expiration = 0;
   24.21 -    }
   24.22      return 0;
   24.23  }
   24.24  
   24.25 @@ -516,13 +510,6 @@
   24.26          }
   24.27          joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
   24.28      }
   24.29 -
   24.30 -    if (joystick->hwdata->rumble_expiration) {
   24.31 -        Uint32 now = SDL_GetTicks();
   24.32 -        if (SDL_TICKS_PASSED(now, joystick->hwdata->rumble_expiration)) {
   24.33 -            SDL_XINPUT_JoystickRumble(joystick, 0, 0, 0);
   24.34 -        }
   24.35 -    }
   24.36  }
   24.37  
   24.38  void
   24.39 @@ -565,7 +552,7 @@
   24.40  }
   24.41  
   24.42  int
   24.43 -SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
   24.44 +SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
   24.45  {
   24.46      return SDL_Unsupported();
   24.47  }
    25.1 --- a/src/joystick/windows/SDL_xinputjoystick_c.h	Tue Feb 04 07:23:44 2020 -0800
    25.2 +++ b/src/joystick/windows/SDL_xinputjoystick_c.h	Tue Feb 04 12:48:53 2020 -0800
    25.3 @@ -26,7 +26,7 @@
    25.4  extern int SDL_XINPUT_JoystickInit(void);
    25.5  extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
    25.6  extern int SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice);
    25.7 -extern int SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
    25.8 +extern int SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
    25.9  extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick);
   25.10  extern void SDL_XINPUT_JoystickClose(SDL_Joystick * joystick);
   25.11  extern void SDL_XINPUT_JoystickQuit(void);