From 1a63e72f5c28c06962132e871213f4fb1450b200 Mon Sep 17 00:00:00 2001
From: Lactozilla <jp6781615@gmail.com>
Date: Mon, 29 Jan 2024 04:32:52 -0300
Subject: [PATCH] Fix #1183 - Fixed an incorrect access of skincolor_remaps[]
 in R_GetTranslationRemap - Fixed R_GetTranslationForThing not being able to
 apply a translation over TC_RAINBOW or TC_DASHMODE - OpenGL: Fixed
 MF2_LINKDRAW sprites possibly not using the correct translation

---
 src/hardware/hw_main.c |  5 ++++-
 src/r_draw.c           |  4 ++--
 src/r_draw.h           |  2 ++
 src/r_things.c         | 33 +++++++++++++++++----------------
 src/r_translation.c    | 10 ++++++----
 5 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index efbcf81d7..0f1a8eed7 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -5510,7 +5510,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
 		translation = thing->translation;
 
 	//Hurdler: 25/04/2000: now support colormap in hardware mode
-	vis->colormap = R_GetTranslationForThing(vis->mobj, color, translation);
+	if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
+		vis->colormap = R_GetTranslationForThing(thing->tracer, color, translation);
+	else
+		vis->colormap = R_GetTranslationForThing(thing, color, translation);
 
 	// set top/bottom coords
 	vis->gzt = gzt;
diff --git a/src/r_draw.c b/src/r_draw.c
index ff2e43df3..4648bf1a1 100644
--- a/src/r_draw.c
+++ b/src/r_draw.c
@@ -129,7 +129,7 @@ static colorcache_t **translationtablecache[TT_CACHE_SIZE] = {NULL};
 
 boolean skincolor_modified[MAXSKINCOLORS];
 
-static INT32 SkinToCacheIndex(INT32 translation)
+INT32 R_SkinTranslationToCacheIndex(INT32 translation)
 {
 	switch (translation)
 	{
@@ -556,7 +556,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
 	else if (skinnum <= TC_DEFAULT)
 	{
 		// Do default translation
-		index = SkinToCacheIndex(skinnum);
+		index = R_SkinTranslationToCacheIndex(skinnum);
 	}
 	else
 		I_Error("Invalid translation %d", skinnum);
diff --git a/src/r_draw.h b/src/r_draw.h
index 29370015a..e6c416cc2 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -117,6 +117,8 @@ enum
 	TC_DEFAULT
 };
 
+INT32 R_SkinTranslationToCacheIndex(INT32 translation);
+
 // Amount of colors in the palette
 #define NUM_PALETTE_ENTRIES 256
 
diff --git a/src/r_things.c b/src/r_things.c
index 7291594eb..052b55de7 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -770,6 +770,22 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
 	if (is_player) // This thing is a player!
 		skinnum = ((skin_t*)mobj->skin)->skinnum;
 
+	if (color != SKINCOLOR_NONE)
+	{
+		// New colormap stuff for skins Tails 06-07-2002
+		if (mobj->colorized)
+			skinnum = TC_RAINBOW;
+		else if (mobj->player && mobj->player->dashmode >= DASHMODE_THRESHOLD
+			&& (mobj->player->charflags & SF_DASHMODE)
+			&& ((leveltime/2) & 1))
+		{
+			if (mobj->player->charflags & SF_MACHINE)
+				skinnum = TC_DASHMODE;
+			else
+				skinnum = TC_RAINBOW;
+		}
+	}
+
 	if (R_ThingIsFlashing(mobj)) // Bosses "flash"
 	{
 		if (mobj->type == MT_CYBRAKDEMON || mobj->colorized)
@@ -786,22 +802,7 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
 			return tr;
 	}
 	else if (color != SKINCOLOR_NONE)
-	{
-		// New colormap stuff for skins Tails 06-07-2002
-		if (mobj->colorized)
-			return R_GetTranslationColormap(TC_RAINBOW, color, GTC_CACHE);
-		else if (mobj->player && mobj->player->dashmode >= DASHMODE_THRESHOLD
-			&& (mobj->player->charflags & SF_DASHMODE)
-			&& ((leveltime/2) & 1))
-		{
-			if (mobj->player->charflags & SF_MACHINE)
-				return R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
-			else
-				return R_GetTranslationColormap(TC_RAINBOW, color, GTC_CACHE);
-		}
-		else
-			return R_GetTranslationColormap(skinnum, color, GTC_CACHE);
-	}
+		return R_GetTranslationColormap(skinnum, color, GTC_CACHE);
 	else if (mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
 		return R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE);
 
diff --git a/src/r_translation.c b/src/r_translation.c
index 7e1e30d0c..3b123f14c 100644
--- a/src/r_translation.c
+++ b/src/r_translation.c
@@ -1126,17 +1126,19 @@ UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum)
 	if (!tr->skincolor_remaps)
 		Z_Calloc(sizeof(*tr->skincolor_remaps) * TT_CACHE_SIZE, PU_LEVEL, &tr->skincolor_remaps);
 
-	if (!tr->skincolor_remaps[skinnum])
-		tr->skincolor_remaps[skinnum] = Z_Calloc(NUM_PALETTE_ENTRIES * MAXSKINCOLORS, PU_LEVEL, NULL);
+	INT32 index = R_SkinTranslationToCacheIndex(skinnum);
 
-	colorcache_t *cache = tr->skincolor_remaps[skinnum][skincolor];
+	if (!tr->skincolor_remaps[index])
+		tr->skincolor_remaps[index] = Z_Calloc(NUM_PALETTE_ENTRIES * (MAXSKINCOLORS - 1), PU_LEVEL, NULL);
+
+	colorcache_t *cache = tr->skincolor_remaps[index][skincolor - 1];
 	if (!cache)
 	{
 		cache = Z_Calloc(sizeof(colorcache_t), PU_LEVEL, NULL);
 
 		R_ApplyTranslationRemap(tr, cache->colors, skincolor, skinnum);
 
-		tr->skincolor_remaps[skinnum][skincolor] = cache;
+		tr->skincolor_remaps[index][skincolor - 1] = cache;
 	}
 
 	return cache->colors;