View Issue Details

IDProjectCategoryView StatusLast Update
0003064FSSCPtablespublic2014-07-20 20:54
ReporterMageKing17 Assigned ToMageKing17  
PrioritylowSeverityfeatureReproducibilityN/A
Status resolvedResolutionfixed 
Target Version3.7.2 
Summary0003064: New colors.tbl features
DescriptionThis patch overhauls colors.tbl in a number of ways.

* "#Start Colors" is now optional; no more need for a blank section at the start of a colors.tbl just to define some team colors.
* "#Interface Colors" section added for redefining various colors used by the interface.
* "#Color Tags" section added for redefining or adding your own text color tags.
* "#Default Text Color" section for choosing what color tag is the baseline default for various different screens.
* And the big one, support for *-clr.tbm modular table files.

Example colors.tbl file that basically just lists all of the hardcoded defaults (to demonstrate syntax) included. Using it with this patch should result in no noticeable change from not having a colors.tbl file.

Also included are a couple sample .tbm files that can be used in any combination to result in altered behavior.
TagsNo tags attached.

Activities

MageKing17

2014-06-20 22:39

developer   ~0015898

Patch updated to fix issue whereby trying to copy Blue would fail due to using the color index as the conditional of whether or not to copy at all, and Blue's index being 0 (i.e. false in a boolean context).

MageKing17

2014-06-24 05:09

developer   ~0015910

Corrected a silly mistake with the Assertion() (was checking "> 0" instead of ">= 0"); also made the message slightly less confusing if it somehow gets triggered anyway.

MageKing17

2014-07-09 06:22

developer   ~0016040

New version of patch; you want to define your own color tags? Now you can. And now you can set the default recommendation color; bright blue anyone?

MageKing17

2014-07-12 02:59

developer   ~0016067

