mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-26 22:01:50 +00:00
d4d365175d
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1448 fc73d0e0-1445-4013-8a0c-d673dee63da5
1804 lines
43 KiB
C
1804 lines
43 KiB
C
#include "quakedef.h"
|
|
|
|
#ifdef MENU_DAT
|
|
|
|
#ifdef RGLQUAKE
|
|
#include "glquake.h"
|
|
#ifdef Q3SHADERS
|
|
#include "shader.h"
|
|
#endif
|
|
#endif
|
|
|
|
#include "pr_common.h"
|
|
|
|
|
|
typedef struct menuedict_s
|
|
{
|
|
qboolean isfree;
|
|
float freetime; // sv.time when the object was freed
|
|
int entnum;
|
|
qboolean readonly; //world
|
|
void *fields;
|
|
} menuedict_t;
|
|
|
|
|
|
|
|
int menuentsize;
|
|
|
|
// cvars
|
|
#define MENUPROGSGROUP "Menu progs control"
|
|
cvar_t forceqmenu = {"forceqmenu", "0"};
|
|
cvar_t pr_menuqc_coreonerror = {"pr_menuqc_coreonerror", "1"};
|
|
|
|
|
|
//new generic functions.
|
|
|
|
//float isfunction(string function_name) = #607;
|
|
void PF_isfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *name = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = !!PR_FindFunction(prinst, name, PR_CURRENT);
|
|
}
|
|
|
|
//void callfunction(...) = #605;
|
|
void PF_callfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *name;
|
|
func_t f;
|
|
if (*prinst->callargc < 1)
|
|
PR_BIError(prinst, "callfunction needs at least one argument\n");
|
|
name = PR_GetStringOfs(prinst, OFS_PARM0+(*prinst->callargc-1)*3);
|
|
f = PR_FindFunction(prinst, name, PR_CURRENT);
|
|
if (f)
|
|
PR_ExecuteProgram(prinst, f);
|
|
}
|
|
|
|
//void loadfromfile(string file) = #69;
|
|
void PF_loadfromfile (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *filename = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
char *file = COM_LoadTempFile(filename);
|
|
|
|
int size;
|
|
|
|
if (!file)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1;
|
|
return;
|
|
}
|
|
|
|
while(prinst->restoreent(prinst, file, &size, NULL))
|
|
{
|
|
file += size;
|
|
}
|
|
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void PF_loadfromdata (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *file = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
int size;
|
|
|
|
if (!*file)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1;
|
|
return;
|
|
}
|
|
|
|
while(prinst->restoreent(prinst, file, &size, NULL))
|
|
{
|
|
file += size;
|
|
}
|
|
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void PF_parseentitydata(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
void *ed = G_EDICT(prinst, OFS_PARM0);
|
|
char *file = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
|
|
int size;
|
|
|
|
if (!*file)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1;
|
|
return;
|
|
}
|
|
|
|
if (!prinst->restoreent(prinst, file, &size, ed))
|
|
Con_Printf("parseentitydata: missing opening data\n");
|
|
else
|
|
{
|
|
file += size;
|
|
while(*file < ' ' && *file)
|
|
file++;
|
|
if (*file)
|
|
Con_Printf("parseentitydata: too much data\n");
|
|
}
|
|
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = (float)(((int)G_FLOAT(OFS_PARM0))%((int)G_FLOAT(OFS_PARM1)));
|
|
}
|
|
|
|
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 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 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 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_GetMove(int num, int *w, int *h);
|
|
//a bit pointless really
|
|
void 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_GetMove(mode, &w, &h);
|
|
|
|
ret[0] = w;
|
|
ret[1] = h;
|
|
ret[2] = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
void 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);
|
|
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 PF_isserver (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = sv.state != ss_dead;
|
|
}
|
|
|
|
//float clientstate(void) = #62;
|
|
void 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 PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
Con_Printf("\n");
|
|
|
|
prinst->RunError(prinst, "\nBuiltin %i not implemented.\nMenu is not compatable.", prinst->lastcalledbuiltinnumber);
|
|
PR_BIError (prinst, "bulitin not implemented");
|
|
}
|
|
|
|
|
|
|
|
void 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 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 PF_CL_precache_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *str;
|
|
mpic_t *pic;
|
|
|
|
str = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
|
|
pic = Draw_SafeCachePic(str);
|
|
|
|
if (pic)
|
|
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
|
else
|
|
G_INT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
void 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 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);
|
|
|
|
const float fsize = 0.0625;
|
|
float frow, fcol;
|
|
|
|
if (!chara)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1; //was null..
|
|
return;
|
|
}
|
|
|
|
chara &= 255;
|
|
frow = (chara>>4)*fsize;
|
|
fcol = (chara&15)*fsize;
|
|
|
|
if (Draw_ImageColours)
|
|
Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
|
if (Draw_Image)
|
|
Draw_Image(pos[0], pos[1], size[0], size[1], fcol, frow, fcol+fsize, frow+fsize, Draw_CachePic("conchars"));
|
|
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
//float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455;
|
|
void PF_CL_drawstring (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);
|
|
|
|
if (!text)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = -1; //was null..
|
|
return;
|
|
}
|
|
|
|
while(*text)
|
|
{
|
|
G_FLOAT(OFS_PARM1) = *text++;
|
|
PF_CL_drawcharacter(prinst, pr_globals);
|
|
pos[0] += size[0];
|
|
}
|
|
}
|
|
#ifdef Q3SHADERS
|
|
void GLDraw_ShaderPic (int x, int y, int width, int height, shader_t *pic, float r, float g, float b, float a);
|
|
#endif
|
|
//float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456;
|
|
void 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);
|
|
float flag = G_FLOAT(OFS_PARM5);
|
|
|
|
mpic_t *p;
|
|
|
|
#ifdef RGLQUAKE
|
|
if (qrenderer == QR_OPENGL)
|
|
{
|
|
#ifdef Q3SHADERS
|
|
shader_t *s;
|
|
|
|
s = R_RegisterCustom(picname, NULL);
|
|
if (s)
|
|
{
|
|
GLDraw_ShaderPic(pos[0], pos[1], size[0], size[1], s, rgb[0], rgb[1], rgb[2], alpha);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if (flag == 1) //add
|
|
qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
|
else if(flag == 2) //modulate
|
|
qglBlendFunc(GL_DST_COLOR, GL_ZERO);
|
|
else if(flag == 3) //modulate*2
|
|
qglBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
|
|
else //blend
|
|
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
}
|
|
#endif
|
|
|
|
p = Draw_SafeCachePic(picname);
|
|
|
|
if (Draw_ImageColours)
|
|
Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha);
|
|
if (Draw_Image)
|
|
Draw_Image(pos[0], pos[1], size[0], size[1], 0, 0, 1, 1, p);
|
|
|
|
#ifdef RGLQUAKE
|
|
if (qrenderer == QR_OPENGL)
|
|
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
#endif
|
|
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
//float drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #457;
|
|
void 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);
|
|
#ifdef RGLQUAKE
|
|
if (qrenderer == QR_OPENGL)
|
|
{
|
|
qglColor4f(rgb[0], rgb[1], rgb[2], alpha);
|
|
|
|
qglDisable(GL_TEXTURE_2D);
|
|
|
|
qglBegin(GL_QUADS);
|
|
qglVertex2f(pos[0], pos[1]);
|
|
qglVertex2f(pos[0]+size[0], pos[1]);
|
|
qglVertex2f(pos[0]+size[0], pos[1]+size[1]);
|
|
qglVertex2f(pos[0], pos[1]+size[1]);
|
|
qglEnd();
|
|
|
|
qglEnable(GL_TEXTURE_2D);
|
|
}
|
|
#endif
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
//void drawsetcliparea(float x, float y, float width, float height) = #458;
|
|
void 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 RGLQUAKE
|
|
if (qrenderer == QR_OPENGL && qglScissor)
|
|
{
|
|
|
|
x *= (float)glwidth/vid.width;
|
|
y *= (float)glheight/vid.height;
|
|
|
|
w *= (float)glwidth/vid.width;
|
|
h *= (float)glheight/vid.height;
|
|
|
|
//add a pixel because this makes DP's menus come out right.
|
|
x-=1;
|
|
y-=1;
|
|
w+=2;
|
|
h+=2;
|
|
|
|
|
|
qglScissor (x, glheight-(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 PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
#ifdef RGLQUAKE
|
|
if (qrenderer == QR_OPENGL)
|
|
{
|
|
qglDisable(GL_SCISSOR_TEST);
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
return;
|
|
}
|
|
#endif
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
}
|
|
|
|
//void (float width, vector rgb, float alpha, float flags, vector pos1, ...) drawline;
|
|
void PF_CL_drawline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float width = G_FLOAT(OFS_PARM0);
|
|
float *rgb = G_VECTOR(OFS_PARM1);
|
|
float alpha = G_FLOAT(OFS_PARM2);
|
|
float flags = G_FLOAT(OFS_PARM3);
|
|
float *pos = G_VECTOR(OFS_PARM4);
|
|
int numpoints = *prinst->callargc-4;
|
|
|
|
#ifdef RGLQUAKE // :(
|
|
|
|
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 PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *picname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
mpic_t *p = Draw_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;
|
|
}
|
|
}
|
|
|
|
//void setkeydest(float dest) = #601;
|
|
void PF_cl_setkeydest (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
switch((int)G_FLOAT(OFS_PARM0))
|
|
{
|
|
case 0:
|
|
// key_game
|
|
key_dest = key_game;
|
|
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 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 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 PF_cl_getmousetarget (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
}
|
|
|
|
int MP_TranslateDPtoFTECodes(int code);
|
|
//string keynumtostring(float keynum) = #609;
|
|
void PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int code = G_FLOAT(OFS_PARM0);
|
|
char *keyname = PF_TempStr(prinst);
|
|
|
|
code = MP_TranslateDPtoFTECodes (code);
|
|
|
|
strcpy(keyname, Key_KeynumToString(code));
|
|
RETURN_SSTRING(keyname);
|
|
}
|
|
|
|
void PF_cl_getkeybind (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *binding = Key_GetBinding(G_FLOAT(OFS_PARM0));
|
|
char *result = PF_TempStr(prinst);
|
|
if (!binding)
|
|
binding = "";
|
|
Q_strncpyz(result, binding, MAXTEMPBUFFERLEN);
|
|
RETURN_SSTRING(result);
|
|
}
|
|
|
|
int MP_TranslateDPtoFTECodes(int code);
|
|
//string findkeysforcommand(string command) = #610;
|
|
void PF_cl_findkeysforcommand (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
|
|
int keynums[2];
|
|
char *keyname = PF_TempStr(prinst);
|
|
|
|
M_FindKeysForCommand(cmdname, keynums);
|
|
|
|
keyname[0] = '\0';
|
|
|
|
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[0])), MAXTEMPBUFFERLEN);
|
|
Q_strncatz (keyname, va(" \'%i\'", MP_TranslateFTEtoDPCodes(keynums[1])), MAXTEMPBUFFERLEN);
|
|
|
|
RETURN_SSTRING(keyname);
|
|
}
|
|
|
|
//vector getmousepos(void) = #66;
|
|
void PF_cl_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
float *ret = G_VECTOR(OFS_RETURN);
|
|
extern int mousemove_x, mousemove_y;
|
|
|
|
ret[0] = mousemove_x;
|
|
ret[1] = mousemove_y;
|
|
|
|
mousemove_x=0;
|
|
mousemove_y=0;
|
|
|
|
/* ret[0] = mousecursor_x;
|
|
ret[1] = mousecursor_y;*/
|
|
ret[2] = 0;
|
|
}
|
|
|
|
|
|
static void 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 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 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:
|
|
G_FLOAT(OFS_RETURN) = Master_NumSorted();
|
|
return;
|
|
case SLIST_HOSTCACHETOTALCOUNT:
|
|
CL_QueryServers();
|
|
NET_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 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 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 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 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)
|
|
{
|
|
Master_SetSortField(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
|
|
}
|
|
//void refreshhostcache(void) = #620;
|
|
void PF_M_refreshhostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
MasterInfo_Begin();
|
|
}
|
|
//float gethostcachenumber(float fld, float hostnr) = #621;
|
|
void 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 PF_M_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *keyname = PF_TempStr(prinst);
|
|
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);
|
|
|
|
Q_strncpyz(keyname, ret, MAXTEMPBUFFERLEN);
|
|
RETURN_SSTRING(keyname);
|
|
}
|
|
|
|
//float gethostcacheindexforkey(string key) = #622;
|
|
void 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 PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
PF_M_gethostcacheindexforkey(prinst, pr_globals);
|
|
}
|
|
#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 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 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 PF_gettime (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = *prinst->parms->gametime;
|
|
}
|
|
|
|
void 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 PF_menu_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int i, f;
|
|
char *s, *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] + prinst->stringtable;
|
|
if (!t)
|
|
continue;
|
|
if (strcmp(t, 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);
|
|
}
|
|
//entity findchainfloat(.float _field, float match) = #27;
|
|
void 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 PF_etof(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = G_EDICTNUM(prinst, OFS_PARM0);
|
|
}
|
|
void PF_ftoe(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int entnum = G_FLOAT(OFS_PARM0);
|
|
|
|
RETURN_EDICT(prinst, EDICT_NUM(prinst, entnum));
|
|
}
|
|
|
|
void PF_IsNotNull(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int str = G_INT(OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = !!str;
|
|
}
|
|
|
|
void PF_cl_stringtokeynum(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int i;
|
|
int modifier;
|
|
char *s;
|
|
|
|
s = PR_GetStringOfs(prinst, OFS_PARM1);
|
|
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;
|
|
}
|
|
|
|
|
|
//float altstr_count(string str) = #82;
|
|
//returns number of single quoted strings in the string.
|
|
void 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 PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *outstr, *out;
|
|
char *instr, *in;
|
|
int size;
|
|
|
|
// VM_SAFEPARMCOUNT( 1, VM_altstr_prepare );
|
|
|
|
instr = PR_GetStringOfs(prinst, OFS_PARM0 );
|
|
//VM_CheckEmptyString( instr );
|
|
outstr = PF_TempStr(prinst);
|
|
|
|
for( out = outstr, in = instr, size = MAXTEMPBUFFERLEN - 1 ; size && *in ; size--, in++, out++ )
|
|
if( *in == '\'' ) {
|
|
*out++ = '\\';
|
|
*out = '\'';
|
|
size--;
|
|
} else
|
|
*out = *in;
|
|
*out = 0;
|
|
|
|
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, outstr );
|
|
}
|
|
//string altstr_get(string str, float num) = #84;
|
|
void PF_altstr_get(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
char *altstr, *pos, *outstr, *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;
|
|
}
|
|
|
|
outstr = PF_TempStr(prinst);
|
|
for( out = outstr, size = MAXTEMPBUFFERLEN - 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 PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|
{
|
|
int num;
|
|
char *altstr, *str;
|
|
char *in;
|
|
char *outstr, *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 );
|
|
|
|
outstr = out = PF_TempStr(prinst);
|
|
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_SetString( 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
|
|
skip1
|
|
skip1
|
|
skip1
|
|
//90
|
|
skip10
|
|
//100
|
|
skip100
|
|
//200
|
|
skip100
|
|
//300
|
|
skip100
|
|
//400
|
|
skip50
|
|
//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_drawstring,//5
|
|
PF_CL_drawpic,//6
|
|
PF_CL_drawfill,//7
|
|
PF_CL_drawsetcliparea,//8
|
|
PF_CL_drawresetcliparea,//9
|
|
|
|
//460
|
|
PF_CL_drawgetimagesize,//10
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
skip1
|
|
//470
|
|
skip10
|
|
//480
|
|
skip10
|
|
//490
|
|
skip10
|
|
//500
|
|
skip100
|
|
//600
|
|
skip1
|
|
PF_cl_setkeydest,
|
|
PF_cl_getkeydest,
|
|
PF_cl_setmousetarget,
|
|
PF_cl_getmousetarget,
|
|
PF_callfunction,
|
|
skip1 //void writetofile(float fhandle, entity ent) = #606;
|
|
PF_isfunction,
|
|
PF_cl_getresolution,
|
|
PF_cl_keynumtostring,
|
|
PF_cl_findkeysforcommand,
|
|
PF_M_gethostcachevalue,
|
|
PF_M_gethostcachestring,
|
|
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
|
|
};
|
|
int menu_numbuiltins = sizeof(menu_builtins)/sizeof(menu_builtins[0]);
|
|
|
|
|
|
|
|
|
|
void M_Init_Internal (void);
|
|
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);
|
|
menuprogs = NULL;
|
|
|
|
key_dest = key_game;
|
|
m_state = 0;
|
|
|
|
mouseusedforgui = false;
|
|
|
|
M_Init_Internal();
|
|
|
|
if (inmenuprogs) //something in the menu caused the problem, so...
|
|
{
|
|
inmenuprogs = 0;
|
|
longjmp(mp_abort, 1);
|
|
}
|
|
}
|
|
|
|
int COM_FileSize(char *path);
|
|
pbool QC_WriteFile(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();
|
|
}
|
|
|
|
double menutime;
|
|
void MP_Init (void)
|
|
{
|
|
if (!qrenderer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (forceqmenu.value)
|
|
return;
|
|
|
|
M_DeInit_Internal();
|
|
|
|
|
|
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_COMPILEEXISTANDCHANGED;//enum {PR_NOCOMPILE, PR_COMPILENEXIST, PR_COMPILECHANGED, PR_COMPILEALWAYS} autocompile;
|
|
|
|
menuprogparms.gametime = &menutime;
|
|
|
|
menuprogparms.sv_edicts = (edict_t **)&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;
|
|
M_Init_Internal();
|
|
return;
|
|
}
|
|
if (setjmp(mp_abort))
|
|
{
|
|
M_Init_Internal();
|
|
Con_DPrintf("Failed to initialize menu.dat\n");
|
|
inmenuprogs = false;
|
|
return;
|
|
}
|
|
inmenuprogs++;
|
|
|
|
PF_InitTempStrings(menuprogs);
|
|
|
|
mp_time = (float*)PR_FindGlobal(menuprogs, "time", 0);
|
|
if (mp_time)
|
|
*mp_time = Sys_DoubleTime();
|
|
|
|
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");
|
|
}
|
|
}
|
|
|
|
void MP_CoreDump(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_RegisterCvarsAndCmds(void)
|
|
{
|
|
Cmd_AddCommand("coredump_menuqc", MP_CoreDump);
|
|
|
|
Cvar_Register(&forceqmenu, MENUPROGSGROUP);
|
|
Cvar_Register(&pr_menuqc_coreonerror, MENUPROGSGROUP);
|
|
|
|
if (COM_CheckParm("-qmenu"))
|
|
Cvar_Set(&forceqmenu, "1");
|
|
}
|
|
|
|
void MP_Draw(void)
|
|
{
|
|
if (setjmp(mp_abort))
|
|
return;
|
|
|
|
#ifdef RGLQUAKE
|
|
if (qrenderer == QR_OPENGL)
|
|
{
|
|
GL_TexEnv(GL_MODULATE);
|
|
qglDisable(GL_ALPHA_TEST);
|
|
qglEnable(GL_BLEND);
|
|
}
|
|
#endif
|
|
|
|
menutime = Sys_DoubleTime();
|
|
if (mp_time)
|
|
*mp_time = menutime;
|
|
|
|
inmenuprogs++;
|
|
if (mp_draw_function)
|
|
PR_ExecuteProgram(menuprogs, mp_draw_function);
|
|
inmenuprogs--;
|
|
}
|
|
|
|
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 515;
|
|
case K_MOUSE5: return 516;
|
|
// case K_MOUSE6: return 517;
|
|
// case K_MOUSE7: return 518;
|
|
// case K_MOUSE8: return 519;
|
|
// case K_MOUSE9: return 520;
|
|
// case K_MOUSE10: return 521;
|
|
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 515: return K_MOUSE4;
|
|
// case 516: return K_MOUSE5;
|
|
case 517: return K_MOUSE6;
|
|
case 518: return K_MOUSE7;
|
|
case 519: return K_MOUSE8;
|
|
// case 520: return K_MOUSE9;
|
|
// case 521: return K_MOUSE10;
|
|
case 515: return K_MWHEELDOWN;//K_MOUSE4;
|
|
case 516: return K_MWHEELUP;//K_MOUSE5;
|
|
default: return code;
|
|
}
|
|
}
|
|
|
|
void MP_Keydown(int key)
|
|
{
|
|
if (setjmp(mp_abort))
|
|
return;
|
|
|
|
if (key == 'c')
|
|
{
|
|
extern int keydown[];
|
|
if (keydown[K_CTRL])
|
|
{
|
|
MP_Shutdown();
|
|
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);
|
|
if (G_FLOAT(OFS_PARM0) > 127)
|
|
G_FLOAT(OFS_PARM1) = 0;
|
|
else
|
|
G_FLOAT(OFS_PARM1) = G_FLOAT(OFS_PARM0);
|
|
PR_ExecuteProgram(menuprogs, mp_keydown_function);
|
|
}
|
|
inmenuprogs--;
|
|
}
|
|
|
|
void MP_Keyup(int key)
|
|
{
|
|
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);
|
|
if (G_FLOAT(OFS_PARM0) > 127)
|
|
G_FLOAT(OFS_PARM1) = 0;
|
|
else
|
|
G_FLOAT(OFS_PARM1) = G_FLOAT(OFS_PARM0);
|
|
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
|