From bf8a39f7eedcf8011e3f19015d22bdde9b3e7589 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Sat, 11 Jan 2020 15:40:18 -0800
Subject: [PATCH 01/19] Only exit if base files fail to load

---
 src/w_wad.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/w_wad.c b/src/w_wad.c
index bbb30d3fa..cfd2db50e 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -822,13 +822,11 @@ UINT16 W_InitFile(const char *filename, boolean mainfile)
   * backwards, so a later file overrides all earlier ones.
   *
   * \param filenames A null-terminated list of files to use.
-  * \return 1 if all files were loaded, 0 if at least one was missing or
+  * \return 1 if base files were loaded, 0 if at least one was missing or
   *           invalid.
   */
 INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles)
 {
-	INT32 rc = 1;
-
 	// open all the files, load headers, and count lumps
 	numwadfiles = 0;
 
@@ -836,13 +834,15 @@ INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles)
 	for (; *filenames; filenames++)
 	{
 		//CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames);
-		rc &= (W_InitFile(*filenames, numwadfiles < mainfiles) != INT16_MAX) ? 1 : 0;
+		if (W_InitFile(*filenames, numwadfiles < mainfiles) == INT16_MAX)
+		{
+			CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), *filenames);
+			if (numwadfiles < mainfiles)
+				return 0;
+		}
 	}
 
