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