r5773 - in trunk/data/qcsrc: client common menu menu/item menu/nexuiz server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Fri Feb 6 03:58:55 EST 2009


Author: div0
Date: 2009-02-06 03:58:41 -0500 (Fri, 06 Feb 2009)
New Revision: 5773

Modified:
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/main.qh
   trunk/data/qcsrc/client/mapvoting.qc
   trunk/data/qcsrc/client/miscfunctions.qc
   trunk/data/qcsrc/client/sbar.qc
   trunk/data/qcsrc/common/campaign_file.qc
   trunk/data/qcsrc/common/util.qc
   trunk/data/qcsrc/common/util.qh
   trunk/data/qcsrc/menu/draw.qc
   trunk/data/qcsrc/menu/draw.qh
   trunk/data/qcsrc/menu/item/label.c
   trunk/data/qcsrc/menu/nexuiz/campaign.c
   trunk/data/qcsrc/menu/nexuiz/util.qc
   trunk/data/qcsrc/menu/nexuiz/util.qh
   trunk/data/qcsrc/server/campaign.qc
   trunk/data/qcsrc/server/cl_player.qc
   trunk/data/qcsrc/server/miscfunctions.qc
   trunk/data/qcsrc/server/teamplay.qc
Log:
centerprint handlign in csqc (#2555668 after large cleanups)


Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/client/Main.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -807,10 +807,11 @@
 {
 	print(ColorTranslateRGB(strMessage));
 }
-// CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided.  To execute standard behavior, simply execute cprint with the string.
+
+// CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided.  
 void CSQC_Parse_CenterPrint(string strMessage)
 {
-	cprint(ColorTranslateRGB(strMessage));
+	centerprint(strMessage);
 }
 
 void CSQC_CheckRevision();

Modified: trunk/data/qcsrc/client/main.qh
===================================================================
--- trunk/data/qcsrc/client/main.qh	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/client/main.qh	2009-02-06 08:58:41 UTC (rev 5773)
@@ -149,3 +149,5 @@
 float chase_active_backup;
 float camera_roll;
 vector camera_direction;
+
+void centerprint(string strMessage);

Modified: trunk/data/qcsrc/client/mapvoting.qc
===================================================================
--- trunk/data/qcsrc/client/mapvoting.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/client/mapvoting.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -22,7 +22,7 @@
 	else
 		post = "";
 	maxwidth -= stringwidth(pre, FALSE) + stringwidth(post, FALSE);
-	map = textShortenToWidth(map, maxwidth, FALSE);
+	map = textShortenToWidth(map, maxwidth, stringwidth_nocolors);
 	return strcat(pre, map, post);
 }
 

Modified: trunk/data/qcsrc/client/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/client/miscfunctions.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/client/miscfunctions.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -9,7 +9,7 @@
 	countdown_rounded = floor(0.5 + countdown);
 	if(countdown <= 0) {
 		if (!spectatee_status) //do cprint only for players
-			cprint(NEWLINES, "^1Begin!");
+			centerprint("^1Begin!");
 
 		sound(self, CHAN_VOICE, "announcer/robotic/begin.wav", VOL_BASEVOICE, ATTN_NONE);
 		remove(self);
@@ -17,7 +17,7 @@
 	}
 	else {
 		if (!spectatee_status) //do cprint only for players
-			cprint(NEWLINES, "^1Game starts in ", ftos(countdown_rounded), " seconds");
+			centerprint(strcat("^1Game starts in ", ftos(countdown_rounded), " seconds"));
 
 		if(countdown_rounded <= 3 && countdown_rounded >= 1) {
 			sound(self, CHAN_VOICE, strcat("announcer/robotic/", ftos(countdown_rounded), ".wav"), VOL_BASEVOICE, ATTN_NONE);

Modified: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/client/sbar.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -661,52 +661,21 @@
 	//return "error";
 }
 
-// shamelessly stolen from menu QC :P <- as if I would steal YOUR code pfft ;)
-float textLengthUpToWidth(string theText, float maxWidth, float handleColors)
+float xmin, xmax, ymin, ymax, sbwidth;
+float sbar_fixscoreboardcolumnwidth_len;
+float sbar_fixscoreboardcolumnwidth_iconlen;
+float sbar_fixscoreboardcolumnwidth_marginlen;
+
+float stringwidth_colors(string s)
 {
-	// STOP.
-	// The following function is SLOW.
-	// For your safety and for the protection of those around you...
-	// DO NOT CALL THIS AT HOME.
-	// No really, don't.
-	if(stringwidth(theText, handleColors) <= maxWidth)
-		return strlen(theText); // yeah!
+	return stringwidth(s, TRUE);
+}
 
-	// binary search for right place to cut string
-	float left, right, middle; // this always works
-	left = 0;
-	right = strlen(theText); // this always fails
-	do
-	{
-		middle = floor((left + right) / 2);
-		if(stringwidth(substring(theText, 0, middle), handleColors) <= maxWidth)
-			left = middle;
-		else
-			right = middle;
-	}
-	while(left < right - 1);
-
-	// NOTE: when color codes are involved, this binary search is,
-	// mathematically, BROKEN. However, it is obviously guaranteed to
-	// terminate, as the range still halves each time - but nevertheless, it is
-	// guaranteed that it finds ONE valid cutoff place (where "left" is in
-	// range, and "right" is outside).
-
-	return left;
-}
-string textShortenToWidth(string theText, float maxWidth, float handleColors)
+float stringwidth_nocolors(string s)
 {
-	if(stringwidth(theText, handleColors) <= maxWidth)
-		return theText;
-	else
-		return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - stringwidth("...", handleColors), handleColors)), "...");
+	return stringwidth(s, FALSE);
 }
 