-	if (!numwadfiles)
-		I_Error("W_InitMultipleFiles: no files found");
-
-	return rc;
+	return 1;
 }
 
 /** Make sure a lump number is valid.

From bbbe76d2ca4a12745bb54e35be48fd1b3714cfe0 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Thu, 16 Jan 2020 03:09:02 -0800
Subject: [PATCH 02/19] Expose viewmobj as r_viewmobj

---
 src/r_main.c  | 55 +++++++++++++++++++++++++--------------------------
 src/r_state.h |  1 +
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/src/r_main.c b/src/r_main.c
index 4cbf101b7..f25ea96fd 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -71,6 +71,7 @@ angle_t viewangle, aimingangle;
 fixed_t viewcos, viewsin;
 sector_t *viewsector;
 player_t *viewplayer;
+mobj_t *r_viewmobj;
 
 //
 // precalculated math tables
@@ -741,8 +742,6 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
 // R_SetupFrame
 //
 
-static mobj_t *viewmobj;
-
 // WARNING: a should be unsigned but to add with 2048, it isn't!
 #define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan)
 
@@ -799,16 +798,16 @@ void R_SetupFrame(player_t *player)
 	if (player->awayviewtics)
 	{
 		// cut-away view stuff
-		viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
-		I_Assert(viewmobj != NULL);
-		viewz = viewmobj->z + 20*FRACUNIT;
+		r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
+		I_Assert(r_viewmobj != NULL);
+		viewz = r_viewmobj->z + 20*FRACUNIT;
 		aimingangle = player->awayviewaiming;
-		viewangle = viewmobj->angle;
+		viewangle = r_viewmobj->angle;
 	}
 	else if (!player->spectator && chasecam)
 	// use outside cam view
 	{
-		viewmobj = NULL;
+		r_viewmobj = NULL;
 		viewz = thiscam->z + (thiscam->height>>1);
 		aimingangle = thiscam->aiming;
 		viewangle = thiscam->angle;
@@ -818,11 +817,11 @@ void R_SetupFrame(player_t *player)
 	{
 		viewz = player->viewz;
 
-		viewmobj = player->mo;
-		I_Assert(viewmobj != NULL);
+		r_viewmobj = player->mo;
+		I_Assert(r_viewmobj != NULL);
 
 		aimingangle = player->aiming;
-		viewangle = viewmobj->angle;
+		viewangle = r_viewmobj->angle;
 
 		if (!demoplayback && player->playerstate != PST_DEAD)
 		{
@@ -856,13 +855,13 @@ void R_SetupFrame(player_t *player)
 	}
 	else
 	{
-		viewx = viewmobj->x;
-		viewy = viewmobj->y;
+		viewx = r_viewmobj->x;
+		viewy = r_viewmobj->y;
 		viewx += quake.x;
 		viewy += quake.y;
 
-		if (viewmobj->subsector)
-			viewsector = viewmobj->subsector->sector;
+		if (r_viewmobj->subsector)
+			viewsector = r_viewmobj->subsector->sector;
 		else
 			viewsector = R_PointInSubsector(viewx, viewy)->sector;
 	}
@@ -884,12 +883,12 @@ void R_SkyboxFrame(player_t *player)
 		thiscam = &camera;
 
 	// cut-away view stuff
-	viewmobj = skyboxmo[0];
+	r_viewmobj = skyboxmo[0];
 #ifdef PARANOIA
-	if (!viewmobj)
+	if (!r_viewmobj)
 	{
 		const size_t playeri = (size_t)(player - players);
-		I_Error("R_SkyboxFrame: viewmobj null (player %s)", sizeu1(playeri));
+		I_Error("R_SkyboxFrame: r_viewmobj null (player %s)", sizeu1(playeri));
 	}
 #endif
 	if (player->awayviewtics)
@@ -920,13 +919,13 @@ void R_SkyboxFrame(player_t *player)
 			}
 		}
 	}
-	viewangle += viewmobj->angle;
+	viewangle += r_viewmobj->angle;
 
 	viewplayer = player;
 
-	viewx = viewmobj->x;
-	viewy = viewmobj->y;
-	viewz = viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
+	viewx = r_viewmobj->x;
+	viewy = r_viewmobj->y;
+	viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
 
 	if (mapheaderinfo[gamemap-1])
 	{
@@ -966,29 +965,29 @@ void R_SkyboxFrame(player_t *player)
 			else if (mh->skybox_scaley < 0)
 				y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley;
 
-			if (viewmobj->angle == 0)
+			if (r_viewmobj->angle == 0)
 			{
 				viewx += x;
 				viewy += y;
 			}
-			else if (viewmobj->angle == ANGLE_90)
+			else if (r_viewmobj->angle == ANGLE_90)
 			{
 				viewx -= y;
 				viewy += x;
 			}
-			else if (viewmobj->angle == ANGLE_180)
+			else if (r_viewmobj->angle == ANGLE_180)
 			{
 				viewx -= x;
 				viewy -= y;
 			}
-			else if (viewmobj->angle == ANGLE_270)
+			else if (r_viewmobj->angle == ANGLE_270)
 			{
 				viewx += y;
 				viewy -= x;
 			}
 			else
 			{
-				angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT;
+				angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT;
 				viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y,  FINESINE(ang));
 				viewy += FixedMul(x,  FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
 			}
@@ -999,8 +998,8 @@ void R_SkyboxFrame(player_t *player)
 			viewz += campos.z * -mh->skybox_scalez;
 	}
 
-	if (viewmobj->subsector)
-		viewsector = viewmobj->subsector->sector;
+	if (r_viewmobj->subsector)
+		viewsector = r_viewmobj->subsector->sector;
 	else
 		viewsector = R_PointInSubsector(viewx, viewy)->sector;
 
diff --git a/src/r_state.h b/src/r_state.h
index 75566923b..e7838e9fb 100644
--- a/src/r_state.h
+++ b/src/r_state.h
@@ -83,6 +83,7 @@ extern fixed_t viewx, viewy, viewz;
 extern angle_t viewangle, aimingangle;
 extern sector_t *viewsector;
 extern player_t *viewplayer;
+extern mobj_t *r_viewmobj;
 
 extern consvar_t cv_allowmlook;
 extern consvar_t cv_maxportals;

From 542e38e717e2a8cf38a9ce5b9fa2affe56424781 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Thu, 16 Jan 2020 03:09:16 -0800
Subject: [PATCH 03/19] Don't draw player mobj in first person

This solves that annoying albeit slightly amusing bug
where your sprite clips into your view during a quake.

For OpenGL, this also solves the player's model
rendering while in first person. So you'll no
longer be looking through Sonic's body!
---
 src/hardware/hw_main.c | 6 ++++--
 src/r_things.c         | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index f5f3edfc1..e658051a6 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -5422,7 +5422,8 @@ static void HWR_AddSprites(sector_t *sec)
 	{
 		for (thing = sec->thinglist; thing; thing = thing->snext)
 		{
-			if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
+			if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
+					thing == r_viewmobj)
 				continue;
 
 			approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
@@ -5445,7 +5446,8 @@ static void HWR_AddSprites(sector_t *sec)
 	{
 		// Draw everything in sector, no checks
 		for (thing = sec->thinglist; thing; thing = thing->snext)
-			if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW))
+			if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
+						thing == r_viewmobj))
 				HWR_ProjectSprite(thing);
 	}
 
diff --git a/src/r_things.c b/src/r_things.c
index ef496335e..2a18c06a4 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1845,7 +1845,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
 	{
 		for (thing = sec->thinglist; thing; thing = thing->snext)
 		{
-			if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
+			if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
+					thing == r_viewmobj)
 				continue;
 
 			approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
@@ -1868,7 +1869,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
 	{
 		// Draw everything in sector, no checks
 		for (thing = sec->thinglist; thing; thing = thing->snext)
-			if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW))
+			if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
+						thing == r_viewmobj))
 				R_ProjectSprite(thing);
 	}
 

From 762223db7ceca9ed428da723c84f121c6292bf4c Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Fri, 17 Jan 2020 20:45:55 -0800
Subject: [PATCH 04/19] Duplicated code is gone, so sad

---
 src/hardware/hw_main.c | 44 +++-----------------
 src/r_things.c         | 93 ++++++++++++++++++++++++------------------
 src/r_things.h         |  9 ++++
 3 files changed, 68 insertions(+), 78 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index e658051a6..7ab0929da 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -5399,7 +5399,7 @@ static void HWR_AddSprites(sector_t *sec)
 #ifdef HWPRECIP
 	precipmobj_t *precipthing;
 #endif
-	fixed_t approx_dist, limit_dist, hoop_limit_dist;
+	fixed_t limit_dist, hoop_limit_dist;
 
 	// BSP is traversed by subsector.
 	// A sector might have been split into several
@@ -5418,37 +5418,10 @@ static void HWR_AddSprites(sector_t *sec)
 	// If a limit exists, handle things a tiny bit different.
 	limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
 	hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
-	if (limit_dist || hoop_limit_dist)
+	for (thing = sec->thinglist; thing; thing = thing->snext)
 	{
-		for (thing = sec->thinglist; thing; thing = thing->snext)
-		{
-			if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
-					thing == r_viewmobj)
-				continue;
-
-			approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
-
-			if (thing->sprite == SPR_HOOP)
-			{
-				if (hoop_limit_dist && approx_dist > hoop_limit_dist)
-					continue;
-			}
-			else
-			{
-				if (limit_dist && approx_dist > limit_dist)
-					continue;
-			}
-
+		if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist))
 			HWR_ProjectSprite(thing);
-		}
-	}
-	else
-	{
-		// Draw everything in sector, no checks
-		for (thing = sec->thinglist; thing; thing = thing->snext)
-			if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
-						thing == r_viewmobj))
-				HWR_ProjectSprite(thing);
 	}
 
 #ifdef HWPRECIP
@@ -5457,15 +5430,8 @@ static void HWR_AddSprites(sector_t *sec)
 	{
 		for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
 		{
-			if (precipthing->precipflags & PCF_INVISIBLE)
-				continue;
-
-			approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
-
-			if (approx_dist > limit_dist)
-				continue;
-
-			HWR_ProjectPrecipitationSprite(precipthing);
+			if (R_PrecipThingVisible(precipthing, limit_dist))
+				HWR_ProjectPrecipitationSprite(precipthing);
 		}
 	}
 #endif
diff --git a/src/r_things.c b/src/r_things.c
index 2a18c06a4..2a2872a34 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1808,7 +1808,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
 	mobj_t *thing;
 	precipmobj_t *precipthing; // Tails 08-25-2002
 	INT32 lightnum;
-	fixed_t approx_dist, limit_dist, hoop_limit_dist;
+	fixed_t limit_dist, hoop_limit_dist;
 
 	if (rendermode != render_soft)
 		return;
@@ -1841,37 +1841,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
 	// If a limit exists, handle things a tiny bit different.
 	limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
 	hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
-	if (limit_dist || hoop_limit_dist)
+	for (thing = sec->thinglist; thing; thing = thing->snext)
 	{
-		for (thing = sec->thinglist; thing; thing = thing->snext)
-		{
-			if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
-					thing == r_viewmobj)
-				continue;
-
-			approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
-
-			if (thing->sprite == SPR_HOOP)
-			{
-				if (hoop_limit_dist && approx_dist > hoop_limit_dist)
-					continue;
-			}
-			else
-			{
-				if (limit_dist && approx_dist > limit_dist)
-					continue;
-			}
-
+		if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist))
 			R_ProjectSprite(thing);
-		}
-	}
-	else
-	{
-		// Draw everything in sector, no checks
-		for (thing = sec->thinglist; thing; thing = thing->snext)
-			if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW ||
-						thing == r_viewmobj))
-				R_ProjectSprite(thing);
 	}
 
 	// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
@@ -1879,15 +1852,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
 	{
 		for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
 		{
-			if (precipthing->precipflags & PCF_INVISIBLE)
-				continue;
-
-			approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
-
-			if (approx_dist > limit_dist)
-				continue;
-
-			R_ProjectPrecipitationSprite(precipthing);
+			if (R_PrecipThingVisible(precipthing, limit_dist))
+				R_ProjectPrecipitationSprite(precipthing);
 		}
 	}
 }
@@ -2582,6 +2548,55 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
 	}
 }
 
+/* Check if thing may be drawn from our current view. */
+boolean R_ThingVisible (mobj_t *thing)
+{
+	return (!(
+				thing->sprite == SPR_NULL ||
+				( thing->flags2 & (MF2_DONTDRAW) ) ||
+				thing == r_viewmobj
+	));
+}
+
+boolean R_ThingVisibleWithinDist (mobj_t *thing,
+		fixed_t      limit_dist,
+		fixed_t hoop_limit_dist)
+{
+	fixed_t approx_dist;
+
+	if (! R_ThingVisible(thing))
+		return false;
+
+	approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
+
+	if (thing->sprite == SPR_HOOP)
+	{
+		if (hoop_limit_dist && approx_dist > hoop_limit_dist)
+			return false;
+	}
+	else
+	{
+		if (limit_dist && approx_dist > limit_dist)
+			return false;
+	}
+
+	return true;
+}
+
+/* Check if precipitation may be drawn from our current view. */
+boolean R_PrecipThingVisible (precipmobj_t *precipthing,
+		fixed_t limit_dist)
+{
+	fixed_t approx_dist;
+
+	if (( precipthing->precipflags & PCF_INVISIBLE ))
+		return false;
+
+	approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
+
+	return ( approx_dist <= limit_dist );
+}
+
 //
 // R_DrawMasked
 //
