r3806 - in trunk/data: . qcsrc/client qcsrc/common
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Thu Jul 10 03:10:34 EDT 2008
Author: div0
Date: 2008-07-10 03:10:23 -0400 (Thu, 10 Jul 2008)
New Revision: 3806
Modified:
trunk/data/defaultNexuiz.cfg
trunk/data/qcsrc/client/csqc_builtins.qc
trunk/data/qcsrc/client/sbar.qc
trunk/data/qcsrc/common/campaign_file.qc
trunk/data/qcsrc/common/mapinfo.qc
trunk/data/qcsrc/common/util.qc
Log:
CSQC scoreboard now knows about fonts
Modified: trunk/data/defaultNexuiz.cfg
===================================================================
--- trunk/data/defaultNexuiz.cfg 2008-07-10 06:04:04 UTC (rev 3805)
+++ trunk/data/defaultNexuiz.cfg 2008-07-10 07:10:23 UTC (rev 3806)
@@ -1047,3 +1047,8 @@
// CTF capture limit placeholder cvar
set capturelimit 0
+
+// sbar: font size
+set sbar_fontsize 11
+alias sbar_font "loadfont user1 $*; sbar_columns_set"
+sbar_font gfx/vera-sans
Modified: trunk/data/qcsrc/client/csqc_builtins.qc
===================================================================
--- trunk/data/qcsrc/client/csqc_builtins.qc 2008-07-10 06:04:04 UTC (rev 3805)
+++ trunk/data/qcsrc/client/csqc_builtins.qc 2008-07-10 07:10:23 UTC (rev 3806)
@@ -97,6 +97,8 @@
void drawsetcliparea(float x, float y, float width, float height) = #324;
void drawresetcliparea(void) = #325;
float drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag) = #326;
+float stringwidth(string text, float handleColors) = #327;
+float drawsubpic(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag) = #328;
float (float statnum) getstatf = #330;
Modified: trunk/data/qcsrc/client/sbar.qc
===================================================================
--- trunk/data/qcsrc/client/sbar.qc 2008-07-10 06:04:04 UTC (rev 3805)
+++ trunk/data/qcsrc/client/sbar.qc 2008-07-10 07:10:23 UTC (rev 3806)
@@ -2,6 +2,7 @@
float sb_lines; // still don't know what to do with that NOTE: check dp's sbar.c to see what that should be
vector sbar;
+vector sbar_fontsize;
entity sortedPlayers;
entity sortedTeams;
@@ -270,35 +271,49 @@
}
+#define MIN_NAMELEN 24
+#define MAX_NAMELEN 24
+
void Cmd_Sbar_SetFields(float argc)
{
float i;
string str;
+ float digit;
if(argc < 2)
argc = tokenize(strcat("x ", cvar_string("sbar_columns")));
argc = min(MAX_SBAR_FIELDS, argc);
sbar_num_fields = 0;
+ drawfont = FONT_USER+1;
+ digit = stringwidth("0123456789", FALSE) / 10;
for(i = 0; i < argc-1; ++i)
{
str = argv(i+1);
strunzone(sbar_title[i]);
sbar_title[i] = strzone(str);
- sbar_size[i] = strlen(str)*8;
+ sbar_size[i] = stringwidth(str, FALSE);
str = strtolower(str);
if(str == "ping") {
sbar_field[i] = SBF_PING;
} else if(str == "name" || str == "nick") {
sbar_field[i] = SBF_NAME;
- sbar_size[i] = 24*8; // minimum size? any use?
+ sbar_size[i] = MIN_NAMELEN; // minimum size? any use?
} else if(str == "caps" || str == "captures") {
+ if(sbar_size[i] < 3*digit)
+ sbar_size[i] = 3*digit;
sbar_field[i] = SBF_CAPS;
} else if(str == "rets" || str == "returns") {
+ if(sbar_size[i] < 3*digit)
+ sbar_size[i] = 3*digit;
sbar_field[i] = SBF_RETS;
} else if(str == "frags" || str == "kills") {
+ if(sbar_size[i] < 5*digit)
+ sbar_size[i] = 5*digit;
sbar_field[i] = SBF_FRAGS;
} else if(str == "deaths" || str == "dths") {
+ if(sbar_size[i] < 5*digit)
+ sbar_size[i] = 5*digit;
sbar_field[i] = SBF_DEATHS;
} else if(str == "kdratio") {
sbar_field[i] = SBF_KDRATIO;
@@ -362,8 +377,47 @@
return false;
}
-#define MAX_NAMELEN 24
+// shamelessly stolen from menu QC :P
+float textLengthUpToWidth(string theText, float maxWidth, float handleColors)
+{
+ // 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!
+ // 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)
+{
+ if(stringwidth(theText, handleColors) <= maxWidth)
+ return theText;
+ else
+ return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - stringwidth("...", handleColors), handleColors)), "...");
+}
+
float xmin, xmax, ymin, ymax, sbwidth, sbheight;
void Sbar_PrintScoreboardItem(vector pos, entity pl, float is_self, float mask)
{
@@ -376,7 +430,7 @@
if(is_self)
{
tmp_x = sbwidth;
- tmp_y = 8;
+ tmp_y = sbar_fontsize_y;
drawfill(pos - '1 1', tmp + '2 2', '1 1 1', 0.3, DRAWFLAG_NORMAL);
}
tmp_y = 0;
@@ -391,35 +445,35 @@
str = Sbar_GetField(pl, field);
- if(field == SBF_NAME) {
- len = strlen(strdecolorize(str));
- if(len > MAX_NAMELEN)
- {
- while(len > MAX_NAMELEN)
+ if(field == SBF_NAME)
+ {
+ float realsize;
+ float j;
+ realsize = sbar_size[i];
+ if(i+1 < sbar_num_fields)
+ if(sbar_field[i+1] == SBF_SEPARATOR)
{
- // this way should be the fastest with 100% safety :P
- // worst case: decolored length maxnamelen+1, and then only color codes =)
- // cutting of reallength - (decolored-length - maxnamelen) characters
- str = substring(str, 0, strlen(str) - (len-MAX_NAMELEN));
- len = strlen(strdecolorize(str));
+ realsize = (xmax - xmin) / sbar_fontsize_x;
+ print("remaining size: ", ftos(realsize), "\n");
+ for(j = 0; j < sbar_num_fields; ++j) if(j != i) if(sbar_field[j] != SBF_SEPARATOR)
+ realsize -= sbar_size[j] + 1;
+ realsize += 1;
+ print("remaining size: ", ftos(realsize), "\n");
}
- str = strcat(str, "^7...");
- len += 3;
- }
- len *= 8;
- } else
- len = 8*strlen(str);
+ str = textShortenToWidth(str, realsize, TRUE);
+ }
+ len = stringwidth(str, TRUE);
if(sbar_size[i] < len)
sbar_size[i] = len;
- pos_x += sbar_size[i] + 8;
+ pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
if(field == SBF_NAME) {
- tmp_x = sbar_size[i] + 8;
- drawcolorcodedstring(pos - tmp, str, '8 8', 1, DRAWFLAG_NORMAL);
+ tmp_x = sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+ drawcolorcodedstring(pos - tmp, str, sbar_fontsize, 1, DRAWFLAG_NORMAL);
} else {
- tmp_x = 8*strlen(str) + 8;
- drawstring(pos - tmp, str, '8 8', sbar_field_rgb, 1, DRAWFLAG_NORMAL);
+ tmp_x = len*sbar_fontsize_x + sbar_fontsize_x;
+ drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, 1, DRAWFLAG_NORMAL);
}
}
@@ -436,33 +490,21 @@
str = Sbar_GetField(pl, field);
- if(field == SBF_NAME) {
- len = strlen(strdecolorize(str));
- if(len > MAX_NAMELEN)
- {
- while(len > MAX_NAMELEN)
- {
- str = substring(str, 0, strlen(str) - (len-MAX_NAMELEN));
- len = strlen(strdecolorize(str));
- }
- str = strcat(str, "^7...");
- len += 3;
- }
- len *= 8;
- } else
- len = 8*strlen(str);
- //len = 8*strlen(str);
+ if(field == SBF_NAME)
+ str = textShortenToWidth(str, sbar_size[i], TRUE);
+ len = stringwidth(str, TRUE);
+
if(sbar_size[i] < len)
sbar_size[i] = len;
if(field == SBF_NAME) {
- tmp_x = len; // left or right aligned? let's put it right...
- drawcolorcodedstring(pos - tmp, str, '8 8', 1, DRAWFLAG_NORMAL);
+ tmp_x = sbar_fontsize_x*len; // left or right aligned? let's put it right...
+ drawcolorcodedstring(pos - tmp, str, sbar_fontsize, 1, DRAWFLAG_NORMAL);
} else {
- tmp_x = len; //strlen(str);
- drawstring(pos - tmp, str, '8 8', sbar_field_rgb, 1, DRAWFLAG_NORMAL);
+ tmp_x = sbar_fontsize_x*len; //strlen(str);
+ drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, 1, DRAWFLAG_NORMAL);
}
- pos_x -= sbar_size[i] + 8;
+ pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
}
}
}
@@ -475,6 +517,12 @@
float specs, i;
float center_x;
string str;
+
+ sbar_fontsize = stov(cvar_string("sbar_fontsize"));
+ if(sbar_fontsize_x == 0)
+ sbar_fontsize = '8 8 0';
+ if(sbar_fontsize_y == 0)
+ sbar_fontsize_y = sbar_fontsize_x;
xmin = vid_conwidth / 5;
ymin = 20;
@@ -495,50 +543,49 @@
pos_z = 0;
// Heading
- drawfont = FONT_USER+0;
- pos_x = center_x - 4*24;
+ drawfont = FONT_USER+1;
+ pos_x = center_x - stringwidth("Scoreboard", TRUE)*0.5*24;
drawstring(pos, "Scoreboard", '24 24', '1 1 1', 1, DRAWFLAG_NORMAL);
pos_x = xmin;
pos_y += 24 + 4;
- drawfont = FONT_DEFAULT;
// Titlebar background:
tmp_x = sbwidth;
- tmp_y = 8;
+ tmp_y = sbar_fontsize_y;
drawfill(pos - '1 1', tmp + '2 2', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
for(i = 0; i < sbar_num_fields; ++i)
{
if(sbar_field[i] == SBF_SEPARATOR)
break;
- drawstring(pos, sbar_title[i], '8 8', '1 1 1', 1, DRAWFLAG_NORMAL);
- pos_x += sbar_size[i] + 8;
+ drawstring(pos, sbar_title[i], sbar_fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+ pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
}
if(sbar_field[i] == SBF_SEPARATOR)
{
- pos_x = xmax + 8;
+ pos_x = xmax + sbar_fontsize_x;
tmp_y = tmp_z = 0;
for(i = sbar_num_fields-1; i > 0; --i)
{
if(sbar_field[i] == SBF_SEPARATOR)
break;
- pos_x -= sbar_size[i] + 8;
+ pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
/**
* FTEQCC BUG!
* Using the following line will fuck it all up:
**
* tmp_x = sbar_size[i] - strlen(sbar_title[i])*8;
*/
- tmp_x = sbar_size[i];
- tmp_x -= strlen(sbar_title[i])*8;
- drawstring(pos + tmp, sbar_title[i], '8 8', '1 1 1', 1, DRAWFLAG_NORMAL);
+ tmp_x = sbar_fontsize_x*sbar_size[i];
+ tmp_x -= stringwidth(sbar_title[i], FALSE)*sbar_fontsize_x;
+ drawstring(pos + tmp, sbar_title[i], sbar_fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
}
}
pos_x = xmin;
- pos_y += 12;
+ pos_y += 1.5 * sbar_fontsize_y;
sbar_save = sbar;
sbar = '0 0 0';
@@ -580,7 +627,7 @@
specs = 4;
tmp_x = sbwidth;
- tmp_y = 10 * specs;
+ tmp_y = 1.25 * sbar_fontsize_y * specs;
drawfill(pos - '1 1', tmp + '2 0', rgb, 0.2, DRAWFLAG_NORMAL);
for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
@@ -588,14 +635,14 @@
if(pl.sb_team != tm.sb_team)
continue;
Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 0);
- pos_y += 10;
- tmp_y -= 10;
+ pos_y += 1.25 * sbar_fontsize_y;
+ tmp_y -= 1.25 * sbar_fontsize_y;
}
- pos_y += tmp_y + 12;
+ pos_y += tmp_y + 1.5 * sbar_fontsize_y;
}
// rgb := tempvector :)
- rgb = pos + '0 12 0';
- pos_y += 24;
+ rgb = pos + '0 1.5 0' * sbar_fontsize_y;
+ pos_y += 3 * sbar_fontsize_y;
specs = 0;
for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
{
@@ -603,12 +650,12 @@
continue;
//drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 1);
- pos += '0 10 0';
+ pos += '0 1.25 0' * sbar_fontsize_y;
++specs;
}
if(specs)
- drawstring(rgb, "Spectators", '8 8 0', '1 1 1', 1, 0);
+ drawstring(rgb, "Spectators", sbar_fontsize, '1 1 1', 1, 0);
}
sbar = sbar_save;
}
@@ -727,7 +774,7 @@
drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
x = pos_x;
pos_x += 5*8;
- pos_x -= strlen(ftos(pl.sb_frags))*8;
+ pos_x -= stringwidth(ftos(pl.sb_frags), FALSE)*8;
drawstring(pos, ftos(pl.sb_frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
pos_x = x;
if(is_self)
@@ -751,7 +798,7 @@
drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
x = pos_x;
pos_x += 5*8;
- pos_x -= strlen(ftos(frags))*8;
+ pos_x -= stringwidth(ftos(frags), FALSE)*8;
drawstring(pos, ftos(frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
pos_x = x;
if(is_self)
Modified: trunk/data/qcsrc/common/campaign_file.qc
===================================================================
--- trunk/data/qcsrc/common/campaign_file.qc 2008-07-10 06:04:04 UTC (rev 3805)
+++ trunk/data/qcsrc/common/campaign_file.qc 2008-07-10 07:10:23 UTC (rev 3806)
@@ -35,7 +35,7 @@
#define CAMPAIGN_GETARG0 if(i >= entlen)
#define CAMPAIGN_GETARG1 CAMPAIGN_GETARG0 error("syntax error in campaign file: line has not enough fields");
-#define CAMPAIGN_GETARG2 CAMPAIGN_GETARG1 a = argv(i++);
+#define CAMPAIGN_GETARG2 CAMPAIGN_GETARG1 a = argv(++i);
#define CAMPAIGN_GETARG3 CAMPAIGN_GETARG2 if(a == ",")
#define CAMPAIGN_GETARG4 CAMPAIGN_GETARG3 a = "";
#define CAMPAIGN_GETARG5 CAMPAIGN_GETARG4 else
@@ -43,7 +43,7 @@
// What you're seeing here is what people will do when your compiler supports
// C-style macros but no line continuations.
- i = 0;
+ i = -1; // starts at -1 so I don't need postincrement; that is, i points to BEFORE the current arg!
CAMPAIGN_GETARG; campaign_gametype[campaign_entries] = strzone(a);
CAMPAIGN_GETARG; campaign_mapname[campaign_entries] = strzone(a);
CAMPAIGN_GETARG; campaign_bots[campaign_entries] = stof(a);
Modified: trunk/data/qcsrc/common/mapinfo.qc
===================================================================
--- trunk/data/qcsrc/common/mapinfo.qc 2008-07-10 06:04:04 UTC (rev 3805)
+++ trunk/data/qcsrc/common/mapinfo.qc 2008-07-10 07:10:23 UTC (rev 3806)
@@ -133,12 +133,12 @@
i = stof(s);
// now store all the stuff
- bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_bspname);
- bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_title);
- bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_description);
- bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_author);
- bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, ftos(MapInfo_Map_supportedGametypes));
- bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, ftos(MapInfo_Map_supportedFeatures));
+ bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i, MapInfo_Map_bspname);
+ bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_title);
+ bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_description);
+ bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_author);
+ bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedGametypes));
+ bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedFeatures));
}
float MapInfo_Cache_Retrieve(string map)
@@ -154,12 +154,12 @@
i = stof(s);
// now retrieve all the stuff
- MapInfo_Map_bspname = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
- MapInfo_Map_title = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
- MapInfo_Map_description = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
- MapInfo_Map_author = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
- MapInfo_Map_supportedGametypes = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++));
- MapInfo_Map_supportedFeatures = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++));
+ MapInfo_Map_bspname = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i);
+ MapInfo_Map_title = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i);
+ MapInfo_Map_description = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i);
+ MapInfo_Map_author = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i);
+ MapInfo_Map_supportedGametypes = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i));
+ MapInfo_Map_supportedFeatures = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i));
return 1;
}
@@ -255,7 +255,7 @@
_MapInfo_filtered = buf_create();
}
MapInfo_count = 0;
- for(i = 0, j = 0; i < _MapInfo_globcount; ++i)
+ for(i = 0, j = -1; i < _MapInfo_globcount; ++i)
{
if(MapInfo_Get_ByName(_MapInfo_GlobItem(i), 1, 0) == 2) // if we generated one... BAIL OUT and let the caller continue in the next frame.
if(pAbortOnGenerate)
@@ -265,9 +265,9 @@
return 0;
}
if(((MapInfo_Map_supportedGametypes & pGametype) != 0) && ((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures))
- bufstr_set(_MapInfo_filtered, j++, ftos(i));
+ bufstr_set(_MapInfo_filtered, ++j, ftos(i));
}
- MapInfo_count = j;
+ MapInfo_count = j + 1;
MapInfo_ClearTemps();
return 1;
}
Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc 2008-07-10 06:04:04 UTC (rev 3805)
+++ trunk/data/qcsrc/common/util.qc 2008-07-10 07:10:23 UTC (rev 3806)
@@ -75,13 +75,13 @@
s = strzone(s);
lleft = l;
- for (i = 0;i < strlen(s);i++)
+ for (i = 0;i < strlen(s);++i)
{
if (substring(s, i, 2) == "\\n")
{
callback("\n");
lleft = l;
- i++;
+ ++i;
}
else if (substring(s, i, 1) == "\n")
{
@@ -98,7 +98,7 @@
}
else
{
- for (j = i+1;j < strlen(s);j++)
+ for (j = i+1;j < strlen(s);++j)
// ^^ this skips over the first character of a word, which
// is ALWAYS part of the word
// this is safe since if i+1 == strlen(s), i will become
More information about the nexuiz-commits
mailing list