Okay, with the introduction of modular table support (with #freespace providing "*-clr.tbm" as the chosen suffix), I think this patch is now feature-complete and ready for code review.

MageKing17

2014-07-12 03:18

developer  

add_z-clr.tbm (47 bytes)

MageKing17

2014-07-12 03:18

developer  

MageKing17

2014-07-12 03:18

developer  

MageKing17

2014-07-12 03:30

developer  

colors.tbl (2,277 bytes)

MageKing17

2014-07-19 17:20

developer   ~0016096

Updated to correct a silly parsing bug that broke existing team color-defining .tbl files (instead of skipping "#Start Colors", parse_everything_else() was skipping "#Star Colors"; to quote Zacam in #scp, "Twinkle Twinkle motherfucker"), and to use required_string_any_of() instead of required_string_4() now that the former is in trunk.

MageKing17

2014-07-20 17:24

developer  

colors.patch (40,102 bytes)   
Index: code/fred2/management.cpp
===================================================================
--- code/fred2/management.cpp	(revision 10925)
+++ code/fred2/management.cpp	(working copy)
@@ -397,9 +397,7 @@
 
 	hud_init_comm_orders();		// Goober5000
 
-	if (!new_alpha_colors_init()) {
-		old_alpha_colors_init();
-	}
+	alpha_colors_init();
 	
 	gamesnd_parse_soundstbl();		// needs to be loaded after species stuff but before interface/weapon/ship stuff - taylor
 	mission_brief_common_init();	
Index: code/freespace2/freespace.cpp
===================================================================
--- code/freespace2/freespace.cpp	(revision 10925)
+++ code/freespace2/freespace.cpp	(working copy)
@@ -2001,9 +2001,7 @@
 
 	// initialize alpha colors
 	// CommanderDJ: try with colors.tbl first, then use the old way if that doesn't work
-	if (!new_alpha_colors_init()) {
-		old_alpha_colors_init();
-	}
+	alpha_colors_init();
 
 	obj_init();	
 	mflash_game_init();	
Index: code/globalincs/alphacolors.cpp
===================================================================
--- code/globalincs/alphacolors.cpp	(revision 10925)
+++ code/globalincs/alphacolors.cpp	(working copy)
@@ -15,10 +15,17 @@
 SCP_map<SCP_string, team_color> Team_Colors;
 SCP_vector<SCP_string> Team_Names;
 
+SCP_map<char, color> Tagged_Colors;
+SCP_vector<char> Color_Tags;
+
 // -----------------------------------------------------------------------------------
 // ALPHA DEFINES/VARS
 //
 
+color Color_text_normal, Color_text_subselected, Color_text_selected;
+color Color_text_error, Color_text_error_hi, Color_text_active, Color_text_active_hi;
+color Color_text_heading, Color_more_indicator, Color_more_bright, Color_bright, Color_normal;
+
 color Color_blue, Color_bright_blue, Color_green, Color_bright_green;
 color Color_black, Color_grey, Color_silver, Color_white, Color_bright_white;
 color Color_violet_gray, Color_violet, Color_pink, Color_light_pink;
@@ -26,6 +33,170 @@
 color Color_ui_light_green, Color_ui_green;
 color Color_ui_light_pink, Color_ui_pink;
 
+color Brief_color_red, Brief_color_green, Brief_color_legacy_neutral;
+
+char default_fiction_viewer_color = 'w';
+char default_command_briefing_color = 'w';
+char default_briefing_color = 'w';
+char default_redalert_briefing_color = 'w';
+char default_debriefing_color = 'w';
+char default_recommendation_color = 'r';
+char default_loop_briefing_color = 'w';
+
+color *COLOR_LIST[TOTAL_COLORS] = {
+	&Color_blue,
+	&Color_bright_blue,
+	&Color_green,
+	&Color_bright_green,
+	&Color_black,
+	&Color_grey,
+	&Color_silver,
+	&Color_white,
+	&Color_bright_white,
+	&Color_violet_gray,
+	&Color_violet,
+	&Color_dim_red,
+	&Color_red,
+	&Color_bright_red,
+	&Color_pink,
+	&Color_light_pink,
+	&Color_yellow,
+	&Color_bright_yellow,
+	&Color_ui_light_green,
+	&Color_ui_green,
+	&Color_ui_light_pink,
+	&Color_ui_pink,
+};
+
+const char *COLOR_NAMES[TOTAL_COLORS] = {
+	"Blue",
+	"Bright Blue",
+	"Green",
+	"Bright Green",
+	"Black",
+	"Grey",
+	"Silver",
+	"White",
+	"Bright White",
+	"Violet Gray",
+	"Violet",
+	"Dim Red",
+	"Red",
+	"Bright Red",
+	"Pink",
+	"Light Pink",
+	"Yellow",
+	"Bright Yellow",
+	"UI Light Green",
+	"UI Green",
+	"UI Light Pink",
+	"UI Pink"
+};
+
+const int rgba_defaults[TOTAL_COLORS][4] = {
+	{93, 93, 128, 255},
+	{185, 185, 255, 255},
+	{0, 120, 0, 255},
+	{50, 190, 50, 255},
+	{0, 0, 0, 255},
+	{65, 65, 65, 255},
+	{160, 160, 160, 255},
+	{105, 105, 105, 255},
+	{255, 255, 255 ,255},
+	{160, 144, 160, 255},
+	{192, 104, 192, 255},
+	{80, 6, 6, 255},
+	{126, 6, 6, 255},
+	{200, 0, 0, 255},
+	{185, 150, 150, 255},
+	{230, 190, 190, 255},
+	{255, 255, 122, 255},
+	{255, 255, 0, 255},
+	{161, 184, 161, 255},
+	{190, 228, 190, 255},
+	{184, 161, 161, 255},
+	{228, 190, 190, 255}
+};
+
+color *interface_colors[INTERFACE_COLORS] = {
+	&Color_text_normal,
+	&Color_text_subselected,
+	&Color_text_selected,
+	&Color_text_error,
+	&Color_text_error_hi,
+	&Color_text_active,
+	&Color_text_active_hi,
+	&Color_text_heading,
+	&Color_more_indicator,
+	&Color_more_bright,
+	&Color_bright,
+	&Color_normal,
+};
+
+const int interface_defaults[INTERFACE_COLORS] = {
+	7,	//"White"
+	0,	//"Blue"
+	1,	//"Bright Blue"
+	12,	//"Red"
+	13,	//"Bright Red"
+	8,	//"Bright White"
+	8,	//"Bright White"
+	9,	//"Violet Gray"
+	12,	//"Red"
+	13,	//"Bright Red"
+	1,	//"Bright Blue"
+	7,	//"White"
+};
+
+#define DEFAULT_TAGS	20
+
+const char DEFAULT_TAG_LIST[DEFAULT_TAGS] = {
+	'w',
+	'W',
+	'r',
+	'g',
+	'y',
+	'b',
+	'f',
+	'h',
+	'n',
+	'B',
+	'G',
+	'R',
+	'Y',
+	'k',
+	'e',
+	'E',
+	'v',
+	'V',
+	'p',
+	'P',
+};
+
+color* DEFAULT_TAG_COLORS[DEFAULT_TAGS] = {
+	&Color_white,
+	&Color_bright_white,
+	&Color_red,
+	&Color_green,
+	&Color_yellow,
+	&Color_blue,
+	&Brief_color_green,
+	&Brief_color_red,
+	&Brief_color_legacy_neutral,
+	&Color_bright_blue,
+	&Color_bright_green,
+	&Color_bright_red,
+	&Color_bright_yellow,
+	&Color_black,
+	&Color_grey,
+	&Color_silver,
+	&Color_violet_gray,
+	&Color_violet,
+	&Color_pink,
+	&Color_light_pink,
+};
+
+
 // netplayer colors
 color *Color_netplayer[NETPLAYER_COLORS] = {
 
@@ -52,6 +223,9 @@
 };
 
 
+void parse_colors(const char *filename);
+void parse_everything_else(const char *filename);	// needs a better name
+
 // -----------------------------------------------------------------------------------
 // ALPHA FUNCTIONS
 //
@@ -58,63 +232,60 @@
 
 /**
 * CommanderDJ: initialise alpha colors based on colors.tbl
-* \return 1 if successful, 0 if init fails for any reason
+* Made modular and given a wider range of features by MageKing17
 */
-int new_alpha_colors_init()
+void alpha_colors_init()
 {
-	int err_code;
-	if ((err_code = setjmp(parse_abort)) != 0)
-	{
-		mprintf(("Unable to parse 'colors.tbl'!  Error code = %d.\n", err_code));
-		return 0;
+	// Set our default colors.
+	int i;
+	for (i = 0; i < TOTAL_COLORS; i++) {
+		gr_init_alphacolor(COLOR_LIST[i], rgba_defaults[i][0], rgba_defaults[i][1], rgba_defaults[i][2], rgba_defaults[i][3]);
 	}
 
-	if (cf_exists_full("colors.tbl", CF_TYPE_TABLES))
-	{
-		read_file_text("colors.tbl", CF_TYPE_TABLES);
-		mprintf(("TABLES => Starting parse of 'colors.tbl'...\n"));
+	if (cf_exists_full("colors.tbl", CF_TYPE_TABLES)) {
+		mprintf(("TABLES => Starting parse of 'colors.tbl' (checking '#Start Colors' section only)...\n"));
+		parse_colors("colors.tbl");
 	}
-	else
-	{
-		//colors.tbl doesn't exist
-		mprintf(("TABLES => Unable to find 'colors.tbl'. Initialising colors with default values.\n"));
-		return 0;
+	parse_modular_table(NOX("*-clr.tbm"), parse_colors);
+
+	// Set defaults for interface colors and color tags (must be done after the above because they're generally just copies of above-defined colors).
+	for (i = 0; i < INTERFACE_COLORS; i++) {
+		memcpy(interface_colors[i], COLOR_LIST[interface_defaults[i]], sizeof(color));
 	}
 
+	for (i = 0; i < DEFAULT_TAGS; i++) {
+		Tagged_Colors[DEFAULT_TAG_LIST[i]] = *DEFAULT_TAG_COLORS[i];
+		Color_Tags.push_back(DEFAULT_TAG_LIST[i]);
+	}
+
+	if (cf_exists_full("colors.tbl", CF_TYPE_TABLES)) {
+		mprintf(("TABLES => Starting parse of 'colors.tbl' (skipping '#Start Colors' section)...\n"));
+		parse_everything_else("colors.tbl");
+	}
+	parse_modular_table(NOX("*-clr.tbm"), parse_everything_else);
+}
+
+void parse_colors(const char *filename)
+{
+	Assertion(filename != NULL, "parse_colors() called on NULL; get a coder!\n");
+	read_file_text(filename, CF_TYPE_TABLES);
+
+	int err_code;
+	if ((err_code = setjmp(parse_abort)) != 0) {
+		mprintf(("TABLES: Unable to parse '%s'!  Error code = %d.\n", filename, err_code));
+		return;
+	}
+
 	reset_parse();
 
 	// we search for the colors based on their order of definition above
 	// if the color isn't found, we just use default values
-	if (required_string("#Start Colors"))
+	if (optional_string("#Start Colors"))
 	{
 		// vars for holding rgba values
 		int rgba[4] = {0,0,0,0};
+		int i, j;
 
-		color *colors[TOTAL_COLORS] = {
-			&Color_blue,
-			&Color_bright_blue,
-			&Color_green,
-			&Color_bright_green,
-			&Color_black,
-			&Color_grey,
-			&Color_silver,
-			&Color_white,
-			&Color_bright_white,
-			&Color_violet_gray,
-			&Color_violet,
-			&Color_dim_red,
-			&Color_red,
-			&Color_bright_red,
-			&Color_pink,
-			&Color_light_pink,
-			&Color_yellow,
-			&Color_bright_yellow,
-			&Color_ui_light_green,
-			&Color_ui_green,
-			&Color_ui_light_pink,
-			&Color_ui_pink,
-		};
-
 		char* color_names[TOTAL_COLORS] = {
 			"$Blue:",
 			"$Bright Blue:",
@@ -140,72 +311,66 @@
 			"$UI Pink:"
 		};
 
-		int rgba_defaults[TOTAL_COLORS][4] = {
-			{93, 93, 128, 255},
-			{185, 185, 255, 255},
-			{0, 120, 0, 255},
-			{50, 190, 50, 255},
-			{0, 0, 0, 255},
-			{65, 65, 65, 255},
-			{160, 160, 160, 255},
-			{105, 105, 105, 255},
-			{255, 255, 255 ,255},
-			{160, 144, 160, 255},
-			{192, 104, 192, 255},
-			{80, 6, 6, 255},
-			{126, 6, 6, 255},
-			{200, 0, 0, 255},
-			{185, 150, 150, 255},
-			{230, 190, 190, 255},
-			{255, 255, 122, 255},
-			{255, 255, 0, 255},
-			{161, 184, 161, 255},
-			{190, 228, 190, 255},
-			{184, 161, 161, 255},
-            {228, 190, 190, 255}
-		};
-
 		// now for each color, check if it's corresponding string is there
-		for (int i=0; i<TOTAL_COLORS; i++)
-		{
-			if (optional_string(color_names[i]))
-			{
+		for (i = 0; i < TOTAL_COLORS; i++) {
+			if (optional_string(color_names[i])) {
 				// if so, get its rgba values and initialise it using them
 				mprintf(("'%s' has been redefined.\n", color_names[i]));
-				stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
-				for (int j=0; j<4; j++)
-				{
-					if (rgba[j] < 0)
-					{
-						Warning(LOCATION, "RGBA value for '%s' in colors.tbl too low (%d), capping to 0.", color_names[i], rgba[j]);
-						rgba[j] = 0;
+				//if (check_for_string("(")) {
+					stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
+					for (j = 0; j < 4; j++) {
+						if (rgba[j] < 0) {
+							Warning(LOCATION, "RGBA value for '%s' in %s too low (%d), capping to 0.\n", color_names[i], filename, rgba[j]);
+							rgba[j] = 0;
+						} else if (rgba[j] > 255) {
+							Warning(LOCATION, "RGBA value for '%s' in %s too high (%d), capping to 255.\n", color_names[i], filename, rgba[j]);
+							rgba[j] = 255;
+						}
 					}
-					else if (rgba[j] > 255)
-					{
-						Warning(LOCATION, "RGBA value for '%s' in colors.tbl too high (%d), capping to 255.", color_names[i], rgba[j]);
-						rgba[j] = 255;
-					}
-				}
-				gr_init_alphacolor(colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
+				//} else {
+				//	stuff_hex_list(rgba, 4);
+				//}
+				gr_init_alphacolor(COLOR_LIST[i], rgba[0], rgba[1], rgba[2], rgba[3]);
 			}
-			// otherwise use its defaults
-			else
-				gr_init_alphacolor(colors[i], rgba_defaults[i][0], rgba_defaults[i][1], rgba_defaults[i][2], rgba_defaults[i][3]);
 		}
 		required_string("#End");
 	}
+}
 
+void parse_everything_else(const char *filename)
+{
+	Assertion(filename != NULL, "parse_everything_else() called on NULL; get a coder!\n");
+	read_file_text(filename, CF_TYPE_TABLES);
+
+	int err_code;
+	if ((err_code = setjmp(parse_abort)) != 0) {
+		mprintf(("TABLES: Unable to parse '%s'!  Error code = %d.\n", filename, err_code));
+		return;
+	}
+
+	reset_parse();
+
+	int rgba[4] = {0,0,0,0};
+
+	// reusable temp vars
+	int i, j;
+	SCP_string temp;
+
+	if (optional_string("#Start Colors")) {
+		// Skip this section; we already parsed it in every file.
+		skip_to_string("#End", NULL);
+	}
+
 	//Team coloring
 	if (optional_string("#Team Colors")) {
 
 		while (required_string_either("#End", "$Team Name:")) {
 			required_string("$Team Name:"); // required to move the parse pointer forward
-			char temp[NAME_LENGTH];
-			SCP_string temp2;
 			team_color temp_color;
 
-			stuff_string(temp, F_NAME, NAME_LENGTH);
-			temp2 = SCP_string(temp);
+			char temp2[NAME_LENGTH];
+			stuff_string(temp2, F_NAME, NAME_LENGTH);
+			temp = temp2;
 
 			if (required_string("$Team Stripe Color:")) {
 				int rgb[3];
@@ -231,46 +396,218 @@
 				temp_color.base.b = rgb[2] / 255.0f;
 			}
 
-			Team_Colors[temp2] = temp_color;
-			Team_Names.push_back(temp2);
+			Team_Colors[temp] = temp_color;
+			Team_Names.push_back(temp);
 		}
+		required_string("#End");
 	}
 
-	return 1;
-}
+	// Previously-hardcoded interface colors
+	if (optional_string("#Interface Colors")) {
+		char *color_names[INTERFACE_COLORS] = {
+			"$Text Normal:",
+			"$Text Subselected:",
+			"$Text Selected:",
+			"$Text Error:",
+			"$Text Error Highlighted:",
+			"$Text Active:",
+			"$Text Active Highlighted:",
+			"$Text Heading:",
+			"$More Indicator:",
+			"$Bright More Indicator:",
+			"$Bright:",
+			"$Normal:",
+		};
 
-// initialize all alpha colors (call at startup)
-void old_alpha_colors_init()
-{
-	// See the variable declarations above for color usage
-	gr_init_alphacolor( &Color_blue, 93, 93, 128, 255 );
-	gr_init_alphacolor( &Color_bright_blue, 185, 185, 255, 255 );
+		// now for each color, check if its corresponding string is there
+		for (i = 0; i < INTERFACE_COLORS; i++) {
+			if (optional_string(color_names[i])) {
+				// if so, get its rgba values and initialise it using them
+				mprintf(("'%s' has been redefined.\n", color_names[i]));
+				if ( check_for_string("(") ) {
+					// If we have a list of integers, use them.
+					stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
+					for (j = 0; j < 4; j++) {
+						if (rgba[j] < 0)
+						{
+							Warning(LOCATION, "RGBA value for '%s' in %s too low (%d), capping to 0.\n", color_names[i], filename, rgba[j]);
+							rgba[j] = 0;
+						}
+						else if (rgba[j] > 255)
+						{
+							Warning(LOCATION, "RGBA value for '%s' in %s too high (%d), capping to 255.\n", color_names[i], filename, rgba[j]);
+							rgba[j] = 255;
+						}
+					}
+					gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
+				//} else if (check_for_string("#")) {
+				//	stuff_hex_list(rgba, 4);
+				//	gr_init_alphacolor(interface_colors[i], rgba[0], rgba[1], rgba[2], rgba[3]);
+				} else {
+					// We have a string; it should be the name of a color to use.
+					stuff_string(temp, F_NAME);
+					for (j = 0; j < TOTAL_COLORS; j++) {
+						if ( !temp.compare(COLOR_NAMES[j]) ) {
+							break;
+						}
+					}
+					if ( j == TOTAL_COLORS ) {
+						Warning(LOCATION, "Unknown color '%s' in %s, for definition of '%s'; using default ('%s').\n", temp.c_str(), filename, color_names[i], COLOR_NAMES[interface_defaults[i]]);
+					} else {
+						Assertion(j >= 0 && j < TOTAL_COLORS, "Attempting to copy nonexistant color (%d out of 0-%d)!\n", j, TOTAL_COLORS-1);
+						memcpy(interface_colors[i], COLOR_LIST[j], sizeof(color));
+					}
+				}
+			}
+		}
+		required_string("#End");
+	}
 
-	gr_init_alphacolor( &Color_green, 0, 120, 0, 255 );
-	gr_init_alphacolor( &Color_bright_green, 50, 190, 50, 255 );
+	// Text color tags; for briefings, command briefings, debriefings, and the fiction viewer
+	if (optional_string("#Color Tags")) {
+		while (required_string_either("$Tag:", "#End") < 1) {
+			required_string("$Tag:");
+			color temp_color;
+			char tag;
 
-	gr_init_alphacolor( &Color_black, 0, 0, 0, 255 );
-	gr_init_alphacolor( &Color_grey, 65, 65, 65, 255 );
-	gr_init_alphacolor( &Color_silver, 160, 160, 160, 255 );
-	gr_init_alphacolor( &Color_white, 105, 105, 105, 255 );
-	gr_init_alphacolor( &Color_bright_white, 255, 255, 255, 255 );
+			stuff_string(temp, F_RAW);
+			if (temp[0] == '$') {
+				if (temp[1] == '\0') {
+					Error(LOCATION, "%s - found a '$Tag:' entry with a solitary '$'.\n", filename);
+				}
+				tag = temp[1];
+				if (temp[2] != '\0') {
+					Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
+				}
+			} else if (temp[0] == '\0') {
+				Error(LOCATION, "%s - found a '$Tag:' entry with no tag.\n", filename);
+			} else {
+				tag = temp[0];
+				if (temp[1] != '\0') {
+					Warning(LOCATION, "%s - tag '$%c' has extra text in its definition.\n", filename, tag);
+				}
+			}
 
-	gr_init_alphacolor( &Color_violet_gray, 160, 144, 160, 255 );
-	gr_init_alphacolor( &Color_violet, 192, 104, 192, 255 );
+			if (Tagged_Colors.find(tag) == Tagged_Colors.end()) {	// Only push the tag to our list of tags if it's actually new, not just a redefinition.
+				Color_Tags.push_back(tag);
+			}
 
-	gr_init_alphacolor( &Color_dim_red, 80, 6, 6, 255 );
-	gr_init_alphacolor( &Color_red, 126, 6, 6, 255 );
-	gr_init_alphacolor( &Color_bright_red, 200, 0, 0, 255 );
+			switch(required_string_one_of(4, "+Color:", "+Friendly", "+Hostile", "+Neutral")) {
+			case 0:	// +Color
+				required_string("+Color:");
 
-	gr_init_alphacolor( &Color_pink, 185, 150, 150, 255 );
-	gr_init_alphacolor( &Color_light_pink, 230, 190, 190, 255 );
+				rgba[0] = rgba[1] = rgba[2] = 0;
+				rgba[3] = 255;	// Odds are pretty high you want it to have full alpha...
 
-	gr_init_alphacolor( &Color_yellow, 255, 255, 122, 255 );
-	gr_init_alphacolor( &Color_bright_yellow, 255, 255, 0, 255 );
+				if ( check_for_string("(") ) {
+					stuff_int_list(rgba, 4, RAW_INTEGER_TYPE);
+					for (j = 0; j < 4; j++) {
+						if (rgba[j] < 0)
+						{
+							Warning(LOCATION, "RGBA value for '$%c' in %s too low (%d), capping to 0.\n", tag, filename, rgba[j]);
+							rgba[j] = 0;
+						}
+						else if (rgba[j] > 255)
+						{
+							Warning(LOCATION, "RGBA value for '$%c' in %s too high (%d), capping to 255.\n", tag, filename, rgba[j]);
+							rgba[j] = 255;
+						}
+					}
+					gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
+					Tagged_Colors[tag] = temp_color;
+				//} else if ( check_for_string ("#") ) {
+				//	stuff_hex_list(rgba, 4);
+				//	gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
+				//	Tagged_Colors[tag] = temp_color;
+				} else {
+					// We have a string; it should be the name of a color to use.
+					stuff_string(temp, F_NAME);
+					for (j = 0; j < TOTAL_COLORS; j++) {
+						if ( !temp.compare(COLOR_NAMES[j]) ) {
+							break;
+						}
+					}
+					if ( j == TOTAL_COLORS ) {
+						Error(LOCATION, "Unknown color '%s' in %s, for definition of tag '$%c'.\n", temp.c_str(), filename, tag);
+					}
+					Tagged_Colors[tag] = *COLOR_LIST[j];
+				}
+				break;
+			case 1:	// +Friendly
+				required_string("+Friendly");
+				Tagged_Colors[tag] = Brief_color_green;
+				break;
+			case 2:	// +Hostile
+				required_string("+Hostile");
+				Tagged_Colors[tag] = Brief_color_red;
+				break;
+			case 3:	// +Neutral
+				required_string("+Neutral");
+				Tagged_Colors[tag] = Brief_color_legacy_neutral;
+				break;
+			case -1:
+				// -noparseerrors is set
+				if (Tagged_Colors.find(tag) == Tagged_Colors.end()) {	// It was a new color, but since we haven't actually defined it...
+					Color_Tags.pop_back();
+				}
+				break;
+			default:
+				Assertion(false, "MageKing17 made a coding error somewhere, and you should laugh at him (and report this error).\n");
+				break;
+			}
+		}
 
-	gr_init_alphacolor( &Color_ui_light_green, 161, 184, 161, 255 );
-	gr_init_alphacolor( &Color_ui_green, 190, 228, 190, 255 );
+		required_string("#End");
+	}
+	Assertion(Color_Tags.size() == Tagged_Colors.size(), "Color_Tags and Tagged_Colors size mismatch; get a coder!\n");
 
-	gr_init_alphacolor( &Color_ui_light_pink, 184, 161, 161, 255 );
-	gr_init_alphacolor( &Color_ui_pink, 228, 190, 190, 255 );
-}
+	if (optional_string("#Default Text Colors")) {
+
+		char* color_names[MAX_DEFAULT_TEXT_COLORS] = {
+			"$Fiction Viewer:",
+			"$Command Briefing:",
+			"$Briefing:",
+			"$Redalert Briefing:",
+			"$Debriefing:",
+			"$Recommendation:",
+			"$Loop Briefing:",
+		};
+
+		char *color_value[MAX_DEFAULT_TEXT_COLORS] = {
+			&default_fiction_viewer_color,
+			&default_command_briefing_color,
+			&default_briefing_color,
+			&default_redalert_briefing_color,
+			&default_debriefing_color,
+			&default_recommendation_color,
+			&default_loop_briefing_color,
+		};
+
+		for (i = 0; i < MAX_DEFAULT_TEXT_COLORS; i++) {
+			if ( optional_string(color_names[i]) ) {
+				stuff_string(temp, F_RAW);
+				if (temp[0] == '$') {
+					if (temp[1] == '\0') {
+						Error(LOCATION, "%s - default text color '%s' entry with a solitary '$'.\n", filename, color_names[i]);
+					}
+					*color_value[i] = temp[1];
+					if (temp[2] != '\0') {
+						Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
+					}
+				} else if (temp[0] == '\0') {
+					Error(LOCATION, "%s - default text color '%s' entry with no tag.\n", filename, color_names[i]);
+				} else {
+					*color_value[i] = temp[0];
+					if (temp[1] != '\0') {
+						Warning(LOCATION, "%s - default text color '%s' has extra text after the tag '$%c'.\n", filename, color_names[i], *color_value[i]);
+					}
+				}
+				if (Tagged_Colors.find(*color_value[i]) == Tagged_Colors.end()) {
+					// Just mprintf() this information instead of complaining with a Warning(); the tag might be defined in a later-loading TBM, and if it isn't, nothing too terrible will happen.
+					mprintf(("%s - default text color '%s' set to non-existant tag '$%c'.\n", filename, color_names[i], *color_value[i]));
+				}
+			}
+		}
+		required_string("#End");
+	}
+}
\ No newline at end of file
Index: code/globalincs/alphacolors.h
===================================================================
--- code/globalincs/alphacolors.h	(revision 10925)
+++ code/globalincs/alphacolors.h	(working copy)
@@ -21,28 +21,11 @@
 // Colors for UI
 // See FreeSpace.cpp for usage
 
-// The following colors are for text drawing:
-// normal text
-#define Color_text_normal		Color_white
-// text highlighted while down still down on a line
-#define Color_text_subselected	Color_blue
-// text highlighted as the selected line
-#define Color_text_selected		Color_bright_blue
-// text that indicates an error
-#define Color_text_error		Color_red
-// text that indicates an error, and line is selected or subselected
-#define Color_text_error_hi		Color_bright_red
-// text that indicates line is active item
-#define Color_text_active		Color_bright_white
-// text that indicates line is active item, and line is selected or subselected
-#define Color_text_active_hi	Color_bright_white
-// text drawn as a heading for a section or title, etc
-#define Color_text_heading		Color_violet_gray
-// color of the "more" indicator in briefings/command briefings/debrefings
-#define Color_more_indicator	Color_red
+#define INTERFACE_COLORS 12
+extern color Color_text_normal, Color_text_subselected, Color_text_selected;
+extern color Color_text_error, Color_text_error_hi, Color_text_active, Color_text_active_hi;
+extern color Color_text_heading, Color_more_indicator, Color_more_bright, Color_bright, Color_normal;
 
-#define Color_bright Color_bright_blue
-#define Color_normal Color_white
 #define TOTAL_COLORS 22
 extern color Color_blue, Color_bright_blue, Color_green, Color_bright_green;
 extern color Color_black, Color_grey, Color_silver, Color_white, Color_bright_white;
@@ -52,6 +35,9 @@
 extern color Color_ui_light_green, Color_ui_green;
 extern color Color_ui_light_pink, Color_ui_pink;
 
+// briefing hostile/friendly/neutral colors
+extern color Brief_color_red, Brief_color_green, Brief_color_legacy_neutral;
+
 // netplayer colors
 #define NETPLAYER_COLORS 20
 extern color *Color_netplayer[NETPLAYER_COLORS];
@@ -60,14 +46,23 @@
 extern SCP_map<SCP_string, team_color> Team_Colors;
 extern SCP_vector<SCP_string> Team_Names;
 
+extern SCP_map<char, color> Tagged_Colors;
+extern SCP_vector<char> Color_Tags;
+
+#define MAX_DEFAULT_TEXT_COLORS	7
+extern char default_fiction_viewer_color;
+extern char default_command_briefing_color;
+extern char default_briefing_color;
+extern char default_redalert_briefing_color;
+extern char default_debriefing_color;
+extern char default_recommendation_color;
+extern char default_loop_briefing_color;
+
 // -----------------------------------------------------------------------------------
 // ALPHA FUNCTIONS
 //
 
 //initialize alpha colors based on colors.tbl
-int new_alpha_colors_init();
+void alpha_colors_init();
 
-//initialize alpha colors based on hardcoded values
-void old_alpha_colors_init();
-
 #endif
Index: code/mission/missionbriefcommon.cpp
===================================================================
--- code/mission/missionbriefcommon.cpp	(revision 10925)
+++ code/mission/missionbriefcommon.cpp	(working copy)
@@ -117,6 +117,8 @@
 #define LOOKAT_DIST	500.0f
 #define STAGE_ADVANCE_DELAY	1000		// time in ms to wait after voice stops before advancing stage
 
+extern const float		BRIEF_TEXT_WIPE_TIME	= 1.5f;		// time in seconds for wipe to occur
+
 // --------------------------------------------------------------------------------------
 // Game-wide global data
 // --------------------------------------------------------------------------------------
@@ -181,7 +183,7 @@
 typedef struct colored_char
 {
 	char	letter;
-	ubyte	color;		// index into Brief_text_colors[]
+	char	color;		// tag to look up in Tagged_Colors
 } colored_char;
 
 typedef SCP_vector<colored_char> briefing_line; 
@@ -188,32 +190,6 @@
 typedef SCP_vector<briefing_line> briefing_stream; 
 static briefing_stream Colored_stream[MAX_TEXT_STREAMS];
 
-color Brief_color_red, Brief_color_green, Brief_color_legacy_neutral;
-
-color *Brief_text_colors[MAX_BRIEF_TEXT_COLORS] = 
-{
-	&Color_white,
-	&Color_bright_white,
-	&Color_red,
-	&Color_green,
-	&Color_yellow,
-	&Color_blue,
-	&Brief_color_green,
-	&Brief_color_red,
-	&Brief_color_legacy_neutral,
-	&Color_bright_blue,
-	&Color_bright_green,
-	&Color_bright_red,
-	&Color_bright_yellow,
-	&Color_black,
-	&Color_grey,
-	&Color_silver,
-	&Color_violet_gray,
-	&Color_violet,
-	&Color_pink,
-	&Color_light_pink,
-};
-
 #define BRIGHTEN_LEAD	2
 
 float Brief_text_wipe_time_elapsed;
@@ -288,7 +264,7 @@
 void	brief_render_grid(grid *gridp);
 void	brief_modify_grid(grid *gridp);
 void	brief_rpd_line(vec3d *v0, vec3d *v1);
-void	brief_set_text_color(int color_index);
+void	brief_set_text_color(char color_tag);
 extern void get_camera_limits(matrix *start_camera, matrix *end_camera, float time, vec3d *acc_max, vec3d *w_max);
 int brief_text_wipe_finished();
 
@@ -1216,7 +1192,7 @@
 	// The following algorithm builds a character sequence of color 'last_color' into 'line' buffer.
 	// When the color changes, the buffer is drawn and reset.
 	{
-		int last_color = src->at(0).color;    
+		char last_color = src->at(0).color;
 		for (int current_pos=0; current_pos<truncate_len; current_pos++) {
 			colored_char &current_char=src->at(current_pos);		
 			//when the current color changes, the accumulated character sequence is drawn.
@@ -1428,81 +1404,18 @@
 }
 
 
-ubyte brief_return_color_index(char c)
+bool brief_verify_color_tag(char color_tag)
 {
-	switch (c) {
-		case 'f':
-			return BRIEF_TEXT_FRIENDLY;
-
-		case 'h':
-			return BRIEF_TEXT_HOSTILE;
-
-		case 'n':
-			return BRIEF_TEXT_NEUTRAL;
-
-		case 'r':
-			return BRIEF_TEXT_RED;
-
-		case 'g':
-			return BRIEF_TEXT_GREEN;
-
-		case 'b':
-			return BRIEF_TEXT_BLUE;
-
-//The following added by Zacam for expanded BRIEF colors
- 		case 'w':
- 			return BRIEF_TEXT_WHITE;
-
- 		case 'y':
- 			return BRIEF_TEXT_YELLOW;
-
-		case 'W':
-			return BRIEF_TEXT_BRIGHT_WHITE;
-
-		case 'B':
-			return BRIEF_TEXT_BRIGHT_BLUE;
-
-		case 'G':
-			return BRIEF_TEXT_BRIGHT_GREEN;
-
-		case 'R':
-			return BRIEF_TEXT_BRIGHT_RED;
-
-		case 'Y':
-			return BRIEF_TEXT_BRIGHT_YELLOW;
-
-		case 'k':
-			return BRIEF_TEXT_BLACK;
-
-		case 'e':
-			return BRIEF_TEXT_GREY;
-
-		case 'E':
-			return BRIEF_TEXT_SILVER;
-
-		case 'v':
-			return BRIEF_TEXT_VIOLET_GRAY;
-
-		case 'V':
-			return BRIEF_TEXT_VIOLET;
-
-		case 'p':
-			return BRIEF_TEXT_PINK;
-
-		case 'P':
-			return BRIEF_TEXT_LIGHT_PINK;
-
-		default:	//Zacam: Changed fron an Int3() in order to provide better feedback while still allowing play.
-			Warning(LOCATION, "Unrecognized or undefined case character: '$%c' used in Briefing in mission: '%s'. Tell Zacam.", c, Mission_filename);
-	} // end switch
-
-	return BRIEF_TEXT_WHITE;
+	if ( Tagged_Colors.find(color_tag) == Tagged_Colors.end() ) {
+		Warning(LOCATION, "Invalid text color tag '$%c' used in mission: '%s'.\n", color_tag, Mission_filename);
+		return false;
+	}
+	return true;
 }
 
-void brief_set_text_color(int color_index)
+void brief_set_text_color(char color_tag)
 {
-	Assert(color_index < MAX_BRIEF_TEXT_COLORS);
-	gr_set_color_fast(Brief_text_colors[color_index]);
+	gr_set_color_fast(&Tagged_Colors[color_tag]);
 }
 
 /**
@@ -1529,13 +1442,13 @@
  * @param[in,out] color_stack_index pointer to the current index in the above stack
  * @return number of character of the resulting sequence.
  */
-int brief_text_colorize(char *src, int instance, ubyte default_color_stack[], int &color_stack_index)
+int brief_text_colorize(char *src, int instance, char default_color_stack[], int &color_stack_index)
 {
 	Assert(src);
 	Assert((0 <= instance) && (instance < (int)(sizeof(Colored_stream) / sizeof(*Colored_stream))));
 
 	briefing_line dest_line;	//the resulting vector of colored character
-	ubyte active_color_index;	//the current drawing color
+	char active_color_index;	//the current drawing color
 
 	active_color_index = default_color_stack[color_stack_index];
 
@@ -1567,7 +1480,7 @@
 			// normal $c or $c{
 			else
 			{
-				active_color_index = brief_return_color_index(src[i]);
+				if (brief_verify_color_tag(src[i])) active_color_index = src[i];
 				i++; // Consume the color identifier and focus on the white character (if any)
 
 				// special case: color spans (different default color within braces)
@@ -1612,12 +1525,12 @@
  *
  * @param src paragraph of text to process
  * @param w	max width of line in pixels
+ * @param[in] default_color optional, default color for this text (defaults to '\0', which gets converted to the first defined color tag (should be 'w'))
  * @param instance optional parameter, used when multiple text streams are required (default value is 0)
  * @param max_lines maximum number of lines
- * @param[in] default_color default color for this text (defaults to BRIEF_TEXT_WHITE)
  * @param[in] append add on to the existing lines instead of replacing them (defaults to false)
  */
-int brief_color_text_init(const char* src, int w, int instance, int max_lines, const ubyte default_color, const bool append)
+int brief_color_text_init(const char* src, int w, const char default_color, int instance, int max_lines, const bool append)
 {
 	int i, n_lines, len;
 	SCP_vector<int> n_chars;
@@ -1625,11 +1538,15 @@
 	char brief_line[MAX_BRIEF_LINE_LEN];
 
 	// manage different default colors (don't use a SCP_ stack because eh)
-	ubyte default_color_stack[HIGHEST_COLOR_STACK_INDEX + 1];
+	char default_color_stack[HIGHEST_COLOR_STACK_INDEX + 1];
 	int color_stack_index = 0;
 
 	// start off with white, or whatever our default is
-	default_color_stack[0] = default_color;
+	if (default_color == '\0' || !brief_verify_color_tag(default_color)) {	// call brief_verify_color_tag() to make sure our default is actually a defined color tag
+		default_color_stack[0] = Color_Tags[0];
+	} else {
+		default_color_stack[0] = default_color;
+	}
 
 	Assert(src != NULL);
 	n_lines = split_str(src, w, n_chars, p_str, BRIEF_META_CHAR);
@@ -1845,10 +1762,10 @@
 
 	if (gr_screen.res == GR_640) {
 		// GR_640
-		Num_brief_text_lines[0] = brief_color_text_init(msg, MAX_BRIEF_LINE_W_640);
+		Num_brief_text_lines[0] = brief_color_text_init(msg, MAX_BRIEF_LINE_W_640, default_briefing_color);
 	} else {
 		// GR_1024
-		Num_brief_text_lines[0] = brief_color_text_init(msg, MAX_BRIEF_LINE_W_1024);		
+		Num_brief_text_lines[0] = brief_color_text_init(msg, MAX_BRIEF_LINE_W_1024, default_briefing_color);
 	}
 
 	Top_brief_text_line = 0;
Index: code/mission/missionbriefcommon.h
===================================================================
--- code/mission/missionbriefcommon.h	(revision 10925)
+++ code/mission/missionbriefcommon.h	(working copy)
@@ -74,36 +74,9 @@
 
 
 
-// Moving briefing color definitions out of missionbriefcommon.cpp so they can be referenced elsewhere -MageKing17
+// Moving out of missionbriefcommon.cpp so it can be referenced elsewhere -MageKing17
+extern const float		BRIEF_TEXT_WIPE_TIME;		// time in seconds for wipe to occur
 
-enum
-{
-	BRIEF_TEXT_WHITE = 0,
-	BRIEF_TEXT_BRIGHT_WHITE,
-	BRIEF_TEXT_RED,
-	BRIEF_TEXT_GREEN,
-	BRIEF_TEXT_YELLOW,
-	BRIEF_TEXT_BLUE,
-	BRIEF_TEXT_FRIENDLY,
-	BRIEF_TEXT_HOSTILE,
-	BRIEF_TEXT_NEUTRAL,
-	BRIEF_TEXT_BRIGHT_BLUE,
-	BRIEF_TEXT_BRIGHT_GREEN,
-	BRIEF_TEXT_BRIGHT_RED,
-	BRIEF_TEXT_BRIGHT_YELLOW,
-	BRIEF_TEXT_BLACK,
-	BRIEF_TEXT_GREY,
-	BRIEF_TEXT_SILVER,
-	BRIEF_TEXT_VIOLET_GRAY,
-	BRIEF_TEXT_VIOLET,
-	BRIEF_TEXT_PINK,
-	BRIEF_TEXT_LIGHT_PINK,
-	MAX_BRIEF_TEXT_COLORS
-};
-
-// And the same here
-const float		BRIEF_TEXT_WIPE_TIME	= 1.5f;		// time in seconds for wipe to occur
-
 // ------------------------------------------------------------------------
 // Structures to hold briefing data
 // ------------------------------------------------------------------------
@@ -335,7 +308,7 @@
 void brief_voice_unpause(int stage_num);
 
 // fancy briefing style text functions for use in other modules.
-int brief_color_text_init(const char *src, int w, int instance = 0, int max_lines = MAX_BRIEF_LINES, const ubyte default_color = BRIEF_TEXT_WHITE, const bool append = false);
+int brief_color_text_init(const char *src, int w, const char default_color = '\0', int instance = 0, int max_lines = MAX_BRIEF_LINES, const bool append = false);
 int brief_render_text(int line_offset, int x, int y, int h, float frametime, int instance = 0, int line_spacing = 0);
 
 void cmd_brief_reset();
Index: code/missionui/fictionviewer.cpp
===================================================================
--- code/missionui/fictionviewer.cpp	(revision 10925)
+++ code/missionui/fictionviewer.cpp	(working copy)
@@ -320,7 +320,7 @@
 	Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][FVW_BUTTON_SCROLL_DOWN].button.set_hotkey(KEY_DOWN);
 
 	// init brief text
-	brief_color_text_init(Fiction_viewer_text, Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][2], 0, 0);
+	brief_color_text_init(Fiction_viewer_text, Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][2], default_fiction_viewer_color, 0, 0);
 
 	// if the story is going to overflow the screen, add a slider
 	if (Num_brief_text_lines[0] > Fiction_viewer_text_max_lines)
Index: code/missionui/missioncmdbrief.cpp
===================================================================
--- code/missionui/missioncmdbrief.cpp	(revision 10925)
+++ code/missionui/missioncmdbrief.cpp	(working copy)
@@ -351,7 +351,7 @@
 	}
 
 	Cur_stage = stage;
-	brief_color_text_init(Cur_cmd_brief->stage[stage].text.c_str(), Cmd_text_wnd_coords[Uses_scroll_buttons][gr_screen.res][CMD_W_COORD]);
+	brief_color_text_init(Cur_cmd_brief->stage[stage].text.c_str(), Cmd_text_wnd_coords[Uses_scroll_buttons][gr_screen.res][CMD_W_COORD], default_command_briefing_color);
 
 	// load a new animation if it's different to what's already playing
 	if (strcmp(Cur_anim_filename, Cur_cmd_brief->stage[stage].ani_filename) != 0) {
Index: code/missionui/missiondebrief.cpp
===================================================================
--- code/missionui/missiondebrief.cpp	(revision 10925)
+++ code/missionui/missiondebrief.cpp	(working copy)
@@ -1831,7 +1831,7 @@
 		}
 	}
 
-	Num_text_lines = Text_offset = brief_color_text_init("", Debrief_text_wnd_coords[gr_screen.res][2], 0, 0);	// Initialize color stuff -MageKing17
+	Num_text_lines = Text_offset = brief_color_text_init("", Debrief_text_wnd_coords[gr_screen.res][2], default_debriefing_color, 0, 0);	// Initialize color stuff -MageKing17
 
 	fsspeech_start_buffer();
 
@@ -1839,12 +1839,12 @@
 		for (i=0; i<Num_debrief_stages; i++) {
 			if (i)
 				// add a blank line between stages
-				Num_text_lines += brief_color_text_init("\n", Debrief_text_wnd_coords[gr_screen.res][2], 0, MAX_DEBRIEF_LINES, BRIEF_TEXT_WHITE, true);
+				Num_text_lines += brief_color_text_init("\n", Debrief_text_wnd_coords[gr_screen.res][2], default_debriefing_color, 0, MAX_DEBRIEF_LINES, true);
 
 			src = Debrief_stages[i]->text.c_str();
 
 			if (*src) {
-				Num_text_lines += brief_color_text_init(src, Debrief_text_wnd_coords[gr_screen.res][2], 0, MAX_DEBRIEF_LINES, BRIEF_TEXT_WHITE, true);
+				Num_text_lines += brief_color_text_init(src, Debrief_text_wnd_coords[gr_screen.res][2], default_debriefing_color, 0, MAX_DEBRIEF_LINES, true);
 
 				if (use_sim_speech && !Recommend_active) {
 					fsspeech_stuff_buffer(src);
@@ -1859,9 +1859,9 @@
 					src = XSTR( "We have no recommendations for you.", 1054);
 
 				if (*src) {
-					Num_text_lines += brief_color_text_init("\n", Debrief_text_wnd_coords[gr_screen.res][2], 0, MAX_DEBRIEF_LINES, BRIEF_TEXT_RED, true);
+					Num_text_lines += brief_color_text_init("\n", Debrief_text_wnd_coords[gr_screen.res][2], default_recommendation_color, 0, MAX_DEBRIEF_LINES, true);
 
-					Num_text_lines += brief_color_text_init(src, Debrief_text_wnd_coords[gr_screen.res][2], 0, MAX_DEBRIEF_LINES, BRIEF_TEXT_RED, true);
+					Num_text_lines += brief_color_text_init(src, Debrief_text_wnd_coords[gr_screen.res][2], default_recommendation_color, 0, MAX_DEBRIEF_LINES, true);
 					r_count++;
 
 					if (use_sim_speech) {
Index: code/missionui/missionloopbrief.cpp
===================================================================
--- code/missionui/missionloopbrief.cpp	(revision 10925)
+++ code/missionui/missionloopbrief.cpp	(working copy)
@@ -25,7 +25,9 @@
 
 #include "graphics/generic.h"
 
+extern char default_loop_briefing_color;	// Doesn't seem worth including alphacolors.h for -MageKing17
 
+
 // ---------------------------------------------------------------------------------------------------------------------------------------
 // MISSION LOOP BRIEF DEFINES/VARS
 //
@@ -169,7 +171,7 @@
 
 	// init brief text
 	if(Campaign.missions[Campaign.current_mission].mission_branch_desc != NULL){
-		brief_color_text_init(Campaign.missions[Campaign.current_mission].mission_branch_desc, Loop_brief_text_coords[gr_screen.res][2]);
+		brief_color_text_init(Campaign.missions[Campaign.current_mission].mission_branch_desc, Loop_brief_text_coords[gr_screen.res][2], default_loop_briefing_color);
 	}
 
 	bool sound_played = false;
Index: code/missionui/redalert.cpp
===================================================================
--- code/missionui/redalert.cpp	(revision 10925)
+++ code/missionui/redalert.cpp	(working copy)
@@ -337,7 +337,7 @@
 	}
 
 	if ( Briefing->num_stages > 0 ) {
-		brief_color_text_init(Briefing->stages[0].text.c_str(), Ra_brief_text_wnd_coords[gr_screen.res][RA_W_COORD], 0);
+		brief_color_text_init(Briefing->stages[0].text.c_str(), Ra_brief_text_wnd_coords[gr_screen.res][RA_W_COORD], default_redalert_briefing_color, 0);
 	}
 
 	red_alert_voice_load();
Index: code/network/multiui.cpp
===================================================================
--- code/network/multiui.cpp	(revision 10925)
+++ code/network/multiui.cpp	(working copy)
@@ -222,7 +222,7 @@
 	}
 
 	if ( (Multi_common_num_text_lines - Multi_common_top_text_line) > Multi_common_text_max_display[gr_screen.res] ) {
-		gr_set_color_fast(&Color_bright_red);
+		gr_set_color_fast(&Color_more_bright);
 		gr_string(Multi_common_text_coords[gr_screen.res][0], (Multi_common_text_coords[gr_screen.res][1] + Multi_common_text_coords[gr_screen.res][3])-5, XSTR("more",755), GR_RESIZE_MENU);
 	}
 }
Index: code/popup/popup.cpp
===================================================================
--- code/popup/popup.cpp	(revision 10925)
+++ code/popup/popup.cpp	(working copy)
@@ -731,7 +731,7 @@
 	// maybe draw "more"
 	h = 10;
 	if(i < pi->nlines){
-		gr_set_color_fast(&Color_bright_red);
+		gr_set_color_fast(&Color_more_bright);
 		gr_string(Title_coords[gr_screen.res][4], sy + (Popup_max_display[gr_screen.res]) * h, XSTR("More", 459), GR_RESIZE_MENU);
 	}
 
colors.patch (40,102 bytes)   

MageKing17

2014-07-20 17:24

developer   ~0016097

Another tweak; since there was a reason for it, restored running team names through a char array; also corrected a slight logic error with one of the warnings.

The_E

2014-07-20 17:31

administrator   ~0016098

Fix committed to trunk@10926.

MageKing17

2014-07-20 20:51

developer   ~0016104

Reopening because Axem found that $h, $f, and $n were broken; patch attached to fix the problem by making it use pointers instead, as it should have from the very beginning.

MageKing17

2014-07-20 20:52

developer  

colorfix.patch (3,137 bytes)   
Index: code/globalincs/alphacolors.cpp
===================================================================
--- code/globalincs/alphacolors.cpp	(revision 10927)
+++ code/globalincs/alphacolors.cpp	(working copy)
@@ -15,7 +15,8 @@
 SCP_map<SCP_string, team_color> Team_Colors;
 SCP_vector<SCP_string> Team_Names;
 
-SCP_map<char, color> Tagged_Colors;
+SCP_map<char, color*> Tagged_Colors;
+SCP_map<char, color> Custom_Colors;
 SCP_vector<char> Color_Tags;
 
 // -----------------------------------------------------------------------------------
@@ -254,7 +255,7 @@
 	}
 
 	for (i = 0; i < DEFAULT_TAGS; i++) {
-		Tagged_Colors[DEFAULT_TAG_LIST[i]] = *DEFAULT_TAG_COLORS[i];
+		Tagged_Colors[DEFAULT_TAG_LIST[i]] = DEFAULT_TAG_COLORS[i];
 		Color_Tags.push_back(DEFAULT_TAG_LIST[i]);
 	}
 
@@ -514,11 +515,13 @@
 						}
 					}
 					gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
-					Tagged_Colors[tag] = temp_color;
+					Custom_Colors[tag] = temp_color;
+					Tagged_Colors[tag] = &Custom_Colors[tag];
 				//} else if ( check_for_string ("#") ) {
 				//	stuff_hex_list(rgba, 4);
 				//	gr_init_alphacolor(&temp_color, rgba[0], rgba[1], rgba[2], rgba[3]);
-				//	Tagged_Colors[tag] = temp_color;
+				//	Custom_Colors[tag] = temp_color;
+				//	Tagged_Colors[tag] = &Custom_Colors[tag];
 				} else {
 					// We have a string; it should be the name of a color to use.
 					stuff_string(temp, F_NAME);
@@ -530,20 +533,20 @@
 					if ( j == TOTAL_COLORS ) {
 						Error(LOCATION, "Unknown color '%s' in %s, for definition of tag '$%c'.\n", temp.c_str(), filename, tag);
 					}
-					Tagged_Colors[tag] = *COLOR_LIST[j];
+					Tagged_Colors[tag] = COLOR_LIST[j];
 				}
 				break;
 			case 1:	// +Friendly
 				required_string("+Friendly");
-				Tagged_Colors[tag] = Brief_color_green;
+				Tagged_Colors[tag] = &Brief_color_green;
 				break;
 			case 2:	// +Hostile
 				required_string("+Hostile");
-				Tagged_Colors[tag] = Brief_color_red;
+				Tagged_Colors[tag] = &Brief_color_red;
 				break;
 			case 3:	// +Neutral
 				required_string("+Neutral");
-				Tagged_Colors[tag] = Brief_color_legacy_neutral;
+				Tagged_Colors[tag] = &Brief_color_legacy_neutral;
 				break;
 			case -1:
 				// -noparseerrors is set
Index: code/globalincs/alphacolors.h
===================================================================
--- code/globalincs/alphacolors.h	(revision 10927)
+++ code/globalincs/alphacolors.h	(working copy)
@@ -46,7 +46,7 @@
 extern SCP_map<SCP_string, team_color> Team_Colors;
 extern SCP_vector<SCP_string> Team_Names;
 
-extern SCP_map<char, color> Tagged_Colors;
+extern SCP_map<char, color*> Tagged_Colors;
 extern SCP_vector<char> Color_Tags;
 
 #define MAX_DEFAULT_TEXT_COLORS	7
Index: code/mission/missionbriefcommon.cpp
===================================================================
--- code/mission/missionbriefcommon.cpp	(revision 10927)
+++ code/mission/missionbriefcommon.cpp	(working copy)
@@ -1415,7 +1415,7 @@
 
 void brief_set_text_color(char color_tag)
 {
-	gr_set_color_fast(&Tagged_Colors[color_tag]);
+	gr_set_color_fast(Tagged_Colors[color_tag]);
 }
 
 /**
colorfix.patch (3,137 bytes)   

The_E

2014-07-20 20:54

administrator   ~0016105

Fix committed to trunk@10928.

Related Changesets

fs2open: trunk r10926

2014-07-20 13:56

The_E


Ported: N/A

Details Diff
Fix for Mantis 3064 from MageKing17: Adds more functionality to colors.tbl.
* "#Start Colors" is now optional; no more need for a blank section at the start of a colors.tbl just to define some team colors.
* "#Interface Colors" section added for redefining various colors used by the interface.
* "#Color Tags" section added for redefining or adding your own text color tags.
* "#Default Text Color" section for choosing what color tag is the baseline default for various different screens.
* And the big one, support for *-clr.tbm modular table files.
Affected Issues
0003064
mod - /trunk/fs2_open/code/mission/missionbriefcommon.h Diff File
mod - /trunk/fs2_open/code/globalincs/alphacolors.h Diff File
mod - /trunk/fs2_open/code/freespace2/freespace.cpp Diff File
mod - /trunk/fs2_open/code/missionui/fictionviewer.cpp Diff File
mod - /trunk/fs2_open/code/missionui/missioncmdbrief.cpp Diff File
mod - /trunk/fs2_open/code/fred2/management.cpp Diff File
mod - /trunk/fs2_open/code/missionui/missiondebrief.cpp Diff File
mod - /trunk/fs2_open/code/missionui/redalert.cpp Diff File
mod - /trunk/fs2_open/code/network/multiui.cpp Diff File
mod - /trunk/fs2_open/code/missionui/missionloopbrief.cpp Diff File
mod - /trunk/fs2_open/code/mission/missionbriefcommon.cpp Diff File
mod - /trunk/fs2_open/code/globalincs/alphacolors.cpp Diff File
mod - /trunk/fs2_open/code/popup/popup.cpp Diff File

fs2open: trunk r10928

2014-07-20 17:18

The_E


Ported: N/A

Details Diff
Fix for Mantis 3064 from MageKing17: Followup fix. Affected Issues
0003064
mod - /trunk/fs2_open/code/globalincs/alphacolors.h Diff File
mod - /trunk/fs2_open/code/mission/missionbriefcommon.cpp Diff File
mod - /trunk/fs2_open/code/globalincs/alphacolors.cpp Diff File

Issue History

Date Modified Username Field Change
2014-06-19 06:19 MageKing17 New Issue
2014-06-19 06:19 MageKing17 Status new => assigned
2014-06-19 06:19 MageKing17 Assigned To => MageKing17
2014-06-19 06:19 MageKing17 File Added: colors.patch
2014-06-19 06:19 MageKing17 Status assigned => feedback
2014-06-20 22:36 MageKing17 File Deleted: colors.patch
2014-06-20 22:37 MageKing17 File Added: colors.patch
2014-06-20 22:39 MageKing17 Note Added: 0015898
2014-06-20 22:39 MageKing17 Status feedback => assigned
2014-06-20 22:40 MageKing17 Status assigned => feedback
2014-06-24 05:03 MageKing17 File Deleted: colors.patch
2014-06-24 05:03 MageKing17 File Added: colors.patch
2014-06-24 05:09 MageKing17 Note Added: 0015910
2014-06-24 05:09 MageKing17 Status feedback => assigned
2014-06-24 05:10 MageKing17 Status assigned => feedback
2014-06-26 02:11 MageKing17 Note View State: 0015910: private
2014-06-26 02:12 MageKing17 Note View State: 0015910: public
2014-07-09 06:17 MageKing17 File Added: colors2.patch
2014-07-09 06:19 MageKing17 Summary Move hardcoded interface colors to new section of colors.tbl => New colors.tbl features
2014-07-09 06:19 MageKing17 Description Updated
2014-07-09 06:19 MageKing17 File Deleted: colors2.patch
2014-07-09 06:21 MageKing17 File Added: colors2.patch
2014-07-09 06:22 MageKing17 Note Added: 0016040
2014-07-09 06:22 MageKing17 Status feedback => assigned
2014-07-09 06:24 MageKing17 Status assigned => feedback
2014-07-12 02:41 MageKing17 File Deleted: colors2.patch
2014-07-12 02:41 MageKing17 File Deleted: colors.patch
2014-07-12 02:41 MageKing17 File Added: colors.patch
2014-07-12 02:50 MageKing17 File Deleted: colors.patch
2014-07-12 02:57 MageKing17 File Added: colors.patch
2014-07-12 02:59 MageKing17 Note Added: 0016067
2014-07-12 02:59 MageKing17 Status feedback => assigned
2014-07-12 02:59 MageKing17 Status assigned => code review
2014-07-12 02:59 MageKing17 Target Version 3.7.3 => 3.7.2
2014-07-12 03:14 MageKing17 Description Updated
2014-07-12 03:17 MageKing17 File Deleted: colors.patch
2014-07-12 03:17 MageKing17 File Added: colors.patch
2014-07-12 03:18 MageKing17 File Added: add_z-clr.tbm
2014-07-12 03:18 MageKing17 File Added: make_everything_use_z-clr.tbm
2014-07-12 03:18 MageKing17 File Added: redefine_violet-clr.tbm
2014-07-12 03:30 MageKing17 File Added: colors.tbl
2014-07-19 17:13 MageKing17 File Deleted: colors.patch
2014-07-19 17:18 MageKing17 File Added: colors.patch
2014-07-19 17:20 MageKing17 Note Added: 0016096
2014-07-20 16:40 MageKing17 File Deleted: colors.patch
2014-07-20 16:40 MageKing17 File Added: colors.patch
2014-07-20 17:16 MageKing17 File Deleted: colors.patch
2014-07-20 17:24 MageKing17 File Added: colors.patch
2014-07-20 17:24 MageKing17 Note Added: 0016097
2014-07-20 17:31 The_E Changeset attached => fs2open trunk r10926
2014-07-20 17:31 The_E Note Added: 0016098
2014-07-20 17:31 The_E Status code review => resolved
2014-07-20 17:31 The_E Resolution open => fixed
2014-07-20 20:51 MageKing17 Note Added: 0016104
2014-07-20 20:51 MageKing17 Status resolved => feedback
2014-07-20 20:51 MageKing17 Resolution fixed => reopened
2014-07-20 20:52 MageKing17 File Added: colorfix.patch
2014-07-20 20:52 MageKing17 Status feedback => code review
2014-07-20 20:52 MageKing17 Resolution reopened => open
2014-07-20 20:54 The_E Changeset attached => fs2open trunk r10928
2014-07-20 20:54 The_E Note Added: 0016105
2014-07-20 20:54 The_E Status code review => resolved
2014-07-20 20:54 The_E Resolution open => fixed