-float xmin, xmax, ymin, ymax, sbwidth;
-float sbar_fixscoreboardcolumnwidth_len;
-float sbar_fixscoreboardcolumnwidth_iconlen;
-float sbar_fixscoreboardcolumnwidth_marginlen;
-
 string Sbar_FixScoreboardColumnWidth(float i, string str)
 {
 	float field, maxsize, j, f;
@@ -719,7 +688,7 @@
 		for(j = 0; j < sbar_num_fields; ++j) if(j != i) if(sbar_field[j] != SP_SEPARATOR)
 			maxsize -= sbar_size[j] + 1;
 		maxsize += 1;
-		str = textShortenToWidth(str, maxsize, TRUE);
+		str = textShortenToWidth(str, maxsize, stringwidth_colors);
 		sbar_fixscoreboardcolumnwidth_len = stringwidth(str, TRUE);
 	}
 	else
@@ -854,6 +823,7 @@
 }
 
 float lastpingstime;
+float scoreboard_bottom;
 void Sbar_DrawScoreboard()
 {
 	//float xmin, ymin, xmax, ymax;
@@ -871,7 +841,7 @@
 	sbwidth = Sbar_GetWidth(6.5 * sbar_fontsize_y);
 
 	xmin = 0.5 * (vid_conwidth - sbwidth);
-	ymin = 20;
+	ymin = 45;
 
 	xmax = vid_conwidth - xmin;
     ymax = vid_conheight - 0.2*vid_conheight;
@@ -1062,10 +1032,11 @@
 	}
 	
 
-	pos_y += 1.5 * sbar_fontsize_y;
+	pos_y += 1.2 * sbar_fontsize_y;
 	drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - sbar_fontsize_x * stringwidth(str, TRUE)), str, sbar_fontsize, 0.8, 0);
 	
 	sbar = sbar_save;
+	scoreboard_bottom = pos_y + 2 * sbar_fontsize_y;
 }
 
 string MakeRaceString(float cp, float mytime, float histime, float lapdelta, string hisname)
@@ -1478,19 +1449,6 @@
 	return 0;
 }
 
-vector Sbar_DrawNoteLine(vector offset, string s)
-{
-	dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
-	drawcolorcodedstring(
-		offset - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE),
-		s,
-		sbar_fontsize,
-		sbar_alpha_fg,
-		0
-	);
-	return offset + sbar_fontsize_y * '0 1 0';
-}
-
 void CSQC_Strength_Timer() {
 	float stat_items;
 	stat_items = getstati(STAT_ITEMS);
@@ -1544,6 +1502,186 @@
 	}
 }
 
