From 5aea82ec9173625ec36a8d8f23ad48c6b5d552c8 Mon Sep 17 00:00:00 2001
From: Inuyasha <MattWCSTRFAN@gmail.com>
Date: Wed, 6 Apr 2016 18:01:01 -0700
Subject: [PATCH] Some drawing code cleanup

Fixed mashing buttons during fades causing crashes,
messed up behavior, record attack anywhere,
all the damn stupid bugs that it caused, basically
---
 src/d_main.c   | 68 +++++++++++++++++-------------------------------
 src/m_menu.c   | 70 +++++++++++++++++++++++++++++++++++---------------
 src/st_stuff.c |  7 +++--
 src/st_stuff.h |  2 +-
 4 files changed, 78 insertions(+), 69 deletions(-)

diff --git a/src/d_main.c b/src/d_main.c
index b04c55cbf6..c9282be7e0 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -221,10 +221,7 @@ gamestate_t wipegamestate = GS_LEVEL;
 
 static void D_Display(void)
 {
-	static boolean menuactivestate = false;
-	static gamestate_t oldgamestate = -1;
-	boolean redrawsbar = false;
-
+	boolean forcerefresh = false;
 	static boolean wipe = false;
 	INT32 wipedefindex = 0;
 
@@ -245,23 +242,15 @@ static void D_Display(void)
 	if (setsizeneeded)
 	{
 		R_ExecuteSetViewSize();
-		oldgamestate = -1; // force background redraw
-		redrawsbar = true;
+		forcerefresh = true; // force background redraw
 	}
 
-	// save the current screen if about to wipe
-	if (gamestate != wipegamestate)
-	{
-		wipe = true;
-		F_WipeStartScreen();
-	}
-	else
-		wipe = false;
-
 	// draw buffered stuff to screen
 	// Used only by linux GGI version
 	I_UpdateNoBlit();
 
+	// save the current screen if about to wipe
+	wipe = (gamestate != wipegamestate);
 	if (wipe)
 	{
 		// set for all later
@@ -280,6 +269,7 @@ static void D_Display(void)
 			if (gamestate != GS_LEVEL // fades to black on its own timing, always
 			 && wipedefs[wipedefindex] != UINT8_MAX)
 			{
+				F_WipeStartScreen();
 				V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
 				F_WipeEndScreen();
 				F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
@@ -298,8 +288,6 @@ static void D_Display(void)
 			HU_Erase();
 			if (automapactive)
 				AM_Drawer();
-			if (wipe || menuactivestate || (rendermode != render_soft && rendermode != render_none) || vid.recalc)
-				redrawsbar = true;
 			break;
 
 		case GS_INTERMISSION:
@@ -357,11 +345,6 @@ static void D_Display(void)
 	// see if the border needs to be initially drawn
 	if (gamestate == GS_LEVEL)
 	{
-#if 0
-		if (oldgamestate != GS_LEVEL)
-			R_FillBackScreen(); // draw the pattern into the back screen
-#endif
-
 		// draw the view directly
 		if (!automapactive && !dedicated && cv_renderview.value)
 		{
@@ -417,17 +400,17 @@ static void D_Display(void)
 			lastdraw = false;
 		}
 
-		ST_Drawer(redrawsbar);
+		ST_Drawer();
 
 		HU_Drawer();
 	}
 
 	// change gamma if needed
-	if (gamestate != oldgamestate && gamestate != GS_LEVEL)
+	// (GS_LEVEL handles this already due to level-specific palettes)
+	if (forcerefresh && gamestate != GS_LEVEL)
 		V_SetPalette(0);
 
-	menuactivestate = menuactive;
-	oldgamestate = wipegamestate = gamestate;
+	wipegamestate = gamestate;
 
 	// draw pause pic
 	if (paused && cv_showhud.value && (!menuactive || netgame))
@@ -450,15 +433,22 @@ static void D_Display(void)
 		CON_Drawer();
 
 	M_Drawer(); // menu is drawn even on top of everything
+	// focus lost moved to M_Drawer
 
-	// focus lost notification goes on top of everything, even the former everything
-	if (window_notinfocus)
+	//
+	// wipe update
+	//
+	if (wipe)
 	{
-		M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2);
-		if (gamestate == GS_LEVEL && (P_AutoPause() || paused))
-			V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused");
-		else
-			V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost");
+		// note: moved up here because NetUpdate does input changes
+		// and input during wipe tends to mess things up
+		wipedefindex += WIPEFINALSHIFT;
+
+		if (rendermode != render_none)
+		{
+			F_WipeEndScreen();
+			F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
+		}
 	}
 
 	NetUpdate(); // send out any new accumulation
@@ -493,18 +483,6 @@ static void D_Display(void)
 		}
 
 		I_FinishUpdate(); // page flip or blit buffer
-		return;
-	}
-
-	//
-	// wipe update
-	//
-	wipedefindex += WIPEFINALSHIFT;
-
-	if (rendermode != render_none)
-	{
-		F_WipeEndScreen();
-		F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
 	}
 }
 
diff --git a/src/m_menu.c b/src/m_menu.c
index 95752c7aac..3aad542825 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -2059,6 +2059,10 @@ static void M_PrevOpt(void)
 	} while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE);
 }
 