diff --git a/src/r_things.h b/src/r_things.h
index 1b74dd74e..76587868d 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -61,6 +61,15 @@ void R_InitSprites(void);
 void R_ClearSprites(void);
 void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
 
+boolean R_ThingVisible (mobj_t *thing);
+
+boolean R_ThingVisibleWithinDist (mobj_t *thing,
+		fixed_t        draw_dist,
+		fixed_t nights_draw_dist);
+
+boolean R_PrecipThingVisible (precipmobj_t *precipthing,
+		fixed_t precip_draw_dist);
+
 /** Used to count the amount of masked elements
  * per portal to later group them in separate
  * drawnode lists.

From 94a2f0bb4fd40562262f2e37a7fc392b2aa42e75 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Fri, 17 Jan 2020 20:56:32 -0800
Subject: [PATCH 05/19] Don't draw Tails' tails in first person (MF2_LINKDRAW)

---
 src/hardware/hw_main.c | 2 +-
 src/r_things.c         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 7ab0929da..d4682fc9d 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -5695,7 +5695,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
 	if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
 	{
 		// bodge support - not nearly as comprehensive as r_things.c, but better than nothing
-		if (thing->tracer->sprite == SPR_NULL || thing->tracer->flags2 & MF2_DONTDRAW)
+		if (! R_ThingVisible(thing->tracer))
 			return;
 	}
 
diff --git a/src/r_things.c b/src/r_things.c
index 2a2872a34..cba080448 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1413,7 +1413,7 @@ static void R_ProjectSprite(mobj_t *thing)
 
 		thing = thing->tracer;
 
-		if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
+		if (! R_ThingVisible(thing))
 			return;
 
 		tr_x = thing->x - viewx;

From dfcd058c80db463c4564e1bc7db746e25cc7819e Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Tue, 21 Jan 2020 02:29:29 -0800
Subject: [PATCH 06/19] (BRUH MOMENT) activettscale was -1, so do recache after
 it's set

---
 src/f_finale.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/f_finale.c b/src/f_finale.c
index bc904d8f2..e37eab764 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -2693,8 +2693,18 @@ static void F_FigureActiveTtScale(void)
 	SINT8 newttscale = max(1, min(6, vid.dupx));
 	SINT8 oldttscale = activettscale;
 
-	if (newttscale == testttscale)
-		return;
+	if (needpatchrecache)
+		ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
+	else
+	{
+		if (newttscale == testttscale)
+			return;
+
+		// We have a new ttscale, so load gfx
+		if(oldttscale > 0)
+			F_UnloadAlacroixGraphics(oldttscale);
+	}
+
 	testttscale = newttscale;
 
 	// If ttscale is unavailable: look for lower scales, then higher scales.
@@ -2712,10 +2722,6 @@ static void F_FigureActiveTtScale(void)
 
 	activettscale = (newttscale >= 1 && newttscale <= 6) ? newttscale : 0;
 
-	// We have a new ttscale, so load gfx
-	if(oldttscale > 0)
-		F_UnloadAlacroixGraphics(oldttscale);
-
 	if(activettscale > 0)
 		F_LoadAlacroixGraphics(activettscale);
 }
@@ -2757,12 +2763,6 @@ void F_TitleScreenDrawer(void)
 		return;
 #endif
 
-	if (needpatchrecache && (curttmode == TTMODE_ALACROIX))
-	{
-		ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
-		F_LoadAlacroixGraphics(activettscale);
-	}
-
 	switch(curttmode)
 	{
 		case TTMODE_OLD:

From e57589b1068ea3dec70bd3aa501f38371d409b24 Mon Sep 17 00:00:00 2001
From: fickleheart <fickle@tinted.red>
Date: Sat, 25 Jan 2020 19:03:15 -0600
Subject: [PATCH 07/19] Fix the minecart angle thing

---
 src/p_user.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/p_user.c b/src/p_user.c
index 901cd8ae6..fd3f860cf 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -10790,12 +10790,23 @@ static void P_MinecartThink(player_t *player)
 		else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX))
 			player->mo->angle = minecart->angle - MINECARTCONEMAX;
 
-		if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_AnalogMove(player)))
+		if (!demoplayback || P_AnalogMove(player))
 		{
+			angle_t *ang = NULL;
+
 			if (player == &players[consoleplayer])
-				localangle = player->mo->angle;
+				ang = &localangle;
 			else if (player == &players[secondarydisplayplayer])
-				localangle2 = player->mo->angle;
+				ang = &localangle2;
+
+			if (ang)
+			{
+				angdiff = *ang - minecart->angle;
+				if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX)
+					*ang = minecart->angle + MINECARTCONEMAX;
+				else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX))
+					*ang = minecart->angle - MINECARTCONEMAX;
+			}
 		}
 	}
 

From d08929b3d77d9e5686abddf8e07c0b2cdd927949 Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Sun, 26 Jan 2020 22:46:57 -0300
Subject: [PATCH 08/19] Move line drawer setting to AM_Drawer

---
 src/am_map.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/am_map.c b/src/am_map.c
index 7dfbf4ba4..0f8f0f74f 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -354,12 +354,6 @@ static void AM_LevelInit(void)
 	f_w = vid.width;
 	f_h = vid.height;
 
-	AM_drawFline = AM_drawFline_soft;
-#ifdef HWRENDER
-	if (rendermode == render_opengl)
-		AM_drawFline = HWR_drawAMline;
-#endif
-
 	AM_findMinMaxBoundaries();
 	scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT);
 	if (scale_mtof > max_scale_mtof)
@@ -1100,6 +1094,12 @@ void AM_Drawer(void)
 	if (!automapactive)
 		return;
 
+	AM_drawFline = AM_drawFline_soft;
+#ifdef HWRENDER
+	if (rendermode == render_opengl)
+		AM_drawFline = HWR_drawAMline;
+#endif
+
 	AM_clearFB(BACKGROUND);
 	if (draw_grid) AM_drawGrid(GRIDCOLORS);
 	AM_drawWalls();

From ba6018aea44ec6cdf0245acb116deec64a5941fa Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Sun, 26 Jan 2020 22:52:15 -0300
Subject: [PATCH 09/19] Optimise pixel drawing

---
 src/am_map.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/am_map.c b/src/am_map.c
index 0f8f0f74f..c06bd2561 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -205,6 +205,7 @@ static boolean followplayer = true; // specifies whether to follow the player ar
 typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color);
 static AMDRAWFLINEFUNC AM_drawFline;
 
+static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc);
 static void AM_drawFline_soft(const fline_t *fl, INT32 color);
 
 static void AM_activateNewScale(void)
@@ -712,6 +713,17 @@ static boolean AM_clipMline(const mline_t *ml, fline_t *fl)
 }
 #undef DOOUTCODE
 
+//
+// Draws a pixel.
+//
+static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc)
+{
+	UINT8 *dest = screens[0];
+	if (xx < 0 || yy < 0 || xx >= vid.width || yy >= vid.height)
+		return; // off the screen
+	dest[(yy*vid.rowbytes) + (xx * vid.bpp)] = (cc & 0xFF);
+}
+
 //
 // Classic Bresenham w/ whatever optimizations needed for speed
 //
@@ -733,8 +745,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
 	}
 #endif
 
-	#define PUTDOT(xx,yy,cc) V_DrawFill(xx,yy,1,1,cc|V_NOSCALESTART);
-
 	dx = fl->b.x - fl->a.x;
 	ax = 2 * (dx < 0 ? -dx : dx);
 	sx = dx < 0 ? -1 : 1;
@@ -751,7 +761,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
 		d = ay - ax/2;
 		for (;;)
 		{
-			PUTDOT(x, y, color)
+			AM_drawPixel(x, y, color);
 			if (x == fl->b.x)
 				return;
 			if (d >= 0)
@@ -768,7 +778,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
 		d = ax - ay/2;
 		for (;;)
 		{
-			PUTDOT(x, y, color)
+			AM_drawPixel(x, y, color);
 			if (y == fl->b.y)
 				return;
 			if (d >= 0)
@@ -780,8 +790,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
 			d += ax;
 		}
 	}
-
-	#undef PUTDOT
 }
 
 //

From dd8166ca5f4f9dce7a4189a7e89992e42e0cbf9d Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Sun, 26 Jan 2020 22:57:14 -0300
Subject: [PATCH 10/19] Doesn't matter.

---
 src/am_map.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/am_map.c b/src/am_map.c
index c06bd2561..4ad40b7aa 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -721,7 +721,7 @@ static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc)
 	UINT8 *dest = screens[0];
 	if (xx < 0 || yy < 0 || xx >= vid.width || yy >= vid.height)
 		return; // off the screen
-	dest[(yy*vid.rowbytes) + (xx * vid.bpp)] = (cc & 0xFF);
+	dest[(yy*vid.width) + xx] = cc;
 }
 
 //

From 8f3855d09f93da34fbe56fe62b90c36c283f65ec Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Sun, 26 Jan 2020 23:12:28 -0300
Subject: [PATCH 11/19] Don't stop the automap (just restart it instead.)

---
 src/am_map.c | 24 +++++++++++++++++-------
 src/am_map.h |  3 +++
 src/screen.c |  7 +++++--
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/src/am_map.c b/src/am_map.c
index 4ad40b7aa..6cd9a3f0f 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -345,16 +345,22 @@ static void AM_initVariables(void)
 	old_m_h = m_h;
 }
 
+//
+// Called when the screen size changed.
+//
+static void AM_FrameBufferInit(void)
+{
+	f_x = f_y = 0;
+	f_w = vid.width;
+	f_h = vid.height;
+}
+
 //
 // should be called at the start of every level
 // right now, i figure it out myself
 //
 static void AM_LevelInit(void)
 {
-	f_x = f_y = 0;
-	f_w = vid.width;
-	f_h = vid.height;
-
 	AM_findMinMaxBoundaries();
 	scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT);
 	if (scale_mtof > max_scale_mtof)
@@ -376,7 +382,7 @@ void AM_Stop(void)
   *
   * \sa AM_Stop
   */
