mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-26 22:01:50 +00:00
8ae45223dc
Some memory leaks fixed. latency with the nq protocol over loopback is much reduced. Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2042 lines
50 KiB
C
2042 lines
50 KiB
C
#include "quakedef.h"
|
|
|
|
#include "pr_common.h"
|
|
#include "shader.h"
|
|
|
|
#ifdef GLQUAKE
|
|
#include "glquake.h"
|
|
#endif
|
|
|
|
#if defined(MENU_DAT) || defined(CSQC_DAT)
|
|
|
|
struct
|
|
{
|
|
float *drawfont;
|
|
float *drawfontscale;
|
|
} mp_globs;
|
|
|
|
|
|
int MP_TranslateFTEtoDPCodes(int code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case K_TAB: return 9;
|
|
case K_ENTER: return 13;
|
|
case K_ESCAPE: return 27;
|
|
case K_SPACE: return 32;
|
|
case K_BACKSPACE: return 127;
|
|
case K_UPARROW: return 128;
|
|
case K_DOWNARROW: return 129;
|
|
case K_LEFTARROW: return 130;
|
|
case K_RIGHTARROW: return 131;
|
|
case K_ALT: return 132;
|
|
case K_CTRL: return 133;
|
|
case K_SHIFT: return 134;
|
|
case K_F1: return 135;
|
|
case K_F2: return 136;
|
|
case K_F3: return 137;
|
|
case K_F4: return 138;
|
|
case K_F5: return 139;
|
|
case K_F6: return 140;
|
|
case K_F7: return 141;
|
|
case K_F8: return 142;
|
|
case K_F9: return 143;
|
|
case K_F10: return 144;
|
|
case K_F11: return 145;
|
|
case K_F12: return 146;
|
|
case K_INS: return 147;
|
|
case K_DEL: return 148;
|
|
case K_PGDN: return 149;
|
|
case K_PGUP: return 150;
|
|
case K_HOME: return 151;
|
|
case K_END: return 152;
|
|
case K_KP_HOME: return 160;
|
|
case K_KP_UPARROW: return 161;
|
|
case K_KP_PGUP: return 162;
|
|
case K_KP_LEFTARROW: return 163;
|
|
case K_KP_5: return 164;
|
|
case K_KP_RIGHTARROW: return 165;
|
|
case K_KP_END: return 166;
|
|
case K_KP_DOWNARROW: return 167;
|
|
case K_KP_PGDN: return 168;
|
|
case K_KP_ENTER: return 169;
|
|
case K_KP_INS: return 170;
|
|
case K_KP_DEL: return 171;
|
|
case K_KP_SLASH: return 172;
|
|
case K_KP_MINUS: return 173;
|
|
case K_KP_PLUS: return 174;
|
|
case K_PAUSE: return 255;
|
|
case K_JOY1: return 768;
|
|
case K_JOY2: return 769;
|
|
case K_JOY3: return 770;
|
|
case K_JOY4: return 771;
|
|
case K_AUX1: return 772;
|
|
case K_AUX2: return 773;
|
|
case K_AUX3: return 774;
|
|
case K_AUX4: return 775;
|
|
case K_AUX5: return 776;
|
|
case K_AUX6: return 777;
|
|
case K_AUX7: return 778;
|
|
case K_AUX8: return 779;
|
|
case K_AUX9: return 780;
|
|
case K_AUX10: return 781;
|
|
case K_AUX11: return 782;
|
|
case K_AUX12: return 783;
|
|
case K_AUX13: return 784;
|
|
case K_AUX14: return 785;
|
|
case K_AUX15: return 786;
|
|
case K_AUX16: return 787;
|
|
case K_AUX17: return 788;
|
|
case K_AUX18: return 789;
|
|
case K_AUX19: return 790;
|
|
case K_AUX20: return 791;
|
|
case K_AUX21: return 792;
|
|
case K_AUX22: return 793;
|
|
case K_AUX23: return 794;
|
|
case K_AUX24: return 795;
|
|
case K_AUX25: return 796;
|
|
case K_AUX26: return 797;
|
|
case K_AUX27: return 798;
|
|
case K_AUX28: return 799;
|
|
case K_AUX29: return 800;
|
|
case K_AUX30: return 801;
|
|
case K_AUX31: return 802;
|
|
case K_AUX32: return 803;
|
|
case K_MOUSE1: return 512;
|
|
case K_MOUSE2: return 513;
|
|
case K_MOUSE3: return 514;
|
|
case K_MOUSE4: return 517;
|
|
case K_MOUSE5: return 518;
|
|
case K_MOUSE6: return 519;
|
|
case K_MOUSE7: return 520;
|
|
case K_MOUSE8: return 521;
|
|
case K_MOUSE9: return 522;
|
|
case K_MOUSE10: return 523;
|
|
case K_MWHEELDOWN: return 515;//K_MOUSE4;
|
|
case K_MWHEELUP: return 516;//K_MOUSE5;
|
|
default: return code;
|
|
}
|
|
}
|
|
|
|
int MP_TranslateDPtoFTECodes(int code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case 9: return K_TAB;
|
|
case 13: return K_ENTER;
|
|
case 27: return K_ESCAPE;
|
|
case 32: return K_SPACE;
|
|
case 127: return K_BACKSPACE;
|
|
case 128: return K_UPARROW;
|
|
case 129: return K_DOWNARROW;
|
|
case 130: return K_LEFTARROW;
|
|
case 131: return K_RIGHTARROW;
|
|
case 132: return K_ALT;
|
|
case 133: return K_CTRL;
|
|
case 134: return K_SHIFT;
|
|
case 135: return K_F1;
|
|
case 136: return K_F2;
|
|
case 137: return K_F3;
|
|
case 138: return K_F4;
|
|
case 139: return K_F5;
|
|
case 140: return K_F6;
|
|
case 141: return K_F7;
|
|
case 142: return K_F8;
|
|
case 143: return K_F9;
|
|
case 144: return K_F10;
|
|
case 145: return K_F11;
|
|
case 146: return K_F12;
|
|
case 147: return K_INS;
|
|
case 148: return K_DEL;
|
|
case 149: return K_PGDN;
|
|
case 150: return K_PGUP;
|
|
case 151: return K_HOME;
|
|
case 152: return K_END;
|
|
case 160: return K_KP_HOME;
|
|
case 161: return K_KP_UPARROW;
|
|
case 162: return K_KP_PGUP;
|
|
case 163: return K_KP_LEFTARROW;
|
|
case 164: return K_KP_5;
|
|
case 165: return K_KP_RIGHTARROW;
|
|
case 166: return K_KP_END;
|
|
case 167: return K_KP_DOWNARROW;
|
|
case 168: return K_KP_PGDN;
|
|
case 169: return K_KP_ENTER;
|
|
case 170: return K_KP_INS;
|
|
case 171: return K_KP_DEL;
|
|
case 172: return K_KP_SLASH;
|
|
case 173: return K_KP_MINUS;
|
|
case 174: return K_KP_PLUS;
|
|
case 255: return K_PAUSE;
|
|
|
|
case 768: return K_JOY1;
|
|
case 769: return K_JOY2;
|
|
case 770: return K_JOY3;
|
|
case 771: return K_JOY4;
|
|
case 772: return K_AUX1;
|
|
case 773: return K_AUX2;
|
|
case 774: return K_AUX3;
|
|
case 775: return K_AUX4;
|
|
case 776: return K_AUX5;
|
|
case 777: return K_AUX6;
|
|
case 778: return K_AUX7;
|
|
case 779: return K_AUX8;
|
|
case 780: return K_AUX9;
|
|
case 781: return K_AUX10;
|
|
case 782: return K_AUX11;
|
|
case 783: return K_AUX12;
|
|
case 784: return K_AUX13;
|
|
case 785: return K_AUX14;
|
|
case 786: return K_AUX15;
|
|
case 787: return K_AUX16;
|
|
case 788: return K_AUX17;
|
|
case 789: return K_AUX18;
|
|
case 790: return K_AUX19;
|
|
case 791: return K_AUX20;
|
|
case 792: return K_AUX21;
|
|
case 793: return K_AUX22;
|
|
case 794: return K_AUX23;
|
|
case 795: return K_AUX24;
|
|
case 796: return K_AUX25;
|
|
case 797: return K_AUX26;
|
|
case 798: return K_AUX27;
|
|
case 799: return K_AUX28;
|
|
case 800: return K_AUX29;
|
|
case 801: return K_AUX30;
|
|
case 802: return K_AUX31;
|
|
case 803: return K_AUX32;
|
|
case 512: return K_MOUSE1;
|
|
case 513: return K_MOUSE2;
|
|
case 514: return K_MOUSE3;
|
|
case 517: return K_MOUSE4;
|
|
case 518: return K_MOUSE5;
|
|
case 519: return K_MOUSE6;
|
|
case 520: return K_MOUSE7;
|
|
case 521: return K_MOUSE8;
|
|
case 522: return K_MOUSE9;
|
|
case 523: return K_MOUSE10;
|
|
case 515: return K_MWHEELDOWN;//K_MOUSE4;
|
|
case 516: return K_MWHEELUP;//K_MOUSE5;
|
|
default: return code;
|
|
}
|
|
}
|
|
|
|
//string findkeysforcommand(string command) = #610;
|
|
void QCBUILTIN PF_cl_findkeysforcommand (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
int keynums[2];
|
|
char keyname[512];
|
|
|
|
M_FindKeysForCommand(0, cmdname, keynums);
|
|
|
|
keyname[0] = '\0';
|
|
|
|
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[0])), sizeof(keyname));
|
|
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[1])), sizeof(keyname));
|
|
|
|
RETURN_TSTRING(keyname);
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_getkeybind (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *binding = Key_GetBinding(G_FLOAT(OFS_PARM0));
|
|
RETURN_TSTRING(binding);
|
|
}
|
|
|
|
void QCBUILTIN PF_cl_stringtokeynum(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int i;
|
|
int modifier;
|
|
char *s;
|
|
|
|
s = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
i = Key_StringToKeynum(s, &modifier);
|
|
if (i < 0 || modifier != ~0)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1;
|
|
return;
|
|
}
|
|
i = MP_TranslateFTEtoDPCodes(i);
|
|
G_FLOAT(OFS_RETURN) = i;
|
|
}
|
|
|
|
//string keynumtostring(float keynum) = #609;
|
|
void QCBUILTIN PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int code = G_FLOAT(OFS_PARM0);
|
|
|
|
code = MP_TranslateDPtoFTECodes (code);
|
|
|
|
RETURN_TSTRING(Key_KeynumToString(code));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//float drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #457;
|
|
void QCBUILTIN PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *pos = G_VECTOR(OFS_PARM0);
|
|
float *size = G_VECTOR(OFS_PARM1);
|
|
float *rgb = G_VECTOR(OFS_PARM2);
|
|
float alpha = G_FLOAT(OFS_PARM3);
|
|
|
|
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
|
R2D_FillBlock(pos[0], pos[1], size[0], size[1]);
|
|
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
//void drawsetcliparea(float x, float y, float width, float height) = #458;
|
|
void QCBUILTIN PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float x = G_FLOAT(OFS_PARM0), y = G_FLOAT(OFS_PARM1), w = G_FLOAT(OFS_PARM2), h = G_FLOAT(OFS_PARM3);
|
|
|
|
#ifdef GLQUAKE
|
|
if (qrenderer == QR_OPENGL && qglScissor)
|
|
{
|
|
|
|
x *= (float)vid.pixelwidth/vid.width;
|
|
y *= (float)vid.pixelheight/vid.height;
|
|
|
|
w *= (float)vid.pixelwidth/vid.width;
|
|
h *= (float)vid.pixelheight/vid.height;
|
|
|
|
//add a pixel because this makes DP's menus come out right.
|
|
x-=1;
|
|
y-=1;
|
|
w+=2;
|
|
h+=2;
|
|
|
|
|
|
qglScissor (x, vid.pixelheight-(y+h), w, h);
|
|
qglEnable(GL_SCISSOR_TEST);
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
return;
|
|
}
|
|
#endif
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
//void drawresetcliparea(void) = #459;
|
|
void QCBUILTIN PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
#ifdef GLQUAKE
|
|
if (qrenderer == QR_OPENGL)
|
|
{
|
|
qglDisable(GL_SCISSOR_TEST);
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
return;
|
|
}
|
|
#endif
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void QCBUILTIN PF_CL_DrawTextField (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *pos = G_VECTOR(OFS_PARM0);
|
|
float *size = G_VECTOR(OFS_PARM1);
|
|
unsigned int flags = G_FLOAT(OFS_PARM2);
|
|
char *text = PR_GetStringOfs(prinst, OFS_PARM3);
|
|
R_DrawTextField(pos[0], pos[1], size[0], size[1], text, CON_WHITEMASK, flags);
|
|
}
|
|
|
|
//float drawstring(vector position, string text, vector scale, float alpha, float flag) = #455;
|
|
void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *pos = G_VECTOR(OFS_PARM0);
|
|
char *text = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
float *size = G_VECTOR(OFS_PARM2);
|
|
float alpha = 0;
|
|
float flag = 0;
|
|
float r, g, b;
|
|
|
|
conchar_t buffer[2048], *str;
|
|
float px, py;
|
|
|
|
if (*prinst->callargc >= 6)
|
|
{
|
|
r = G_FLOAT(OFS_PARM3 + 0);
|
|
g = G_FLOAT(OFS_PARM3 + 1);
|
|
b = G_FLOAT(OFS_PARM3 + 2);
|
|
alpha = G_FLOAT(OFS_PARM4);
|
|
flag = G_FLOAT(OFS_PARM5);
|
|
}
|
|
else
|
|
{
|
|
r = 1;
|
|
g = 1;
|
|
b = 1;
|
|
alpha = G_FLOAT(OFS_PARM3);
|
|
flag = G_FLOAT(OFS_PARM4);
|
|
}
|
|
|
|
if (!text)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1; //was null..
|
|
return;
|
|
}
|
|
|
|
COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), false);
|
|
str = buffer;
|
|
|
|
Font_BeginScaledString(font_conchar, pos[0], pos[1], &px, &py);
|
|
Font_ForceColour(r, g, b, alpha);
|
|
while(*str)
|
|
{
|
|
px = Font_DrawScaleChar(px, py, size[0], size[1], *str++);
|
|
}
|
|
Font_InvalidateColour();
|
|
Font_EndString(font_conchar);
|
|
}
|
|
|
|
void QCBUILTIN PF_CL_stringwidth(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
conchar_t buffer[2048], *end;
|
|
float px, py;
|
|
char *text = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
int usecolours = G_FLOAT(OFS_PARM1);
|
|
float fontsize;
|
|
if (*prinst->callargc > 2)
|
|
fontsize = G_FLOAT(OFS_PARM2+1);
|
|
else
|
|
fontsize = 8;
|
|
|
|
if (mp_globs.drawfontscale)
|
|
fontsize *= mp_globs.drawfontscale[1];
|
|
|
|
end = COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), !usecolours);
|
|
|
|
Font_BeginScaledString(font_conchar, 0, 0, &px, &py);
|
|
fontsize /= Font_CharHeight();
|
|
px = Font_LineWidth(buffer, end);
|
|
Font_EndString(font_conchar);
|
|
|
|
if (mp_globs.drawfontscale)
|
|
px *= mp_globs.drawfontscale[1];
|
|
|
|
G_FLOAT(OFS_RETURN) = px * fontsize;
|
|
}
|
|
|
|
#define DRAWFLAG_NORMAL 0
|
|
#define DRAWFLAG_ADD 1
|
|
#define DRAWFLAG_MODULATE 2
|
|
#define DRAWFLAG_MODULATE2 3
|
|
|
|
extern unsigned int r2d_be_flags;
|
|
static unsigned int PF_SelectDPDrawFlag(int flag)
|
|
{
|
|
//flags:
|
|
//0 = blend
|
|
//1 = add
|
|
//2 = modulate
|
|
//3 = modulate*2
|
|
if (flag == 1)
|
|
return BEF_FORCEADDITIVE;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
//float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456;
|
|
void QCBUILTIN PF_CL_drawpic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *pos = G_VECTOR(OFS_PARM0);
|
|
char *picname = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
float *size = G_VECTOR(OFS_PARM2);
|
|
float *rgb = G_VECTOR(OFS_PARM3);
|
|
float alpha = G_FLOAT(OFS_PARM4);
|
|
int flag = (int)G_FLOAT(OFS_PARM5);
|
|
|
|
mpic_t *p;
|
|
|
|
p = R2D_SafeCachePic(picname);
|
|
if (!p)
|
|
p = R2D_SafePicFromWad(picname);
|
|
|
|
r2d_be_flags = PF_SelectDPDrawFlag(flag);
|
|
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
|
R2D_Image(pos[0], pos[1], size[0], size[1], 0, 0, 1, 1, p);
|
|
r2d_be_flags = 0;
|
|
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
|
|
void QCBUILTIN PF_CL_drawsubpic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *pos = G_VECTOR(OFS_PARM0);
|
|
float *size = G_VECTOR(OFS_PARM1);
|
|
char *picname = PR_GetStringOfs(prinst, OFS_PARM2);
|
|
float *srcPos = G_VECTOR(OFS_PARM3);
|
|
float *srcSize = G_VECTOR(OFS_PARM4);
|
|
float *rgb = G_VECTOR(OFS_PARM5);
|
|
float alpha = G_FLOAT(OFS_PARM6);
|
|
int flag = (int) G_FLOAT(OFS_PARM7);
|
|
|
|
mpic_t *p;
|
|
|
|
p = R2D_SafeCachePic(picname);
|
|
|
|
r2d_be_flags = PF_SelectDPDrawFlag(flag);
|
|
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
|
R2D_Image( pos[0], pos[1],
|
|
size[0], size[1],
|
|
srcPos[0], srcPos[1],
|
|
srcPos[0]+srcSize[0], srcPos[1]+srcSize[1],
|
|
p);
|
|
r2d_be_flags = 0;
|
|
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
void QCBUILTIN PF_CL_is_cached_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *str;
|
|
|
|
str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
// if (Draw_IsCached)
|
|
// G_FLOAT(OFS_RETURN) = !!Draw_IsCached(str);
|
|
// else
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
|
|
void QCBUILTIN PF_CL_precache_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *str;
|
|
mpic_t *pic;
|
|
float fromwad;
|
|
|
|
str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
if (*prinst->callargc > 1)
|
|
fromwad = G_FLOAT(OFS_PARM1);
|
|
else
|
|
fromwad = false;
|
|
|
|
if (fromwad)
|
|
pic = R2D_SafePicFromWad(str);
|
|
else
|
|
{
|
|
if (cls.state
|
|
#ifndef CLIENTONLY
|
|
&& !sv.active
|
|
#endif
|
|
)
|
|
CL_CheckOrEnqueDownloadFile(str, str, 0);
|
|
|
|
pic = R2D_SafeCachePic(str);
|
|
}
|
|
|
|
if (pic)
|
|
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
|
else
|
|
G_INT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void QCBUILTIN PF_CL_free_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *str;
|
|
|
|
str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
//we don't support this.
|
|
}
|
|
|
|
|
|
//float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag) = #454;
|
|
void QCBUILTIN PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *pos = G_VECTOR(OFS_PARM0);
|
|
int chara = G_FLOAT(OFS_PARM1);
|
|
float *size = G_VECTOR(OFS_PARM2);
|
|
float *rgb = G_VECTOR(OFS_PARM3);
|
|
float alpha = G_FLOAT(OFS_PARM4);
|
|
// float flag = G_FLOAT(OFS_PARM5);
|
|
|
|
float x, y;
|
|
|
|
if (!chara)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1; //was null..
|
|
return;
|
|
}
|
|
|
|
Font_BeginScaledString(font_conchar, pos[0], pos[1], &x, &y);
|
|
Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha);
|
|
Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK | /*0xe000|*/(chara&0xff));
|
|
Font_InvalidateColour();
|
|
Font_EndString(font_conchar);
|
|
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
//float drawrawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455;
|
|
void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *pos = G_VECTOR(OFS_PARM0);
|
|
char *text = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
float *size = G_VECTOR(OFS_PARM2);
|
|
float *rgb = G_VECTOR(OFS_PARM3);
|
|
float alpha = G_FLOAT(OFS_PARM4);
|
|
// float flag = G_FLOAT(OFS_PARM5);
|
|
float x, y;
|
|
|
|
if (!text)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1; //was null..
|
|
return;
|
|
}
|
|
|
|
Font_BeginScaledString(font_conchar, pos[0], pos[1], &x, &y);
|
|
x = pos[0];
|
|
y = pos[1];
|
|
Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha);
|
|
|
|
if (mp_globs.drawfontscale)
|
|
{
|
|
size[0] *= mp_globs.drawfontscale[0];
|
|
size[1] *= mp_globs.drawfontscale[1];
|
|
}
|
|
while(*text)
|
|
{
|
|
//FIXME: which charset is this meant to be using?
|
|
//quakes? 8859-1? utf8? some weird hacky mixture?
|
|
x = Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK|/*0xe000|*/(*text++&0xff));
|
|
}
|
|
Font_InvalidateColour();
|
|
Font_EndString(font_conchar);
|
|
}
|
|
|
|
//void (float width, vector rgb, float alpha, float flags, vector pos1, ...) drawline;
|
|
void QCBUILTIN PF_CL_drawline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *rgb = G_VECTOR(OFS_PARM1);
|
|
float alpha = G_FLOAT(OFS_PARM2);
|
|
float *pos = G_VECTOR(OFS_PARM4);
|
|
int numpoints = *prinst->callargc-4;
|
|
|
|
#ifdef GLQUAKE // :(
|
|
|
|
if (qrenderer == QR_OPENGL)
|
|
{
|
|
qglColor4f(rgb[0], rgb[1], rgb[2], alpha);
|
|
qglBegin(GL_LINES);
|
|
while (numpoints-->0)
|
|
{
|
|
qglVertex3fv(pos);
|
|
pos += 3;
|
|
}
|
|
|
|
qglEnd();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//vector drawgetimagesize(string pic) = #460;
|
|
void QCBUILTIN PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *picname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
mpic_t *p = R2D_SafeCachePic(picname);
|
|
|
|
float *ret = G_VECTOR(OFS_RETURN);
|
|
|
|
if (p)
|
|
{
|
|
ret[0] = p->width;
|
|
ret[1] = p->height;
|
|
ret[2] = 0;
|
|
}
|
|
else
|
|
{
|
|
ret[0] = 0;
|
|
ret[1] = 0;
|
|
ret[2] = 0;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef MENU_DAT
|
|
|
|
typedef struct menuedict_s
|
|
{
|
|
qboolean isfree;
|
|
float freetime; // sv.time when the object was freed
|
|
int entnum;
|
|
qboolean readonly; //world
|
|
void *fields;
|
|
} menuedict_t;
|
|
|
|
|
|
|
|
evalc_t menuc_eval_chain;
|
|
|
|
int menuentsize;
|
|
|
|
// cvars
|
|
#define MENUPROGSGROUP "Menu progs control"
|
|
cvar_t forceqmenu = SCVAR("forceqmenu", "0");
|
|
cvar_t pr_menuqc_coreonerror = SCVAR("pr_menuqc_coreonerror", "1");
|
|
|
|
|
|
//new generic functions.
|
|
|
|
void QCBUILTIN PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int a = G_FLOAT(OFS_PARM0);
|
|
int b = G_FLOAT(OFS_PARM1);
|
|
if (b == 0)
|
|
{
|
|
Con_Printf("mod by zero\n");
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
else
|
|
G_FLOAT(OFS_RETURN) = a % b;
|
|
}
|
|
|
|
char *RemapCvarNameFromDPToFTE(char *name)
|
|
{
|
|
if (!stricmp(name, "vid_bitsperpixel"))
|
|
return "vid_bpp";
|
|
if (!stricmp(name, "_cl_playermodel"))
|
|
return "model";
|
|
if (!stricmp(name, "_cl_playerskin"))
|
|
return "skin";
|
|
if (!stricmp(name, "_cl_color"))
|
|
return "topcolor";
|
|
if (!stricmp(name, "_cl_name"))
|
|
return "name";
|
|
|
|
if (!stricmp(name, "v_contrast"))
|
|
return "v_contrast";
|
|
if (!stricmp(name, "v_hwgamma"))
|
|
return "vid_hardwaregamma";
|
|
if (!stricmp(name, "showfps"))
|
|
return "show_fps";
|
|
if (!stricmp(name, "sv_progs"))
|
|
return "progs";
|
|
|
|
return name;
|
|
}
|
|
|
|
static void QCBUILTIN PF_menu_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
cvar_t *var;
|
|
char *str;
|
|
|
|
str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
str = RemapCvarNameFromDPToFTE(str);
|
|
var = Cvar_Get(str, "", 0, "menu cvars");
|
|
if (var)
|
|
{
|
|
if (var->latched_string)
|
|
G_FLOAT(OFS_RETURN) = atof(var->latched_string); else
|
|
G_FLOAT(OFS_RETURN) = var->value;
|
|
}
|
|
else
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
static void QCBUILTIN PF_menu_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *var_name, *val;
|
|
cvar_t *var;
|
|
|
|
var_name = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
var_name = RemapCvarNameFromDPToFTE(var_name);
|
|
val = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
|
|
var = Cvar_Get(var_name, val, 0, "QC variables");
|
|
Cvar_Set (var, val);
|
|
}
|
|
static void QCBUILTIN PF_menu_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
cvar_t *cv = Cvar_Get(RemapCvarNameFromDPToFTE(str), "", 0, "QC variables");
|
|
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, cv->string );
|
|
}
|
|
|
|
qboolean M_Vid_GetMode(int num, int *w, int *h);
|
|
//a bit pointless really
|
|
void QCBUILTIN PF_cl_getresolution (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float mode = G_FLOAT(OFS_PARM0);
|
|
float *ret = G_VECTOR(OFS_RETURN);
|
|
int w, h;
|
|
|
|
w=h=0;
|
|
M_Vid_GetMode(mode, &w, &h);
|
|
|
|
ret[0] = w;
|
|
ret[1] = h;
|
|
ret[2] = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
void QCBUILTIN PF_nonfatalobjerror (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *s;
|
|
struct edict_s *ed;
|
|
eval_t *selfp;
|
|
|
|
s = PF_VarString(prinst, 0, pr_globals);
|
|
|
|
PR_StackTrace(prinst);
|
|
|
|
selfp = PR_FindGlobal(prinst, "self", PR_CURRENT, NULL);
|
|
if (selfp && selfp->_int)
|
|
{
|
|
ed = PROG_TO_EDICT(prinst, selfp->_int);
|
|
|
|
PR_PrintEdict(prinst, ed);
|
|
|
|
|
|
if (developer.value)
|
|
*prinst->pr_trace = 2;
|
|
else
|
|
{
|
|
ED_Free (prinst, ed);
|
|
}
|
|
}
|
|
|
|
Con_Printf ("======OBJECT ERROR======\n%s\n", s);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//float isserver(void) = #60;
|
|
void QCBUILTIN PF_isserver (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
#ifdef CLIENTONLY
|
|
G_FLOAT(OFS_RETURN) = false;
|
|
#else
|
|
G_FLOAT(OFS_RETURN) = sv.state != ss_dead;
|
|
#endif
|
|
}
|
|
|
|
//float clientstate(void) = #62;
|
|
void QCBUILTIN PF_clientstate (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = cls.state >= ca_connected ? 2 : 1; //fit in with netquake (we never run a menu.dat dedicated)
|
|
}
|
|
|
|
//too specific to the prinst's builtins.
|
|
static void QCBUILTIN PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Con_Printf("\n");
|
|
|
|
prinst->RunError(prinst, "\nBuiltin %i not implemented.\nMenu is not compatible.", prinst->lastcalledbuiltinnumber);
|
|
PR_BIError (prinst, "bulitin not implemented");
|
|
}
|
|
|
|
|
|
|
|
void QCBUILTIN PF_CL_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *str;
|
|
|
|
str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
if (S_PrecacheSound(str))
|
|
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
|
else
|
|
G_INT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
//void setkeydest(float dest) = #601;
|
|
void QCBUILTIN PF_cl_setkeydest (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
switch((int)G_FLOAT(OFS_PARM0))
|
|
{
|
|
case 0:
|
|
// key_game
|
|
key_dest = ((cls.state == ca_active)?key_game:key_console);
|
|
break;
|
|
case 2:
|
|
// key_menu
|
|
key_dest = key_menu;
|
|
m_state = m_menu_dat;
|
|
break;
|
|
case 1:
|
|
// key_message
|
|
// key_dest = key_message
|
|
// break;
|
|
default:
|
|
PR_BIError (prinst, "PF_setkeydest: wrong destination %i !\n",(int)G_FLOAT(OFS_PARM0));
|
|
}
|
|
}
|
|
//float getkeydest(void) = #602;
|
|
void QCBUILTIN PF_cl_getkeydest (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
switch(key_dest)
|
|
{
|
|
case key_game:
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
break;
|
|
case key_menu:
|
|
if (m_state == m_menu_dat)
|
|
G_FLOAT(OFS_RETURN) = 2;
|
|
else
|
|
G_FLOAT(OFS_RETURN) = 3;
|
|
break;
|
|
case 1:
|
|
// key_message
|
|
// key_dest = key_message
|
|
// break;
|
|
default:
|
|
G_FLOAT(OFS_RETURN) = 3;
|
|
}
|
|
}
|
|
|
|
//void setmousetarget(float trg) = #603;
|
|
void QCBUILTIN PF_cl_setmousetarget (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
extern int mouseusedforgui;
|
|
switch ((int)G_FLOAT(OFS_PARM0))
|
|
{
|
|
case 1:
|
|
mouseusedforgui = true;
|
|
break;
|
|
case 2:
|
|
mouseusedforgui = false;
|
|
break;
|
|
default:
|
|
PR_BIError(prinst, "PF_setmousetarget: not a valid destination\n");
|
|
}
|
|
}
|
|
|
|
//float getmousetarget(void) = #604;
|
|
void QCBUILTIN PF_cl_getmousetarget (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
extern int mouseusedforgui;
|
|
G_FLOAT(OFS_RETURN) = mouseusedforgui?1:2;
|
|
}
|
|
|
|
//vector getmousepos(void) = #66;
|
|
void QCBUILTIN PF_cl_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *ret = G_VECTOR(OFS_RETURN);
|
|
extern int mousemove_x, mousemove_y;
|
|
extern int mousecursor_x, mousecursor_y;
|
|
|
|
if (Key_MouseShouldBeFree())
|
|
{
|
|
ret[0] = mousecursor_x;
|
|
ret[1] = mousecursor_y;
|
|
}
|
|
else
|
|
{
|
|
ret[0] = mousemove_x;
|
|
ret[1] = mousemove_y;
|
|
}
|
|
|
|
mousemove_x=0;
|
|
mousemove_y=0;
|
|
|
|
// extern int mousecursor_x, mousecursor_y;
|
|
// ret[0] = mousecursor_x;
|
|
// ret[1] = mousecursor_y;
|
|
ret[2] = 0;
|
|
}
|
|
|
|
|
|
static void QCBUILTIN PF_Remove_ (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
menuedict_t *ed;
|
|
|
|
ed = (void*)G_EDICT(prinst, OFS_PARM0);
|
|
|
|
if (ed->isfree)
|
|
{
|
|
Con_DPrintf("Tried removing free entity\n");
|
|
return;
|
|
}
|
|
|
|
ED_Free (prinst, (void*)ed);
|
|
}
|
|
|
|
static void QCBUILTIN PF_CopyEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
menuedict_t *in, *out;
|
|
|
|
in = (menuedict_t*)G_EDICT(prinst, OFS_PARM0);
|
|
out = (menuedict_t*)G_EDICT(prinst, OFS_PARM1);
|
|
|
|
memcpy(out->fields, in->fields, menuentsize);
|
|
}
|
|
|
|
#ifdef CL_MASTER
|
|
#include "cl_master.h"
|
|
|
|
typedef enum{
|
|
SLIST_HOSTCACHEVIEWCOUNT,
|
|
SLIST_HOSTCACHETOTALCOUNT,
|
|
SLIST_MASTERQUERYCOUNT,
|
|
SLIST_MASTERREPLYCOUNT,
|
|
SLIST_SERVERQUERYCOUNT,
|
|
SLIST_SERVERREPLYCOUNT,
|
|
SLIST_SORTFIELD,
|
|
SLIST_SORTDESCENDING
|
|
} hostcacheglobal_t;
|
|
|
|
void QCBUILTIN PF_M_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
hostcacheglobal_t hcg = G_FLOAT(OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
switch(hcg)
|
|
{
|
|
case SLIST_HOSTCACHEVIEWCOUNT:
|
|
CL_QueryServers();
|
|
Master_CheckPollSockets();
|
|
G_FLOAT(OFS_RETURN) = Master_NumSorted();
|
|
return;
|
|
case SLIST_HOSTCACHETOTALCOUNT:
|
|
CL_QueryServers();
|
|
Master_CheckPollSockets();
|
|
G_FLOAT(OFS_RETURN) = Master_TotalCount();
|
|
return;
|
|
|
|
case SLIST_MASTERQUERYCOUNT:
|
|
case SLIST_MASTERREPLYCOUNT:
|
|
case SLIST_SERVERQUERYCOUNT:
|
|
case SLIST_SERVERREPLYCOUNT:
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
return;
|
|
|
|
case SLIST_SORTFIELD:
|
|
G_FLOAT(OFS_RETURN) = Master_GetSortField();
|
|
return;
|
|
case SLIST_SORTDESCENDING:
|
|
G_FLOAT(OFS_RETURN) = Master_GetSortDescending();
|
|
return;
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
//void resethostcachemasks(void) = #615;
|
|
void QCBUILTIN PF_M_resethostcachemasks(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Master_ClearMasks();
|
|
}
|
|
//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616;
|
|
void QCBUILTIN PF_M_sethostcachemaskstring(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int mask = G_FLOAT(OFS_PARM0);
|
|
int field = G_FLOAT(OFS_PARM1);
|
|
char *str = PR_GetStringOfs(prinst, OFS_PARM2);
|
|
int op = G_FLOAT(OFS_PARM3);
|
|
|
|
Master_SetMaskString(mask, field, str, op);
|
|
}
|
|
//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617;
|
|
void QCBUILTIN PF_M_sethostcachemasknumber(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int mask = G_FLOAT(OFS_PARM0);
|
|
int field = G_FLOAT(OFS_PARM1);
|
|
int str = G_FLOAT(OFS_PARM2);
|
|
int op = G_FLOAT(OFS_PARM3);
|
|
|
|
Master_SetMaskInteger(mask, field, str, op);
|
|
}
|
|
//void resorthostcache(void) = #618;
|
|
void QCBUILTIN PF_M_resorthostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Master_SortServers();
|
|
}
|
|
//void sethostcachesort(float fld, float descending) = #619;
|
|
void QCBUILTIN PF_M_sethostcachesort(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Master_SetSortField(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
|
|
}
|
|
//void refreshhostcache(void) = #620;
|
|
void QCBUILTIN PF_M_refreshhostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
MasterInfo_Refresh();
|
|
}
|
|
//float gethostcachenumber(float fld, float hostnr) = #621;
|
|
void QCBUILTIN PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float ret = 0;
|
|
int keynum = G_FLOAT(OFS_PARM0);
|
|
int svnum = G_FLOAT(OFS_PARM1);
|
|
serverinfo_t *sv;
|
|
sv = Master_SortedServer(svnum);
|
|
|
|
ret = Master_ReadKeyFloat(sv, keynum);
|
|
|
|
G_FLOAT(OFS_RETURN) = ret;
|
|
}
|
|
void QCBUILTIN PF_M_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *ret;
|
|
int keynum = G_FLOAT(OFS_PARM0);
|
|
int svnum = G_FLOAT(OFS_PARM1);
|
|
serverinfo_t *sv;
|
|
|
|
sv = Master_SortedServer(svnum);
|
|
ret = Master_ReadKeyString(sv, keynum);
|
|
|
|
RETURN_TSTRING(ret);
|
|
}
|
|
|
|
//float gethostcacheindexforkey(string key) = #622;
|
|
void QCBUILTIN PF_M_gethostcacheindexforkey(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *keyname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
G_FLOAT(OFS_RETURN) = Master_KeyForName(keyname);
|
|
}
|
|
//void addwantedhostcachekey(string key) = #623;
|
|
void QCBUILTIN PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
PF_M_gethostcacheindexforkey(prinst, pr_globals);
|
|
}
|
|
|
|
void QCBUILTIN PF_M_getextresponse(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
//this does something weird
|
|
G_INT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void QCBUILTIN PF_netaddress_resolve(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *address = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
netadr_t adr;
|
|
char result[256];
|
|
if (NET_StringToAdr(address, &adr))
|
|
RETURN_TSTRING(NET_AdrToString (result, sizeof(result), adr));
|
|
else
|
|
RETURN_TSTRING("");
|
|
}
|
|
#else
|
|
|
|
void PF_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
|
void PF_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals) {G_INT(OFS_RETURN) = 0;}
|
|
//void resethostcachemasks(void) = #615;
|
|
void PF_M_resethostcachemasks(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616;
|
|
void PF_M_sethostcachemaskstring(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617;
|
|
void PF_M_sethostcachemasknumber(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void resorthostcache(void) = #618;
|
|
void PF_M_resorthostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void sethostcachesort(float fld, float descending) = #619;
|
|
void PF_M_sethostcachesort(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
//void refreshhostcache(void) = #620;
|
|
void PF_M_refreshhostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals) {}
|
|
//float gethostcachenumber(float fld, float hostnr) = #621;
|
|
void PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
|
//float gethostcacheindexforkey(string key) = #622;
|
|
void PF_M_gethostcacheindexforkey(progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
|
//void addwantedhostcachekey(string key) = #623;
|
|
void PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
|
#endif
|
|
|
|
|
|
void QCBUILTIN PF_localsound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *soundname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
S_LocalSound (soundname);
|
|
}
|
|
|
|
#define skip1 PF_Fixme,
|
|
#define skip5 skip1 skip1 skip1 skip1 skip1
|
|
#define skip10 skip5 skip5
|
|
#define skip50 skip10 skip10 skip10 skip10 skip10
|
|
#define skip100 skip50 skip50
|
|
|
|
void QCBUILTIN PF_menu_checkextension (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
//yeah, this is a stub... not sure what form extex
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void QCBUILTIN PF_gettime (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = *prinst->parms->gametime;
|
|
}
|
|
|
|
void QCBUILTIN PF_CL_precache_file (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
|
}
|
|
|
|
//entity findchainstring(.string _field, string match) = #26;
|
|
void QCBUILTIN PF_menu_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int i, f;
|
|
char *s;
|
|
string_t t;
|
|
menuedict_t *ent, *chain; //note, all edicts share the common header, but don't use it's fields!
|
|
eval_t *val;
|
|
|
|
chain = (menuedict_t *) *prinst->parms->sv_edicts;
|
|
|
|
f = G_INT(OFS_PARM0)+prinst->fieldadjust;
|
|
s = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
|
|
for (i = 1; i < *prinst->parms->sv_num_edicts; i++)
|
|
{
|
|
ent = (menuedict_t *)EDICT_NUM(prinst, i);
|
|
if (ent->isfree)
|
|
continue;
|
|
t = *(string_t *)&((float*)ent->fields)[f];
|
|
if (!t)
|
|
continue;
|
|
if (strcmp(PR_GetString(prinst, t), s))
|
|
continue;
|
|
|
|
val = prinst->GetEdictFieldValue(prinst, (void*)ent, "chain", &menuc_eval_chain);
|
|
if (val)
|
|
val->edict = EDICT_TO_PROG(prinst, (void*)chain);
|
|
chain = ent;
|
|
}
|
|
|
|
RETURN_EDICT(prinst, (void*)chain);
|
|
}
|
|
//entity findchainfloat(.float _field, float match) = #27;
|
|
void QCBUILTIN PF_menu_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int i, f;
|
|
float s;
|
|
menuedict_t *ent, *chain; //note, all edicts share the common header, but don't use it's fields!
|
|
eval_t *val;
|
|
|
|
chain = (menuedict_t *) *prinst->parms->sv_edicts;
|
|
|
|
f = G_INT(OFS_PARM0)+prinst->fieldadjust;
|
|
s = G_FLOAT(OFS_PARM1);
|
|
|
|
for (i = 1; i < *prinst->parms->sv_num_edicts; i++)
|
|
{
|
|
ent = (menuedict_t*)EDICT_NUM(prinst, i);
|
|
if (ent->isfree)
|
|
continue;
|
|
if (((float *)ent->fields)[f] != s)
|
|
continue;
|
|
|
|
val = prinst->GetEdictFieldValue(prinst, (void*)ent, "chain", NULL);
|
|
if (val)
|
|
val->edict = EDICT_TO_PROG(prinst, (void*)chain);
|
|
chain = ent;
|
|
}
|
|
|
|
RETURN_EDICT(prinst, (void*)chain);
|
|
}
|
|
|
|
void QCBUILTIN PF_etof(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = G_EDICTNUM(prinst, OFS_PARM0);
|
|
}
|
|
void QCBUILTIN PF_ftoe(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int entnum = G_FLOAT(OFS_PARM0);
|
|
|
|
RETURN_EDICT(prinst, EDICT_NUM(prinst, entnum));
|
|
}
|
|
|
|
void QCBUILTIN PF_IsNotNull(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int str = G_INT(OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = !!str;
|
|
}
|
|
|
|
//float altstr_count(string str) = #82;
|
|
//returns number of single quoted strings in the string.
|
|
void QCBUILTIN PF_altstr_count(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *s;
|
|
int count = 0;
|
|
s = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
for (;*s;s++)
|
|
{
|
|
if (*s == '\\')
|
|
{
|
|
if (!*++s)
|
|
break;
|
|
}
|
|
else if (*s == '\'')
|
|
count++;
|
|
}
|
|
G_FLOAT(OFS_RETURN) = count/2;
|
|
}
|
|
//string altstr_prepare(string str) = #83;
|
|
void QCBUILTIN PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char outstr[8192], *out;
|
|
char *instr, *in;
|
|
int size;
|
|
|
|
// VM_SAFEPARMCOUNT( 1, VM_altstr_prepare );
|
|
|
|
instr = PR_GetStringOfs(prinst, OFS_PARM0 );
|
|
//VM_CheckEmptyString( instr );
|
|
|
|
for( out = outstr, in = instr, size = sizeof(outstr) - 1 ; size && *in ; size--, in++, out++ )
|
|
{
|
|
if( *in == '\'' )
|
|
{
|
|
*out++ = '\\';
|
|
*out = '\'';
|
|
size--;
|
|
}
|
|
else
|
|
*out = *in;
|
|
}
|
|
*out = 0;
|
|
|
|
G_INT( OFS_RETURN ) = (int)PR_TempString( prinst, outstr );
|
|
}
|
|
//string altstr_get(string str, float num) = #84;
|
|
void QCBUILTIN PF_altstr_get(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *altstr, *pos, outstr[8192], *out;
|
|
int count, size;
|
|
|
|
// VM_SAFEPARMCOUNT( 2, VM_altstr_get );
|
|
|
|
altstr = PR_GetStringOfs(prinst, OFS_PARM0 );
|
|
//VM_CheckEmptyString( altstr );
|
|
|
|
count = G_FLOAT( OFS_PARM1 );
|
|
count = count * 2 + 1;
|
|
|
|
for( pos = altstr ; *pos && count ; pos++ )
|
|
{
|
|
if( *pos == '\\' && !*++pos )
|
|
break;
|
|
else if( *pos == '\'' )
|
|
count--;
|
|
}
|
|
|
|
if( !*pos )
|
|
{
|
|
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
|
|
return;
|
|
}
|
|
|
|
for( out = outstr, size = sizeof(outstr) - 1 ; size && *pos ; size--, pos++, out++ )
|
|
{
|
|
if( *pos == '\\' )
|
|
{
|
|
if( !*++pos )
|
|
break;
|
|
*out = *pos;
|
|
size--;
|
|
}
|
|
else if( *pos == '\'' )
|
|
break;
|
|
else
|
|
*out = *pos;
|
|
}
|
|
|
|
*out = 0;
|
|
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, outstr );
|
|
}
|
|
//string altstr_set(string str, float num, string set) = #85
|
|
void QCBUILTIN PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int num;
|
|
char *altstr, *str;
|
|
char *in;
|
|
char outstr[8192], *out;
|
|
|
|
// VM_SAFEPARMCOUNT( 3, VM_altstr_set );
|
|
|
|
altstr = PR_GetStringOfs(prinst, OFS_PARM0 );
|
|
//VM_CheckEmptyString( altstr );
|
|
|
|
num = G_FLOAT( OFS_PARM1 );
|
|
|
|
str = PR_GetStringOfs(prinst, OFS_PARM2 );
|
|
//VM_CheckEmptyString( str );
|
|
|
|
out = outstr;
|
|
for( num = num * 2 + 1, in = altstr; *in && num; *out++ = *in++ )
|
|
{
|
|
if( *in == '\\' && !*++in )
|
|
break;
|
|
else if( *in == '\'' )
|
|
num--;
|
|
}
|
|
|
|
if( !in )
|
|
{
|
|
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
|
|
return;
|
|
}
|
|
// copy set in
|
|
for( ; *str; *out++ = *str++ )
|
|
;
|
|
// now jump over the old contents
|
|
for( ; *in ; in++ )
|
|
{
|
|
if( *in == '\'' || (*in == '\\' && !*++in) )
|
|
break;
|
|
}
|
|
|
|
if( !in ) {
|
|
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, "" );
|
|
return;
|
|
}
|
|
|
|
strcpy( out, in );
|
|
G_INT( OFS_RETURN ) = (int)PR_TempString( prinst, outstr );
|
|
|
|
}
|
|
|
|
builtin_t menu_builtins[] = {
|
|
//0
|
|
PF_Fixme,
|
|
PF_menu_checkextension, //void checkextension(string ext) = #1;
|
|
PF_error,
|
|
PF_nonfatalobjerror,
|
|
PF_print,
|
|
skip1 //void bprint(string text,...) = #5;
|
|
skip1 //void sprint(float clientnum, string text,...) = #6;
|
|
skip1 //void centerprint(string text,...) = #7;
|
|
PF_normalize, //vector normalize(vector v) = #8;
|
|
PF_vlen, //float vlen(vector v) = #9;
|
|
//10
|
|
PF_vectoyaw,//10 //float vectoyaw(vector v) = #10;
|
|
PF_vectoangles,//11 //vector vectoangles(vector v) = #11;
|
|
PF_random,//12
|
|
PF_localcmd,//13
|
|
PF_menu_cvar,//14
|
|
PF_menu_cvar_set,//15
|
|
PF_dprint,//16
|
|
PF_ftos,//17
|
|
PF_fabs,//18
|
|
PF_vtos,//19
|
|
|
|
PF_etos,//20
|
|
PF_stof,//21
|
|
PF_Spawn,//22
|
|
PF_Remove_,//23
|
|
PF_FindString,//24
|
|
PF_FindFloat,//25
|
|
PF_menu_findchain,//26 //entity findchainstring(.string _field, string match) = #26;
|
|
PF_menu_findchainfloat,//27 //entity findchainfloat(.float _field, float match) = #27;
|
|
PF_CL_precache_file,//28
|
|
PF_CL_precache_sound,//29
|
|
|
|
//30
|
|
PF_coredump, //void coredump(void) = #30;
|
|
PF_traceon, //void traceon(void) = #31;
|
|
PF_traceoff, //void traceoff(void) = #32;
|
|
PF_eprint, //void eprint(entity e) = #33;
|
|
PF_rint,
|
|
PF_floor,
|
|
PF_ceil,
|
|
PF_nextent,
|
|
PF_Sin,
|
|
PF_Cos,
|
|
//40
|
|
PF_Sqrt,
|
|
PF_randomvector,
|
|
PF_registercvar,
|
|
PF_min,
|
|
PF_max,
|
|
PF_bound,
|
|
PF_pow,
|
|
PF_CopyEntity,
|
|
PF_fopen,
|
|
PF_fclose,
|
|
//50
|
|
PF_fgets,
|
|
PF_fputs,
|
|
PF_strlen,
|
|
PF_strcat,
|
|
PF_substring,
|
|
PF_stov,
|
|
PF_dupstring,
|
|
PF_forgetstring,
|
|
PF_Tokenize,
|
|
PF_ArgV,
|
|
//60
|
|
PF_isserver,
|
|
skip1 //float clientcount(void) = #61;
|
|
PF_clientstate,
|
|
skip1 //void clientcommand(float client, string s) = #63;
|
|
skip1 //void changelevel(string map) = #64;
|
|
PF_localsound,
|
|
PF_cl_getmousepos,
|
|
PF_gettime,
|
|
PF_loadfromdata,
|
|
PF_loadfromfile,
|
|
//70
|
|
PF_mod,//0
|
|
PF_menu_cvar_string,//1
|
|
PF_Fixme,//2 //void crash(void) = #72;
|
|
PF_Fixme,//3 //void stackdump(void) = #73;
|
|
PF_search_begin,//4
|
|
PF_search_end,//5
|
|
PF_search_getsize ,//6
|
|
PF_search_getfilename,//7
|
|
PF_chr2str,//8
|
|
PF_etof,//9 //float etof(entity ent) = #79;
|
|
//80
|
|
PF_ftoe,//10
|
|
PF_IsNotNull,
|
|
|
|
|
|
PF_altstr_count, //float altstr_count(string str) = #82;
|
|
PF_altstr_prepare, //string altstr_prepare(string str) = #83;
|
|
PF_altstr_get, //string altstr_get(string str, float num) = #84;
|
|
PF_altstr_set, //string altstr_set(string str, float num, string set) = #85
|
|
|
|
skip1 //altstr_ins
|
|
skip1 //findflags
|
|
skip1 //findchainflags
|
|
PF_cvar_defstring,
|
|
//90
|
|
skip10
|
|
//100
|
|
skip100
|
|
//200
|
|
skip10
|
|
skip10
|
|
//220
|
|
skip1
|
|
PF_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
|
|
PF_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
|
|
PF_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
|
|
PF_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
|
|
PF_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
|
|
PF_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
|
|
PF_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
|
|
PF_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
|
|
PF_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
|
|
//230
|
|
PF_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
//240
|
|
skip10
|
|
skip50
|
|
//300
|
|
skip100
|
|
//400
|
|
skip10
|
|
skip10
|
|
skip10
|
|
skip10
|
|
//440
|
|
PF_buf_create, // #440 float() buf_create (DP_QC_STRINGBUFFERS)
|
|
PF_buf_del, // #441 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
|
|
PF_buf_getsize, // #442 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
|
|
PF_buf_copy, // #443 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
|
|
PF_buf_sort, // #444 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
|
|
PF_buf_implode, // #445 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
|
|
PF_bufstr_get, // #446 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
|
|
PF_bufstr_set, // #447 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
|
|
PF_bufstr_add, // #448 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
|
|
PF_bufstr_free, // #449 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
|
|
//450
|
|
PF_Fixme,//0
|
|
PF_CL_is_cached_pic,//1
|
|
PF_CL_precache_pic,//2
|
|
PF_CL_free_pic,//3
|
|
PF_CL_drawcharacter,//4
|
|
PF_CL_drawrawstring,//5
|
|
PF_CL_drawpic,//6
|
|
PF_CL_drawfill,//7
|
|
PF_CL_drawsetcliparea,//8
|
|
PF_CL_drawresetcliparea,//9
|
|
|
|
//460
|
|
PF_CL_drawgetimagesize,//460
|
|
PF_cin_open, // #461
|
|
PF_cin_close, // #462
|
|
PF_cin_setstate, // #463
|
|
PF_cin_getstate, // #464
|
|
PF_cin_restart, // #465
|
|
PF_drawline, // #466
|
|
PF_CL_drawcolouredstring, // #467
|
|
PF_CL_stringwidth, // #468
|
|
PF_CL_drawsubpic, // #469
|
|
|
|
//470
|
|
skip1 // #470
|
|
PF_asin, // #471
|
|
PF_acos, // #472
|
|
PF_atan, // #473
|
|
PF_atan2, // #474
|
|
PF_tan, // #475
|
|
PF_strlennocol, // #476
|
|
PF_strdecolorize, // #477
|
|
PF_strftime, // #478
|
|
PF_tokenizebyseparator, // #479
|
|
|
|
//480
|
|
PF_strtolower, // #480 string(string s) VM_strtolower : DRESK - Return string as lowercase
|
|
PF_strtoupper, // #481 string(string s) VM_strtoupper : DRESK - Return string as uppercase
|
|
PF_cvar_defstring, // #482
|
|
skip1 // #483
|
|
PF_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
|
|
PF_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
|
|
skip1 // #486
|
|
PF_gecko_create, // #487 float gecko_create( string name )
|
|
PF_gecko_destroy, // #488 void gecko_destroy( string name )
|
|
PF_gecko_navigate, // #489 void gecko_navigate( string name, string URI )
|
|
|
|
//490
|
|
PF_gecko_keyevent, // #490 float gecko_keyevent( string name, float key, float eventtype )
|
|
PF_gecko_movemouse, // #491 void gecko_mousemove( string name, float x, float y )
|
|
PF_gecko_resize, // #492 void gecko_resize( string name, float w, float h )
|
|
PF_gecko_get_texture_extent, // #493 vector gecko_get_texture_extent( string name )
|
|
PF_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
|
|
PF_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
|
|
skip1 // #496
|
|
skip1 // #497
|
|
skip1 // #498
|
|
skip1 // #499
|
|
|
|
//500
|
|
skip1 // #500
|
|
skip1 // #501
|
|
skip1 // #502
|
|
PF_whichpack, // #503 string(string) whichpack = #503;
|
|
skip1 // #504
|
|
skip1 // #505
|
|
skip1 // #506
|
|
skip1 // #507
|
|
skip1 // #508
|
|
skip1 // #509
|
|
|
|
//510
|
|
PF_uri_escape, // #510 string(string in) uri_escape = #510;
|
|
PF_uri_unescape, // #511 string(string in) uri_unescape = #511;
|
|
PF_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
|
|
PF_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
|
|
PF_tokenize_console, // #514
|
|
PF_argv_start_index, // #515
|
|
PF_argv_end_index, // #516
|
|
PF_buf_cvarlist, // #517
|
|
PF_cvar_description, // #518
|
|
skip1 // #519
|
|
|
|
//520
|
|
skip10
|
|
skip10
|
|
skip10
|
|
skip50
|
|
//600
|
|
skip1
|
|
PF_cl_setkeydest,
|
|
PF_cl_getkeydest,
|
|
PF_cl_setmousetarget,
|
|
PF_cl_getmousetarget,
|
|
PF_callfunction,
|
|
PF_writetofile, //void writetofile(float fhandle, entity ent) = #606;
|
|
PF_isfunction,
|
|
PF_cl_getresolution,
|
|
PF_cl_keynumtostring,
|
|
PF_cl_findkeysforcommand,
|
|
#ifdef CL_MASTER
|
|
PF_M_gethostcachevalue,
|
|
PF_M_gethostcachestring,
|
|
#else
|
|
skip1
|
|
skip1
|
|
#endif
|
|
PF_parseentitydata, //void parseentitydata(entity ent, string data) = #613;
|
|
|
|
PF_cl_stringtokeynum,
|
|
|
|
PF_M_resethostcachemasks,
|
|
PF_M_sethostcachemaskstring,
|
|
PF_M_sethostcachemasknumber,
|
|
PF_M_resorthostcache,
|
|
PF_M_sethostcachesort,
|
|
PF_M_refreshhostcache,
|
|
PF_M_gethostcachenumber,
|
|
PF_M_gethostcacheindexforkey,
|
|
PF_M_addwantedhostcachekey,
|
|
#ifdef CL_MASTER
|
|
PF_M_getextresponse, // #624
|
|
PF_netaddress_resolve,
|
|
#else
|
|
skip1
|
|
skip1
|
|
#endif
|
|
skip1 /*get gamedir info*/
|
|
PF_sprintf, /*sprintf*/
|
|
skip1 /*not listed in dp*/
|
|
skip1 /*not listed in dp*/
|
|
skip1 /*setkeybind*/
|
|
skip1 /*getbindmaps*/
|
|
skip1 /*setbindmaps*/
|
|
skip1 /*crypto*/
|
|
skip1 /*crypto*/
|
|
skip1 /*crypto*/
|
|
skip1 /*crypto*/
|
|
skip1 /*crypto #637*/
|
|
|
|
|
|
};
|
|
int menu_numbuiltins = sizeof(menu_builtins)/sizeof(menu_builtins[0]);
|
|
|
|
|
|
|
|
|
|
void M_DeInit_Internal (void);
|
|
|
|
int inmenuprogs;
|
|
progfuncs_t *menuprogs;
|
|
progparms_t menuprogparms;
|
|
menuedict_t *menu_edicts;
|
|
int num_menu_edicts;
|
|
|
|
func_t mp_init_function;
|
|
func_t mp_shutdown_function;
|
|
func_t mp_draw_function;
|
|
func_t mp_keydown_function;
|
|
func_t mp_keyup_function;
|
|
func_t mp_toggle_function;
|
|
|
|
float *mp_time;
|
|
|
|
jmp_buf mp_abort;
|
|
|
|
|
|
void MP_Shutdown (void)
|
|
{
|
|
extern int mouseusedforgui;
|
|
func_t temp;
|
|
if (!menuprogs)
|
|
return;
|
|
/*
|
|
{
|
|
char *buffer;
|
|
int size = 1024*1024*8;
|
|
buffer = Z_Malloc(size);
|
|
menuprogs->save_ents(menuprogs, buffer, &size, 1);
|
|
COM_WriteFile("menucore.txt", buffer, size);
|
|
Z_Free(buffer);
|
|
}
|
|
*/
|
|
temp = mp_shutdown_function;
|
|
mp_shutdown_function = 0;
|
|
if (temp && !inmenuprogs)
|
|
PR_ExecuteProgram(menuprogs, temp);
|
|
|
|
PR_fclose_progs(menuprogs);
|
|
search_close_progs(menuprogs, true);
|
|
|
|
CloseProgs(menuprogs);
|
|
#ifdef TEXTEDITOR
|
|
Editor_ProgsKilled(menuprogs);
|
|
#endif
|
|
menuprogs = NULL;
|
|
|
|
key_dest = key_game;
|
|
m_state = 0;
|
|
|
|
mouseusedforgui = false;
|
|
|
|
if (inmenuprogs) //something in the menu caused the problem, so...
|
|
{
|
|
inmenuprogs = 0;
|
|
longjmp(mp_abort, 1);
|
|
}
|
|
}
|
|
|
|
pbool QC_WriteFile(const char *name, void *data, int len);
|
|
void *VARGS PR_CB_Malloc(int size); //these functions should be tracked by the library reliably, so there should be no need to track them ourselves.
|
|
void VARGS PR_CB_Free(void *mem);
|
|
|
|
//Any menu builtin error or anything like that will come here.
|
|
void VARGS Menu_Abort (char *format, ...)
|
|
{
|
|
va_list argptr;
|
|
char string[1024];
|
|
|
|
va_start (argptr, format);
|
|
vsnprintf (string,sizeof(string)-1, format,argptr);
|
|
va_end (argptr);
|
|
|
|
Con_Printf("Menu_Abort: %s\nShutting down menu.dat\n", string);
|
|
|
|
if (pr_menuqc_coreonerror.value)
|
|
{
|
|
char *buffer;
|
|
int size = 1024*1024*8;
|
|
buffer = Z_Malloc(size);
|
|
menuprogs->save_ents(menuprogs, buffer, &size, 3);
|
|
COM_WriteFile("menucore.txt", buffer, size);
|
|
Z_Free(buffer);
|
|
}
|
|
|
|
MP_Shutdown();
|
|
}
|
|
|
|
void MP_CvarChanged(cvar_t *var)
|
|
{
|
|
if (menuprogs)
|
|
{
|
|
PR_AutoCvar(menuprogs, var);
|
|
}
|
|
}
|
|
|
|
double menutime;
|
|
qboolean MP_Init (void)
|
|
{
|
|
if (qrenderer == QR_NONE)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (forceqmenu.value)
|
|
return false;
|
|
|
|
M_DeInit_Internal();
|
|
|
|
memset(&menuc_eval_chain, 0, sizeof(menuc_eval_chain));
|
|
|
|
|
|
menuprogparms.progsversion = PROGSTRUCT_VERSION;
|
|
menuprogparms.ReadFile = COM_LoadStackFile;//char *(*ReadFile) (char *fname, void *buffer, int *len);
|
|
menuprogparms.FileSize = COM_FileSize;//int (*FileSize) (char *fname); //-1 if file does not exist
|
|
menuprogparms.WriteFile = QC_WriteFile;//bool (*WriteFile) (char *name, void *data, int len);
|
|
menuprogparms.printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...);
|
|
menuprogparms.Sys_Error = Sys_Error;
|
|
menuprogparms.Abort = Menu_Abort;
|
|
menuprogparms.edictsize = sizeof(menuedict_t);
|
|
|
|
menuprogparms.entspawn = NULL;//void (*entspawn) (struct edict_s *ent); //ent has been spawned, but may not have all the extra variables (that may need to be set) set
|
|
menuprogparms.entcanfree = NULL;//bool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed
|
|
menuprogparms.stateop = NULL;//StateOp;//void (*stateop) (float var, func_t func);
|
|
menuprogparms.cstateop = NULL;//CStateOp;
|
|
menuprogparms.cwstateop = NULL;//CWStateOp;
|
|
menuprogparms.thinktimeop = NULL;//ThinkTimeOp;
|
|
|
|
//used when loading a game
|
|
menuprogparms.builtinsfor = NULL;//builtin_t *(*builtinsfor) (int num); //must return a pointer to the builtins that were used before the state was saved.
|
|
menuprogparms.loadcompleate = NULL;//void (*loadcompleate) (int edictsize); //notification to reset any pointers.
|
|
|
|
menuprogparms.memalloc = PR_CB_Malloc;//void *(*memalloc) (int size); //small string allocation malloced and freed randomly
|
|
menuprogparms.memfree = PR_CB_Free;//void (*memfree) (void * mem);
|
|
|
|
|
|
menuprogparms.globalbuiltins = menu_builtins;//builtin_t *globalbuiltins; //these are available to all progs
|
|
menuprogparms.numglobalbuiltins = menu_numbuiltins;
|
|
|
|
menuprogparms.autocompile = PR_COMPILEIGNORE;//PR_COMPILEEXISTANDCHANGED;//enum {PR_NOCOMPILE, PR_COMPILENEXIST, PR_COMPILECHANGED, PR_COMPILEALWAYS} autocompile;
|
|
|
|
menuprogparms.gametime = &menutime;
|
|
|
|
menuprogparms.sv_edicts = (struct edict_s **)&menu_edicts;
|
|
menuprogparms.sv_num_edicts = &num_menu_edicts;
|
|
|
|
menuprogparms.useeditor = NULL;//sorry... QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
|
|
|
|
menutime = Sys_DoubleTime();
|
|
if (!menuprogs)
|
|
{
|
|
Con_DPrintf("Initializing menu.dat\n");
|
|
menuprogs = InitProgs(&menuprogparms);
|
|
PR_Configure(menuprogs, -1, 1);
|
|
if (PR_LoadProgs(menuprogs, "menu.dat", 10020, NULL, 0) < 0) //no per-progs builtins.
|
|
{
|
|
//failed to load or something
|
|
// CloseProgs(menuprogs);
|
|
// menuprogs = NULL;
|
|
return false;
|
|
}
|
|
if (setjmp(mp_abort))
|
|
{
|
|
Con_DPrintf("Failed to initialize menu.dat\n");
|
|
inmenuprogs = false;
|
|
return false;
|
|
}
|
|
inmenuprogs++;
|
|
|
|
PF_InitTempStrings(menuprogs);
|
|
|
|
mp_time = (float*)PR_FindGlobal(menuprogs, "time", 0, NULL);
|
|
if (mp_time)
|
|
*mp_time = Sys_DoubleTime();
|
|
|
|
#ifdef warningmsg
|
|
#pragma warningmsg("disabled until csqc gets forked or some such")
|
|
#endif
|
|
//mp_globs.drawfont = (float*)PR_FindGlobal(menuprogs, "drawfont", 0, NULL);
|
|
//mp_globs.drawfontscale = (float*)PR_FindGlobal(menuprogs, "drawfontscale", 0, NULL);
|
|
|
|
menuentsize = PR_InitEnts(menuprogs, 8192);
|
|
|
|
|
|
//'world' edict
|
|
// EDICT_NUM(menuprogs, 0)->readonly = true;
|
|
EDICT_NUM(menuprogs, 0)->isfree = false;
|
|
|
|
|
|
mp_init_function = PR_FindFunction(menuprogs, "m_init", PR_ANY);
|
|
mp_shutdown_function = PR_FindFunction(menuprogs, "m_shutdown", PR_ANY);
|
|
mp_draw_function = PR_FindFunction(menuprogs, "m_draw", PR_ANY);
|
|
mp_keydown_function = PR_FindFunction(menuprogs, "m_keydown", PR_ANY);
|
|
mp_keyup_function = PR_FindFunction(menuprogs, "m_keyup", PR_ANY);
|
|
mp_toggle_function = PR_FindFunction(menuprogs, "m_toggle", PR_ANY);
|
|
if (mp_init_function)
|
|
PR_ExecuteProgram(menuprogs, mp_init_function);
|
|
inmenuprogs--;
|
|
|
|
Con_DPrintf("Initialized menu.dat\n");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void MP_CoreDump_f(void)
|
|
{
|
|
if (!menuprogs)
|
|
{
|
|
Con_Printf("Can't core dump, you need to be running the CSQC progs first.");
|
|
return;
|
|
}
|
|
|
|
{
|
|
int size = 1024*1024*8;
|
|
char *buffer = BZ_Malloc(size);
|
|
menuprogs->save_ents(menuprogs, buffer, &size, 3);
|
|
COM_WriteFile("menucore.txt", buffer, size);
|
|
BZ_Free(buffer);
|
|
}
|
|
}
|
|
|
|
void MP_Reload_f(void)
|
|
{
|
|
MP_Shutdown();
|
|
MP_Init();
|
|
}
|
|
|
|
void MP_RegisterCvarsAndCmds(void)
|
|
{
|
|
Cmd_AddCommand("coredump_menuqc", MP_CoreDump_f);
|
|
Cmd_AddCommand("menu_restart", MP_Reload_f);
|
|
|
|
Cvar_Register(&forceqmenu, MENUPROGSGROUP);
|
|
Cvar_Register(&pr_menuqc_coreonerror, MENUPROGSGROUP);
|
|
|
|
if (COM_CheckParm("-qmenu"))
|
|
Cvar_Set(&forceqmenu, "1");
|
|
}
|
|
|
|
void MP_Draw(void)
|
|
{
|
|
if (!menuprogs)
|
|
return;
|
|
if (setjmp(mp_abort))
|
|
return;
|
|
|
|
menutime = Sys_DoubleTime();
|
|
if (mp_time)
|
|
*mp_time = menutime;
|
|
|
|
inmenuprogs++;
|
|
if (mp_draw_function)
|
|
PR_ExecuteProgram(menuprogs, mp_draw_function);
|
|
inmenuprogs--;
|
|
}
|
|
|
|
void MP_Keydown(int key, int unicode)
|
|
{
|
|
extern qboolean keydown[K_MAX];
|
|
if (setjmp(mp_abort))
|
|
return;
|
|
|
|
if (key == 'c')
|
|
{
|
|
if (keydown[K_CTRL])
|
|
{
|
|
MP_Shutdown();
|
|
return;
|
|
}
|
|
}
|
|
if (key == K_ESCAPE)
|
|
{
|
|
if (keydown[K_SHIFT])
|
|
{
|
|
Con_ToggleConsole_f();
|
|
return;
|
|
}
|
|
}
|
|
|
|
menutime = Sys_DoubleTime();
|
|
if (mp_time)
|
|
*mp_time = menutime;
|
|
|
|
inmenuprogs++;
|
|
if (mp_keydown_function)
|
|
{
|
|
void *pr_globals = PR_globals(menuprogs, PR_CURRENT);
|
|
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoDPCodes(key);
|
|
G_FLOAT(OFS_PARM1) = unicode;
|
|
PR_ExecuteProgram(menuprogs, mp_keydown_function);
|
|
}
|
|
inmenuprogs--;
|
|
}
|
|
|
|
void MP_Keyup(int key, int unicode)
|
|
{
|
|
if (setjmp(mp_abort))
|
|
return;
|
|
|
|
menutime = Sys_DoubleTime();
|
|
if (mp_time)
|
|
*mp_time = menutime;
|
|
|
|
inmenuprogs++;
|
|
if (mp_keyup_function)
|
|
{
|
|
void *pr_globals = PR_globals(menuprogs, PR_CURRENT);
|
|
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoDPCodes(key);
|
|
G_FLOAT(OFS_PARM1) = unicode;
|
|
PR_ExecuteProgram(menuprogs, mp_keyup_function);
|
|
}
|
|
inmenuprogs--;
|
|
}
|
|
|
|
qboolean MP_Toggle(void)
|
|
{
|
|
if (!menuprogs)
|
|
return false;
|
|
|
|
if (setjmp(mp_abort))
|
|
return false;
|
|
|
|
menutime = Sys_DoubleTime();
|
|
if (mp_time)
|
|
*mp_time = menutime;
|
|
|
|
inmenuprogs++;
|
|
if (mp_toggle_function)
|
|
PR_ExecuteProgram(menuprogs, mp_toggle_function);
|
|
inmenuprogs--;
|
|
|
|
return true;
|
|
}
|
|
#endif
|