+#define CENTERPRINT_MAX_LINES 30
+string centerprint_messages[CENTERPRINT_MAX_LINES]; 
+float centerprint_width[CENTERPRINT_MAX_LINES]; 
+vector centerprint_start;
+float centerprint_expire;
+float centerprint_num;
+float centerprint_offset_hint;
+vector centerprint_fontsize = '11 11 0';
+
+void centerprint(string strMessage)
+{
+	float i, j, n, hcount;
+	string s;
+	
+	// delete old centerprint messages
+	for (i=0; i<centerprint_num; ++i)
+	{
+		if(centerprint_messages[i])
+		{
+			strunzone(centerprint_messages[i]);
+			centerprint_messages[i] = string_null;
+			centerprint_width[i] = 0;
+		}
+	}
+
+	if(strMessage == "")
+		return;
+
+	// strip trailing newlines
+	j = strlen(strMessage) - 1;
+	while(substring(strMessage, j, 1) == "\n" && j >= 0)
+		j = j - 1;
+	strMessage = substring(strMessage, 0, j + 1);
+	
+	if(strMessage == "")
+		return;
+
+	// strip leading newlines and remember them, they are a hint that the message should be lower on the screen
+	j = 0;
+	while(substring(strMessage, j, 1) == "\n" && j < strlen(strMessage))
+		j = j + 1;
+	strMessage = substring(strMessage, j, strlen(strMessage) - j);
+	centerprint_offset_hint = j;
+	
+	// TODO if we're parsing centerprints now anyway, why not word wrap them?
+	n = tokenizebyseparator(strMessage, "\n");
+	i = hcount = 0;
+	for(j = 0; j < n; ++j)
+	{
+		getWrappedLine_remaining = argv(j);
+		while(getWrappedLine_remaining)
+		{
+			s = getWrappedLine(vid_conwidth * 0.75 / centerprint_fontsize_x, stringwidth_colors);
+			centerprint_messages[i] = strzone(s);
+			centerprint_width[i] = stringwidth(s, TRUE);
+			++i;
+
+			// half height for empty lines looks better
+			if(s == "")
+				hcount += 0.5;
+			else
+				hcount += 1;
+
+			if(i >= CENTERPRINT_MAX_LINES)
+				break;
+		}
+	}
+
+	float h, havail;
+	h = centerprint_fontsize_y*hcount;
+
+	havail = vid_conheight;
+	if(cvar("con_chatpos") < 0)
+		havail -= (-cvar("con_chatpos") + cvar("con_chat")) * cvar("con_chatsize"); // avoid overlapping chat
+
+	centerprint_start_x = 0;
+
+#if 0
+	float forbiddenmin, forbiddenmax, allowedmin, allowedmax, preferred;
+
+	// here, the centerprint would cover the crosshair. REALLY BAD.
+	forbiddenmin = vid_conheight * 0.5 - h - 16;
+	forbiddenmax = vid_conheight * 0.5 + 16;
+
+	allowedmin = scoreboard_bottom;
+	allowedmax = havail - h;
+	preferred = (havail - h)/2;
+
+
+	// possible orderings (total: 4! / 4 = 6)
+	//  allowedmin allowedmax forbiddenmin forbiddenmax
+	//  forbiddenmin forbiddenmax allowedmin allowedmax
+	if(allowedmax < forbiddenmin || allowedmin > forbiddenmax)
+	{
+		// forbidden doesn't matter in this case
+		centerprint_start_y = bound(allowedmin, preferred, allowedmax);
+	}
+	//  allowedmin forbiddenmin allowedmax forbiddenmax
+	else if(allowedmin < forbiddenmin && allowedmax < forbiddenmax)
+	{
+		centerprint_start_y = bound(allowedmin, preferred, forbiddenmin);
+	}
+	//  allowedmin forbiddenmin forbiddenmax allowedmax
+	else if(allowedmin < forbiddenmin)
+	{
+		// make sure the forbidden zone is not covered
+		if(preferred > (forbiddenmin + forbiddenmax) * 0.5)
+			centerprint_start_y = bound(allowedmin, preferred, forbiddenmin);
+		else
+			centerprint_start_y = bound(forbiddenmax, preferred, allowedmin);
+	}
+	//  forbiddenmin allowedmin allowedmax forbiddenmax
+	else if(allowedmax < forbiddenmax)
+	{
+		// it's better to leave the allowed zone (overlap with scoreboard) than
+		// to cover the forbidden zone (crosshair)
+		if(preferred > (forbiddenmin + forbiddenmax) * 0.5)
+			centerprint_start_y = forbiddenmax;
+		else
+			centerprint_start_y = forbiddenmin;
+	}
+	//  forbiddenmin allowedmin forbiddenmax allowedmax
+	else
+	{
+		centerprint_start_y = bound(forbiddenmax, preferred, allowedmax);
+	}
+#else
+	centerprint_start_y =
+		min(
+			max(
+				max(scoreboard_bottom, vid_conheight * 0.5 + 16),
+				(havail - h)/2
+			),
+			havail - h
+		);
+#endif
+
+	centerprint_num = i;
+	centerprint_expire = time + cvar("scr_centertime");
+}
+
+void Sbar_DrawCenterPrint (void)
+{
+	float i;
+	vector pos;
+	string ts;
+
+	if(time > centerprint_expire)
+		return;
+	
+	pos = centerprint_start;
+	for (i=0; i<centerprint_num; i = i + 1)
+	{
+		pos_x = (vid_conwidth - centerprint_fontsize_x * centerprint_width[i]) * 0.5;
+		ts = centerprint_messages[i];
+		if (ts != "")
+		{
+			dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+			drawcolorcodedstring(pos, ts, centerprint_fontsize, 1, DRAWFLAG_NORMAL);
+			pos_y = pos_y + centerprint_fontsize_y;
+		}
+		else
+			// half height for empty lines looks better
+			pos_y = pos_y + centerprint_fontsize_y * 0.5;
+	}
+}
+
+vector Sbar_DrawNoteLine(vector offset, string s)
+{
+	dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0)
+	drawcolorcodedstring(
+		offset - sbar_fontsize_x * '1 0 0' * stringwidth(s, TRUE),
+		s,
+		sbar_fontsize,
+		sbar_alpha_fg,
+		0
+	);
+	return offset + sbar_fontsize_y * '0 1 0';
+}
+
 void Sbar_Draw (void)
 {
 	float i;
@@ -1696,14 +1834,21 @@
 	sb_lines = 24;
 
 	if (sb_showscores)
+	{
 		Sbar_DrawScoreboard();
+		Sbar_DrawCenterPrint();
+	}
 	else if (intermission == 1)
 	{
 		Sbar_DrawScoreboard();
+		Sbar_DrawCenterPrint();
 		return;
 	}
 	else if (intermission == 2)
+	{
 		Sbar_FinaleOverlay();
+		Sbar_DrawCenterPrint();
+	}
 	else
 	{
 		if (sb_showscores || sb_showscores_force || (getstati(STAT_HEALTH) <= 0 && cvar("cl_deathscoreboard")))
@@ -1895,6 +2040,7 @@
 				CSQC_ctf_hud();
 			}
 		}
