sdl2-compat: fix joystick events in WaitEventTimeout, fix HapticRumbleSupported return value (#238)

From 89b2d6229baa348aa3ec9d4a10212fc1b9858f47 Mon Sep 17 00:00:00 2001
From: Katharine Chui <[EMAIL REDACTED]>
Date: Wed, 1 Jan 2025 00:04:39 +0100
Subject: [PATCH] fix joystick events in WaitEventTimeout, fix
 HapticRumbleSupported return value (#238)

* update joystick haptic lists before calling Event3to2 in SDL_WaitEventTimeout

* implement SDL_HapticRumbleSupported as a wrapper function
---
 src/sdl2_compat.c | 19 +++++++++++++++++++
 src/sdl3_syms.h   |  2 +-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 0b24a55..0b4f016 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -1783,6 +1783,16 @@ SDL_WaitEventTimeout(SDL2_Event *event2, int timeout)
     SDL_Event event3;
     const int retval = SDL3_WaitEventTimeout(event2 ? &event3 : NULL, timeout);
     if ((retval == 1) && event2) {
+        /* Ensure joystick and haptic IDs are updated before calling Event3to2() */
+        switch (event3.type) {
+            case SDL_EVENT_JOYSTICK_ADDED:
+            case SDL_EVENT_GAMEPAD_ADDED:
+            case SDL_EVENT_GAMEPAD_REMOVED:
+            case SDL_EVENT_JOYSTICK_REMOVED:
+                SDL_NumJoysticks(); /* Refresh */
+                SDL_NumHaptics(); /* Refresh */
+                break;
+        }
         Event3to2(&event3, event2);
     }
     return retval;
@@ -8700,6 +8710,15 @@ SDL_HapticIndex(SDL_Haptic *haptic)
     return -1;
 }
 
+SDL_DECLSPEC int SDLCALL
+SDL_HapticRumbleSupported(SDL_Haptic *haptic)
+{
+    if (SDL3_GetHapticID(haptic) == 0) {
+        return -1;
+    }
+    return SDL3_HapticRumbleSupported(haptic) ? SDL2_TRUE : SDL2_FALSE;
+}
+
 static Uint16 HapticFeatures3to2(Uint32 features)
 {
     Uint16 features2 = 0;
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index 6d1aba5..3ddd3de 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -429,7 +429,6 @@ SDL3_SYM_RENAMED_RETCODE(bool,HapticPause,PauseHaptic,(SDL_Haptic *a),(a),return
 SDL3_SYM_RENAMED_RETCODE(bool,HapticRumbleInit,InitHapticRumble,(SDL_Haptic *a),(a),return)
 SDL3_SYM_RENAMED_RETCODE(bool,HapticRumblePlay,PlayHapticRumble,(SDL_Haptic *a, float b, Uint32 c),(a,b,c),return)
 SDL3_SYM_RENAMED_RETCODE(bool,HapticRumbleStop,StopHapticRumble,(SDL_Haptic *a),(a),return)
-SDL3_SYM_PASSTHROUGH_RETCODE(bool,HapticRumbleSupported,(SDL_Haptic *a),(a),return)
 SDL3_SYM_RENAMED_RETCODE(bool,HapticRunEffect,RunHapticEffect,(SDL_Haptic *a, int b, Uint32 c),(a,b,c),return)
 SDL3_SYM_RENAMED_RETCODE(bool,HapticSetAutocenter,SetHapticAutocenter,(SDL_Haptic *a, int b),(a,b),return)
 SDL3_SYM_RENAMED_RETCODE(bool,HapticSetGain,SetHapticGain,(SDL_Haptic *a, int b),(a,b),return)
@@ -544,6 +543,7 @@ SDL3_SYM_PASSTHROUGH(void,OnApplicationWillTerminate,(void),(),)
 SDL3_SYM(SDL_AudioDeviceID,OpenAudioDevice,(SDL_AudioDeviceID a, const SDL_AudioSpec *b),(a,b),return)
 SDL3_SYM(SDL_Gamepad *,OpenGamepad,(SDL_JoystickID a),(a),return)
 SDL3_SYM(SDL_Haptic*,OpenHaptic,(SDL_HapticID a),(a),return)
+SDL3_SYM(bool,HapticRumbleSupported,(SDL_Haptic *),(a),return)
 SDL3_SYM(SDL_IOStream*,OpenIO,(const SDL_IOStreamInterface *a, void *b),(a,b),return)
 SDL3_SYM(SDL_Joystick *,OpenJoystick,(SDL_JoystickID a),(a),return)
 SDL3_SYM(SDL_Sensor *,OpenSensor,(SDL_SensorID a),(a),return)