From 76920a2058ef94e7631fdc5f2e4fba562264021c Mon Sep 17 00:00:00 2001 From: div0 Date: Thu, 3 Sep 2009 06:23:51 +0000 Subject: [PATCH] race: big preparation for higher-res timer; see the #ifdef in util.qh for how to switch to 100ths accuracy (this however NEEDS sys_ticrate to be lowered) git-svn-id: svn://svn.icculus.org/nexuiz/trunk@7603 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/client/Main.qc | 4 ++-- data/qcsrc/client/sbar.qc | 38 +++++++++++++++--------------- data/qcsrc/common/util.qc | 13 +++++++++- data/qcsrc/common/util.qh | 19 +++++++++++++++ data/qcsrc/server/miscfunctions.qc | 14 +++++------ data/qcsrc/server/race.qc | 30 +++++++++++------------ 6 files changed, 74 insertions(+), 44 deletions(-) diff --git a/data/qcsrc/client/Main.qc b/data/qcsrc/client/Main.qc index b9b26ac7f..b8c389e12 100644 --- a/data/qcsrc/client/Main.qc +++ b/data/qcsrc/client/Main.qc @@ -988,7 +988,7 @@ void Net_ReadRace() case RACE_NET_PENALTY_RACE: race_penaltyeventtime = time; - race_penaltytime = ReadByte(); + race_penaltytime = ReadShort(); //race_penaltyaccumulator += race_penaltytime; if(race_penaltyreason) strunzone(race_penaltyreason); @@ -997,7 +997,7 @@ void Net_ReadRace() case RACE_NET_PENALTY_QUALIFYING: race_penaltyeventtime = time; - race_penaltytime = ReadByte(); + race_penaltytime = ReadShort(); race_penaltyaccumulator += race_penaltytime; if(race_penaltyreason) strunzone(race_penaltyreason); diff --git a/data/qcsrc/client/sbar.qc b/data/qcsrc/client/sbar.qc index 327c303ee..0c3e1e3fc 100644 --- a/data/qcsrc/client/sbar.qc +++ b/data/qcsrc/client/sbar.qc @@ -1200,7 +1200,7 @@ string MakeRaceString(float cp, float mytime, float histime, float lapdelta, str { if(mytime > 0) { - timestr = strcat("+", ftos_decimals(+mytime, 1)); + timestr = strcat("+", ftos_decimals(+mytime, TIME_DECIMALS)); col = "^1"; } else if(mytime == 0) @@ -1210,7 +1210,7 @@ string MakeRaceString(float cp, float mytime, float histime, float lapdelta, str } else { - timestr = strcat("-", ftos_decimals(-mytime, 1)); + timestr = strcat("-", ftos_decimals(-mytime, TIME_DECIMALS)); col = "^2"; } @@ -1228,9 +1228,9 @@ string MakeRaceString(float cp, float mytime, float histime, float lapdelta, str else if(histime > 0) // anticipation { if(mytime >= histime) - timestr = strcat("+", ftos_decimals(mytime - histime, 1)); + timestr = strcat("+", ftos_decimals(mytime - histime, TIME_DECIMALS)); else - timestr = mmsss(histime * 10); + timestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(histime)); col = "^3"; } else @@ -1301,20 +1301,20 @@ void Sbar_Score(float margin) score = me.(scores[ps_primary]); - racemin = floor(score/600); - racesec = floor((score - racemin*600)/10); - racemsec = score - racemin*600 - racesec*10; + racemin = floor(score/(60 * TIME_FACTOR)); + racesec = floor((score - racemin*(60 * TIME_FACTOR))/TIME_FACTOR); + racemsec = score - racemin*60*TIME_FACTOR - racesec*TIME_FACTOR; if (pl && ((!(scores_flags[ps_primary] & SFL_ZERO_IS_WORST)) || score)) { // distribution display distribution = me.(scores[ps_primary]); distribution -= pl.(scores[ps_primary]); - if (distribution < 10 && distribution > -10) + if (distribution < TIME_FACTOR && distribution > -TIME_FACTOR) distmsec = fabs(distribution); else { - distsec = floor(fabs(distribution)/10); - distmsec = fabs(distribution) - distsec*10; + distsec = floor(fabs(distribution)/TIME_FACTOR); + distmsec = fabs(distribution) - distsec*TIME_FACTOR; } if (distribution < 100 && distribution > -100) @@ -1335,7 +1335,7 @@ void Sbar_Score(float margin) drawpic(minuspos, "gfx/hud/num_plus", '16 16 0', distribution_color, sbar_alpha_fg, DRAWFLAG_ADDITIVE); } - Sbar_DrawXNum(bottomright - element_offset - score_offset + '180 -6 0', distmsec, 1, 16, distribution_color, 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL); + Sbar_DrawXNum(bottomright - element_offset - score_offset + '180 -6 0', distmsec, -TIME_DECIMALS, 16, distribution_color, 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL); Sbar_DrawXNum(bottomright - element_offset - score_offset + '112 -6 0', distsec, 4, 16, distribution_color, 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL); drawpic(bottomright - element_offset - score_offset + '170 -6 0', "gfx/hud/num_dot", '16 16 0', distribution_color, sbar_alpha_fg, DRAWFLAG_ADDITIVE); } @@ -1344,7 +1344,7 @@ void Sbar_Score(float margin) if (distribution <= 0 || distribution == score) // draw the highlight background behind the timer if we have the lead drawpic(bottomright - element_offset - score_offset + '20 10 0', "gfx/hud/sb_highlight_4", '178 28 0', '1 1 1', sbar_alpha_fg, DRAWFLAG_NORMAL); - Sbar_DrawXNum(bottomright - element_offset - score_offset + '166 10 0', racemsec, 1, 30, '1 1 1', 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL); + Sbar_DrawXNum(bottomright - element_offset - score_offset + '166 10 0', racemsec, -TIME_DECIMALS, 30, '1 1 1', 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL); Sbar_DrawXNum(bottomright - element_offset - score_offset + '96 10 0', racesec, -2, 30, '1 1 1', 0, 0, sbar_alpha_fg, DRAWFLAG_NORMAL); drawpic(bottomright - element_offset - score_offset + '145 10 0', "gfx/hud/num_dot", '30 30 0', '1 1 1', sbar_alpha_fg, DRAWFLAG_ADDITIVE); @@ -1514,21 +1514,21 @@ void Sbar_Score(float margin) if(race_checkpoint != 254) { if(race_time && race_previousbesttime) - s = MakeRaceString(race_checkpoint, race_time / 10 - race_previousbesttime / 10, 0, 0, race_previousbestname); + s = MakeRaceString(race_checkpoint, TIME_DECODE(race_time) - TIME_DECODE(race_previousbesttime), 0, 0, race_previousbestname); else s = MakeRaceString(race_checkpoint, 0, -1, 0, race_previousbestname); if(race_time) - forcetime = mmsss(race_time); + forcetime = TIME_ENCODED_TOSTRING(race_time); } } else { if(race_laptime && race_nextbesttime && race_nextcheckpoint != 254) { - a = bound(0, 2 - ((race_laptime + race_nextbesttime/10) - (time + race_penaltyaccumulator/10)), 1); + a = bound(0, 2 - ((race_laptime + TIME_DECODE(race_nextbesttime)) - (time + TIME_DECODE(race_penaltyaccumulator))), 1); if(a > 0) // next one? { - s = MakeRaceString(race_nextcheckpoint, (time + race_penaltyaccumulator/10) - race_laptime, race_nextbesttime / 10, 0, race_nextbestname); + s = MakeRaceString(race_nextcheckpoint, (time + TIME_DECODE(race_penaltyaccumulator)) - race_laptime, TIME_DECODE(race_nextbesttime), 0, race_nextbestname); } } } @@ -1560,7 +1560,7 @@ void Sbar_Score(float margin) if(race_laptime && race_checkpoint != 255) { - s = mmsss(10*(time + race_penaltyaccumulator/10 - race_laptime)); + s = TIME_ENCODED_TOSTRING(TIME_ENCODE(time + TIME_DECODE(race_penaltyaccumulator) - race_laptime)); drawstring(m - '16 0 0' * stringwidth(s, FALSE), s, '32 32 0', '1 1 1', sbar_alpha_fg * a, DRAWFLAG_NORMAL); } } @@ -1569,14 +1569,14 @@ void Sbar_Score(float margin) if(race_mycheckpointtime) { a = bound(0, 2 - (time - race_mycheckpointtime), 1); - s = MakeRaceString(race_mycheckpoint, race_mycheckpointdelta / 10, -!race_mycheckpointenemy, race_mycheckpointlapsdelta, race_mycheckpointenemy); + s = MakeRaceString(race_mycheckpoint, TIME_DECODE(race_mycheckpointdelta), -!race_mycheckpointenemy, race_mycheckpointlapsdelta, race_mycheckpointenemy); dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0) drawcolorcodedstring(m - '0 16 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL); } if(race_othercheckpointtime && race_othercheckpointenemy != "") { a = bound(0, 2 - (time - race_othercheckpointtime), 1); - s = MakeRaceString(race_othercheckpoint, -race_othercheckpointdelta / 10, -!race_othercheckpointenemy, race_othercheckpointlapsdelta, race_othercheckpointenemy); + s = MakeRaceString(race_othercheckpoint, -TIME_DECODE(race_othercheckpointdelta), -!race_othercheckpointenemy, race_othercheckpointlapsdelta, race_othercheckpointenemy); dummyfunction(0, 0, 0, 0, 0, 0, 0, 0); // work around DP bug (set OFS_PARAM5 to 0) drawcolorcodedstring(m - '0 0 0' - '8 0 0' * stringwidth(s, TRUE), s, '16 16 0', sbar_alpha_fg * a, DRAWFLAG_NORMAL); } diff --git a/data/qcsrc/common/util.qc b/data/qcsrc/common/util.qc index 289c62632..9e4e8b88b 100644 --- a/data/qcsrc/common/util.qc +++ b/data/qcsrc/common/util.qc @@ -442,6 +442,17 @@ string mmsss(float tenths) return strcat(ftos(minutes), ":", substring(s, 1, 2), ".", substring(s, 3, 1)); } +string mmssss(float hundredths) +{ + float minutes; + string s; + hundredths = floor(hundredths + 0.5); + minutes = floor(hundredths / 6000); + hundredths -= minutes * 6000; + s = ftos(10000 + hundredths); + return strcat(ftos(minutes), ":", substring(s, 1, 2), ".", substring(s, 3, 2)); +} + string ScoreString(float pFlags, float pValue) { string valstr; @@ -467,7 +478,7 @@ string ScoreString(float pFlags, float pValue) valstr = strcat(valstr, "th"); } else if(pFlags & SFL_TIME) - valstr = mmsss(pValue); + valstr = TIME_ENCODED_TOSTRING(pValue); else valstr = ftos(pValue); diff --git a/data/qcsrc/common/util.qh b/data/qcsrc/common/util.qh index e5ca0b77c..45ebad53d 100644 --- a/data/qcsrc/common/util.qh +++ b/data/qcsrc/common/util.qh @@ -57,7 +57,26 @@ float mod(float a, float b) { return a - (floor(a / b) * b); } #endif string GametypeNameFromType(float g); +#define TIME_TO_NTHS(t,n) floor((t) * (n) + 0.4) string mmsss(float t); +string mmssss(float t); + +#ifdef RACE_100THS +#define TIME_DECIMALS 2 +#define TIME_FACTOR 100 +#define TIME_ENCODED_TOSTRING(n) mmssss(n) +#define RACE_RECORD "/race100record/" +#define CTS_RECORD "/cts100record/" +#else +#define TIME_DECIMALS 1 +#define TIME_FACTOR 10 +#define TIME_ENCODED_TOSTRING(n) mmsss(n) +#define RACE_RECORD "/racerecord/" +#define CTS_RECORD "/ctsrecord/" +#endif +#define TIME_ENCODE(t) TIME_TO_NTHS(t, TIME_FACTOR) +#define TIME_DECODE(n) ((n) / TIME_FACTOR) + string ScoreString(float vflags, float value); vector cross(vector a, vector b); diff --git a/data/qcsrc/server/miscfunctions.qc b/data/qcsrc/server/miscfunctions.qc index 810b322f6..1d9c61341 100644 --- a/data/qcsrc/server/miscfunctions.qc +++ b/data/qcsrc/server/miscfunctions.qc @@ -2021,11 +2021,11 @@ string getrecords() { if (MapInfo_Get_ByID(i)) { - r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/racerecord/time"))); + r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "time"))); if (r == 0) continue; - h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/racerecord/netname")); - s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, mmsss(r)), " ", h, "\n"); + h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "netname")); + s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n"); ++rec; } } @@ -2037,11 +2037,11 @@ string getrecords() { if (MapInfo_Get_ByID(i)) { - r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/ctsrecord/time"))); + r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, CTS_RECORD, "time"))); if (r == 0) continue; - h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/ctsrecord/netname")); - s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, mmsss(r)), " ", h, "\n"); + h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, CTS_RECORD, "netname")); + s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n"); ++rec; } } @@ -2194,7 +2194,7 @@ void write_recordmarker(entity pl, float tstart, float dt) // also write a marker into demo files for demotc-race-record-extractor to find stuffcmd(pl, strcat( - strcat("//", strconv(2, 0, 0, GetGametype()), " RECORD SET ", mmsss(dt * 10)), + strcat("//", strconv(2, 0, 0, GetGametype()), " RECORD SET ", TIME_ENCODED_TOSTRING(TIME_ENCODE(dt))), " ", ftos(tstart), " ", ftos(dt), "\n")); } diff --git a/data/qcsrc/server/race.qc b/data/qcsrc/server/race.qc index 343acaa41..b553b4ed4 100644 --- a/data/qcsrc/server/race.qc +++ b/data/qcsrc/server/race.qc @@ -100,7 +100,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid) if(g_race_qualifying) t += e.race_penalty_accumulator; - t = floor(0.4 + 10 * t); // make integer + t = TIME_ENCODE(t); // make integer // adding just 0.4 so it rounds down in the .5 case (matching the timer display) if(tvalid) @@ -117,7 +117,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid) else { s = PlayerScore_Add(e, SP_RACE_TIME, 0); - snew = floor(0.4 + 10 * (time - game_starttime)); + snew = TIME_ENCODE(time - game_starttime); PlayerScore_Add(e, SP_RACE_TIME, snew - s); l = PlayerTeamScore_Add(e, SP_RACE_LAPS, ST_RACE_LAPS, 1); @@ -160,36 +160,36 @@ void race_SendTime(entity e, float cp, float t, float tvalid) string grecordholder; string rr; if(g_cts) - rr = "/ctsrecord/"; + rr = CTS_RECORD; else - rr = "/racerecord/"; + rr = RACE_RECORD; grecordtime = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time"))); grecordholder = db_get(ServerProgsDB, strcat(GetMapname(), rr, "netname")); if(grecordholder == e.netname) grecordholder = ""; if(grecordtime == 0) { - bprint(e.netname, "^7 set the all-time fastest lap record with ", mmsss(t), "\n"); + bprint(e.netname, "^7 set the all-time fastest lap record with ", TIME_ENCODED_TOSTRING(t), "\n"); db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(t)); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), e.netname); - write_recordmarker(e, time - t/10, t/10); + write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t)); } else if(t < grecordtime) { if(grecordholder == "") - bprint(e.netname, "^7 broke his all-time fastest lap record with ", mmsss(t), "\n"); + bprint(e.netname, "^7 broke his all-time fastest lap record with ", TIME_ENCODED_TOSTRING(t), "\n"); else - bprint(e.netname, "^7 broke ", grecordholder, "^7's all-time fastest lap record with ", mmsss(t), "\n"); + bprint(e.netname, "^7 broke ", grecordholder, "^7's all-time fastest lap record with ", TIME_ENCODED_TOSTRING(t), "\n"); db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(t)); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), e.netname); - write_recordmarker(e, time - t/10, t/10); + write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t)); } else { if(grecordholder == "") - bprint(e.netname, "^7's new fastest lap could not break his all-time fastest lap record of ", mmsss(grecordtime), "\n"); + bprint(e.netname, "^7's new fastest lap could not break his all-time fastest lap record of ", TIME_ENCODED_TOSTRING(grecordtime), "\n"); else - bprint(e.netname, "^7's new fastest lap could not break ", grecordholder, "^7's all-time fastest lap record of ", mmsss(grecordtime), "\n"); + bprint(e.netname, "^7's new fastest lap could not break ", grecordholder, "^7's all-time fastest lap record of ", TIME_ENCODED_TOSTRING(grecordtime), "\n"); } } @@ -251,7 +251,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid) } else { - WriteShort(MSG_ONE, floor(10 * (time - race_checkpoint_lasttimes[cp]) + 0.5)); + WriteShort(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp])); WriteByte(MSG_ONE, lself - lother); WriteString(MSG_ONE, oth.netname); // record holder } @@ -275,7 +275,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid) } else { - WriteShort(MSG_ONE, floor(10 * (time - othtime) + 0.5)); + WriteShort(MSG_ONE, TIME_ENCODE(time - othtime)); WriteByte(MSG_ONE, lother - lself); WriteString(MSG_ONE, e.netname); // record holder } @@ -703,7 +703,7 @@ void race_ImposePenaltyTime(entity pl, float penalty, string reason) WriteByte(MSG_ONE, SVC_TEMPENTITY); WriteByte(MSG_ONE, TE_CSQC_RACE); WriteByte(MSG_ONE, RACE_NET_PENALTY_QUALIFYING); - WriteByte(MSG_ONE, floor(0.4 + 10 * penalty)); + WriteShort(MSG_ONE, TIME_ENCODE(penalty)); WriteString(MSG_ONE, reason); }); } @@ -715,7 +715,7 @@ void race_ImposePenaltyTime(entity pl, float penalty, string reason) WriteByte(MSG_ONE, SVC_TEMPENTITY); WriteByte(MSG_ONE, TE_CSQC_RACE); WriteByte(MSG_ONE, RACE_NET_PENALTY_RACE); - WriteByte(MSG_ONE, floor(0.4 + 10 * penalty)); + WriteShort(MSG_ONE, TIME_ENCODE(penalty)); WriteString(MSG_ONE, reason); }); } -- 2.39.2