SDL: Fixed spamming the controller with reset IMU commands when they are failing

From 8e782876bb979aae8c4395f703e3a00b1f8cff9f Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 9 Aug 2022 21:30:11 -0700
Subject: [PATCH] Fixed spamming the controller with reset IMU commands when
 they are failing

---
 src/joystick/hidapi/SDL_hidapi_switch.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 45b7bb14ed8..baf0d622857 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -270,6 +270,7 @@ typedef struct {
     SDL_bool m_bReportSensors;
     SDL_bool m_bHasSensorData;
     Uint32 m_unLastInput;
+    Uint32 m_unLastIMUReset;
 
     SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState;
     SwitchSimpleStatePacket_t m_lastSimpleState;
@@ -1369,7 +1370,7 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
 
     /* Set up for input */
     ctx->m_bSyncWrite = SDL_FALSE;
-    ctx->m_unLastInput = SDL_GetTicks();
+    ctx->m_unLastIMUReset = ctx->m_unLastInput = SDL_GetTicks();
 
     return SDL_TRUE;
 
@@ -2005,16 +2006,22 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
 
         } else if (ctx->m_bHasSensorData) {
             /* Uh oh, someone turned off the IMU? */
-            SDL_HIDAPI_Device *device = ctx->device;
+            const Uint32 IMU_RESET_DELAY_MS = 3000;
+            Uint32 now = SDL_GetTicks();
 
-            if (device->updating) {
-                SDL_UnlockMutex(device->dev_lock);
-            }
+            if (SDL_TICKS_PASSED(now, ctx->m_unLastIMUReset + IMU_RESET_DELAY_MS)) {
+                SDL_HIDAPI_Device *device = ctx->device;
+
+                if (device->updating) {
+                    SDL_UnlockMutex(device->dev_lock);
+                }
 
-            SetIMUEnabled(ctx, SDL_TRUE);
+                SetIMUEnabled(ctx, SDL_TRUE);
 
-            if (device->updating) {
-                SDL_LockMutex(device->dev_lock);
+                if (device->updating) {
+                    SDL_LockMutex(device->dev_lock);
+                }
+                ctx->m_unLastIMUReset = now;
             }
 
         } else {