-static inline void AM_Start(void)
+void AM_Start(void)
 {
 	static INT32 lastlevel = -1;
 
@@ -385,8 +391,12 @@ static inline void AM_Start(void)
 	am_stopped = false;
 	if (lastlevel != gamemap || am_recalc) // screen size changed
 	{
-		AM_LevelInit();
-		lastlevel = gamemap;
+		AM_FrameBufferInit();
+		if (lastlevel != gamemap)
+		{
+			AM_LevelInit();
+			lastlevel = gamemap;
+		}
 		am_recalc = false;
 	}
 	AM_initVariables();
diff --git a/src/am_map.h b/src/am_map.h
index 462bb3d6d..0560207bb 100644
--- a/src/am_map.h
+++ b/src/am_map.h
@@ -38,6 +38,9 @@ void AM_Ticker(void);
 // Called by main loop, instead of view drawer if automap is active.
 void AM_Drawer(void);
 
+// Enables the automap.
+void AM_Start(void);
+
 // Called to force the automap to quit if the level is completed while it is up.
 void AM_Stop(void);
 
diff --git a/src/screen.c b/src/screen.c
index 5bb304c08..fcf6c6b0b 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -360,10 +360,13 @@ void SCR_Recalc(void)
 	vid.fsmalldupy = vid.smalldupy*FRACUNIT;
 #endif
 
-	// toggle off automap because some screensize-dependent values will
+	// toggle off (then back on) the automap because some screensize-dependent values will
 	// be calculated next time the automap is activated.
 	if (automapactive)
-		AM_Stop();
+	{
+		am_recalc = true;
+		AM_Start();
+	}
 
 	// set the screen[x] ptrs on the new vidbuffers
 	V_Init();

From 2cfeaa63d2e8262dec715748132cb29fac834334 Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Sun, 26 Jan 2020 23:34:04 -0300
Subject: [PATCH 12/19] Fix movement to accomodate to window scale changes

---
 src/am_map.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/am_map.c b/src/am_map.c
index 6cd9a3f0f..b1fad1b0c 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -160,6 +160,7 @@ static boolean am_stopped = true;
 static INT32 f_x, f_y;	// location of window on screen (always zero for both)
 static INT32 f_w, f_h;	// size of window on screen (always the screen width and height respectively)
 
+static boolean m_keydown[4]; // which window panning keys are being pressed down?
 static mpoint_t m_paninc; // how far the window pans each tic (map coords)
 static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords)
 static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords)
