From 241794b67045c4a8f6400a4ee1d9dffe1ec2efe8 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Thu, 7 Aug 2025 02:09:43 +0200 Subject: [PATCH] Fix menu replays causing event loop recursion --- src/d_main.cpp | 9 +++++++++ src/g_demo.c | 1 + src/m_menu.c | 22 +++++++++------------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 01f332187..c467ee126 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -189,6 +189,8 @@ UINT8 ctrldown = 0; // 0x1 left, 0x2 right UINT8 altdown = 0; // 0x1 left, 0x2 right boolean capslock = 0; // gee i wonder what this does. +static boolean recursioncheck = false; + // // D_ProcessEvents // Send all the events of the given timestamp down the responder chain @@ -199,6 +201,11 @@ void D_ProcessEvents(void) boolean eaten = false; + if (recursioncheck == true) + I_Error("D_ProcessEvents recursion detected"); + + recursioncheck = true; + // i have to reset this somewhere or else your camera just glides away! for (size_t i = 0; i < 4; i++) gamekeydown[0][KEY_MOUSEMOVE + i] = 0; @@ -263,6 +270,8 @@ void D_ProcessEvents(void) G_Responder(ev); } + + recursioncheck = false; } static void D_RenderLevel(void) diff --git a/src/g_demo.c b/src/g_demo.c index c1f9f0b77..28c789245 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -3398,6 +3398,7 @@ void G_DoPlayDemo(char *defdemoname) boolean skiperrors = false; #endif + M_ClearMenus(true); G_InitDemoRewind(); // No demo name means we're restarting the current demo diff --git a/src/m_menu.c b/src/m_menu.c index 8136955c5..4315db894 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1848,7 +1848,9 @@ void M_ClearMenus(boolean callexitmenufunc) currentMenu->quitroutine(0); // Save the config file. I'm sick of crashing the game later and losing all my changes! - COM_BufAddText(va("saveconfig \"%s\" -silent\n", configfile)); + char buf[sizeof(configfile) + 50]; + sprintf(buf, "saveconfig \"%s\" -silent\n", configfile); + COM_BufAddText(buf); if (currentMenu->exitwipe >= 0) { @@ -4220,11 +4222,9 @@ INT32 MR_HutStartReplay(INT32 choice) { (void)choice; - M_ClearMenus(false); - demo.loadfiles = M_IsItemOn(MN_MISC_REPLAYSTART, "LOADWATCH"); - demo.ignorefiles = !M_IsItemOn(MN_MISC_REPLAYSTART, "LOADWATCH"); - - G_DoPlayDemo(demolist[dir_on[menudepthleft]].filepath); + COM_BufAddText(va("playdemo %s %s", + demolist[dir_on[menudepthleft]].filepath + strlen(srb2home) + 1, // dumb hack + M_IsItemOn(MN_MISC_REPLAYSTART, "LOADWATCH") ? "-addfiles" : "-force")); return true; } @@ -5733,9 +5733,7 @@ INT32 MR_ReplayStaff(INT32 choice) if (l == LUMPERROR) return false; - M_ClearMenus(true); - demo.loadfiles = false; demo.ignorefiles = true; // Just assume that record attack replays have the files needed - G_DoPlayDemo(va("%sS%02u",G_BuildMapName(cv_nextmap.value),cv_dummystaff.value)); + COM_BufAddText(va("playdemo %sS%02u -force", G_BuildMapName(cv_nextmap.value), cv_dummystaff.value)); return true; } @@ -5768,8 +5766,6 @@ INT32 MR_ReplayTimeAttack(INT32 arg) { const char *which; char *gamemode = M_AppendGametypeAndModName(); - M_ClearMenus(true); - demo.loadfiles = false; demo.ignorefiles = true; // Just assume that record attack replays have the files needed switch(arg) { default: @@ -5784,12 +5780,12 @@ INT32 MR_ReplayTimeAttack(INT32 arg) break; case 3: // guest // srb2/replay/main/map01-guest.lmp - G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), gamemode)); + COM_BufAddText(va("playdemo media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-guest.lmp -force", timeattackfolder, G_BuildMapName(cv_nextmap.value), gamemode)); Z_Free(gamemode); return true; } // srb2/replay/main/map01-sonic-time-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value].name, gamemode, which)); + COM_BufAddText(va("playdemo media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s-%s.lmp -force", timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value].name, gamemode, which)); Z_Free(gamemode); return true; }