From 73a78caa5c8832a4659ce607a9f13a6509e46e93 Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@zdoom.fake>
Date: Fri, 16 Mar 2012 02:23:31 +0000
Subject: [PATCH] - Added support for a few extra color ranges to
 Player.Colorset so that the Strife player's   predefined colors can properly
 define the standard Strife translation ranges.

SVN r3446 (trunk)
---
 src/info.h                                   |  8 +++
 src/r_data/r_translate.cpp                   | 51 ++++++++++++--------
 src/thingdef/thingdef_properties.cpp         | 32 +++++++++++-
 wadsrc/static/actors/strife/strifeplayer.txt | 15 +++---
 4 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/src/info.h b/src/info.h
index 39d73f4a7..f29871903 100644
--- a/src/info.h
+++ b/src/info.h
@@ -160,6 +160,12 @@ FArchive &operator<< (FArchive &arc, FState *&state);
 // Standard pre-defined skin colors
 struct FPlayerColorSet
 {
+	struct ExtraRange
+	{
+		BYTE RangeStart, RangeEnd;	// colors to remap
+		BYTE FirstColor, LastColor;	// colors to map to
+	};
+
 	FName Name;			// Name of this color
 
 	int Lump;			// Lump to read the translation from, otherwise use next 2 fields
@@ -167,6 +173,8 @@ struct FPlayerColorSet
 
 	BYTE RepresentativeColor;		// A palette entry representative of this translation,
 									// for map arrows and status bar backgrounds and such
+	BYTE NumExtraRanges;
+	ExtraRange Extra[6];
 };
 
 typedef TMap<FName, fixed_t> DmgFactors;
diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp
index 0e29801e5..818d89d16 100644
--- a/src/r_data/r_translate.cpp
+++ b/src/r_data/r_translate.cpp
@@ -857,6 +857,30 @@ static void SetRemap(FRemapTable *table, int i, float r, float g, float b)
 	table->Palette[i] = PalEntry(255, ir, ig, ib);
 }
 
+//----------------------------------------------------------------------------
+
+static bool SetRange(FRemapTable *table, int start, int end, int first, int last)
+{
+	bool identity = true;
+	if (start == end)
+	{
+		table->Remap[start] = (first + last) / 2;
+	}
+	else
+	{
+		int palrange = last - first;
+		for (int i = start; i <= end; ++i)
+		{
+			int pi = first + palrange * (i - start) / (end - start);
+			table->Remap[i] = GPalette.Remap[pi];
+			identity &= (pi == i);
+			table->Palette[i] = GPalette.BaseColors[table->Remap[i]];
+			table->Palette[i].a = 255;
+		}
+	}
+	return identity;
+}
+
 //----------------------------------------------------------------------------
 //
 //
@@ -921,20 +945,12 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC
 		// Use the pre-defined range instead of a custom one.
 		if (colorset->Lump < 0)
 		{
-			int first = colorset->FirstColor;
-			if (start == end)
+			identity &= SetRange(table, start, end, colorset->FirstColor, colorset->LastColor);
+			for (i = 0; i < colorset->NumExtraRanges; ++i)
 			{
-				table->Remap[i] = (first + colorset->LastColor) / 2;
-			}
-			else
-			{
-				int palrange = colorset->LastColor - first;
-				for (i = start; i <= end; ++i)
-				{
-					int pi = first + palrange * (i - start) / (end - start);
-					table->Remap[i] = GPalette.Remap[pi];
-					if (pi != i) identity = false;
-				}
+				identity &= SetRange(table,
+					colorset->Extra[i].RangeStart, colorset->Extra[i].RangeEnd,
+					colorset->Extra[i].FirstColor, colorset->Extra[i].LastColor);
 			}
 		}
 		else
@@ -944,14 +960,11 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC
 			for (i = start; i <= end; ++i)
 			{
 				table->Remap[i] = GPalette.Remap[trans[i]];
-				if (trans[i] != i) identity = false;
+				identity &= (trans[i] == i);
+				table->Palette[i] = GPalette.BaseColors[table->Remap[i]];
+				table->Palette[i].a = 255;
 			}
 		}
-		for (i = start; i <= end; ++i)
-		{
-			table->Palette[i] = GPalette.BaseColors[table->Remap[i]];
-			table->Palette[i].a = 255;
-		}
 		// If the colorset created an identity translation mark it as inactive
 		table->Inactive = identity;
 	}
diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp
index ec68f8514..87c5f64c2 100644
--- a/src/thingdef/thingdef_properties.cpp
+++ b/src/thingdef/thingdef_properties.cpp
@@ -2065,7 +2065,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn)
 //==========================================================================
 //
 //==========================================================================
-DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIII, PlayerPawn)
+DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIIIiiiiiiiiiiiiiiiiiiiiiiii, PlayerPawn)
 {
 	PROP_INT_PARM(setnum, 0);
 	PROP_STRING_PARM(setname, 1);
@@ -2079,6 +2079,34 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIII, PlayerPawn)
 	color.FirstColor = rangestart;
 	color.LastColor = rangeend;
 	color.RepresentativeColor = representative_color;
+	color.NumExtraRanges = 0;
+
+	if (PROP_PARM_COUNT > 5)
+	{
+		int count = PROP_PARM_COUNT - 5;
+		int start = 5;
+
+		while (count >= 4)
+		{
+			PROP_INT_PARM(range_start, start+0);
+			PROP_INT_PARM(range_end, start+1);
+			PROP_INT_PARM(first_color, start+2);
+			PROP_INT_PARM(last_color, start+3);
+			int extra = color.NumExtraRanges++;
+			assert (extra < countof(color.Extra));
+
+			color.Extra[extra].RangeStart = range_start;
+			color.Extra[extra].RangeEnd = range_end;
+			color.Extra[extra].FirstColor = first_color;
+			color.Extra[extra].LastColor = last_color;
+			count -= 4;
+			start += 4;
+		}
+		if (count != 0)
+		{
+			bag.ScriptPosition.Message(MSG_WARNING, "Extra ranges require 4 parameters each.\n");
+		}
+	}
 
 	if (setnum < 0)
 	{
@@ -2104,6 +2132,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorsetfile, ISSI, PlayerPawn)
 	color.Name = setname;
 	color.Lump = Wads.CheckNumForName(rangefile);
 	color.RepresentativeColor = representative_color;
+	color.NumExtraRanges = 0;
+
 	if (setnum < 0)
 	{
 		bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n");
diff --git a/wadsrc/static/actors/strife/strifeplayer.txt b/wadsrc/static/actors/strife/strifeplayer.txt
index 5b0bdc750..efdfaa30c 100644
--- a/wadsrc/static/actors/strife/strifeplayer.txt
+++ b/wadsrc/static/actors/strife/strifeplayer.txt
@@ -24,13 +24,14 @@ ACTOR StrifePlayer : PlayerPawn
 
 	Player.ColorRange 128, 143
 	Player.Colorset 0, "Brown",			0x80, 0x8F,	 0x82
-	Player.Colorset 1, "Red",			0x40, 0x4F,  0x42
-	Player.Colorset 2, "Rust",			0xB0, 0xBF,  0xB2
-	Player.Colorset 3, "Gray",			0x10, 0x1F,  0x12
-	Player.Colorset 4, "Dark Green",	0x30, 0x3F,  0x32
-	Player.Colorset 5, "Gold",			0x50, 0x5F,  0x52
-	Player.Colorset 6, "Bright Green",	0x60, 0x6F,  0x62
-	Player.Colorset 7, "Blue",			0x90, 0x9F,  0x92
+	Player.Colorset 1, "Red",			0x40, 0x4F,  0x42,  0x20, 0x3F, 0x00, 0x1F,  0xF1, 0xF6, 0xE0, 0xE5,  0xF7, 0xFB, 0xF1, 0xF5
+	Player.Colorset 2, "Rust",			0xB0, 0xBF,  0xB2,  0x20, 0x3F, 0x00, 0x1F
+	Player.Colorset 3, "Gray",			0x10, 0x1F,  0x12,  0x20, 0x2F, 0xD0, 0xDF,  0x30, 0x3F, 0xD0, 0xDF
+	Player.Colorset 4, "Dark Green",	0x30, 0x3F,  0x32,  0x20, 0x2F, 0xD0, 0xDF,  0x30, 0x3F, 0xD0, 0xDF
+
+	Player.Colorset 5, "Gold",			0x50, 0x5F,  0x52,	0x20, 0x3F, 0x00, 0x1F,  0x50, 0x5F, 0x80, 0x8F,  0xC0, 0xCF, 0xA0, 0xAF,                  0xD0, 0xDF, 0xB0, 0xBF
+	Player.Colorset 6, "Bright Green",	0x60, 0x6F,  0x62,	0x20, 0x3F, 0x00, 0x1F,  0x50, 0x5F, 0x10, 0x1F,  0xC0, 0xCF, 0x20, 0x2F,                  0xD0, 0xDF, 0x30, 0x3F
+	Player.Colorset 7, "Blue",			0x90, 0x9F,  0x92,	0x20, 0x3F, 0x00, 0x1F,  0x50, 0x5F, 0x40, 0x4F,  0xC1, 0xCF, 0x01, 0x0F,  0xC0,0xC0,1,1,  0xD0, 0xDF, 0x10, 0x1F
 
 	action native A_ItBurnsItBurns();
 	action native A_CrispyPlayer();