+		Sbar_DrawCenterPrint();
 	}
 }
 

Modified: trunk/data/qcsrc/common/campaign_file.qc
===================================================================
--- trunk/data/qcsrc/common/campaign_file.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/common/campaign_file.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -56,7 +56,7 @@
 				CAMPAIGN_GETARG; campaign_fraglimit[campaign_entries] = stof(a);
 				CAMPAIGN_GETARG; campaign_mutators[campaign_entries] = strzone(a);
 				CAMPAIGN_GETARG; campaign_shortdesc[campaign_entries] = strzone(a);
-				CAMPAIGN_GETARG; campaign_longdesc[campaign_entries] = strzone(a);
+				CAMPAIGN_GETARG; campaign_longdesc[campaign_entries] = strzone(strreplace("\\n", "\n", a));
 				campaign_entries = campaign_entries + 1;
 
 				if(campaign_entries >= n)

Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/common/util.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -1357,3 +1357,116 @@
 	return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform));
 }
 #endif
+
+float textLengthUpToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t w)
+{
+	float ICanHasKallerz;
+
+	// detect color codes support in the width function
+	ICanHasKallerz = (w("^7") == 0);
+
+	// STOP.
+	// The following function is SLOW.
+	// For your safety and for the protection of those around you...
+	// DO NOT CALL THIS AT HOME.
+	// No really, don't.
+	if(w(theText) <= maxWidth)
+		return strlen(theText); // yeah!
+
+	// binary search for right place to cut string
+	float ch;
+	float left, right, middle; // this always works
+	left = 0;
+	right = strlen(theText); // this always fails
+	do
+	{
+		middle = floor((left + right) / 2);
+		if(w(substring(theText, 0, middle)) <= maxWidth)
+			left = middle;
+		else
+			right = middle;
+	}
+	while(left < right - 1);
+
+	if(ICanHasKallerz)
+	{
+		// NOTE: when color codes are involved, this binary search is,
+		// mathematically, BROKEN. However, it is obviously guaranteed to
+		// terminate, as the range still halves each time - but nevertheless, it is
+		// guaranteed that it finds ONE valid cutoff place (where "left" is in
+		// range, and "right" is outside).
+		
+		// terencehill: the following code detects truncated ^xrgb tags (e.g. ^x or ^x4)
+		// and decrease left on the basis of the chars detected of the truncated tag
+		// Even if the ^xrgb tag is not complete/correct, left is decreased
+		// (sometimes too much but with a correct result)
+		// it fixes also ^[0-9]
+		while(left >= 1 && substring(theText, left-1, 1) == "^")
+			left-=1;
+
+		if (left >= 2 && substring(theText, left-2, 2) == "^x") // ^x/
+			left-=2;
+		else if (left >= 3 && substring(theText, left-3, 2) == "^x")
+			{
+				ch = str2chr(theText, left-1);
+				if( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xr/
+					left-=3;
+			}
+		else if (left >= 4 && substring(theText, left-4, 2) == "^x")
+			{
+				ch = str2chr(theText, left-2);
+				if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') )
+				{
+					ch = str2chr(theText, left-1);
+					if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xrg/
+						left-=4;
+				}
+			}
+	}
+	
+	return left;
+}
+
+string getWrappedLine(float w, textLengthUpToWidth_widthFunction_t tw)
+{
+	float cantake;
+	float take;
+	string s;
+
+	s = getWrappedLine_remaining;
+
+	cantake = textLengthUpToWidth(s, w, tw);
+	if(cantake > 0 && cantake < strlen(s))
+	{
+		take = cantake - 1;
+		while(take > 0 && substring(s, take, 1) != " ")
+			--take;
+		if(take == 0)
+		{
+			getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake);
+			if(getWrappedLine_remaining == "")
+				getWrappedLine_remaining = string_null;
+			return substring(s, 0, cantake);
+		}
+		else
+		{
+			getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take);
+			if(getWrappedLine_remaining == "")
+				getWrappedLine_remaining = string_null;
+			return substring(s, 0, take);
+		}
+	}
+	else
+	{
+		getWrappedLine_remaining = string_null;
+		return s;
+	}
+}
+
+string textShortenToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw)
+{
+	if(tw(theText) <= maxWidth)
+		return theText;
+	else
+		return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - tw("..."), tw)), "...");
+}

Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/common/util.qh	2009-02-06 08:58:41 UTC (rev 5773)
@@ -143,3 +143,10 @@
 vector AnglesTransform_TurnDirection(vector transform);
 vector AnglesTransform_Divide(vector to_transform, vector from_transform);
 #endif
