From 0e57d70b95dd9f035d8eb261d38689d9901090a5 Mon Sep 17 00:00:00 2001
From: LJ Sonic <lamr@free.fr>
Date: Sun, 17 Mar 2024 00:41:38 +0100
Subject: [PATCH] Automatically mirror long sprites for missing rotations

---
 src/r_things.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/src/r_things.c b/src/r_things.c
index bda754dba..5c4698e5d 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -312,6 +312,38 @@ static boolean GetFramesAndRotationsFromLongLumpName(
 	return true;
 }
 
+static UINT8 GetOppositeRotation(UINT8 rotation, UINT8 flags)
+{
+	if (flags & ~SRF_3DMASK)
+		I_Error("GetOppositeRotation: rotation type not supported");
+
+	UINT8 numrotations = (flags == SRF_3D) ? 8 : 16;
+	return (rotation == 1) ? 1 : numrotations + 2 - rotation;
+}
+
+static void MirrorMissingRotations(void)
+{
+	for (UINT32 framenum = 0; framenum < maxframe; framenum++)
+	{
+		spriteframe_t *frame = &sprtemp[framenum];
+
+		if (!(frame->rotate & SRF_3DMASK))
+			continue;
+
+		UINT8 numrotations = frame->rotate == SRF_3D ? 8 : 16;
+
+		for (UINT8 rotation = 1; rotation <= numrotations; rotation++)
+		{
+			if (frame->lumppat[rotation - 1] != LUMPERROR)
+				continue;
+
+			UINT8 baserotation = GetOppositeRotation(rotation, frame->rotate);
+			UINT32 lumpnum = frame->lumppat[baserotation - 1];
+			R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), frame->lumpid[baserotation], framenum, rotation, 1);
+		}
+	}
+}
+
 // Some checks to help development
 static void CheckFrame(const char *sprname)
 {
@@ -484,6 +516,9 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
 
 	maxframe++;
 
+	if (longname)
+		MirrorMissingRotations();
+
 	CheckFrame(sprname);
 
 	// allocate space for the frames present and copy sprtemp to it