@@ -422,6 +423,28 @@ static void AM_maxOutWindowScale(void)
 	AM_activateNewScale();
 }
 
+//
+// set window panning
+//
+static void AM_setWindowPanning(void)
+{
+	// up and down
+	if (m_keydown[2]) // pan up
+		m_paninc.y = FTOM(F_PANINC);
+	else if (m_keydown[3]) // pan down
+		m_paninc.y = -FTOM(F_PANINC);
+	else
+		m_paninc.y = 0;
+
+	// left and right
+	if (m_keydown[0]) // pan right
+		m_paninc.x = FTOM(F_PANINC);
+	else if (m_keydown[1]) // pan left
+		m_paninc.x = -FTOM(F_PANINC);
+	else
+		m_paninc.x = 0;
+}
+
 /** Responds to user inputs in automap mode.
   *
   * \param ev Event to possibly respond to.
@@ -454,35 +477,49 @@ boolean AM_Responder(event_t *ev)
 			{
 				case AM_PANRIGHTKEY: // pan right
 					if (!followplayer)
-						m_paninc.x = FTOM(F_PANINC);
+					{
+						m_keydown[0] = true;
+						AM_setWindowPanning();
+					}
 					else
 						rc = false;
 					break;
 				case AM_PANLEFTKEY: // pan left
 					if (!followplayer)
-						m_paninc.x = -FTOM(F_PANINC);
+					{
+						m_keydown[1] = true;
+						AM_setWindowPanning();
+					}
 					else
 						rc = false;
 					break;
 				case AM_PANUPKEY: // pan up
 					if (!followplayer)
-						m_paninc.y = FTOM(F_PANINC);
+					{
+						m_keydown[2] = true;
+						AM_setWindowPanning();
+					}
 					else
 						rc = false;
 					break;
 				case AM_PANDOWNKEY: // pan down
 					if (!followplayer)
-						m_paninc.y = -FTOM(F_PANINC);
+					{
+						m_keydown[3] = true;
+						AM_setWindowPanning();
+					}
 					else
 						rc = false;
 					break;
 				case AM_ZOOMOUTKEY: // zoom out
 					mtof_zoommul = M_ZOOMOUT;
 					ftom_zoommul = M_ZOOMIN;
+					AM_setWindowPanning();
 					break;
 				case AM_ZOOMINKEY: // zoom in
 					mtof_zoommul = M_ZOOMIN;
 					ftom_zoommul = M_ZOOMOUT;
+					AM_setWindowPanning();
 					break;
 				case AM_TOGGLEKEY:
 					AM_Stop();
@@ -515,14 +552,32 @@ boolean AM_Responder(event_t *ev)
 			switch (ev->data1)
 			{
 				case AM_PANRIGHTKEY:
+					if (!followplayer)
+					{
+						m_keydown[0] = false;
+						AM_setWindowPanning();
+					}
+					break;
 				case AM_PANLEFTKEY:
 					if (!followplayer)
-						m_paninc.x = 0;
+					{
+						m_keydown[1] = false;
+						AM_setWindowPanning();
+					}
 					break;
 				case AM_PANUPKEY:
+					if (!followplayer)
+					{
+						m_keydown[2] = false;
+						AM_setWindowPanning();
+					}
+					break;
 				case AM_PANDOWNKEY:
 					if (!followplayer)
-						m_paninc.y = 0;
+					{
+						m_keydown[3] = false;
+						AM_setWindowPanning();
+					}
 					break;
 				case AM_ZOOMOUTKEY:
 				case AM_ZOOMINKEY:

From 46cbe63b43f9cd3b4958c1c911907b4e6b9a6aa0 Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Sun, 26 Jan 2020 23:39:31 -0300
Subject: [PATCH 13/19] Fix going big

---
 src/am_map.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/am_map.c b/src/am_map.c
index b1fad1b0c..f6bafe33b 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -533,6 +533,7 @@ boolean AM_Responder(event_t *ev)
 					}
 					else
 						AM_restoreScaleAndLoc();
+					AM_setWindowPanning();
 					break;
 				case AM_FOLLOWKEY:
 					followplayer = !followplayer;

From 7f57327ff7b806e3aa118c745df142c187d75fc5 Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Sun, 26 Jan 2020 23:41:34 -0300
Subject: [PATCH 14/19] "changes" not "changed"

---
 src/am_map.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/am_map.c b/src/am_map.c
index f6bafe33b..b2c7de442 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -347,7 +347,7 @@ static void AM_initVariables(void)
 }
 
 //
-// Called when the screen size changed.
+// Called when the screen size changes.
 //
 static void AM_FrameBufferInit(void)
 {

From 1548a22ea902a201de6779a6877bd225c7cf735e Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Mon, 27 Jan 2020 00:44:10 -0300
Subject: [PATCH 15/19] Fix M_DrawNightsAttackMountains being broken for
 obvious reasons

---
 src/m_menu.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/m_menu.c b/src/m_menu.c
index f8c14dd69..049b66d67 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -5388,7 +5388,8 @@ static void M_DrawNightsAttackMountains(void)
 	static INT32 bgscrollx;
 	INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
 	patch_t *background = W_CachePatchName(curbgname, PU_PATCH);
-	INT32 x = FixedInt(bgscrollx) % SHORT(background->width);
+	INT16 w = SHORT(background->width);
+	INT32 x = FixedInt(-bgscrollx) % w;
 	INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2;
 
 	if (vid.height != BASEVIDHEIGHT * dupz)
@@ -5396,11 +5397,13 @@ static void M_DrawNightsAttackMountains(void)
 	V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31);
 
 	V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
-	x += SHORT(background->width);
+	x += w;
 	if (x < BASEVIDWIDTH)
 		V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
 
-	bgscrollx -= (FRACUNIT/2);
+	bgscrollx += (FRACUNIT/2);
+	if (bgscrollx > w<<FRACBITS)
+		bgscrollx &= 0xFFFF;
 }
 
 // NiGHTS Attack foreground.

From 28fd2380dfd980804fe18decbb9c8e274f0a3bd5 Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Mon, 27 Jan 2020 13:28:07 -0300
Subject: [PATCH 16/19] Fix F_StartContinue fading out incorrectly in OpenGL

---
 src/f_finale.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/f_finale.c b/src/f_finale.c
index bc904d8f2..ed89e05cd 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -3628,7 +3628,6 @@ void F_StartContinue(void)
 	}
 
 	wipestyleflags = WSF_FADEOUT;
-	F_TryColormapFade(31);
 	G_SetGamestate(GS_CONTINUING);
 	gameaction = ga_nothing;
 

From 636093a59ddd95b25d79c4ebff51dc6412de1956 Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Mon, 27 Jan 2020 13:55:13 -0300
Subject: [PATCH 17/19] Fix color LUT using the wrong palette

---
 src/m_anigif.c | 18 +++++-------------
 src/r_data.c   | 12 ++++++++----
 src/r_data.h   |  3 ++-
 src/v_video.c  |  3 +--
 src/v_video.h  |  5 +----
 5 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/src/m_anigif.c b/src/m_anigif.c
index 32fc2746d..f062bc826 100644
--- a/src/m_anigif.c
+++ b/src/m_anigif.c
@@ -624,14 +624,6 @@ static void GIF_framewrite(void)
 //
 INT32 GIF_open(const char *filename)
 {
-#if 0
-	if (rendermode != render_soft)
-	{
-		CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n"));
-		return 0;
-	}
-#endif
-
 	gif_out = fopen(filename, "wb");
 	if (!gif_out)
 		return 0;
@@ -640,13 +632,13 @@ INT32 GIF_open(const char *filename)
 	gif_downscale = (!!cv_gif_downscale.value);
 
 	// GIF color table
-	// In hardware mode, uses the master palette
-	gif_palette = ((cv_screenshot_colorprofile.value
+	// In hardware mode, forces the local palette
 #ifdef HWRENDER
-	&& (rendermode == render_soft)
+	if (rendermode == render_opengl)
+		gif_palette = pLocalPalette;
+	else
 #endif
-	) ? pLocalPalette
-	: pMasterPalette);
+		gif_palette = ((cv_screenshot_colorprofile.value) ? pLocalPalette : pMasterPalette);
 
 	GIF_headwrite();
 	gif_frames = 0;
diff --git a/src/r_data.c b/src/r_data.c
index 9f80e257b..e0a3d48d4 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -2465,16 +2465,20 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
 
 // Thanks to quake2 source!
 // utils3/qdata/images.c
-UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b)
+UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette)
 {
 	int dr, dg, db;
 	int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i;
 
+	// Use master palette if none specified
+	if (palette == NULL)
+		palette = pMasterPalette;
+
 	for (i = 0; i < 256; i++)
 	{
-		dr = r - pMasterPalette[i].s.red;
-		dg = g - pMasterPalette[i].s.green;
-		db = b - pMasterPalette[i].s.blue;
+		dr = r - palette[i].s.red;
+		dg = g - palette[i].s.green;
+		db = b - palette[i].s.blue;
 		distortion = dr*dr + dg*dg + db*db;
 		if (distortion < bestdistortion)
 		{
diff --git a/src/r_data.h b/src/r_data.h
index f028f2f5d..145f0182b 100644
--- a/src/r_data.h
+++ b/src/r_data.h
@@ -171,7 +171,8 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
 #define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
 #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
 
-UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
+UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette);
+#define NearestColor(r, g, b) NearestPaletteColor(r, g, b, NULL)
 
 extern INT32 numtextures;
 
diff --git a/src/v_video.c b/src/v_video.c
index 4785a1541..81625ff9e 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -3244,7 +3244,6 @@ Unoptimized version
 #endif
 }
 
-// Taken from my videos-in-SRB2 project
 // Generates a color look-up table
 // which has up to 64 colors at each channel
 // (see the defines in v_video.h)
@@ -3261,7 +3260,7 @@ void InitColorLUT(RGBA_t *palette)
 		for (r = 0; r < CLUTSIZE; r++)
 			for (g = 0; g < CLUTSIZE; g++)
 				for (b = 0; b < CLUTSIZE; b++)
-					colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS);
+					colorlookup[r][g][b] = NearestPaletteColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS, palette);
 		clutinit = true;
 		lastpalette = palette;
 	}
diff --git a/src/v_video.h b/src/v_video.h
index eb75a414f..bc19f6e99 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -37,10 +37,7 @@ cv_allcaps;
 // Allocates buffer screens, call before R_Init.
 void V_Init(void);
 
-// Taken from my videos-in-SRB2 project
-// Generates a color look-up table
-// which has up to 64 colors at each channel
-
+// Color look-up table
 #define COLORBITS 6
 #define SHIFTCOLORBITS (8-COLORBITS)
 #define CLUTSIZE (1<<COLORBITS)

From f4de1938098067327731d8502ff4ec68e74ee027 Mon Sep 17 00:00:00 2001
From: Steel Titanium <steeltitanium1@gmail.com>
Date: Thu, 30 Jan 2020 22:11:50 -0500
Subject: [PATCH 18/19] Fix memory leak while chat is on screen

---
 src/hu_stuff.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 274c2bdfd..69e8c99ff 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -1437,7 +1437,7 @@ static void HU_drawMiniChat(void)
 
 	for (; i>0; i--)
 	{
-		const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
+		char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
 		size_t j = 0;
 		INT32 linescount = 0;
 
@@ -1479,6 +1479,9 @@ static void HU_drawMiniChat(void)
 		dy = 0;
 		dx = 0;
 		msglines += linescount+1;
+
+		if (msg)
+			Z_Free(msg);
 	}
 
 	y = chaty - charheight*(msglines+1);
@@ -1501,7 +1504,7 @@ static void HU_drawMiniChat(void)
 		INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
 		INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
 		size_t j = 0;
-		const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
+		char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
 		UINT8 *colormap = NULL;
 
 		while(msg[j]) // iterate through msg
@@ -1547,6 +1550,9 @@ static void HU_drawMiniChat(void)
 		}
 		dy += charheight;
 		dx = 0;
+
+		if (msg)
+			Z_Free(msg);
 	}
 
 	// decrement addy and make that shit smooth:
@@ -1598,7 +1604,7 @@ static void HU_drawChatLog(INT32 offset)
 	{
 		INT32 clrflag = 0;
 		INT32 j = 0;
-		const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
+		char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
 		UINT8 *colormap = NULL;
 		while(msg[j]) // iterate through msg
 		{
@@ -1638,6 +1644,9 @@ static void HU_drawChatLog(INT32 offset)
 		}
 		dy += charheight;
 		dx = 0;
+
+		if (msg)
+			Z_Free(msg);
 	}
 
 

From 3afc766f5e36d094395fe0da41e7142be070e8c1 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Thu, 30 Jan 2020 23:58:35 -0800
Subject: [PATCH 19/19] Oops

---
 src/console.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/console.c b/src/console.c
index ba5ba71df..8746bf036 100644
--- a/src/console.c
+++ b/src/console.c
@@ -769,7 +769,7 @@ boolean CON_Responder(event_t *ev)
 	// check for console toggle key
 	if (ev->type != ev_console)
 	{
-		if (modeattacking || metalrecording || menuactive)
+		if (modeattacking || metalrecording)
 			return false;
 
 		if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])