From 5ea43aa023aaf35c0ba39e483823f59f03a501dc Mon Sep 17 00:00:00 2001
From: Jaime Passos <lazymyuutsu@gmail.com>
Date: Fri, 27 Dec 2019 00:37:40 -0300
Subject: [PATCH] Fix sprite rotation crashes.

---
 src/r_defs.h   |  2 --
 src/r_patch.c  | 14 ++++++++++++++
 src/r_patch.h  |  1 +
 src/r_things.c |  5 +----
 src/screen.c   |  1 +
 src/z_zone.c   | 10 ++++++++++
 src/z_zone.h   |  1 +
 7 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/src/r_defs.h b/src/r_defs.h
index 9e32777df..964956503 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -740,9 +740,7 @@ typedef struct
 {
 	patch_t *patch[8][ROTANGLES];
 	boolean cached[8];
-#ifdef HWRENDER
 	aatree_t *hardware_patch[8];
-#endif
 } rotsprite_t;
 #endif
 
diff --git a/src/r_patch.c b/src/r_patch.c
index d4bfa9cbd..ec394e731 100644
--- a/src/r_patch.c
+++ b/src/r_patch.c
@@ -1374,4 +1374,18 @@ void R_FreeSkinRotSprite(size_t skinnum)
 		skinsprites++;
 	}
 }
+
+//
+// R_FreeAllRotSprite
+//
+// Free ALL sprite rotation data from memory.
+//
+void R_FreeAllRotSprite(void)
+{
+	INT32 i;
+	for (i = 0; i < numsprites; i++)
+		R_FreeSingleRotSprite(&sprites[i]);
+	for (i = 0; i < numskins; ++i)
+		R_FreeSkinRotSprite(i);
+}
 #endif
diff --git a/src/r_patch.h b/src/r_patch.h
index 8a8ab5602..53d306b88 100644
--- a/src/r_patch.h
+++ b/src/r_patch.h
@@ -69,6 +69,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
 void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip);
 void R_FreeSingleRotSprite(spritedef_t *spritedef);
 void R_FreeSkinRotSprite(size_t skinnum);
+void R_FreeAllRotSprite(void);
 extern fixed_t cosang2rad[ROTANGLES];
 extern fixed_t sinang2rad[ROTANGLES];
 #endif
diff --git a/src/r_things.c b/src/r_things.c
index aa2a73515..bbe62d88a 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -125,10 +125,7 @@ static void R_InstallSpriteLump(UINT16 wad,            // graphics patch
 		sprtemp[frame].rotsprite.cached[r] = false;
 		for (ang = 0; ang < ROTANGLES; ang++)
 			sprtemp[frame].rotsprite.patch[r][ang] = NULL;
-#ifdef HWRENDER
-		if (rendermode == render_opengl)
-			sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
-#endif // HWRENDER
+		sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
 	}
 #endif
 
diff --git a/src/screen.c b/src/screen.c
index 94b6c2454..16ba13087 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -200,6 +200,7 @@ void SCR_SetMode(void)
 	// Lactozilla: Renderer switching
 	if (setrenderneeded)
 	{
+		Z_PreparePatchFlush();
 		needpatchflush = true;
 		needpatchrecache = true;
 		VID_CheckRenderer();
diff --git a/src/z_zone.c b/src/z_zone.c
index e0c56ced6..5a0ff638b 100644
--- a/src/z_zone.c
+++ b/src/z_zone.c
@@ -27,6 +27,7 @@
 
 #include "doomdef.h"
 #include "doomstat.h"
+#include "r_patch.h"
 #include "i_system.h" // I_GetFreeMem
 #include "i_video.h" // rendermode
 #include "z_zone.h"
@@ -517,6 +518,15 @@ void Z_FlushCachedPatches(void)
 	Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED);
 }
 
+// happens before a renderer switch
+void Z_PreparePatchFlush(void)
+{
+	CONS_Debug(DBG_RENDER, "Z_PreparePatchFlush()...\n");
+#ifdef ROTSPRITE
+	R_FreeAllRotSprite();
+#endif
+}
+
 // starting value of nextcleanup
 #define CLEANUPCOUNT 2000
 
diff --git a/src/z_zone.h b/src/z_zone.h
index d70e9285b..9e5f74343 100644
--- a/src/z_zone.h
+++ b/src/z_zone.h
@@ -147,5 +147,6 @@ char *Z_StrDup(const char *in);
 extern boolean needpatchflush;
 extern boolean needpatchrecache;
 void Z_FlushCachedPatches(void);
+void Z_PreparePatchFlush(void);
 
 #endif
-- 
GitLab