sdl2-compat: Updated for the latest SDL3 changes

From ca2e2ed1a9f968c238df03a5362e60d96ff5cd23 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 21 Jan 2024 11:38:36 -0800
Subject: [PATCH] Updated for the latest SDL3 changes

---
 src/dynapi/SDL_dynapi_procs.h |   8 +-
 src/sdl2_compat.c             | 274 +++++++++++++++++++++++++++++++++-
 src/sdl2_protos.h             |   8 +-
 src/sdl3_include_wrapper.h    | 243 ++++++++++++++++--------------
 src/sdl3_syms.h               |  76 +++++-----
 test/testautomation_math.c    |   2 +
 test/testautomation_stdlib.c  |  50 ++++++-
 7 files changed, 491 insertions(+), 170 deletions(-)

diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index eefb14e..1edac92 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -375,7 +375,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderDrawRects,(SDL_Renderer *a, const SDL_Rect *b, int
 SDL_DYNAPI_PROC(int,SDL_RenderFillRect,(SDL_Renderer *a, const SDL_Rect *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_RenderFillRects,(SDL_Renderer *a, const SDL_Rect *b, int c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_RenderCopy,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_Rect *d),(a,b,c,d),return)
-SDL_DYNAPI_PROC(int,SDL_RenderCopyEx,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_Rect *d, const double e, const SDL_Point *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return)
+SDL_DYNAPI_PROC(int,SDL_RenderCopyEx,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_Rect *d, const double e, const SDL_Point *f, const SDL_FlipMode g),(a,b,c,d,e,f,g),return)
 SDL_DYNAPI_PROC(int,SDL_RenderReadPixels,(SDL_Renderer *a, const SDL_Rect *b, Uint32 c, void *d, int e),(a,b,c,d,e),return)
 SDL_DYNAPI_PROC(void,SDL_RenderPresent,(SDL_Renderer *a),(a),)
 SDL_DYNAPI_PROC(void,SDL_DestroyTexture,(SDL_Texture *a),(a),)
@@ -504,8 +504,8 @@ SDL_DYNAPI_PROC(int,SDL_UpperBlitScaled,(SDL_Surface *a, const SDL_Rect *b, SDL_
 SDL_DYNAPI_PROC(int,SDL_LowerBlitScaled,(SDL_Surface *a, SDL_Rect *b, SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_GetWindowWMInfo,(SDL_Window *a, SDL_SysWMinfo *b),(a,b),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetThreadName,(SDL_Thread *a),(a),return)
-SDL_DYNAPI_PROC(SDL_threadID,SDL_ThreadID,(void),(),return)
-SDL_DYNAPI_PROC(SDL_threadID,SDL_GetThreadID,(SDL_Thread *a),(a),return)
+SDL_DYNAPI_PROC(unsigned long,SDL_ThreadID,(void),(),return)
+SDL_DYNAPI_PROC(unsigned long,SDL_GetThreadID,(SDL_Thread *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_SetThreadPriority,(SDL_ThreadPriority a),(a),return)
 SDL_DYNAPI_PROC(void,SDL_WaitThread,(SDL_Thread *a, int *b),(a,b),)
 SDL_DYNAPI_PROC(void,SDL_DetachThread,(SDL_Thread *a),(a),)
@@ -768,7 +768,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderDrawRectsF,(SDL_Renderer *a, const SDL_FRect *b, i
 SDL_DYNAPI_PROC(int,SDL_RenderFillRectF,(SDL_Renderer *a, const SDL_FRect *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_RenderFillRectsF,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_RenderCopyF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d),(a,b,c,d),return)
-SDL_DYNAPI_PROC(int,SDL_RenderCopyExF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return)
+SDL_DYNAPI_PROC(int,SDL_RenderCopyExF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_FlipMode g),(a,b,c,d,e,f,g),return)
 SDL_DYNAPI_PROC(SDL_TouchDeviceType,SDL_GetTouchDeviceType,(SDL_TouchID a),(a),return)
 #ifdef __IOS__
 SDL_DYNAPI_PROC(int,SDL_UIKitRunApp,(int a, char *b[], SDL_main_func c),(a,b,c),return)
diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 735cb58..e594450 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -735,6 +735,24 @@ BOOL WINAPI _DllMainCRTStartup(HANDLE dllhandle, DWORD reason, LPVOID reserved)
 #define SDL2_DISABLE  0
 #define SDL2_ENABLE   1
 
+/* changed values in SDL3 */
+#define SDL2_HAPTIC_CONSTANT   (1u<<0)
+#define SDL2_HAPTIC_SINE       (1u<<1)
+#define SDL2_HAPTIC_LEFTRIGHT     (1u<<2)
+#define SDL2_HAPTIC_TRIANGLE   (1u<<3)
+#define SDL2_HAPTIC_SAWTOOTHUP (1u<<4)
+#define SDL2_HAPTIC_SAWTOOTHDOWN (1u<<5)
+#define SDL2_HAPTIC_RAMP       (1u<<6)
+#define SDL2_HAPTIC_SPRING     (1u<<7)
+#define SDL2_HAPTIC_DAMPER     (1u<<8)
+#define SDL2_HAPTIC_INERTIA    (1u<<9)
+#define SDL2_HAPTIC_FRICTION   (1u<<10)
+#define SDL2_HAPTIC_CUSTOM     (1u<<11)
+#define SDL2_HAPTIC_GAIN       (1u<<12)
+#define SDL2_HAPTIC_AUTOCENTER (1u<<13)
+#define SDL2_HAPTIC_STATUS     (1u<<14)
+#define SDL2_HAPTIC_PAUSE      (1u<<15)
+
 #define SDL2_RENDERER_TARGETTEXTURE 0x00000008
 
 /* Events changed in SDL3; notably, the `timestamp` field moved from
@@ -1179,6 +1197,8 @@ static SDL_JoystickID *gamepad_button_swap_list = NULL;
 static int num_gamepad_button_swap_list = 0;
 static SDL_SensorID *sensor_list = NULL;
 static int num_sensors = 0;
+static SDL_HapticID *haptic_list = NULL;
+static int num_haptics = 0;
 
 static SDL_mutex *joystick_lock = NULL;
 static SDL_mutex *sensor_lock = NULL;
@@ -1672,6 +1692,7 @@ EventFilter3to2(void *userdata, SDL_Event *event3)
         case SDL_EVENT_GAMEPAD_REMOVED:
         case SDL_EVENT_JOYSTICK_REMOVED:
             SDL_NumJoysticks(); /* Refresh */
+            SDL_NumHaptics(); /* Refresh */
             break;
 
         /* display events moved to the top level in SDL3. */
@@ -2825,7 +2846,7 @@ SDL_RecordGesture(SDL_TouchID touchId)
 
     SDL3_free(touchdevs);
 
-    if (touchId < 0) {
+    if (touchId == (SDL_TouchID)-1) {
         GestureRecordAll = SDL_TRUE;  /* !!! FIXME: this is never set back to SDL_FALSE anywhere, that's probably a bug. */
         for (i = 0; i < GestureNumTouches; i++) {
             GestureTouches[i].recording = SDL_TRUE;
@@ -2979,7 +3000,7 @@ SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL2_RWops *src)
     if (src == NULL) {
         return 0;
     }
-    if (touchId >= 0) {
+    if (touchId != (SDL_TouchID)-1) {
         for (i = 0; i < GestureNumTouches; i++) {
             if (GestureTouches[i].touchId == touchId) {
                 touch = &GestureTouches[i];
@@ -3008,7 +3029,7 @@ SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL2_RWops *src)
         }
 #endif
 
-        if (touchId >= 0) {
+        if (touchId != (SDL_TouchID)-1) {
             /* printf("Adding loaded gesture to 1 touch\n"); */
             if (GestureAddDollar(touch, templ.path) >= 0) {
                 loaded++;
@@ -3730,7 +3751,7 @@ SDL_RenderTargetSupported(SDL_Renderer *renderer)
     SDL_RendererInfo info;
     ret = SDL_GetRendererInfo(renderer, &info);
     if (ret == 0) {
-        /* SDL_RENDERER_TARGETTEXTURE was removed in SDL3, check by name for 
+        /* SDL_RENDERER_TARGETTEXTURE was removed in SDL3, check by name for
          * renderer that does not support render target. */
         if (SDL3_strcmp(info.name, "opengles") == 0) {
             return SDL_FALSE;
@@ -4129,7 +4150,7 @@ SDL_RenderCopyF(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *sr
 DECLSPEC int SDLCALL
 SDL_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture,
                  const SDL_Rect *srcrect, const SDL_Rect *dstrect,
-                 const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
+                 const double angle, const SDL_Point *center, const SDL_FlipMode flip)
 {
     int retval;
     SDL_FRect srcfrect;
@@ -4168,7 +4189,7 @@ SDL_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture,
 DECLSPEC int SDLCALL
 SDL_RenderCopyExF(SDL_Renderer *renderer, SDL_Texture *texture,
                   const SDL_Rect *srcrect, const SDL_FRect *dstrect,
-                  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
+                  const double angle, const SDL_FPoint *center, const SDL_FlipMode flip)
 {
     int retval;
     SDL_FRect srcfrect;
@@ -4364,6 +4385,12 @@ SDL_Quit(void)
     }
     num_sensors = 0;
 
+    if (haptic_list) {
+        SDL3_free(haptic_list);
+        haptic_list = NULL;
+    }
+    num_haptics = 0;
+
     if (gamepad_button_swap_list) {
         SDL3_free(gamepad_button_swap_list);
         gamepad_button_swap_list = NULL;
@@ -5711,7 +5738,7 @@ CPU_haveCPUID(void)
     : "%eax", "%ecx"
     );
 #elif (defined(__GNUC__) || defined(__llvm__)) && defined(__x86_64__)
-/* Technically, if this is being compiled under __x86_64__ then it has 
+/* Technically, if this is being compiled under __x86_64__ then it has
    CPUid by definition.  But it's nice to be able to prove it.  :)      */
     __asm__ (
 "        pushfq                      # Get original EFLAGS             \n"
@@ -7072,6 +7099,227 @@ SDL_SensorOpen(int idx)
 }
 
 
+static SDL_HapticID
+GetHapticInstanceFromIndex(int idx)
+{
+    if ((idx < 0) || (idx >= num_haptics)) {
+        SDL3_SetError("There are %d haptics available", num_haptics);
+        return 0;
+    }
+    return haptic_list[idx];
+}
+
+DECLSPEC int SDLCALL
+SDL_NumHaptics(void)
+{
+    SDL3_free(haptic_list);
+    haptic_list = SDL3_GetHaptics(&num_haptics);
+    if (haptic_list == NULL) {
+        num_haptics = 0;
+        return -1;
+    }
+    return num_haptics;
+}
+
+DECLSPEC const char * SDLCALL
+SDL_HapticName(int device_index)
+{
+    const SDL_HapticID instance_id = GetHapticInstanceFromIndex(device_index);
+    return instance_id ? SDL3_GetHapticInstanceName(instance_id) : NULL;
+}
+
+DECLSPEC
+SDL_Haptic * SDLCALL
+SDL_HapticOpen(int device_index)
+{
+    const SDL_HapticID instance_id = GetHapticInstanceFromIndex(device_index);
+    return SDL3_OpenHaptic(instance_id);
+}
+
+DECLSPEC int SDLCALL
+SDL_HapticOpened(int device_index)
+{
+    const SDL_HapticID instance_id = GetHapticInstanceFromIndex(device_index);
+    if (SDL3_GetHapticFromInstanceID(instance_id) != NULL) {
+        return 1;
+    }
+    return 0;
+}
+
+DECLSPEC int SDLCALL
+SDL_HapticIndex(SDL_Haptic *haptic)
+{
+    const SDL_HapticID instance_id = SDL3_GetHapticInstanceID(haptic);
+    int i;
+
+    for (i = 0; i < num_haptics; ++i) {
+        if (instance_id == haptic_list[i]) {
+            return i;
+        }
+    }
+    return SDL_SetError("Haptic: Invalid haptic device identifier");
+}
+
+static Uint16 HapticFeatures3to2(Uint32 features)
+{
+    Uint16 features2 = 0;
+
+    /* We could be clever and shift bits around, but let's be clear instead */
+    if (features & SDL_HAPTIC_CONSTANT) {
+        features2 |= SDL2_HAPTIC_CONSTANT;
+    }
+    if (features & SDL_HAPTIC_SINE) {
+        features2 |= SDL2_HAPTIC_SINE;
+    }
+    if (features & SDL_HAPTIC_LEFTRIGHT) {
+        features2 |= SDL2_HAPTIC_LEFTRIGHT;
+    }
+    if (features & SDL_HAPTIC_TRIANGLE) {
+        features2 |= SDL2_HAPTIC_TRIANGLE;
+    }
+    if (features & SDL_HAPTIC_SAWTOOTHUP) {
+        features2 |= SDL2_HAPTIC_SAWTOOTHUP;
+    }
+    if (features & SDL_HAPTIC_SAWTOOTHDOWN) {
+        features2 |= SDL2_HAPTIC_SAWTOOTHDOWN;
+    }
+    if (features & SDL_HAPTIC_RAMP) {
+        features2 |= SDL2_HAPTIC_RAMP;
+    }
+    if (features & SDL_HAPTIC_SPRING) {
+        features2 |= SDL2_HAPTIC_SPRING;
+    }
+    if (features & SDL_HAPTIC_DAMPER) {
+        features2 |= SDL2_HAPTIC_DAMPER;
+    }
+    if (features & SDL_HAPTIC_INERTIA) {
+        features2 |= SDL2_HAPTIC_INERTIA;
+    }
+    if (features & SDL_HAPTIC_FRICTION) {
+        features2 |= SDL2_HAPTIC_FRICTION;
+    }
+    if (features & SDL_HAPTIC_CUSTOM) {
+        features2 |= SDL2_HAPTIC_CUSTOM;
+    }
+    if (features & SDL_HAPTIC_GAIN) {
+        features2 |= SDL2_HAPTIC_GAIN;
+    }
+    if (features & SDL_HAPTIC_AUTOCENTER) {
+        features2 |= SDL2_HAPTIC_AUTOCENTER;
+    }
+    if (features & SDL_HAPTIC_STATUS) {
+        features2 |= SDL2_HAPTIC_STATUS;
+    }
+    if (features & SDL_HAPTIC_PAUSE) {
+        features2 |= SDL2_HAPTIC_PAUSE;
+    }
+    return features2;
+}
+
+static Uint32 HapticFeatures2to3(Uint16 features)
+{
+    Uint32 features3 = 0;
+
+    /* We could be clever and shift bits around, but let's be clear instead */
+    if (features & SDL2_HAPTIC_CONSTANT) {
+        features3 |= SDL_HAPTIC_CONSTANT;
+    }
+    if (features & SDL2_HAPTIC_SINE) {
+        features3 |= SDL_HAPTIC_SINE;
+    }
+    if (features & SDL2_HAPTIC_LEFTRIGHT) {
+        features3 |= SDL_HAPTIC_LEFTRIGHT;
+    }
+    if (features & SDL2_HAPTIC_TRIANGLE) {
+        features3 |= SDL_HAPTIC_TRIANGLE;
+    }
+    if (features & SDL2_HAPTIC_SAWTOOTHUP) {
+        features3 |= SDL_HAPTIC_SAWTOOTHUP;
+    }
+    if (features & SDL2_HAPTIC_SAWTOOTHDOWN) {
+        features3 |= SDL_HAPTIC_SAWTOOTHDOWN;
+    }
+    if (features & SDL2_HAPTIC_RAMP) {
+        features3 |= SDL_HAPTIC_RAMP;
+    }
+    if (features & SDL2_HAPTIC_SPRING) {
+        features3 |= SDL_HAPTIC_SPRING;
+    }
+    if (features & SDL2_HAPTIC_DAMPER) {
+        features3 |= SDL_HAPTIC_DAMPER;
+    }
+    if (features & SDL2_HAPTIC_INERTIA) {
+        features3 |= SDL_HAPTIC_INERTIA;
+    }
+    if (features & SDL2_HAPTIC_FRICTION) {
+        features3 |= SDL_HAPTIC_FRICTION;
+    }
+    if (features & SDL2_HAPTIC_CUSTOM) {
+        features3 |= SDL_HAPTIC_CUSTOM;
+    }
+    if (features & SDL2_HAPTIC_GAIN) {
+        features3 |= SDL_HAPTIC_GAIN;
+    }
+    if (features & SDL2_HAPTIC_AUTOCENTER) {
+        features3 |= SDL_HAPTIC_AUTOCENTER;
+    }
+    if (features & SDL2_HAPTIC_STATUS) {
+        features3 |= SDL_HAPTIC_STATUS;
+    }
+    if (features & SDL2_HAPTIC_PAUSE) {
+        features3 |= SDL_HAPTIC_PAUSE;
+    }
+    return features3;
+}
+
+static void HapticEffect2to3(const SDL_HapticEffect *effect2, SDL_HapticEffect *effect3)
+{
+    SDL3_copyp(effect3, effect2);
+    effect3->type = (Uint16)HapticFeatures2to3(effect2->type);
+}
+
+DECLSPEC unsigned int SDLCALL
+SDL_HapticQuery(SDL_Haptic *haptic)
+{
+    return HapticFeatures3to2(SDL3_GetHapticFeatures(haptic));
+}
+
+DECLSPEC SDL_bool SDLCALL
+SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect)
+{
+    SDL_HapticEffect effect3;
+
+    if (!effect) {
+        return SDL_FALSE;
+    }
+    HapticEffect2to3(effect, &effect3);
+    return SDL3_HapticEffectSupported(haptic, &effect3);
+}
+
+DECLSPEC int SDLCALL
+SDL_HapticNewEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect)
+{
+    SDL_HapticEffect effect3;
+
+    if (!effect) {
+        return SDL3_InvalidParamError("effect");
+    }
+    HapticEffect2to3(effect, &effect3);
+    return SDL3_CreateHapticEffect(haptic, &effect3);
+}
+
+DECLSPEC int SDLCALL
+SDL_HapticUpdateEffect(SDL_Haptic *haptic, int effect, SDL_HapticEffect *data)
+{
+    SDL_HapticEffect effect3;
+
+    if (!data) {
+        return SDL3_InvalidParamError("data");
+    }
+    HapticEffect2to3(data, &effect3);
+    return SDL3_UpdateHapticEffect(haptic, effect, &effect3);
+}
+
 DECLSPEC int SDLCALL
 SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
 {
@@ -7453,6 +7701,18 @@ SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id)
     return retval;
 }
 
+DECLSPEC unsigned long SDLCALL
+SDL_ThreadID(void)
+{
+    return (unsigned long)SDL3_GetCurrentThreadID();
+}
+
+DECLSPEC unsigned long SDLCALL
+SDL_GetThreadID(SDL_Thread *thread)
+{
+    return (unsigned long)SDL3_GetThreadID(thread);
+}
+
 #if defined(__WIN32__) || defined(__WINGDK__)
 DECLSPEC int SDLCALL
 SDL_Direct3D9GetAdapterIndex(int displayIndex)
diff --git a/src/sdl2_protos.h b/src/sdl2_protos.h
index 59e319e..ce718ad 100644
--- a/src/sdl2_protos.h
+++ b/src/sdl2_protos.h
@@ -364,7 +364,7 @@ SDL2_PROTO(int,RenderDrawRects,(SDL_Renderer *a, const SDL_Rect *b, int c))
 SDL2_PROTO(int,RenderFillRect,(SDL_Renderer *a, const SDL_Rect *b))
 SDL2_PROTO(int,RenderFillRects,(SDL_Renderer *a, const SDL_Rect *b, int c))
 SDL2_PROTO(int,RenderCopy,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_Rect *d))
-SDL2_PROTO(int,RenderCopyEx,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_Rect *d, const double e, const SDL_Point *f, const SDL_RendererFlip g))
+SDL2_PROTO(int,RenderCopyEx,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_Rect *d, const double e, const SDL_Point *f, const SDL_FlipMode g))
 SDL2_PROTO(int,RenderReadPixels,(SDL_Renderer *a, const SDL_Rect *b, Uint32 c, void *d, int e))
 SDL2_PROTO(void,RenderPresent,(SDL_Renderer *a))
 SDL2_PROTO(void,DestroyTexture,(SDL_Texture *a))
@@ -493,8 +493,8 @@ SDL2_PROTO(int,UpperBlitScaled,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *
 SDL2_PROTO(int,LowerBlitScaled,(SDL_Surface *a, SDL_Rect *b, SDL_Surface *c, SDL_Rect *d))
 SDL2_PROTO(SDL_bool,GetWindowWMInfo,(SDL_Window *a, SDL_SysWMinfo *b))
 SDL2_PROTO(const char*,GetThreadName,(SDL_Thread *a))
-SDL2_PROTO(SDL_threadID,ThreadID,(void))
-SDL2_PROTO(SDL_threadID,GetThreadID,(SDL_Thread *a))
+SDL2_PROTO(unsigned long,ThreadID,(void))
+SDL2_PROTO(unsigned long,GetThreadID,(SDL_Thread *a))
 SDL2_PROTO(int,SetThreadPriority,(SDL_ThreadPriority a))
 SDL2_PROTO(void,WaitThread,(SDL_Thread *a, int *b))
 SDL2_PROTO(void,DetachThread,(SDL_Thread *a))
@@ -753,7 +753,7 @@ SDL2_PROTO(int,RenderDrawRectsF,(SDL_Renderer *a, const SDL_FRect *b, int c))
 SDL2_PROTO(int,RenderFillRectF,(SDL_Renderer *a, const SDL_FRect *b))
 SDL2_PROTO(int,RenderFillRectsF,(SDL_Renderer *a, const SDL_FRect *b, int c))
 SDL2_PROTO(int,RenderCopyF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d))
-SDL2_PROTO(int,RenderCopyExF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_RendererFlip g))
+SDL2_PROTO(int,RenderCopyExF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_FlipMode g))
 SDL2_PROTO(SDL_TouchDeviceType,GetTouchDeviceType,(SDL_TouchID a))
 #ifdef __IOS__
 SDL2_PROTO(int,UIKitRunApp,(int a, char *b[], SDL_main_func c))
diff --git a/src/sdl3_include_wrapper.h b/src/sdl3_include_wrapper.h
index cb78cca..c37633b 100644
--- a/src/sdl3_include_wrapper.h
+++ b/src/sdl3_include_wrapper.h
@@ -28,6 +28,12 @@
 #ifndef INCL_SDL3_INCLUDE_WRAPPER_H
 #define INCL_SDL3_INCLUDE_WRAPPER_H
 
+#define SDL_SLOW_MEMCPY
+#define SDL_SLOW_MEMMOVE
+#define SDL_SLOW_MEMSET
+
+#define SDL_ThreadID SDL3_ThreadID /* avoid clash with SDL_ThreadID() of SDL2 */
+
 #define SDL_AddEventWatch IGNORE_THIS_VERSION_OF_SDL_AddEventWatch
 #define SDL_AddGamepadMapping IGNORE_THIS_VERSION_OF_SDL_AddGamepadMapping
 #define SDL_AddGamepadMappingsFromRW IGNORE_THIS_VERSION_OF_SDL_AddGamepadMappingsFromRW
@@ -43,15 +49,15 @@
 #define SDL_AndroidSendMessage IGNORE_THIS_VERSION_OF_SDL_AndroidSendMessage
 #define SDL_AndroidShowToast IGNORE_THIS_VERSION_OF_SDL_AndroidShowToast
 #define SDL_AtomicAdd IGNORE_THIS_VERSION_OF_SDL_AtomicAdd
-#define SDL_AtomicCAS IGNORE_THIS_VERSION_OF_SDL_AtomicCAS
-#define SDL_AtomicCASPtr IGNORE_THIS_VERSION_OF_SDL_AtomicCASPtr
+#define SDL_AtomicCompareAndSwap IGNORE_THIS_VERSION_OF_SDL_AtomicCompareAndSwap
+#define SDL_AtomicCompareAndSwapPointer IGNORE_THIS_VERSION_OF_SDL_AtomicCompareAndSwapPointer
 #define SDL_AtomicGet IGNORE_THIS_VERSION_OF_SDL_AtomicGet
 #define SDL_AtomicGetPtr IGNORE_THIS_VERSION_OF_SDL_AtomicGetPtr
-#define SDL_AtomicLock IGNORE_THIS_VERSION_OF_SDL_AtomicLock
+#define SDL_LockSpinlock IGNORE_THIS_VERSION_OF_SDL_LockSpinlock
 #define SDL_AtomicSet IGNORE_THIS_VERSION_OF_SDL_AtomicSet
 #define SDL_AtomicSetPtr IGNORE_THIS_VERSION_OF_SDL_AtomicSetPtr
-#define SDL_AtomicTryLock IGNORE_THIS_VERSION_OF_SDL_AtomicTryLock
-#define SDL_AtomicUnlock IGNORE_THIS_VERSION_OF_SDL_AtomicUnlock
+#define SDL_TryLockSpinlock IGNORE_THIS_VERSION_OF_SDL_TryLockSpinlock
+#define SDL_UnlockSpinlock IGNORE_THIS_VERSION_OF_SDL_UnlockSpinlock
 #define SDL_AttachVirtualJoystick IGNORE_THIS_VERSION_OF_SDL_AttachVirtualJoystick
 #define SDL_AttachVirtualJoystickEx IGNORE_THIS_VERSION_OF_SDL_AttachVirtualJoystickEx
 #define SDL_BlitSurface IGNORE_THIS_VERSION_OF_SDL_BlitSurface
@@ -378,33 +384,30 @@
 #define SDL_GetWindowTitle IGNORE_THIS_VERSION_OF_SDL_GetWindowTitle
 #define SDL_GetYUVConversionMode IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionMode
 #define SDL_GetYUVConversionModeForResolution IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionModeForResolution
-#define SDL_HapticClose IGNORE_THIS_VERSION_OF_SDL_HapticClose
-#define SDL_HapticDestroyEffect IGNORE_THIS_VERSION_OF_SDL_HapticDestroyEffect
+#define SDL_CloseHaptic IGNORE_THIS_VERSION_OF_SDL_CloseHaptic
+#define SDL_DestroyHapticEffect IGNORE_THIS_VERSION_OF_SDL_DestroyHapticEffect
 #define SDL_HapticEffectSupported IGNORE_THIS_VERSION_OF_SDL_HapticEffectSupported
-#define SDL_HapticGetEffectStatus IGNORE_THIS_VERSION_OF_SDL_HapticGetEffectStatus
-#define SDL_HapticIndex IGNORE_THIS_VERSION_OF_SDL_HapticIndex
-#define SDL_HapticName IGNORE_THIS_VERSION_OF_SDL_HapticName
-#define SDL_HapticNewEffect IGNORE_THIS_VERSION_OF_SDL_HapticNewEffect
-#define SDL_HapticNumAxes IGNORE_THIS_VERSION_OF_SDL_HapticNumAxes
-#define SDL_HapticNumEffects IGNORE_THIS_VERSION_OF_SDL_HapticNumEffects
-#define SDL_HapticNumEffectsPlaying IGNORE_THIS_VERSION_OF_SDL_HapticNumEffectsPlaying
-#define SDL_HapticOpen IGNORE_THIS_VERSION_OF_SDL_HapticOpen
-#define SDL_HapticOpenFromJoystick IGNORE_THIS_VERSION_OF_SDL_HapticOpenFromJoystick
-#define SDL_HapticOpenFromMouse IGNORE_THIS_VERSION_OF_SDL_HapticOpenFromMouse
-#define SDL_HapticOpened IGNORE_THIS_VERSION_OF_SDL_HapticOpened
-#define SDL_HapticPause IGNORE_THIS_VERSION_OF_SDL_HapticPause
-#define SDL_HapticQuery IGNORE_THIS_VERSION_OF_SDL_HapticQuery
-#define SDL_HapticRumbleInit IGNORE_THIS_VERSION_OF_SDL_HapticRumbleInit
-#define SDL_HapticRumblePlay IGNORE_THIS_VERSION_OF_SDL_HapticRumblePlay
-#define SDL_HapticRumbleStop IGNORE_THIS_VERSION_OF_SDL_HapticRumbleStop
+#define SDL_GetHapticEffectStatus IGNORE_THIS_VERSION_OF_SDL_GetHapticEffectStatus
+#define SDL_CreateHapticEffect IGNORE_THIS_VERSION_OF_SDL_CreateHapticEffect
+#define SDL_GetNumHapticAxes IGNORE_THIS_VERSION_OF_SDL_GetNumHapticAxes
+#define SDL_GetMaxHapticEffects IGNORE_THIS_VERSION_OF_SDL_GetMaxHapticEffects
+#define SDL_GetMaxHapticEffectsPlaying IGNORE_THIS_VERSION_OF_SDL_GetMaxHapticEffectsPlaying
+#define SDL_OpenHaptic IGNORE_THIS_VERSION_OF_SDL_OpenHaptic
+#define SDL_OpenHapticFromJoystick IGNORE_THIS_VERSION_OF_SDL_OpenHapticFromJoystick
+#define SDL_OpenHapticFromMouse IGNORE_THIS_VERSION_OF_SDL_OpenHapticFromMouse
+#define SDL_PauseHaptic IGNORE_THIS_VERSION_OF_SDL_PauseHaptic
+#define SDL_GetHapticFeatures IGNORE_THIS_VERSION_OF_SDL_GetHapticFeatures
+#define SDL_InitHapticRumble IGNORE_THIS_VERSION_OF_SDL_InitHapticRumble
+#define SDL_PlayHapticRumble IGNORE_THIS_VERSION_OF_SDL_PlayHapticRumble
+#define SDL_StopHapticRumble IGNORE_THIS_VERSION_OF_SDL_StopHapticRumble
 #define SDL_HapticRumbleSupported IGNORE_THIS_VERSION_OF_SDL_HapticRumbleSupported
-#define SDL_HapticRunEffect IGNORE_THIS_VERSION_OF_SDL_HapticRunEffect
-#define SDL_HapticSetAutocenter IGNORE_THIS_VERSION_OF_SDL_HapticSetAutocenter
-#define SDL_HapticSetGain IGNORE_THIS_VERSION_OF_SDL_HapticSetGain
-#define SDL_HapticStopAll IGNORE_THIS_VERSION_OF_SDL_HapticStopAll
-#define SDL_HapticStopEffect IGNORE_THIS_VERSION_OF_SDL_HapticStopEffect
-#define SDL_HapticUnpause IGNORE_THIS_VERSION_OF_SDL_HapticUnpause
-#define SDL_HapticUpdateEffect IGNORE_THIS_VERSION_OF_SDL_HapticUpdateEffect
+#define SDL_RunHapticEffect IGNORE_THIS_VERSION_OF_SDL_RunHapticEffect
+#define SDL_SetHapticAutocenter IGNORE_THIS_VERSION_OF_SDL_SetHapticAutocenter
+#define SDL_SetHapticGain IGNORE_THIS_VERSION_OF_SDL_SetHapticGain
+#define SDL_StopHapticEffects IGNORE_THIS_VERSION_OF_SDL_StopHapticEffects
+#define SDL_StopHapticEffect IGNORE_THIS_VERSION_OF_SDL_StopHapticEffect
+#define SDL_ResumeHaptic IGNORE_THIS_VERSION_OF_SDL_ResumeHaptic
+#define SDL_UpdateHapticEffect IGNORE_THIS_VERSION_OF_SDL_UpdateHapticEffect
 #define SDL_HasARMSIMD IGNORE_THIS_VERSION_OF_SDL_HasARMSIMD
 #define SDL_HasAVX IGNORE_THIS_VERSION_OF_SDL_HasAVX
 #define SDL_HasAVX2 IGNORE_THIS_VERSION_OF_SDL_HasAVX2
@@ -443,7 +446,7 @@
 #define SDL_JoystickHasLED IGNORE_THIS_VERSION_OF_SDL_JoystickHasLED
 #define SDL_JoystickHasRumble IGNORE_THIS_VERSION_OF_SDL_JoystickHasRumble
 #define SDL_JoystickHasRumbleTriggers IGNORE_THIS_VERSION_OF_SDL_JoystickHasRumbleTriggers
-#define SDL_JoystickIsHaptic IGNORE_THIS_VERSION_OF_SDL_JoystickIsHaptic
+#define SDL_IsJoystickHaptic IGNORE_THIS_VERSION_OF_SDL_IsJoystickHaptic
 #define SDL_LinuxSetThreadPriority IGNORE_THIS_VERSION_OF_SDL_LinuxSetThreadPriority
 #define SDL_LinuxSetThreadPriorityAndPolicy IGNORE_THIS_VERSION_OF_SDL_LinuxSetThreadPriorityAndPolicy
 #define SDL_LoadBMP IGNORE_THIS_VERSION_OF_SDL_LoadBMP
@@ -483,8 +486,7 @@
 #define SDL_Metal_DestroyView IGNORE_THIS_VERSION_OF_SDL_Metal_DestroyView
 #define SDL_Metal_GetLayer IGNORE_THIS_VERSION_OF_SDL_Metal_GetLayer
 #define SDL_MinimizeWindow IGNORE_THIS_VERSION_OF_SDL_MinimizeWindow
-#define SDL_MouseIsHaptic IGNORE_THIS_VERSION_OF_SDL_MouseIsHaptic
-#define SDL_NumHaptics IGNORE_THIS_VERSION_OF_SDL_NumHaptics
+#define SDL_IsMouseHaptic IGNORE_THIS_VERSION_OF_SDL_IsMouseHaptic
 #define SDL_OnApplicationDidBecomeActive IGNORE_THIS_VERSION_OF_SDL_OnApplicationDidBecomeActive
 #define SDL_OnApplicationDidChangeStatusBarOrientation IGNORE_THIS_VERSION_OF_SDL_OnApplicationDidChangeStatusBarOrientation
 #define SDL_OnApplicationDidEnterBackground IGNORE_THIS_VERSION_OF_SDL_OnApplicationDidEnterBackground
@@ -642,7 +644,7 @@
 #define SDL_SurfaceHasRLE IGNORE_THIS_VERSION_OF_SDL_SurfaceHasRLE
 #define SDL_TextInputActive IGNORE_THIS_VERSION_OF_SDL_TextInputActive
 #define SDL_TextInputShown IGNORE_THIS_VERSION_OF_SDL_TextInputShown
-#define SDL_ThreadID IGNORE_THIS_VERSION_OF_SDL_ThreadID
+#define SDL_GetCurrentThreadID IGNORE_THIS_VERSION_OF_SDL_GetCurrentThreadID
 #define SDL_TryLockMutex IGNORE_THIS_VERSION_OF_SDL_TryLockMutex
 #define SDL_TryLockRWLockForReading IGNORE_THIS_VERSION_OF_SDL_TryLockRWLockForReading
 #define SDL_TryLockRWLockForWriting IGNORE_THIS_VERSION_OF_SDL_TryLockRWLockForWriting
@@ -987,6 +989,13 @@
 #define SDL_SyncWindow IGNORE_THIS_VERSION_OF_SDL_SyncWindow
 #define SDL_GetGamepadSteamHandle IGNORE_THIS_VERSION_OF_SDL_GetGamepadSteamHandle
 #define SDL_GetRendererFromTexture IGNORE_THIS_VERSION_OF_SDL_GetRendererFromTexture
+#define SDL_GetHaptics IGNORE_THIS_VERSION_OF_SDL_GetHaptics
+#define SDL_GetHapticInstanceName IGNORE_THIS_VERSION_OF_SDL_GetHapticInstanceName
+#define SDL_GetHapticFromInstanceID IGNORE_THIS_VERSION_OF_SDL_GetHapticFromInstanceID
+#define SDL_GetHapticInstanceID IGNORE_THIS_VERSION_OF_SDL_GetHapticInstanceID
+#define SDL_GetHapticName IGNORE_THIS_VERSION_OF_SDL_GetHapticName
+#define SDL_ReadSurfacePixel IGNORE_THIS_VERSION_OF_SDL_ReadSurfacePixel
+#define SDL_FlipSurface IGNORE_THIS_VERSION_OF_SDL_FlipSurface
 
 
 #define SDL_FUNCTION_POINTER_IS_VOID_POINTER 1
@@ -1075,12 +1084,12 @@
 #undef SDL_AtomicAdd
 #endif
 
-#ifdef SDL_AtomicCAS
-#undef SDL_AtomicCAS
+#ifdef SDL_AtomicCompareAndSwap
+#undef SDL_AtomicCompareAndSwap
 #endif
 
-#ifdef SDL_AtomicCASPtr
-#undef SDL_AtomicCASPtr
+#ifdef SDL_AtomicCompareAndSwapPointer
+#undef SDL_AtomicCompareAndSwapPointer
 #endif
 
 #ifdef SDL_AtomicGet
@@ -1091,8 +1100,8 @@
 #undef SDL_AtomicGetPtr
 #endif
 
-#ifdef SDL_AtomicLock
-#undef SDL_AtomicLock
+#ifdef SDL_LockSpinlock
+#undef SDL_LockSpinlock
 #endif
 
 #ifdef SDL_AtomicSet
@@ -1103,12 +1112,12 @@
 #undef SDL_AtomicSetPtr
 #endif
 
-#ifdef SDL_AtomicTryLock
-#undef SDL_AtomicTryLock
+#ifdef SDL_TryLockSpinlock
+#undef SDL_TryLockSpinlock
 #endif
 
-#ifdef SDL_AtomicUnlock
-#undef SDL_AtomicUnlock
+#ifdef SDL_UnlockSpinlock
+#undef SDL_UnlockSpinlock
 #endif
 
 #ifdef SDL_AttachVirtualJoystick
@@ -2415,112 +2424,100 @@
 #undef SDL_GetYUVConversionModeForResolution
 #endif
 
-#ifdef SDL_HapticClose
-#undef SDL_HapticClose
+#ifdef SDL_CloseHaptic
+#undef SDL_CloseHaptic
 #endif
 
-#ifdef SDL_HapticDestroyEffect
-#undef SDL_HapticDestroyEffect
+#ifdef SDL_DestroyHapticEffect
+#undef SDL_DestroyHapticEffect
 #endif
 
 #ifdef SDL_HapticEffectSupported
 #undef SDL_HapticEffectSupported
 #endif
 
-#ifdef SDL_HapticGetEffectStatus
-#undef SDL_HapticGetEffectStatus
-#endif
-
-#ifdef SDL_HapticIndex
-#undef SDL_HapticIndex
+#ifdef SDL_GetHapticEffectStatus
+#undef SDL_GetHapticEffectStatus
 #endif
 
-#ifdef SDL_HapticName
-#undef SDL_HapticName
+#ifdef SDL_CreateHapticEffect
+#undef SDL_CreateHapticEffect
 #endif
 
-#ifdef SDL_HapticNewEffect
-#undef SDL_HapticNewEffect
+#ifdef SDL_GetNumHapticAxes
+#undef SDL_GetNumHapticAxes
 #endif
 
-#ifdef SDL_HapticNumAxes
-#undef SDL_HapticNumAxes
+#ifdef SDL_GetMaxHapticEffects
+#undef SDL_GetMaxHapticEffects
 #endif
 
-#ifdef SDL_HapticNumEffects
-#undef SDL_HapticNumEffects
+#ifdef SDL_GetMaxHapticEffectsPlaying
+#undef SDL_GetMaxHapticEffectsPlaying
 #endif
 
-#ifdef SDL_HapticNumEffectsPlaying
-#undef SDL_HapticNumEffectsPlaying
+#ifdef SDL_OpenHaptic
+#undef SDL_OpenHaptic
 #endif
 
-#ifdef SDL_HapticOpen
-#undef SDL_HapticOpen
+#ifdef SDL_OpenHapticFromJoystick
+#undef SDL_OpenHapticFromJoystick
 #endif
 
-#ifdef SDL_HapticOpenFromJoystick
-#undef SDL_HapticOpenFromJoystick
+#ifdef SDL_OpenHapticFromMouse
+#undef SDL_OpenHapticFromMouse
 #endif
 
-#ifdef SDL_HapticOpenFromMouse
-#undef SDL_HapticOpenFromMouse
+#ifdef SDL_PauseHaptic
+#undef SDL_PauseHaptic
 #endif
 
-#ifdef SDL_HapticOpened
-#undef SDL_HapticOpened
+#ifdef SDL_GetHapticFeatures
+#undef SDL_GetHapticFeatures
 #endif
 
-#ifdef SDL_HapticPause
-#undef SDL_HapticPause
+#ifdef SDL_InitHapticRumble
+#undef SDL_InitHapticRumble
 #endif
 
-#ifdef SDL_HapticQuery
-#undef SDL_HapticQuery
+#ifdef SDL_PlayHapticRumble
+#undef SDL_PlayHapticRumble
 #endif
 
-#ifdef SDL_HapticRumbleInit
-#undef SDL_HapticRumbleInit
-#endif
-
-#ifdef SDL_HapticRumblePlay
-#undef SDL_HapticRumblePlay
-#endif
-
-#ifdef SDL_HapticRumbleStop
-#undef SDL_HapticRumbleStop
+#ifdef SDL_StopHapticRumble
+#undef SDL_StopHapticRumble
 #endif
 
 #ifdef SDL_HapticRumbleSupported
 #undef SDL_HapticRumbleSupported
 #endif
 
-#ifdef SDL_HapticRunEffect
-#undef SDL_HapticRunEffect
+#ifdef SDL_RunHapticEffect
+#undef SDL_RunHapticEffect
 #endif
 
-#ifdef SDL_HapticSetAutocenter
-#undef SDL_HapticSetAutocenter
+#ifdef SDL_SetHapticAutocenter
+#undef SDL_SetHapticAutocenter
 #endif
 
-#ifdef SDL_HapticSetGain
-#undef SDL_HapticSetGain
+#ifdef SDL_SetHapticGain
+#undef SDL_SetHapticGain
 #endif
 
-#ifdef SDL_HapticStopAll
-#undef SDL_HapticStopAll
+#ifdef SDL_StopHapticEffects
+#undef SDL_StopHapticEffects
 #endif
 
-#ifdef SDL_HapticStopEffect
-#undef SDL_HapticStopEffect
+#ifdef SDL_StopHapticEffect
+#undef SDL_StopHapticEffect
 #endif
 
-#ifdef SDL_HapticUnpause
-#undef SDL_HapticUnpause
+#ifdef SDL_ResumeHaptic
+#undef SDL_ResumeHaptic
 #endif
 
-#ifdef SDL_HapticUpdateEffect
-#undef SDL_HapticUpdateEffect
+#ifdef SDL_UpdateHapticEffect
+#undef SDL_UpdateHapticEffect
 #endif
 
 #ifdef SDL_HasARMSIMD
@@ -2675,8 +2672,8 @@
 #undef SDL_JoystickHasRumbleTriggers
 #endif
 
-#ifdef SDL_JoystickIsHaptic
-#undef SDL_JoystickIsHaptic
+#ifdef SDL_IsJoystickHaptic
+#undef SDL_IsJoystickHaptic
 #endif
 
 #ifdef SDL_LinuxSetThreadPriority
@@ -2835,12 +2832,8 @@
 #undef SDL_MinimizeWindow
 #endif
 
-#ifdef SDL_MouseIsHaptic
-#undef SDL_MouseIsHaptic
-#endif
-
-#ifdef SDL_NumHaptics
-#undef SDL_NumHaptics
+#ifdef SDL_IsMouseHaptic
+#undef SDL_IsMouseHaptic
 #endif
 
 #ifdef SDL_OnApplicationDidBecomeActive
@@ -3471,8 +3464,8 @@
 #undef SDL_TextInputShown
 #endif
 
-#ifdef SDL_ThreadID
-#undef SDL_ThreadID
+#ifdef SDL_GetCurrentThreadID
+#undef SDL_GetCurrentThreadID
 #endif
 
 #ifdef SDL_TryLoc

(Patch may be truncated, please check the link at the top of this post.)