2017-12-28 16:24:50 +00:00
|
|
|
#include "../plugin.h"
|
|
|
|
#include "ezquakeisms.h"
|
|
|
|
#include "hud.h"
|
|
|
|
#include "hud_editor.h"
|
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
plug2dfuncs_t *drawfuncs;
|
|
|
|
plugclientfuncs_t *clientfuncs;
|
|
|
|
plugfsfuncs_t *filefuncs;
|
|
|
|
pluginputfuncs_t *inputfuncs;
|
|
|
|
|
2020-07-01 05:32:21 +00:00
|
|
|
struct ezcl_s cl;
|
|
|
|
struct ezcls_s cls;
|
|
|
|
struct ezvid_s vid;
|
|
|
|
|
2017-12-28 16:24:50 +00:00
|
|
|
int sb_lines;
|
|
|
|
float scr_con_current;
|
|
|
|
int sb_showteamscores;
|
|
|
|
int sb_showscores;
|
|
|
|
int host_screenupdatecount;
|
|
|
|
float alphamul;
|
|
|
|
|
|
|
|
cvar_t *scr_newHud;
|
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
static void QDECL EZHud_UpdateVideo(int width, int height)
|
|
|
|
{
|
|
|
|
vid.width = width;
|
|
|
|
vid.height = height;
|
|
|
|
}
|
|
|
|
|
2017-12-28 16:24:50 +00:00
|
|
|
char *Cmd_Argv(int arg)
|
|
|
|
{
|
|
|
|
static char buf[4][128];
|
|
|
|
if (arg >= 4)
|
|
|
|
return "";
|
2019-09-04 07:59:40 +00:00
|
|
|
cmdfuncs->Argv(arg, buf[arg], sizeof(buf[arg]));
|
2017-12-28 16:24:50 +00:00
|
|
|
return buf[arg];
|
|
|
|
}
|
|
|
|
|
|
|
|
float infofloat(char *info, char *findkey, float def);
|
|
|
|
|
|
|
|
void Draw_SetOverallAlpha(float a)
|
|
|
|
{
|
|
|
|
alphamul = a;
|
|
|
|
}
|
|
|
|
void Draw_AlphaFillRGB(float x, float y, float w, float h, qbyte r, qbyte g, qbyte b, qbyte a)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
|
|
|
|
drawfuncs->Fill(x, y, w, h);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_Fill(float x, float y, float w, float h, qbyte pal)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colourpa(pal, alphamul);
|
|
|
|
drawfuncs->Fill(x, y, w, h);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
const char *ColorNameToRGBString (const char *newval)
|
|
|
|
{
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
byte *StringToRGB(const char *str)
|
|
|
|
{
|
2015-04-21 04:12:00 +00:00
|
|
|
static byte rgba[4];
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
2018-03-07 20:31:09 +00:00
|
|
|
while(*str && *str <= ' ')
|
2015-04-21 04:12:00 +00:00
|
|
|
str++;
|
|
|
|
if (!*str)
|
|
|
|
rgba[i] = 255;
|
|
|
|
else
|
|
|
|
rgba[i] = strtoul(str, (char**)&str, 0);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
return rgba;
|
|
|
|
}
|
|
|
|
void Draw_TextBox (int x, int y, int width, int lines)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
char *TP_LocationName (const vec3_t location)
|
2017-12-28 16:24:50 +00:00
|
|
|
{
|
|
|
|
static char locname[256];
|
2019-09-04 07:59:40 +00:00
|
|
|
clientfuncs->GetLocationName(location, locname, sizeof(locname));
|
2017-12-28 16:24:50 +00:00
|
|
|
return locname;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Draw_SPic(float x, float y, mpic_t *pic, float scale)
|
|
|
|
{
|
|
|
|
qhandle_t image = (intptr_t)pic;
|
|
|
|
float w, h;
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->ImageSize(image, &w, &h);
|
|
|
|
drawfuncs->Image(x, y, w*scale, h*scale, 0, 0, 1, 1, image);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_SSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float scale)
|
|
|
|
{
|
|
|
|
qhandle_t image = (intptr_t)pic;
|
|
|
|
float w, h;
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->ImageSize(image, &w, &h);
|
|
|
|
drawfuncs->Image(x, y, (s2-s1)*scale, (t2-t1)*scale, s1/w, t1/h, s2/w, t2/h, image);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_EZString(float x, float y, char *str, float scale, qboolean red)
|
|
|
|
{
|
|
|
|
unsigned int flags = 0;
|
|
|
|
if (red)
|
|
|
|
flags |= 1;
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->StringH(x, y, scale, flags, str);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define Draw_STransPic Draw_SPic
|
|
|
|
void Draw_Character(float x, float y, unsigned int ch)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Character(x, y, 0xe000|ch);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_SCharacter(float x, float y, unsigned int ch, float scale)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->CharacterH(x, y, 8*scale, 0, 0xe000|ch);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SCR_DrawWadString(float x, float y, float scale, char *str)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->String(x, y, str); //FIXME
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Draw_SAlphaSubPic2(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float sw, float sh, float alpha)
|
|
|
|
{
|
|
|
|
qhandle_t image = (intptr_t)pic;
|
|
|
|
float w, h;
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->ImageSize(image, &w, &h);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, alpha * alphamul);
|
|
|
|
drawfuncs->Image(x, y, (s2-s1)*sw, (t2-t1)*sh, s1/w, t1/h, s2/w, t2/h, image);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Draw_AlphaFill(float x, float y, float w, float h, unsigned int pal, float alpha)
|
|
|
|
{
|
|
|
|
if (pal >= 256)
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colour4f(((pal>>16)&0xff)/255.0, ((pal>>8)&0xff)/255.0, ((pal>>0)&0xff)/255.0, alpha * alphamul);
|
2017-12-28 16:24:50 +00:00
|
|
|
else
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colourpa(pal, alpha * alphamul);
|
|
|
|
drawfuncs->Fill(x, y, w, h);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_AlphaPic(float x, float y, mpic_t *pic, float alpha)
|
|
|
|
{
|
|
|
|
qhandle_t image = (intptr_t)pic;
|
|
|
|
float w, h;
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->ImageSize(image, &w, &h);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, alpha * alphamul);
|
|
|
|
drawfuncs->Image(x, y, w, h, 0, 0, 1, 1, image);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_AlphaSubPic(float x, float y, mpic_t *pic, float s1, float t1, float s2, float t2, float alpha)
|
|
|
|
{
|
|
|
|
qhandle_t image = (intptr_t)pic;
|
|
|
|
float w, h;
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->ImageSize(image, &w, &h);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, alpha * alphamul);
|
|
|
|
drawfuncs->Image(x, y, s2-s1, t2-t1, s1/w, t1/h, s2/w, t2/h, image);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void SCR_HUD_DrawBar(int direction, int value, float max_value, float *rgba, int x, int y, int width, int height)
|
|
|
|
{
|
2015-04-21 04:12:00 +00:00
|
|
|
int amount;
|
|
|
|
|
|
|
|
if(direction >= 2)
|
|
|
|
// top-down
|
2018-08-04 19:00:19 +00:00
|
|
|
amount = Q_rint(fabs((height * value) / max_value));
|
2015-04-21 04:12:00 +00:00
|
|
|
else// left-right
|
2018-08-04 19:00:19 +00:00
|
|
|
amount = Q_rint(fabs((width * value) / max_value));
|
2015-04-21 04:12:00 +00:00
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colour4f(rgba[0]/255.0, rgba[1]/255.0, rgba[2]/255.0, rgba[3]/255.0 * alphamul);
|
2015-04-21 04:12:00 +00:00
|
|
|
if(direction == 0)
|
|
|
|
// left->right
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Fill(x, y, amount, height);
|
2015-04-21 04:12:00 +00:00
|
|
|
else if (direction == 1)
|
|
|
|
// right->left
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Fill(x + width - amount, y, amount, height);
|
2015-04-21 04:12:00 +00:00
|
|
|
else if (direction == 2)
|
|
|
|
// down -> up
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Fill(x, y + height - amount, width, amount);
|
2015-04-21 04:12:00 +00:00
|
|
|
else
|
|
|
|
// up -> down
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Fill(x, y, width, amount);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Draw_Polygon(int x, int y, vec3_t *vertices, int num_vertices, qbool fill, byte r, byte g, byte b, byte a)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
|
|
|
|
// drawfuncs->Line(x1, y1, x2, y1);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_ColoredString3(float x, float y, const char *str, clrinfo_t *clr, int huh, int wut)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colour4f(clr->c[0]/255.0, clr->c[1]/255.0, clr->c[2]/255.0, clr->c[3]/255.0 * alphamul);
|
|
|
|
drawfuncs->String(x, y, str);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
2018-10-11 10:31:23 +00:00
|
|
|
void UI_PrintTextBlock(void)
|
2017-12-28 16:24:50 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
void Draw_AlphaRectangleRGB(int x, int y, int w, int h, int foo, int bar, byte r, byte g, byte b, byte a)
|
|
|
|
{
|
|
|
|
float x1 = x;
|
|
|
|
float x2 = x+w;
|
|
|
|
float y1 = y;
|
|
|
|
float y2 = y+h;
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
|
|
|
|
drawfuncs->Line(x1, y1, x2, y1);
|
|
|
|
drawfuncs->Line(x2, y1, x2, y2);
|
|
|
|
drawfuncs->Line(x1, y2, x2, y2);
|
|
|
|
drawfuncs->Line(x1, y1, x1, y2);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
void Draw_AlphaLineRGB(float x1, float y1, float x2, float y2, float width, byte r, byte g, byte b, byte a)
|
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs->Colour4f(r/255.0, g/255.0, b/255.0, a/255.0 * alphamul);
|
|
|
|
drawfuncs->Line(x1, y1, x2, y2);
|
|
|
|
drawfuncs->Colour4f(1, 1, 1, 1);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mpic_t *Draw_CachePicSafe(const char *name, qbool crash, qbool ignorewad)
|
|
|
|
{
|
|
|
|
if (!*name)
|
|
|
|
return NULL;
|
2022-03-08 05:31:34 +00:00
|
|
|
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(name);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
mpic_t *Draw_CacheWadPic(const char *name)
|
|
|
|
{
|
2022-03-08 05:31:34 +00:00
|
|
|
char ftename[MAX_QPATH];
|
|
|
|
Q_snprintf(ftename, sizeof(ftename), "gfx/%s.lmp", name);
|
|
|
|
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(ftename);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mpic_t *SCR_LoadCursorImage(char *cursorimage)
|
|
|
|
{
|
|
|
|
return Draw_CachePicSafe(cursorimage, false, true);
|
|
|
|
}
|
|
|
|
|
2015-04-21 04:12:00 +00:00
|
|
|
unsigned int Sbar_ColorForMap (unsigned int m)
|
|
|
|
{
|
|
|
|
if (m >= 16)
|
|
|
|
return m;
|
|
|
|
m = (m < 0) ? 0 : ((m > 13) ? 13 : m);
|
|
|
|
m *= 16;
|
|
|
|
return m < 128 ? m + 8 : m + 8;
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
int Sbar_TopColor(player_info_t *pi)
|
|
|
|
{
|
|
|
|
return Sbar_ColorForMap(pi->topcolour);
|
|
|
|
}
|
|
|
|
int Sbar_BottomColor(player_info_t *pi)
|
|
|
|
{
|
|
|
|
return Sbar_ColorForMap(pi->bottomcolour);
|
|
|
|
}
|
|
|
|
int dehex(char nib)
|
|
|
|
{
|
|
|
|
if (nib >= '0' && nib <= '9')
|
|
|
|
return nib - '0';
|
|
|
|
if (nib >= 'a' && nib <= 'f')
|
|
|
|
return nib - 'a' + 10;
|
|
|
|
if (nib >= 'A' && nib <= 'F')
|
|
|
|
return nib - 'A' + 10;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
char *TP_ParseFunChars(char *str, qbool chat)
|
|
|
|
{
|
|
|
|
static char resultbuf[1024];
|
|
|
|
char *out = resultbuf, *end = resultbuf+sizeof(resultbuf)-1;
|
|
|
|
|
|
|
|
while (out < end)
|
|
|
|
{
|
|
|
|
if (str[0] == '$' && str[1] == 'x' && str[2] && str[3])
|
|
|
|
{
|
|
|
|
*out++ = (dehex(str[2]) << 4) | dehex(str[3]);
|
|
|
|
str+=4;
|
|
|
|
}
|
|
|
|
else if (str[0] == '$')
|
|
|
|
{
|
2015-07-01 23:15:25 +00:00
|
|
|
int c = 0;
|
|
|
|
switch (str[1])
|
|
|
|
{
|
|
|
|
case '\\': c = 0x0D; break;
|
|
|
|
case ':': c = 0x0A; break;
|
|
|
|
case '[': c = 0x10; break;
|
|
|
|
case ']': c = 0x11; break;
|
|
|
|
case 'G': c = 0x86; break;
|
|
|
|
case 'R': c = 0x87; break;
|
|
|
|
case 'Y': c = 0x88; break;
|
|
|
|
case 'B': c = 0x89; break;
|
|
|
|
case '(': c = 0x80; break;
|
|
|
|
case '=': c = 0x81; break;
|
|
|
|
case ')': c = 0x82; break;
|
|
|
|
case 'a': c = 0x83; break;
|
|
|
|
case '<': c = 0x1d; break;
|
|
|
|
case '-': c = 0x1e; break;
|
|
|
|
case '>': c = 0x1f; break;
|
|
|
|
case ',': c = 0x1c; break;
|
|
|
|
case '.': c = 0x9c; break;
|
|
|
|
case 'b': c = 0x8b; break;
|
|
|
|
case 'c':
|
|
|
|
case 'd': c = 0x8d; break;
|
|
|
|
case '$': c = '$'; break;
|
|
|
|
case '^': c = '^'; break;
|
|
|
|
case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': c = str[1] -'0' + 0x12;break;
|
|
|
|
}
|
|
|
|
if (c)
|
|
|
|
{
|
|
|
|
*out++ = c;
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
str++;
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
else if (*str)
|
|
|
|
*out++ = *str++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*out = 0;
|
|
|
|
return resultbuf;
|
|
|
|
}
|
|
|
|
char *TP_ItemName(unsigned int itbit)
|
|
|
|
{
|
|
|
|
return "Dunno";
|
|
|
|
}
|
|
|
|
|
|
|
|
void Replace_In_String(char *src, size_t strsize, char leadchar, int patterns, ...)
|
|
|
|
{
|
|
|
|
char orig[1024];
|
|
|
|
char *out, *outstop;
|
|
|
|
va_list ap;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
strlcpy(orig, src, sizeof(orig));
|
|
|
|
out = src;
|
|
|
|
outstop = out + strsize-1;
|
|
|
|
src = orig;
|
|
|
|
|
|
|
|
while(*src)
|
|
|
|
{
|
|
|
|
if (out == outstop)
|
|
|
|
break;
|
|
|
|
if (*src != leadchar)
|
|
|
|
*out++ = *src++;
|
|
|
|
else if (*++src == leadchar)
|
|
|
|
*out++ = leadchar;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
va_start(ap, patterns);
|
|
|
|
for (i = 0; i < patterns; i++)
|
|
|
|
{
|
|
|
|
const char *arg = va_arg(ap, const char *);
|
|
|
|
const char *val = va_arg(ap, const char *);
|
|
|
|
size_t alen = strlen(arg);
|
|
|
|
if (!strncmp(src, arg, strlen(arg)))
|
|
|
|
{
|
|
|
|
strlcpy(out, val, (outstop-out)+1);
|
|
|
|
out += strlen(out);
|
|
|
|
src += alen;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i == patterns)
|
|
|
|
{
|
|
|
|
strlcpy(out, "unknown", (outstop-out)+1);
|
|
|
|
out += strlen(out);
|
|
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*out = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SCR_GetClockStringWidth(const char *s, qbool big, float scale)
|
|
|
|
{
|
|
|
|
int w = 0;
|
|
|
|
if (big)
|
|
|
|
{
|
|
|
|
while(*s)
|
|
|
|
w += ((*s++==':')?16:24);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
w = strlen(s) * 8;
|
|
|
|
return w * scale;
|
|
|
|
}
|
|
|
|
int SCR_GetClockStringHeight(qbool big, float scale)
|
|
|
|
{
|
|
|
|
return (big?24:8)*scale;
|
|
|
|
}
|
2015-04-21 04:12:00 +00:00
|
|
|
char *SecondsToMinutesString(int print_time, char *buffer, size_t buffersize) {
|
|
|
|
int tens_minutes, minutes, tens_seconds, seconds;
|
|
|
|
|
|
|
|
tens_minutes = fmod (print_time / 600, 6);
|
|
|
|
minutes = fmod (print_time / 60, 10);
|
|
|
|
tens_seconds = fmod (print_time / 10, 6);
|
|
|
|
seconds = fmod (print_time, 10);
|
|
|
|
snprintf (buffer, buffersize, "%i%i:%i%i", tens_minutes, minutes, tens_seconds, seconds);
|
|
|
|
return buffer;
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
2015-04-21 04:12:00 +00:00
|
|
|
char *SCR_GetGameTime(int t, char *buffer, size_t buffersize)
|
|
|
|
{
|
|
|
|
float timelimit;
|
|
|
|
|
|
|
|
timelimit = (t == TIMETYPE_GAMECLOCKINV) ? 60 * infofloat(cl.serverinfo, "timelimit", 0) + 1: 0;
|
|
|
|
|
|
|
|
if (cl.countdown || cl.standby)
|
|
|
|
SecondsToMinutesString(timelimit, buffer, buffersize);
|
|
|
|
else
|
2018-08-04 19:00:19 +00:00
|
|
|
SecondsToMinutesString((int) fabs(timelimit - (cl.time - cl.matchstart)), buffer, buffersize);
|
2015-04-21 04:12:00 +00:00
|
|
|
return buffer;
|
|
|
|
}
|
2017-12-28 16:24:50 +00:00
|
|
|
|
|
|
|
const char* SCR_GetTimeString(int timetype, const char *format)
|
|
|
|
{
|
|
|
|
static char buffer[256];
|
|
|
|
switch(timetype)
|
|
|
|
{
|
2015-04-21 04:12:00 +00:00
|
|
|
case TIMETYPE_CLOCK:
|
|
|
|
{
|
|
|
|
time_t t;
|
|
|
|
struct tm *ptm;
|
|
|
|
time (&t);
|
|
|
|
ptm = localtime (&t);
|
|
|
|
if (!ptm) return "-:-";
|
|
|
|
if (!strftime(buffer, sizeof(buffer)-1, format, ptm)) return "-:-";
|
2017-12-28 16:24:50 +00:00
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
case TIMETYPE_GAMECLOCK:
|
|
|
|
case TIMETYPE_GAMECLOCKINV:
|
|
|
|
return SCR_GetGameTime(timetype, buffer, sizeof(buffer));
|
|
|
|
|
|
|
|
case TIMETYPE_DEMOCLOCK:
|
|
|
|
return SecondsToMinutesString(infofloat(cl.serverinfo, "demotime", 0), buffer, sizeof(buffer));
|
|
|
|
|
|
|
|
default:
|
|
|
|
return "01234";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void SCR_DrawBigClock(int x, int y, int style, int blink, float scale, const char *t)
|
|
|
|
{
|
2015-04-21 04:12:00 +00:00
|
|
|
extern mpic_t *sb_nums[2][11];
|
|
|
|
extern mpic_t *sb_colon/*, *sb_slash*/;
|
|
|
|
qbool lblink = (int)(cls.realtime*2) & 1;
|
|
|
|
|
|
|
|
if (style > 1) style = 1;
|
|
|
|
if (style < 0) style = 0;
|
|
|
|
|
|
|
|
while (*t)
|
|
|
|
{
|
|
|
|
if (*t >= '0' && *t <= '9')
|
|
|
|
{
|
|
|
|
Draw_STransPic(x, y, sb_nums[style][*t-'0'], scale);
|
|
|
|
x += 24*scale;
|
|
|
|
}
|
|
|
|
else if (*t == ':')
|
|
|
|
{
|
|
|
|
if (lblink || !blink)
|
|
|
|
Draw_STransPic (x, y, sb_colon, scale);
|
|
|
|
|
|
|
|
x += 16*scale;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Draw_SCharacter(x, y, *t+(style?128:0), 3*scale);
|
|
|
|
x += 24*scale;
|
|
|
|
}
|
|
|
|
t++;
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void SCR_DrawSmallClock(int x, int y, int style, int blink, float scale, const char *t)
|
|
|
|
{
|
2015-04-21 04:12:00 +00:00
|
|
|
qbool lblink = (int)(cls.realtime*2) & 1;
|
|
|
|
int c;
|
|
|
|
|
|
|
|
if (style > 3) style = 3;
|
|
|
|
if (style < 0) style = 0;
|
|
|
|
|
|
|
|
while (*t)
|
|
|
|
{
|
|
|
|
c = (int) *t;
|
|
|
|
if (c >= '0' && c <= '9')
|
|
|
|
{
|
|
|
|
if (style == 1)
|
|
|
|
c += 128;
|
|
|
|
else if (style == 2 || style == 3)
|
|
|
|
c -= 30;
|
|
|
|
}
|
|
|
|
else if (c == ':')
|
|
|
|
{
|
|
|
|
if (style == 1 || style == 3)
|
|
|
|
c += 128;
|
|
|
|
if (lblink || !blink)
|
|
|
|
;
|
|
|
|
else
|
|
|
|
c = ' ';
|
|
|
|
}
|
|
|
|
Draw_SCharacter(x, y, c, scale);
|
|
|
|
x+= 8*scale;
|
|
|
|
t++;
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "builtin_huds.h"
|
|
|
|
void EZHud_UseNquake_f(void)
|
|
|
|
{
|
|
|
|
const char *hudstr = builtin_hud_nquake;
|
2019-09-04 07:59:40 +00:00
|
|
|
cmdfuncs->AddText(hudstr, true);
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Cmd_AddCommand (const char *funcname, xcommand_t function)
|
|
|
|
{
|
2022-03-08 05:31:34 +00:00
|
|
|
return cmdfuncs->AddCommand(funcname, function, NULL);
|
2017-12-28 16:24:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
int IN_BestWeapon(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
qbool VID_VSyncIsOn(void){return false;}
|
|
|
|
double vid_vsync_lag;
|
|
|
|
|
|
|
|
|
|
|
|
vrect_t scr_vrect;
|
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
void EZHud_Tick(double realtime, double gametime)
|
2017-12-28 16:24:50 +00:00
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
cls.realtime = realtime;
|
|
|
|
cl.time = gametime;
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
|
|
|
char *findinfo(char *info, char *findkey)
|
|
|
|
{
|
|
|
|
int kl = strlen(findkey);
|
|
|
|
char *key, *value;
|
|
|
|
while(*info)
|
|
|
|
{
|
|
|
|
key = strchr(info, '\\');
|
|
|
|
if (!key)
|
|
|
|
break;
|
|
|
|
key++;
|
|
|
|
value = strchr(key, '\\');
|
|
|
|
if (!value)
|
|
|
|
break;
|
|
|
|
info = value+1;
|
|
|
|
if (!strncmp(key, findkey, kl) && key[kl] == '\\')
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
char *infostring(char *info, char *findkey, char *buffer, size_t bufsize)
|
|
|
|
{
|
|
|
|
char *value = findinfo(info, findkey);
|
|
|
|
char *end;
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
end = strchr(value, '\\');
|
|
|
|
if (!end)
|
|
|
|
end = value + strlen(value);
|
|
|
|
bufsize--;
|
|
|
|
if (bufsize > (end - value))
|
|
|
|
bufsize = (end - value);
|
|
|
|
memcpy(buffer, value, bufsize);
|
|
|
|
buffer[bufsize] = 0;
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
*buffer = 0;
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
float infofloat(char *info, char *findkey, float def)
|
|
|
|
{
|
|
|
|
char *value = findinfo(info, findkey);
|
|
|
|
if (value)
|
|
|
|
return atof(value);
|
|
|
|
return def;
|
|
|
|
}
|
2019-09-04 07:59:40 +00:00
|
|
|
int EZHud_Draw(int seat, float viewx, float viewy, float viewwidth, float viewheight, int showscores)
|
2017-12-28 16:24:50 +00:00
|
|
|
{
|
|
|
|
char serverinfo[4096];
|
|
|
|
char val[64];
|
|
|
|
int i;
|
2021-07-03 01:47:04 +00:00
|
|
|
|
|
|
|
static float lasttime, lasttime_min = 99999;
|
|
|
|
static int framecount;
|
|
|
|
static float oldtime;
|
|
|
|
if (cls.realtime - lasttime > 1)
|
|
|
|
{
|
|
|
|
cls.fps = framecount/(cls.realtime - lasttime);
|
|
|
|
lasttime = cls.realtime;
|
|
|
|
framecount = 0;
|
|
|
|
|
|
|
|
if (cls.realtime - lasttime_min > 30)
|
|
|
|
{
|
|
|
|
cls.min_fps = cls.fps;
|
|
|
|
lasttime_min = cls.realtime;
|
|
|
|
}
|
|
|
|
else if (cls.min_fps > cls.fps)
|
|
|
|
cls.min_fps = cls.fps;
|
|
|
|
}
|
|
|
|
if (!seat)
|
|
|
|
{
|
|
|
|
cls.frametime = cls.realtime - oldtime;
|
|
|
|
framecount++;
|
|
|
|
oldtime = cls.realtime;
|
|
|
|
}
|
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
cl.splitscreenview = seat;
|
|
|
|
scr_vrect.x = viewx;
|
|
|
|
scr_vrect.y = viewy;
|
|
|
|
scr_vrect.width = viewwidth;
|
|
|
|
scr_vrect.height = viewheight;
|
|
|
|
sb_showscores = showscores & 1;
|
|
|
|
sb_showteamscores = showscores & 2;
|
|
|
|
|
|
|
|
clientfuncs->GetStats(0, cl.stats, sizeof(cl.stats)/sizeof(cl.stats[0]));
|
2017-12-28 16:24:50 +00:00
|
|
|
for (i = 0; i < 32; i++)
|
2019-09-04 07:59:40 +00:00
|
|
|
clientfuncs->GetPlayerInfo(i, &cl.players[i]);
|
2017-12-28 16:24:50 +00:00
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
clientfuncs->GetLocalPlayerNumbers(cl.splitscreenview, 1, &cl.playernum, &cl.tracknum);
|
|
|
|
clientfuncs->GetServerInfo(cl.serverinfo, sizeof(serverinfo));
|
2017-12-28 16:24:50 +00:00
|
|
|
cl.deathmatch = infofloat(cl.serverinfo, "deathmatch", 0);
|
|
|
|
cl.teamplay = infofloat(cl.serverinfo, "teamplay", 0);
|
|
|
|
cl.intermission = infofloat(cl.serverinfo, "intermission", 0);
|
|
|
|
cl.spectator = (cl.playernum>=32)||cl.players[cl.playernum].spectator;
|
|
|
|
infostring(cl.serverinfo, "status", val, sizeof(val));
|
|
|
|
cl.standby = !strcmp(val, "standby");
|
|
|
|
cl.countdown = !strcmp(val, "countdown");
|
|
|
|
cl.matchstart = infofloat(cl.serverinfo, "matchstart", 0);
|
|
|
|
cls.state = ca_active;
|
|
|
|
|
|
|
|
infostring(cl.serverinfo, "demotype", val, sizeof(val));
|
|
|
|
cls.mvdplayback = !strcmp(val, "mvd");
|
|
|
|
cls.demoplayback = strcmp(val, "");
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
static cvar_t *pscr_viewsize = NULL;
|
|
|
|
int size;
|
|
|
|
if (!pscr_viewsize)
|
2019-09-04 07:59:40 +00:00
|
|
|
pscr_viewsize = cvarfuncs->GetNVFDG("viewsize", "100", 0, NULL, NULL);
|
2015-10-27 15:20:15 +00:00
|
|
|
size = cl.intermission ? 120 : pscr_viewsize->value;
|
|
|
|
if (size >= 120)
|
|
|
|
sb_lines = 0; // no status bar at all
|
|
|
|
else if (size >= 110)
|
|
|
|
sb_lines = 24; // no inventory
|
|
|
|
else
|
2017-12-28 16:24:50 +00:00
|
|
|
sb_lines = 24 + 16 + 8;
|
|
|
|
}
|
|
|
|
|
2020-02-11 18:06:10 +00:00
|
|
|
clientfuncs->GetPredInfo(seat, cl.simvel);
|
|
|
|
|
2017-12-28 16:24:50 +00:00
|
|
|
|
|
|
|
//cl.faceanimtime
|
|
|
|
//cl.item_gettime
|
|
|
|
|
|
|
|
//cls.state;
|
|
|
|
//cls.min_fps;
|
|
|
|
//cls.fps;
|
|
|
|
////cls.realtime;
|
|
|
|
////cls.trueframetime;
|
|
|
|
|
|
|
|
host_screenupdatecount++;
|
|
|
|
HUD_Draw();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-07-17 15:10:22 +00:00
|
|
|
unsigned int keydown[K_MAX];
|
2017-12-28 16:24:50 +00:00
|
|
|
float cursor_x;
|
|
|
|
float cursor_y;
|
|
|
|
float mouse_x;
|
|
|
|
float mouse_y;
|
|
|
|
mpic_t *scr_cursor_icon = NULL;
|
2019-09-04 07:59:40 +00:00
|
|
|
qboolean QDECL EZHud_MenuEvent(int eventtype, int keyparam, int unicodeparm, float mousecursor_x, float mousecursor_y, float vidwidth, float vidheight)
|
2017-12-28 16:24:50 +00:00
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
mouse_x += mousecursor_x - cursor_x; //FIXME: the hud editor should NOT need this sort of thing
|
|
|
|
mouse_y += mousecursor_y - cursor_y;
|
|
|
|
cursor_x = mousecursor_x;
|
|
|
|
cursor_y = mousecursor_y;
|
2017-12-28 16:24:50 +00:00
|
|
|
|
|
|
|
HUD_Editor_MouseEvent(cursor_x, cursor_y);
|
|
|
|
|
|
|
|
switch(eventtype)
|
|
|
|
{
|
|
|
|
case 0: //draw
|
|
|
|
host_screenupdatecount++;
|
|
|
|
HUD_Draw();
|
|
|
|
HUD_Editor_Draw();
|
|
|
|
|
|
|
|
mouse_x = 0;
|
|
|
|
mouse_y = 0;
|
|
|
|
break;
|
|
|
|
case 1:
|
2019-09-04 07:59:40 +00:00
|
|
|
if (keyparam < K_MAX)
|
|
|
|
keydown[keyparam] = true;
|
|
|
|
HUD_Editor_Key(keyparam, 0, true);
|
2017-12-28 16:24:50 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2019-09-04 07:59:40 +00:00
|
|
|
if (keyparam < K_MAX)
|
|
|
|
keydown[keyparam] = false;
|
|
|
|
HUD_Editor_Key(keyparam, 0, false);
|
2017-12-28 16:24:50 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-09-04 07:59:40 +00:00
|
|
|
qboolean Plug_Init(void)
|
2017-12-28 16:24:50 +00:00
|
|
|
{
|
2019-09-04 07:59:40 +00:00
|
|
|
drawfuncs = plugfuncs->GetEngineInterface(plug2dfuncs_name, sizeof(*drawfuncs));
|
|
|
|
clientfuncs = plugfuncs->GetEngineInterface(plugclientfuncs_name, sizeof(*clientfuncs));
|
|
|
|
filefuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*filefuncs));
|
|
|
|
inputfuncs = plugfuncs->GetEngineInterface(pluginputfuncs_name, sizeof(*inputfuncs));
|
|
|
|
|
|
|
|
plugfuncs->ExportFunction("UpdateVideo", EZHud_UpdateVideo);
|
|
|
|
|
|
|
|
if (cvarfuncs && drawfuncs && clientfuncs && filefuncs && inputfuncs &&
|
|
|
|
plugfuncs->ExportFunction("SbarBase", EZHud_Draw) &&
|
|
|
|
plugfuncs->ExportFunction("MenuEvent", EZHud_MenuEvent) &&
|
2022-03-08 05:31:34 +00:00
|
|
|
plugfuncs->ExportFunction("Tick", EZHud_Tick))
|
2015-04-21 04:12:00 +00:00
|
|
|
{
|
2015-06-12 14:44:50 +00:00
|
|
|
Cmd_AddCommand("ezhud_nquake", EZHud_UseNquake_f);
|
2015-04-21 04:12:00 +00:00
|
|
|
HUD_Init();
|
|
|
|
HUD_Editor_Init();
|
2019-09-04 07:59:40 +00:00
|
|
|
return true;
|
2017-12-28 16:24:50 +00:00
|
|
|
}
|
2019-09-04 07:59:40 +00:00
|
|
|
Con_Printf("EZHud: Unable to initiailise\n");
|
2017-12-28 16:24:50 +00:00
|
|
|
return false;
|
|
|
|
}
|