sdl12-compat: Call PumpEvents in PresentScreen when SDL_EVENTTHREAD enabled

From e8de4b55eff752cd5fa80b37b1d1e4261bf11932 Mon Sep 17 00:00:00 2001
From: David Gow <[EMAIL REDACTED]>
Date: Sun, 27 Nov 2022 14:52:48 +0800
Subject: [PATCH] Call PumpEvents in PresentScreen when SDL_EVENTTHREAD enabled

At the moment, we "emulate" SDL_EVENTTHREAD by calling SDL_PumpEvents()
in SDL_PeekEvent(). But some games don't even do this, so events aren't
pumped at all, particularly while (e.g.) videos are playing, which is
often just a tight SDL_DisplayYUVOverlay() loop.

If we SDL_PumpEvents() from within PresentScreen(), we should at least
get events as long as the screen is being updated.

The complexity here is that SDL_PumpEvents() itself calls
PresentScreen() to get a minimal framerate from things rendering
directly to the front buffer. So we add a quick check to avoid
SDL_PumpEvents() from entering infinite recursion by calling itself.

Should fix the difficulty with skipping videos in Alpha Centauri
mentioned in #278.
---
 src/SDL12_compat.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index 968cc6318..bfa02f905 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -6593,6 +6593,17 @@ PresentScreen(void)
         return;
     }
 
+    /* We don't actually implement an event thread in sdl12-compat, but some
+     * games will only call SDL_PeepEvents(), which doesn't otherwise pump
+     * events, and get stuck when they've consumed all the events.
+     *
+     * Just pumping the event loop here simulates an event thread well enough
+     * for most things.
+     */
+    if (EventThreadEnabled) {
+        SDL_PumpEvents();
+    }
+
     SDL20_RenderClear(renderer);
     SDL20_RenderCopy(renderer, VideoTexture20, NULL, NULL);
 
@@ -6923,11 +6934,16 @@ SDL_PumpEvents(void)
 {
     const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE;
     SDL_Event e;
+    static SDL_bool InPumpEvents = SDL_FALSE;
 
     if (!ThisIsSetVideoModeThread && !AllowThreadedPumps) {
         return;
     }
 
+    if (InPumpEvents)
+        return;
+    InPumpEvents = SDL_TRUE;
+
     /* If the app is doing dirty rectangles, we set a flag and present the
      * screen surface when they pump for new events if we're close to 60Hz,
      * which we consider a sign that they are done rendering for the current
@@ -6958,6 +6974,7 @@ SDL_PumpEvents(void)
     if (EventQueueMutex) {
         SDL20_UnlockMutex(EventQueueMutex);
     }
+    InPumpEvents = SDL_FALSE;
 }
 
 DECLSPEC12 void SDLCALL