-// checkextension wrapper for log
-float sqrt(float f); // declared later
-float exp(float f); // declared later
-float pow(float f, float e); // declared later
-float checkextension(string s); // declared later
-float log_synth(float f)
-{
- float p, l;
- if(f < 0)
- return sqrt(-1); // nan? -inf?
- if(f == 0)
- return sqrt(-1); // ACTUALLY this should rather be -inf, but we cannot create a +inf in QC
- if(f + f == f)
- return l; // +inf
- if(f < 1)
- {
- f = 1 / f;
- p = -1;
- }
- else
- p = 1;
- while(f > 2)
- {
- f = sqrt(f);
- p *= 2;
- }
- // two steps are good enough
- l = ((6-f) * f - 5) / 4.32808512266689022212;
- l += exp(-l) * f - 1;
- l += exp(-l) * f - 1;
- return l * p;
-}
-float log(float f)
-{
- if(checkextension("DP_QC_LOG"))
- return log_builtin(f);
- else
- return log_synth(f);
-}
-
string wordwrap_buffer;
void wordwrap_buffer_put(string s)
// works for up to 10 decimals!
string ftos_decimals(float number, float decimals)
{
- string result;
- string tmp;
- float len;
-
- // if negative, cut off the sign first
- if(number < 0)
- return strcat("-", ftos_decimals(-number, decimals));
- // it now is always positive!
-
- // 3.516 -> 352
- number = floor(number * pow(10, decimals) + 0.5);
-
- // 352 -> "352"
- result = ftos(number);
- len = strlen(result);
- // does it have a decimal point (should not happen)? If there is one, it is always at len-7)
- // if ftos had messed it up, which should never happen: "34278.000000"
- if(len >= 7)
- if(substring(result, len - 7, 1) == ".")
- {
- dprint("ftos(integer) has comma? Can't be. Affected result: ", result, "\n");
- result = substring(result, 0, len - 7);
- len -= 7;
- }
- // "34278"
- if(decimals == 0)
- return result; // don't insert a point for zero decimals
- // is it too short? If yes, insert leading zeroes
- if(len <= decimals)
- {
- result = strcat(substring("0000000000", 0, decimals - len + 1), result);
- len = decimals + 1;
- }
- // and now... INSERT THE POINT!
- tmp = substring(result, len - decimals, decimals);
- result = strcat(substring(result, 0, len - decimals), ".", tmp);
- return result;
+ // we have sprintf...
+ return sprintf("%.*f", decimals, number);
}
float time;
fh = fopen(pFilename, FILE_READ);
if(fh < 0)
return db;
- if(stof(fgets(fh)) == DB_BUCKETS)
+ l = fgets(fh);
+ if(stof(l) == DB_BUCKETS)
{
i = 0;
while((l = fgets(fh)))
}
else
{
- // different count of buckets?
+ // different count of buckets, or a dump?
// need to reorganize the database then (SLOW)
- while((l = fgets(fh)))
+ //
+ // note: we also parse the first line (l) in case the DB file is
+ // missing the bucket count
+ do
{
n = tokenizebyseparator(l, "\\");
for(j = 2; j < n; j += 2)
db_put(db, argv(j-1), uri_unescape(argv(j)));
}
+ while((l = fgets(fh)));
}
fclose(fh);
return db;
else if (g == GAME_RACE) return "rc";
else if (g == GAME_NEXBALL) return "nexball";
else if (g == GAME_CTS) return "cts";
+ else if (g == GAME_FREEZETAG) return "freezetag";
+ else if (g == GAME_KEEPAWAY) return "ka";
return "dm";
}
return 1;
}
-// return name of given panel id
-string HUD_Panel_GetName(float id)
-{
- switch(id) {
- case HUD_PANEL_WEAPONICONS: return "weaponicons"; break;
- case HUD_PANEL_INVENTORY: return "inventory"; break;
- case HUD_PANEL_POWERUPS: return "powerups"; break;
- case HUD_PANEL_HEALTHARMOR: return "healtharmor"; break;
- case HUD_PANEL_NOTIFY: return "notify"; break;
- case HUD_PANEL_TIMER: return "timer"; break;
- case HUD_PANEL_RADAR: return "radar"; break;
- case HUD_PANEL_SCORE: return "score"; break;
- case HUD_PANEL_RACETIMER: return "racetimer"; break;
- case HUD_PANEL_VOTE: return "vote"; break;
- case HUD_PANEL_MODICONS: return "modicons"; break;
- case HUD_PANEL_PRESSEDKEYS: return "pressedkeys"; break;
- case HUD_PANEL_CHAT: return "chat"; break;
- case HUD_PANEL_ENGINEINFO: return "engineinfo"; break;
- default: return "";
- }
+vector vec2(vector v)
+{
+ v_z = 0;
+ return v;
+}
+
+#ifndef MENUQC
+vector NearestPointOnBox(entity box, vector org)
+{
+ vector m1, m2, nearest;
+
+ m1 = box.mins + box.origin;
+ m2 = box.maxs + box.origin;
+
+ nearest_x = bound(m1_x, org_x, m2_x);
+ nearest_y = bound(m1_y, org_y, m2_y);
+ nearest_z = bound(m1_z, org_z, m2_z);
+
+ return nearest;
+}
+#endif
+
+float vercmp_recursive(string v1, string v2)
+{
+ float dot1, dot2;
+ string s1, s2;
+ float r;
+
+ dot1 = strstrofs(v1, ".", 0);
+ dot2 = strstrofs(v2, ".", 0);
+ if(dot1 == -1)
+ s1 = v1;
+ else
+ s1 = substring(v1, 0, dot1);
+ if(dot2 == -1)
+ s2 = v2;
+ else
+ s2 = substring(v2, 0, dot2);
+
+ r = stof(s1) - stof(s2);
+ if(r != 0)
+ return r;
+
+ r = strcasecmp(s1, s2);
+ if(r != 0)
+ return r;
+
+ if(dot1 == -1)
+ if(dot2 == -1)
+ return 0;
+ else
+ return -1;
+ else
+ if(dot2 == -1)
+ return 1;
+ else
+ return vercmp_recursive(substring(v1, dot1 + 1, 999), substring(v2, dot2 + 1, 999));
+}
+
+float vercmp(string v1, string v2)
+{
+ if(strcasecmp(v1, v2) == 0) // early out check
+ return 0;
+
+ // "git" beats all
+ if(v1 == "git")
+ return 1;
+ if(v2 == "git")
+ return -1;
+
+ return vercmp_recursive(v1, v2);
}