+
+typedef float(string s) textLengthUpToWidth_widthFunction_t;
+float textLengthUpToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw);
+string textShortenToWidth(string theText, float maxWidth, textLengthUpToWidth_widthFunction_t tw);
+
+string getWrappedLine_remaining;
+string getWrappedLine(float w, textLengthUpToWidth_widthFunction_t tw);

Modified: trunk/data/qcsrc/menu/draw.qc
===================================================================
--- trunk/data/qcsrc/menu/draw.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/menu/draw.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -284,62 +284,20 @@
 		return strcat(substring(theText, 0, draw_TextLengthUpToWidth(theText, maxWidth - draw_TextWidth("...", ICanHasKallerz), ICanHasKallerz)), "...");
 }
 
-float draw_TextLengthUpToWidth(string theText, float maxWidth, float ICanHasKallerz)
+float draw_TextWidth_WithColors(string s)
 {
-	// STOP.
-	// The following function is SLOW.
-	// For your safety and for the protection of those around you...
-	// DO NOT CALL THIS AT HOME.
-	// No really, don't.
-	if(draw_TextWidth(theText, ICanHasKallerz) <= maxWidth)
-		return strlen(theText); // yeah!
+	return draw_TextWidth(s, TRUE);
+}
 
-	// binary search for right place to cut string
-	float ch;
-	float left, right, middle; // this always works
-	left = 0;
-	right = strlen(theText); // this always fails
-	do
-	{
-		middle = floor((left + right) / 2);
-		if(draw_TextWidth(substring(theText, 0, middle), ICanHasKallerz) <= maxWidth)
-			left = middle;
-		else
-			right = middle;
-	}
-	while(left < right - 1);
+float draw_TextWidth_WithoutColors(string s)
+{
+	return draw_TextWidth(s, FALSE);
+}
 
