sdl2-compat: Added support for SDL_INIT_TIMER

From fc20612ffcd590ccd77965f1395dea26464f45ba Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 5 Feb 2025 08:57:32 -0800
Subject: [PATCH] Added support for SDL_INIT_TIMER

Fixes https://github.com/libsdl-org/sdl2-compat/issues/317
---
 src/sdl2_compat.c | 53 ++++++++++++++++++++++++++++-------------------
 src/sdl2_compat.h |  3 +++
 src/sdl3_syms.h   |  2 +-
 3 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 84c4c5c..996684e 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -802,6 +802,7 @@ BOOL WINAPI _DllMainCRTStartup(HANDLE dllhandle, DWORD reason, LPVOID reserved)
 /* Some SDL2 state we need to keep... */
 
 /* !!! FIXME: unify coding convention on the globals: some are MyVariableName and some are my_variable_name */
+static int timer_init = 0;
 static SDL2_Surface *OldWindowSurfaces[16];
 static SDL2_EventFilter EventFilter2 = NULL;
 static void *EventFilterUserData2 = NULL;
@@ -5568,24 +5569,13 @@ SDL_VideoQuit(void)
 SDL_DECLSPEC int SDLCALL
 SDL_Init(Uint32 flags)
 {
-    int ret;
-
-    ret = SDL3_InitSubSystem(flags) ? 0 : -1;
-    if (flags & SDL_INIT_VIDEO) {
-        /* default SDL2 GL attributes */
-        SDL_GL_SetAttribute(SDL2_GL_RED_SIZE, 3);
-        SDL_GL_SetAttribute(SDL2_GL_GREEN_SIZE, 3);
-        SDL_GL_SetAttribute(SDL2_GL_BLUE_SIZE, 2);
-        SDL_GL_SetAttribute(SDL2_GL_ALPHA_SIZE, 0);
-    }
-
-    return ret;
+    return SDL_InitSubSystem(flags);
 }
 
 SDL_DECLSPEC int SDLCALL
 SDL_InitSubSystem(Uint32 flags)
 {
-    int ret;
+    int result;
 
     SDL2Compat_InitLogPrefixes();
 
@@ -5612,15 +5602,30 @@ SDL_InitSubSystem(Uint32 flags)
         SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, hint);
     }
 
-    ret = SDL3_InitSubSystem(flags) ? 0 : -1;
-    if (flags & SDL_INIT_VIDEO) {
-        /* default SDL2 GL attributes */
-        SDL_GL_SetAttribute(SDL2_GL_RED_SIZE, 3);
-        SDL_GL_SetAttribute(SDL2_GL_GREEN_SIZE, 3);
-        SDL_GL_SetAttribute(SDL2_GL_BLUE_SIZE, 2);
-        SDL_GL_SetAttribute(SDL2_GL_ALPHA_SIZE, 0);
+    result = SDL3_InitSubSystem(flags) ? 0 : -1;
+    if (result == 0) {
+        if (flags & SDL2_INIT_TIMER) {
+            ++timer_init;
+        }
+        if (flags & SDL_INIT_VIDEO) {
+            /* default SDL2 GL attributes */
+            SDL_GL_SetAttribute(SDL2_GL_RED_SIZE, 3);
+            SDL_GL_SetAttribute(SDL2_GL_GREEN_SIZE, 3);
+            SDL_GL_SetAttribute(SDL2_GL_BLUE_SIZE, 2);
+            SDL_GL_SetAttribute(SDL2_GL_ALPHA_SIZE, 0);
+        }
     }
-    return ret;
+    return result;
+}
+
+SDL_DECLSPEC Uint32 SDLCALL
+SDL_WasInit(Uint32 flags)
+{
+    Uint32 result = SDL3_WasInit(flags);
+    if ((flags & SDL2_INIT_TIMER) && timer_init) {
+        result |= SDL2_INIT_TIMER;
+    }
+    return result;
 }
 
 SDL_DECLSPEC void SDLCALL
@@ -5630,6 +5635,8 @@ SDL_Quit(void)
     SDL_LogPriority priorities[SDL_LOG_CATEGORY_CUSTOM];
     relative_mouse_mode = SDL2_FALSE;
 
+    timer_init = 0;
+
     if (SDL3_WasInit(SDL_INIT_VIDEO)) {
         GestureQuit();
     }
@@ -5689,6 +5696,10 @@ SDL_Quit(void)
 SDL_DECLSPEC void SDLCALL
 SDL_QuitSubSystem(Uint32 flags)
 {
+    if ((flags & SDL2_INIT_TIMER) && timer_init > 0) {
+        --timer_init;
+    }
+
     if (flags & SDL_INIT_VIDEO) {
         GestureQuit();
     }
diff --git a/src/sdl2_compat.h b/src/sdl2_compat.h
index f81c92a..17ac80f 100644
--- a/src/sdl2_compat.h
+++ b/src/sdl2_compat.h
@@ -39,6 +39,9 @@ typedef enum
 } SDL2_bool;
 #endif
 
+/* removed in SDL3 */
+#define SDL2_INIT_TIMER 0x00000001u
+
 /* removed in SDL3 (which only uses SDL_WINDOW_HIDDEN now). */
 #define SDL2_WINDOW_SHOWN 0x000000004
 #define SDL2_WINDOW_FULLSCREEN_DESKTOP (0x00001000 | SDL_WINDOW_FULLSCREEN)
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index 29a8e7a..7fc819e 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -704,7 +704,7 @@ SDL3_SYM(bool,WaitSemaphoreTimeout,(SDL_Semaphore *a, Sint32 b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(void,WaitThread,(SDL_Thread *a, int *b),(a,b),)
 SDL3_SYM(bool,WarpMouseGlobal,(float a, float b),(a,b),return)
 SDL3_SYM(void,WarpMouseInWindow,(SDL_Window *a, float b, float c),(a,b,c),)
-SDL3_SYM_PASSTHROUGH(Uint32,WasInit,(Uint32 a),(a),return)
+SDL3_SYM(Uint32,WasInit,(Uint32 a),(a),return)
 SDL3_SYM(size_t,WriteIO,(SDL_IOStream *a, const void *b, size_t c),(a,b,c),return)
 SDL3_SYM_PASSTHROUGH(int,abs,(int a),(a),return)
 SDL3_SYM_PASSTHROUGH(double,acos,(double a),(a),return)