+// lock out further input in a tic when important buttons are pressed
+// (in other words -- stop bullshit happening by mashing buttons in fades)
+static boolean noFurtherInput = false;
+
 //
 // M_Responder
 //
@@ -2081,6 +2085,12 @@ boolean M_Responder(event_t *ev)
 		shiftdown = false;
 		return false;
 	}
+	if (noFurtherInput)
+	{
+		// Ignore input after enter/escape/other buttons
+		// (but still allow shift keyup so caps doesn't get stuck)
+		return false;
+	}
 	else if (ev->type == ev_keydown)
 	{
 		ch = ev->data1;
@@ -2182,6 +2192,7 @@ boolean M_Responder(event_t *ev)
 	// F-Keys
 	if (!menuactive)
 	{
+		noFurtherInput = true;
 		switch (ch)
 		{
 			case KEY_F1: // Help key
@@ -2252,6 +2263,7 @@ boolean M_Responder(event_t *ev)
 					M_StartControlPanel();
 				return true;
 		}
+		noFurtherInput = false; // turns out we didn't care
 		return false;
 	}
 
@@ -2275,6 +2287,7 @@ boolean M_Responder(event_t *ev)
 				if (routine)
 					routine(ch);
 				M_StopMessage(0);
+				noFurtherInput = true;
 				return true;
 			}
 			return true;
@@ -2354,6 +2367,7 @@ boolean M_Responder(event_t *ev)
 			return true;
 
 		case KEY_ENTER:
+			noFurtherInput = true;
 			currentMenu->lastOn = itemOn;
 			if (routine)
 			{
@@ -2387,6 +2401,7 @@ boolean M_Responder(event_t *ev)
 			return true;
 
 		case KEY_ESCAPE:
+			noFurtherInput = true;
 			currentMenu->lastOn = itemOn;
 			if (currentMenu->prevMenu)
 			{
@@ -2443,35 +2458,45 @@ void M_Drawer(void)
 	if (currentMenu == &MessageDef)
 		menuactive = true;
 
-	if (!menuactive)
-		return;
-
-	// now that's more readable with a faded background (yeah like Quake...)
-	if (!WipeInAction)
-		V_DrawFadeScreen();
+	if (menuactive)
+	{
+		// now that's more readable with a faded background (yeah like Quake...)
+		if (!WipeInAction)
+			V_DrawFadeScreen();
 
-	if (currentMenu->drawroutine)
-		currentMenu->drawroutine(); // call current menu Draw routine
+		if (currentMenu->drawroutine)
+			currentMenu->drawroutine(); // call current menu Draw routine
 
-	// Draw version down in corner
-	// ... but only in the MAIN MENU.  I'm a picky bastard.
-	if (currentMenu == &MainDef)
-	{
-		if (customversionstring[0] != '\0')
-		{
-			V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:");
-			V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
-		}
-		else
+		// Draw version down in corner
+		// ... but only in the MAIN MENU.  I'm a picky bastard.
+		if (currentMenu == &MainDef)
 		{
+			if (customversionstring[0] != '\0')
+			{
+				V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:");
+				V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
+			}
+			else
+			{
 #ifdef DEVELOP // Development -- show revision / branch info
-			V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
-			V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy,  V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
+				V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
+				V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy,  V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
 #else // Regular build
-			V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
+				V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
 #endif
+			}
 		}
 	}
+
+	// focus lost notification goes on top of everything, even the former everything
+	if (window_notinfocus)
+	{
+		M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2);
+		if (gamestate == GS_LEVEL && (P_AutoPause() || paused))
+			V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused");
+		else
+			V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost");
+	}
 }
 
 //
@@ -2656,6 +2681,9 @@ void M_SetupNextMenu(menu_t *menudef)
 //
 void M_Ticker(void)
 {
+	// reset input trigger
+	noFurtherInput = false;
+
 	if (dedicated)
 		return;
 
diff --git a/src/st_stuff.c b/src/st_stuff.c
index 585db0c873..9a4df8a07b 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -1889,7 +1889,7 @@ static void ST_overlayDrawer(void)
 	ST_drawDebugInfo();
 }
 
-void ST_Drawer(boolean refresh)
+void ST_Drawer(void)
 {
 #ifdef SEENAMES
 	if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo)
@@ -1906,8 +1906,11 @@ void ST_Drawer(boolean refresh)
 	}
 #endif
 
+	// Doom's status bar only updated if necessary.
+	// However, ours updates every frame regardless, so the "refresh" param was removed
+	//(void)refresh;
+
 	// force a set of the palette by using doPaletteStuff()
-	(void)refresh; //?
 	if (vid.recalc)
 		st_palette = -1;
 
diff --git a/src/st_stuff.h b/src/st_stuff.h
index 9873efbe74..44994a6d30 100644
--- a/src/st_stuff.h
+++ b/src/st_stuff.h
@@ -27,7 +27,7 @@
 void ST_Ticker(void);
 
 // Called by main loop.
-void ST_Drawer(boolean refresh);
+void ST_Drawer(void);
 
 // Called when the console player is spawned on each level.
 void ST_Start(void);
-- 
GitLab