-	// NOTE: when color codes are involved, this binary search is,
-	// mathematically, BROKEN. However, it is obviously guaranteed to
-	// terminate, as the range still halves each time - but nevertheless, it is
-	// guaranteed that it finds ONE valid cutoff place (where "left" is in
-	// range, and "right" is outside).
-	
-	// terencehill: the following code detects truncated ^xrgb tags (e.g. ^x or ^x4)
-	// and decrease left on the basis of the chars detected of the truncated tag
-	// Even if the ^xrgb tag is not complete/correct, left is decreased
-	// (sometimes too much but with a correct result)
-	// it fixes also ^[0-9]
-	if (left >= 1 && substring(theText, left-1, 1) == "^") // * it doesn't consider one or more ^ before the current ^
-		left-=1;
-	else if (left >= 2 && substring(theText, left-2, 2) == "^x") // ^x/
-		left-=2;
-	else if (left >= 3 && substring(theText, left-3, 2) == "^x")
-		{
-			ch = str2chr(theText, left-1);
-			if( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xr/
-				left-=3;
-		}
-	else if (left >= 4 && substring(theText, left-4, 2) == "^x")
-		{
-			ch = str2chr(theText, left-2);
-			if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') )
-			{
-				ch = str2chr(theText, left-1);
-				if ( (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') ) // ^xrg/
-					left-=4;
-			}
-		}
-	
-	return left;
+float draw_TextLengthUpToWidth(string theText, float maxWidth, float allowColorCodes)
+{
+	if(allowColorCodes)
+		return textLengthUpToWidth(theText, maxWidth, draw_TextWidth_WithColors);
+	else
+		return textLengthUpToWidth(theText, maxWidth, draw_TextWidth_WithoutColors);
 }

Modified: trunk/data/qcsrc/menu/draw.qh
===================================================================
--- trunk/data/qcsrc/menu/draw.qh	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/menu/draw.qh	2009-02-06 08:58:41 UTC (rev 5773)
@@ -31,3 +31,6 @@
 float draw_NeedResizeNotify;
 
 string draw_currentSkin;
+
+float draw_TextWidth_WithColors(string s);
+float draw_TextWidth_WithoutColors(string s);

Modified: trunk/data/qcsrc/menu/item/label.c
===================================================================
--- trunk/data/qcsrc/menu/item/label.c	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/menu/item/label.c	2009-02-06 08:58:41 UTC (rev 5773)
@@ -78,7 +78,7 @@
 				o = me.realOrigin;
 				while(getWrappedLine_remaining)
 				{
-					t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight) / me.realFontSize_x);
+					t = getWrappedLine((1 - me.keepspaceLeft - me.keepspaceRight) / me.realFontSize_x, draw_TextWidth_WithoutColors);
 					draw_Text(o, t, me.realFontSize, me.colorL, me.alpha, 0);
 					o_y += me.realFontSize_y;
 				}

Modified: trunk/data/qcsrc/menu/nexuiz/campaign.c
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/campaign.c	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/menu/nexuiz/campaign.c	2009-02-06 08:58:41 UTC (rev 5773)
@@ -74,7 +74,7 @@
 			getWrappedLine_remaining = s;
 			while(getWrappedLine_remaining)
 			{
-				s = getWrappedLine(w);
+				s = getWrappedLine(w, draw_TextWidth_WithoutColors);
 				if(--l < 0) goto toolong;
 				r = strcat(r, s, "\n");
 			}

Modified: trunk/data/qcsrc/menu/nexuiz/util.qc
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/util.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/menu/nexuiz/util.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -312,40 +312,3 @@
 		campaign_won_previous = cvar(strcat("g_campaign", campaign_name, "_won"));
 	}
 }
