sdl2-compat: init: consolidate logic from SDL_AudioInit/SDL_VideoInit/SDL_InitSubsystem

From 3d5071d81989930dc52c58fcd2db6ae69d7638f2 Mon Sep 17 00:00:00 2001
From: Cameron Gutman <[EMAIL REDACTED]>
Date: Mon, 10 Feb 2025 19:58:26 -0600
Subject: [PATCH] init: consolidate logic from
 SDL_AudioInit/SDL_VideoInit/SDL_InitSubsystem

---
 src/sdl2_compat.c | 164 +++++++++++++++++++++++++---------------------
 1 file changed, 91 insertions(+), 73 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 342706c5..32094099 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -5597,6 +5597,93 @@ static void SynchronizeEnvironmentVariables()
     SDL3_DestroyEnvironment(fresh_env);
 }
 
+static SDL_InitFlags PreInitSubsystem(SDL_InitFlags flags)
+{
+    /* If the subsystem is already initialized, mask out the flag for it */
+    flags &= ~SDL_WasInit(flags);
+
+    if (flags & SDL_INIT_VIDEO) {
+        const char *old_hint;
+        const char *hint;
+
+        /* Update IME UI hint */
+#if defined(SDL_PLATFORM_WIN32)
+        old_hint = SDL3_GetHint("SDL_IME_SHOW_UI");
+        if (old_hint && *old_hint == '1') {
+            hint = "composition";
+        } else {
+            hint = "composition,candidates";
+        }
+#else
+        old_hint = SDL3_GetHint("SDL_IME_INTERNAL_EDITING");
+        if (old_hint && *old_hint == '1') {
+            hint = "0";
+        } else {
+            hint = "composition";
+        }
+#endif
+        SDL3_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, hint);
+    }
+
+    /* Return only the flags that we will expect to change */
+    return flags;
+}
+
+static void PostInitSubsystem(SDL_InitFlags new_flags)
+{
+    /* The timer subsystem flag is gone in SDL3, so we maintain it ourselves */
+    if (new_flags & SDL2_INIT_TIMER) {
+        ++timer_init;
+    }
+
+    /* If the subsystem failed to initialize, mask out the flag for it */
+    new_flags &= SDL_WasInit(new_flags);
+
+    if (new_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);
+    }
+
+    /* if audio was initialized and there are no devices enumerated yet, build some initial device lists. */
+    if (new_flags & SDL_INIT_AUDIO) {
+        if (AudioSDL3PlaybackDevices.num_devices == 0) {
+            SDL_GetNumAudioDevices(SDL2_FALSE);
+        }
+        if (AudioSDL3RecordingDevices.num_devices == 0) {
+            SDL_GetNumAudioDevices(SDL2_TRUE);
+        }
+    }
+
+    /* enumerate joysticks and haptics to build device list */
+    if (new_flags & (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) {
+        SDL_NumJoysticks();
+    }
+    if (new_flags & SDL_INIT_HAPTIC) {
+        SDL_NumHaptics();
+    }
+}
+
+static int InitSubsystemInternal(SDL_InitFlags flags)
+{
+    int result;
+    SDL_InitFlags new_flags;
+
+    if (!SDL2Compat_InitOnStartup()) {
+        return -1;
+    }
+
+    new_flags = PreInitSubsystem(flags);
+
+    result = SDL3_InitSubSystem(flags) ? 0 : -1;
+
+    PostInitSubsystem(new_flags);
+
+    return result;
+}
+
 SDL_DECLSPEC int SDLCALL
 SDL_AudioInit(const char *driver_name)
 {
@@ -5605,7 +5692,8 @@ SDL_AudioInit(const char *driver_name)
     if (driver_name) {
         SDL3_SetHint("SDL_AUDIO_DRIVER", driver_name);
     }
-    return SDL3_InitSubSystem(SDL_INIT_AUDIO) ? 0 : -1;
+
+    return InitSubsystemInternal(SDL_INIT_AUDIO);
 }
 
 SDL_DECLSPEC void SDLCALL
@@ -5807,23 +5895,13 @@ SDL_GL_SetAttribute(SDL2_GLattr attr, int value)
 SDL_DECLSPEC int SDLCALL
 SDL_VideoInit(const char *driver_name)
 {
-    int ret;
-
     SynchronizeEnvironmentVariables();
 
     if (driver_name) {
         SDL3_SetHint("SDL_VIDEO_DRIVER", driver_name);
     }
 
-    ret = SDL3_InitSubSystem(SDL_INIT_VIDEO) ? 0 : -1;
-
-    /* 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 InitSubsystemInternal(SDL_INIT_VIDEO);
 }
 
 SDL_DECLSPEC void SDLCALL
@@ -5841,69 +5919,9 @@ SDL_Init(Uint32 flags)
 SDL_DECLSPEC int SDLCALL
 SDL_InitSubSystem(Uint32 flags)
 {
-    int result;
-
-    if (!SDL2Compat_InitOnStartup()) {
-        return -1;
-    }
-
     SynchronizeEnvironmentVariables();
 
-    /* Update IME UI hint */
-    if (flags & SDL_INIT_VIDEO) {
-        const char *old_hint;
-        const char *hint;
-
-#if defined(SDL_PLATFORM_WIN32)
-        old_hint = SDL_GetHint("SDL_IME_SHOW_UI");
-        if (old_hint && *old_hint == '1') {
-            hint = "composition";
-        } else {
-            hint = "composition,candidates";
-        }
-#else
-        old_hint = SDL_GetHint("SDL_IME_INTERNAL_EDITING");
-        if (old_hint && *old_hint == '1') {
-            hint = "0";
-        } else {
-            hint = "composition";
-        }
-#endif
-        SDL_SetHint(SDL_HINT_IME_IMPLEMENTED_UI, hint);
-    }
-
-    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);
-        }
-
-        /* if audio was initialized and there are no devices enumerated yet, build some initial device lists. */
-        if ((flags & SDL_INIT_AUDIO) && SDL3_WasInit(SDL_INIT_AUDIO)) {
-            if (AudioSDL3PlaybackDevices.num_devices == 0) {
-                SDL_GetNumAudioDevices(SDL2_FALSE);
-            }
-            if (AudioSDL3RecordingDevices.num_devices == 0) {
-                SDL_GetNumAudioDevices(SDL2_TRUE);
-            }
-        }
-
-        /* enumerate joysticks and haptics to build device list */
-        if (flags & (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) {
-            SDL_NumJoysticks();
-        }
-        if (flags & SDL_INIT_HAPTIC) {
-            SDL_NumHaptics();
-        }
-    }
-    return result;
+    return InitSubsystemInternal(flags);
 }
 
 SDL_DECLSPEC Uint32 SDLCALL