sdl12-compat: init: Deal with SDL 1.2 subsystem init vs SDL2.

From 0dcdfe0fc9e2b61055dfc0681abc50df60a18620 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 30 Aug 2022 16:40:30 -0400
Subject: [PATCH] init: Deal with SDL 1.2 subsystem init vs SDL2.

In 1.2 each subsystem has a flag that tracks if it's initialized, so
quitting a subsystem once cancels all previous init attempts. In SDL2,
each subsystem has a reference count.

So keep a bitmask here that tracks 1.2-style init and only init SDL2 once.

Reference Issue #143.
---
 src/SDL12_compat.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index f340fc3b..9ef44c14 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -959,6 +959,7 @@ typedef struct EventQueueType
 } EventQueueType;
 
 
+static Uint32 InitializedSubsystems20 = 0;
 static Uint32 LinkedSDL2VersionInt = 0;
 static SDL_bool IsDummyVideo = SDL_FALSE;
 static VideoModeList *VideoModes = NULL;
@@ -2335,7 +2336,14 @@ SDL_InitSubSystem(Uint32 sdl12flags)
        have this problem, so we're ignoring the parachute until a reasonable
        need arises. */
 
-    #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag
+    #define SETFLAG(flag) { \
+        const Uint32 f12 = SDL12_INIT_##flag; \
+        const Uint32 f20 = SDL_INIT_##flag; \
+        if ((sdl12flags & f12) && ((InitializedSubsystems20 & f20) == 0)) { \
+            sdl20flags |= f20; \
+        } \
+    }
+
     SETFLAG(TIMER);
     SETFLAG(AUDIO);
     SETFLAG(VIDEO);
@@ -2369,6 +2377,8 @@ SDL_InitSubSystem(Uint32 sdl12flags)
         Init12Joystick();  /* if this fails, we just won't report any sticks. */
     }
 
+    InitializedSubsystems20 |= sdl20flags;
+
     return rc;
 }
 
@@ -2462,6 +2472,9 @@ Quit12Video(void)
         SDL20_DestroyMutex(EventQueueMutex);
         EventQueueMutex = NULL;
     }
+
+    /* Shutdown the fake event thread. */
+    EventThreadEnabled = SDL_FALSE;
 }
 
 DECLSPEC void SDLCALL
@@ -2488,9 +2501,6 @@ SDL_QuitSubSystem(Uint32 sdl12flags)
 
     if (sdl12flags & SDL12_INIT_VIDEO) {
         Quit12Video();
-
-        /* Shutdown the fake event thread. */
-        EventThreadEnabled = SDL_FALSE;
     }
 
     if (sdl12flags & SDL12_INIT_JOYSTICK) {
@@ -2502,12 +2512,15 @@ SDL_QuitSubSystem(Uint32 sdl12flags)
     if ((SDL20_WasInit(0) == 0) && (!CDRomInit)) {
         SDL20_Quit();
     }
+
+    InitializedSubsystems20 &= ~sdl20flags;
 }
 
 DECLSPEC void SDLCALL
 SDL_Quit(void)
 {
     SDL_QuitSubSystem(SDL_WasInit(0) | SDL12_INIT_CDROM);
+    SDL_assert(InitializedSubsystems20 == 0);
 }
 
 DECLSPEC void SDLCALL
@@ -8226,7 +8239,6 @@ InitializeCDSubsystem(void)
 {
     const char *cdpath;
 
-    FIXME("Is subsystem init reference counted in SDL 1.2?");  /* it is in SDL2, but I don't know for 1.2. */
     if (CDRomInit) {
         return;
     }