-
-string getWrappedLine_remaining;
-string getWrappedLine(float w)
-{
-	float cantake;
-	float take;
-	string s;
-
-	s = getWrappedLine_remaining;
-
-	cantake = draw_TextLengthUpToWidth(s, w, 0);
-	if(cantake > 0 && cantake < strlen(s))
-	{
-		take = cantake - 1;
-		while(take > 0 && substring(s, take, 1) != " ")
-			--take;
-		if(take == 0)
-		{
-			getWrappedLine_remaining = substring(s, cantake, strlen(s) - cantake);
-			if(getWrappedLine_remaining == "")
-				getWrappedLine_remaining = string_null;
-			return substring(s, 0, cantake);
-		}
-		else
-		{
-			getWrappedLine_remaining = substring(s, take + 1, strlen(s) - take);
-			if(getWrappedLine_remaining == "")
-				getWrappedLine_remaining = string_null;
-			return substring(s, 0, take);
-		}
-	}
-	else
-	{
-		getWrappedLine_remaining = string_null;
-		return s;
-	}
-}

Modified: trunk/data/qcsrc/menu/nexuiz/util.qh
===================================================================
--- trunk/data/qcsrc/menu/nexuiz/util.qh	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/menu/nexuiz/util.qh	2009-02-06 08:58:41 UTC (rev 5773)
@@ -9,6 +9,3 @@
 void setDependentOR(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max);
 void setDependentAND3(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max, string theCvar3Name, float theCvar3Min, float theCvar3Max);
 void setDependentStringNotEqual(entity e, string theCvarName, string theCvarValue);
-
-string getWrappedLine_remaining;
-string getWrappedLine(float w);

Modified: trunk/data/qcsrc/server/campaign.qc
===================================================================
--- trunk/data/qcsrc/server/campaign.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/server/campaign.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -39,7 +39,7 @@
 
 	title = campaign_shortdesc[0];
 	title = strzone(strcat("Level ", ftos(campaign_level + 1), ": ", title));
-	campaign_message = strzone(strcat("\n\n\n\n\n\n\n\n\n\n^1\n", title, "\n^3\n", wordwrap(campaign_longdesc[0], 50), "\n\n^1press jump to enter the game"));
+	campaign_message = strzone(strcat("\n\n\n\n\n\n\n\n\n\n^1\n", title, "\n^3\n", campaign_longdesc[0], "\n\n^1press jump to enter the game"));
 	strunzone(title);
 }
 

Modified: trunk/data/qcsrc/server/cl_player.qc
===================================================================
--- trunk/data/qcsrc/server/cl_player.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/server/cl_player.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -742,11 +742,13 @@
 		namestr = source.netname;
 	if(teamsay)
 	{
-		msgstr = strzone(strcat("\{1}\{13}", colorstr, "(^3", namestr, colorstr, ") ^7", msgin, "\n"));
-		cmsgstr = strcat(colorstr, "(^3", namestr, colorstr, ")\n^7", wordwrap(msgin, 50));
+		msgstr = strcat("\{1}\{13}", colorstr, "(^3", namestr, colorstr, ") ^7", msgin);
+		cmsgstr = strcat(colorstr, "(^3", namestr, colorstr, ")\n^7", msgin);
 	}
 	else
-		msgstr = strzone(strcat("\{1}", namestr, "^7: ", msgin, "\n"));
+		msgstr = strcat("\{1}", namestr, "^7: ", msgin);
+	
+	msgstr = strcat(strreplace("\n", " ", msgstr), "\n"); // newlines only are good for centerprint
 
 	// FLOOD CONTROL
 	flood = 0;
@@ -830,8 +832,6 @@
 		else
 			bprint(msgstr);
 	}
