#include "miscfunctions.qh"
-#include "hud.qh"
+#include "autocvars.qh"
+#include "hud/_mod.qh"
+#include "main.qh"
-#include "../common/command/generic.qh"
+#include <common/command/_mod.qh>
-#include "../common/teams.qh"
+#include <common/teams.qh>
-#include "../lib/csqcmodel/cl_model.qh"
+#include <lib/csqcmodel/cl_model.qh>
void AuditLists()
void MoveToLast(entity e)
{
AuditLists();
- other = e.sort_next;
- while(other)
+ entity ent = e.sort_next;
+ while(ent)
{
- SORT_SWAP(other, e);
- other = e.sort_next;
+ SORT_SWAP(ent, e);
+ ent = e.sort_next;
}
AuditLists();
}
float RegisterTeam(entity Team)
{
+ assert_once(Team.team, eprint(Team));
entity tm;
AuditLists();
for(tm = teams.sort_next; tm; tm = tm.sort_next)
entity GetTeam(int Team, bool add)
{
+ TC(int, Team); TC(bool, add);
int num = (Team == NUM_SPECTATOR) ? 16 : Team;
if(teamslots[num])
return teamslots[num];
if (!add)
- return world;
- entity tm = new(team);
- make_pure(tm);
+ return NULL;
+ entity tm = new_pure(team);
tm.team = Team;
teamslots[num] = tm;
RegisterTeam(tm);
return false;
}
-vector rotate(vector v, float a)
-{
- vector w = '0 0 0';
- // FTEQCC SUCKS AGAIN
- w.x = v.x * cos(a) + v.y * sin(a);
- w.y = -1 * v.x * sin(a) + v.y * cos(a);
- return w;
-}
-
// decolorizes and team colors the player name when needed
string playername(string thename, float teamid)
{
+ TC(int, teamid);
string t;
if (teamplay)
{
return vec;
}
-void dummyfunction(float a1, float a2, float a3, float a4, float a5, float a6, float a7, float a8)
+bool projected_on_screen(vector screen_pos)
{
+ return screen_pos.z >= 0
+ && screen_pos.x >= 0
+ && screen_pos.y >= 0
+ && screen_pos.x < vid_conwidth
+ && screen_pos.y < vid_conheight;
}
float expandingbox_sizefactor_from_fadelerp(float fadelerp)
return boxsize * (0.5 * (1 - sz));
}
+// NOTE base is the central value
+// freq: circle frequency, = 2*pi*frequency in hertz
+// start_pos:
+// -1 start from the lower value
+// 0 start from the base value
+// 1 start from the higher value
+float blink_synced(float base, float range, float freq, float start_time, int start_pos)
+{
+ // note:
+ // RMS = sqrt(base^2 + 0.5 * range^2)
+ // thus
+ // base = sqrt(RMS^2 - 0.5 * range^2)
+ // ensure RMS == 1
+
+ return base + range * sin((time - start_time - (M_PI / 2) * start_pos) * freq);
+}
+
+float blink(float base, float range, float freq)
+{
+ return blink_synced(base, range, freq, 0, 0);
+}
+
void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag)
{
vector line_dim = '0 0 0';
void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float theAlpha, float drawflag)
{
+ pos = HUD_Shift(pos);
+ sz = HUD_Scale(sz);
+ area = HUD_Scale(area);
+
vector current_pos = '0 0 0', end_pos, new_size = '0 0 0', ratio = '0 0 0';
end_pos = pos + area;
drawpic_skin(position, pic, theScale, rgb, theAlpha * fadelerp, flag);
}
+void HUD_Scale_Disable()
+{
+ hud_scale = '1 1 0';
+ hud_shift = '0 0 0';
+ drawfontscale = hud_scale;
+}
+
+void HUD_Scale_Enable()
+{
+ hud_scale = hud_scale_current;
+ hud_shift = hud_shift_current;
+ drawfontscale = hud_scale;
+}
+
+vector HUD_Scale(vector v)
+{
+ v.x = HUD_ScaleX(v.x);
+ v.y = HUD_ScaleY(v.y);
+ return v;
+}
+
+vector HUD_Shift(vector v)
+{
+ v.x = HUD_ShiftX(v.x);
+ v.y = HUD_ShiftY(v.y);
+ return v;
+}
+
+float stringwidth(string text, float handleColors, vector sz)
+{
+ vector dfs = drawfontscale;
+ drawfontscale = '1 1 0';
+ float r = stringwidth_builtin(text, handleColors, sz);
+ drawfontscale = dfs;
+ return r;
+}
+
+#define SET_POS_AND_SZ_Y_ASPECT(allow_colors) MACRO_BEGIN \
+ float textaspect, oldsz; \
+ vector dfs = drawfontscale; \
+ drawfontscale = '1 1 0'; \
+ textaspect = stringwidth(text, allow_colors, '1 1 1' * sz.y) / sz.y; \
+ drawfontscale = dfs; \
+ if(sz.x/sz.y > textaspect) { \
+ oldsz = sz.x; \
+ sz.x = sz.y * textaspect; \
+ pos.x += (oldsz - sz.x) * 0.5; \
+ } else { \
+ oldsz = sz.y; \
+ sz.y = sz.x / textaspect; \
+ pos.y += (oldsz - sz.y) * 0.5; \
+ } \
+MACRO_END
+
// drawstring wrapper to draw a string as large as possible with preserved aspect ratio into a box
void drawstring_aspect(vector pos, string text, vector sz, vector color, float theAlpha, float drawflag) {
SET_POS_AND_SZ_Y_ASPECT(false);
float sz;
sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
+ drawfontscale = hud_scale * sz;
+ vector dfs = drawfontscale;
drawfontscale = sz * '1 1 0';
- dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
- drawstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth(text, false, theScale * (sz / drawfontscale.x)) / (theScale.x * sz)), text, theScale * (sz / drawfontscale.x), rgb, theAlpha * (1 - fadelerp), flag);
+ float textaspect = stringwidth_builtin(text, false, theScale * (sz / drawfontscale.x)) / (theScale.x * sz);
+ drawfontscale = dfs;
+ drawstring(position + expandingbox_resize_centered_box_offset(sz, theScale, textaspect), text, HUD_Scale(theScale * (sz / drawfontscale.x)), rgb, theAlpha * (1 - fadelerp), flag);
// width parameter:
- // (scale_x * sz / drawfontscale_x) * drawfontscale_x * SIZE1 / (scale_x * sz)
+ // (scale_x * sz / drawfontscale.x) * drawfontscale.x * SIZE1 / (scale_x * sz)
// SIZE1
- drawfontscale = '1 1 0';
+ drawfontscale = hud_scale;
}
// drawstring wrapper to draw a string as large as possible with preserved aspect ratio into a box
float sz;
sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
- drawfontscale = sz * '1 1 0';
- dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
- drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth(text, true, theScale * (sz / drawfontscale.x)) / (theScale.x * sz)), text, theScale * (sz / drawfontscale.x), theAlpha * (1 - fadelerp), flag);
- drawfontscale = '1 1 0';
+ drawfontscale = hud_scale * sz;
+ // eventually replace with drawcolorcodedstring
+ drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth_builtin(text, true, theScale * (sz / drawfontscale.x)) / (theScale.x * sz)), text, theScale * (sz / drawfontscale.x), theAlpha * (1 - fadelerp), flag);
+ drawfontscale = hud_scale;
}
void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, float theAlpha, float drawflag, float fadelerp) {
drawcolorcodedstring_expanding(pos, text, '1 1 0' * sz.y, theAlpha, drawflag, fadelerp);
}
+void update_mousepos()
+{
+ mousepos += getmousepos() * autocvar_menu_mouse_speed;
+ mousepos.x = bound(0, mousepos.x, vid_conwidth);
+ mousepos.y = bound(0, mousepos.y, vid_conheight);
+}
+
// this draws the triangles of a model DIRECTLY. Don't expect high performance, really...
float PolyDrawModelSurface(entity e, float i_s)
{
for(i_t = 0; i_t < n_t; ++i_t)
{
tri = getsurfacetriangle(e, i_s, i_t);
- R_BeginPolygon(tex, 0);
+ R_BeginPolygon(tex, 0, false);
R_PolygonVertex(getsurfacepoint(e, i_s, tri.x), getsurfacepointattribute(e, i_s, tri.x, SPA_TEXCOORDS0), '1 1 1', 1);
R_PolygonVertex(getsurfacepoint(e, i_s, tri.y), getsurfacepointattribute(e, i_s, tri.y, SPA_TEXCOORDS0), '1 1 1', 1);
R_PolygonVertex(getsurfacepoint(e, i_s, tri.z), getsurfacepointattribute(e, i_s, tri.z, SPA_TEXCOORDS0), '1 1 1', 1);
void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag)
{
- float x, y, q, d;
vector ringsize, v, t;
ringsize = radi * '1 1 0';
-
- x = cos(f * 2 * M_PI);
- y = sin(f * 2 * M_PI);
- q = fabs(x) + fabs(y);
- x /= q;
- y /= q;
+ centre = HUD_Shift(centre);
+ ringsize = HUD_Scale(ringsize);
if(f >= 1)
{
// draw full rectangle
- R_BeginPolygon(pic, drawflag);
+ R_BeginPolygon(pic, drawflag, true);
v = centre; t = '0.5 0.5 0';
v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
v.y -= 0.5 * ringsize.y; t -= '0.5 -0.5 0';
R_PolygonVertex(v, t, rgb, a);
R_EndPolygon();
+ return; // Complete rectangle, nothing more needed.
+ }
- d = q - 1;
- if(d > 0)
- {
- R_BeginPolygon(pic, drawflag);
- v = centre; t = '0.5 0.5 0';
- R_PolygonVertex(v, t, rgb, a);
+ float co = cos(f * 2 * M_PI);
+ float si = sin(f * 2 * M_PI);
+ float q = fabs(co) + fabs(si);
+ co /= q;
+ si /= q;
- v = centre; t = '0.5 0.5 0';
- v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
- R_PolygonVertex(v, t, rgb, a);
- }
- }
- else if(f > 0.75)
+ if(f > 0.75)
{
- // draw upper and first triangle
- R_BeginPolygon(pic, drawflag);
+ // draw upper half in full
+ R_BeginPolygon(pic, drawflag, true);
v = centre; t = '0.5 0.5 0';
v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
R_EndPolygon();
- R_BeginPolygon(pic, drawflag);
+ // draw clipped lower half as a quad
+ R_BeginPolygon(pic, drawflag, true);
v = centre; t = '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
v = centre; t = '0.5 0.5 0';
v.y -= 0.5 * ringsize.y; t -= '0.5 -0.5 0';
R_PolygonVertex(v, t, rgb, a);
-
- d = q - 0.75;
- if(d <= 0)
- R_EndPolygon();
}
else if(f > 0.5)
{
- // draw upper triangle
- R_BeginPolygon(pic, drawflag);
+ // draw upper half in full
+ R_BeginPolygon(pic, drawflag, true);
v = centre; t = '0.5 0.5 0';
v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
R_EndPolygon();
+ // draw clipped lower half as a triangle
+ R_BeginPolygon(pic, drawflag, true);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
- d = q - 0.5;
- if(d > 0)
- {
- R_BeginPolygon(pic, drawflag);
- v = centre; t = '0.5 0.5 0';
- R_PolygonVertex(v, t, rgb, a);
-
- v = centre; t = '0.5 0.5 0';
- v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
- R_PolygonVertex(v, t, rgb, a);
- }
+ v = centre; t = '0.5 0.5 0';
+ v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
}
else if(f > 0.25)
{
- // draw first triangle
- R_BeginPolygon(pic, drawflag);
+ // draw clipped lower half as a quad
+ R_BeginPolygon(pic, drawflag, true);
v = centre; t = '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
v = centre; t = '0.5 0.5 0';
v.y += 0.5 * ringsize.y; t += '0.5 -0.5 0';
R_PolygonVertex(v, t, rgb, a);
-
- d = q - 0.25;
- if(d <= 0)
- R_EndPolygon();
}
- else
+ else if (f > 0)
{
- d = q;
- if(d > 0)
- {
- R_BeginPolygon(pic, drawflag);
- v = centre; t = '0.5 0.5 0';
- R_PolygonVertex(v, t, rgb, a);
-
- v = centre; t = '0.5 0.5 0';
- v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
- R_PolygonVertex(v, t, rgb, a);
- }
- }
+ // draw clipped lower half as a triangle
+ R_BeginPolygon(pic, drawflag, true);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
- if(d > 0)
- {
v = centre; t = '0.5 0.5 0';
- v.x += x * 0.5 * ringsize.x; t += x * '0.5 0.5 0';
- v.y += y * 0.5 * ringsize.y; t += y * '0.5 -0.5 0';
+ v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
R_PolygonVertex(v, t, rgb, a);
- R_EndPolygon();
}
-}
-
-vector getplayerorigin(int pl)
-{
- entity e;
-
- e = CSQCModel_server2csqc(pl + 1);
- if(e)
- return e.origin;
-
- e = entcs_receiver[pl];
- if(e)
- return e.origin;
-
- return GETPLAYERORIGIN_ERROR;
-}
-
-float getplayeralpha(float pl)
-{
- entity e;
-
- e = CSQCModel_server2csqc(pl + 1);
- if(e)
- return e.alpha;
-
- return 1;
-}
-
-vector getcsqcplayercolor(float pl)
-{
- entity e;
-
- e = CSQCModel_server2csqc(pl);
- if(e)
+ else
{
- if(e.colormap > 0)
- return colormapPaletteColor(((e.colormap >= 1024) ? e.colormap : stof(getplayerkeyvalue(e.colormap - 1, "colors"))) & 0x0F, true);
+ // Nothing to draw.
+ return;
}
- return '1 1 1';
+ // The last, moving vertex.
+ v = centre; t = '0.5 0.5 0';
+ v.x += co * 0.5 * ringsize.x; t += co * '0.5 0.5 0';
+ v.y += si * 0.5 * ringsize.y; t += si * '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
}
-float getplayerisdead(float pl)
-{
- entity e;
-
- e = CSQCModel_server2csqc(pl + 1);
- if(e)
- return e.csqcmodel_isdead;
-
- return false;
-}
-
-void URI_Get_Callback(int id, float status, string data)
+/** engine callback */
+void URI_Get_Callback(int id, int status, string data)
{
+ TC(int, id); TC(int, status);
if(url_URI_Get_Callback(id, status, data))
{
// handled
}
else
{
- LOG_INFOF("Received HTTP request data for an invalid id %d.\n", id);
+ LOG_INFOF("Received HTTP request data for an invalid id %d.", id);
}
}
-void draw_beginBoldFont()
-{
- drawfont = FONT_USER+2;
-}
-
-void draw_endBoldFont()
-{
- drawfont = FONT_USER+1;
-}
-
void Accuracy_LoadLevels()
{
if(autocvar_accuracy_color_levels != acc_color_levels)
{
- if(acc_color_levels)
- strunzone(acc_color_levels);
- acc_color_levels = strzone(autocvar_accuracy_color_levels);
+ strcpy(acc_color_levels, autocvar_accuracy_color_levels);
acc_levels = tokenize_console(acc_color_levels);
if(acc_levels > MAX_ACCURACY_LEVELS)
acc_levels = MAX_ACCURACY_LEVELS;
if(acc_levels < 2)
- LOG_INFO("Warning: accuracy_color_levels must contain at least 2 values\n");
+ LOG_INFO("Warning: accuracy_color_levels must contain at least 2 values");
int i;
for(i = 0; i < acc_levels; ++i)
color = color + factor * (acc_col[j+1] - color);
return color;
}
-