-
-	strunzone(msgstr);
 }
 
 float GetVoiceMessageVoiceType(string type)

Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/server/miscfunctions.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -395,12 +395,10 @@
 
 string formatmessage(string msg)
 {
-	float p;
+	float p, p1, p2;
 	float n;
-	string msg_save;
 	string escape;
 	string replacement;
-	msg_save = strzone(msg);
 	p = 0;
 	n = 7;
 	while(1)
@@ -408,13 +406,25 @@
 		if(n < 1)
 			break; // too many replacements
 		n = n - 1;
-		p = strstr(msg_save, "%", p); // NOTE: this destroys msg as it's a tempstring!
+		p1 = strstr(msg, "%", p); // NOTE: this destroys msg as it's a tempstring!
+		p2 = strstr(msg, "\\", p); // NOTE: this destroys msg as it's a tempstring!
+
+		if(p1 < 0)
+			p1 = p2;
+		if(p2 < 0)
+			p2 = p1;
+		p = min(p1, p2);
+		
 		if(p < 0)
 			break;
-		replacement = substring(msg_save, p, 2);
-		escape = substring(msg_save, p + 1, 1);
+		replacement = substring(msg, p, 2);
+		escape = substring(msg, p + 1, 1);
 		if(escape == "%")
 			replacement = "%";
+		else if(escape == "\\")
+			replacement = "\\";
+		else if(escape == "n")
+			replacement = "\n";
 		else if(escape == "a")
 			replacement = ftos(floor(self.armorvalue));
 		else if(escape == "h")
@@ -456,14 +466,9 @@
 			else
 				replacement = "(nobody)";
 		}
-		msg = strcat(substring(msg_save, 0, p), replacement);
-		msg = strcat(msg, substring(msg_save, p+2, strlen(msg_save) - (p+2)));
-		strunzone(msg_save);
-		msg_save = strzone(msg);
-		p = p + 2;
+		msg = strcat(substring(msg, 0, p), replacement, substring(msg, p+2, strlen(msg) - (p+2)));
+		p = p + strlen(replacement);
 	}
-	msg = strcat(msg_save, "");
-	strunzone(msg_save);
 	return msg;
 }
 

Modified: trunk/data/qcsrc/server/teamplay.qc
===================================================================
--- trunk/data/qcsrc/server/teamplay.qc	2009-02-06 07:32:54 UTC (rev 5772)
+++ trunk/data/qcsrc/server/teamplay.qc	2009-02-06 08:58:41 UTC (rev 5773)
@@ -1,6 +1,4 @@
-string cache_motd;
 string cache_mutatormsg;
-string cache_lastmotd;
 string cache_lastmutatormsg;
 
 // client counts for each team
@@ -330,9 +328,7 @@
 	cvar_set("gamecfg", ftos(game));
 
 	cache_mutatormsg = strzone("");
-	cache_motd = strzone("");
 	cache_lastmutatormsg = strzone("");
-	cache_lastmotd = strzone("");
 
 	// enforce the server's universal frag/time limits
 	if(!cvar("g_campaign"))
@@ -369,7 +365,7 @@
 
 void PrintWelcomeMessage(entity pl)
 {
-	string s, mutator, modifications;
+	string s, mutator, modifications, motd;
 
 	/*if(self.welcomemessage_time > time)
 		return;
@@ -475,26 +471,17 @@
 		if(cache_mutatormsg)
 			strunzone(cache_mutatormsg);
 		cache_lastmutatormsg = strzone(cvar_string("g_mutatormsg"));
-		cache_mutatormsg = strzone(wordwrap(cache_lastmutatormsg, 50));
+		cache_mutatormsg = strzone(cache_lastmutatormsg);
 	}
 
 	if (cache_mutatormsg != "") {
 		s = strcat(s, "\n\n^8special gameplay tips: ^7", cache_mutatormsg);
 	}
 
-	if(cache_lastmotd != cvar_string("sv_motd"))
-	{
-		if(cache_lastmotd)
-			strunzone(cache_lastmotd);
-		if(cache_motd)
-			strunzone(cache_motd);
-		cache_lastmotd = strzone(cvar_string("sv_motd"));
-		cache_motd = strzone(wordwrap(cache_lastmotd, 50));
+	motd = cvar_string("sv_motd");
+	if (motd != "") {
+		s = strcat(s, "\n\n^8MOTD: ^7", strreplace("\\n", "\n", motd));
 	}
-
-	if (cache_motd != "") {
-		s = strcat(s, "\n\n^8MOTD: ^7", cache_motd);
-	}
 	s = strcat(s, "\n");
 
 	centerprint(pl, s);




More information about the nexuiz-commits mailing list