mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-02 22:11:22 +00:00
Fix some csqc bugs+omissions.
This commit is contained in:
parent
f166000a04
commit
8d84bf8d2f
15 changed files with 495 additions and 69 deletions
|
@ -44,6 +44,15 @@ qpic_t *Draw_CachePic (const char *path);
|
|||
qpic_t *Draw_TryCachePic (const char *path);
|
||||
void Draw_NewGame (void);
|
||||
|
||||
//Spike -- this is for csqc
|
||||
typedef struct
|
||||
{
|
||||
vec_t xy[2];
|
||||
vec_t st[2];
|
||||
vec4_t rgba;
|
||||
} polygonvert_t;
|
||||
void Draw_PicPolygon(qpic_t *pic, unsigned int numverts, polygonvert_t *verts);
|
||||
|
||||
void GL_SetCanvas (canvastype newcanvas); //johnfitz
|
||||
|
||||
#endif /* _QUAKE_DRAW_H */
|
||||
|
|
|
@ -314,6 +314,24 @@ qpic_t *Draw_TryCachePic (const char *path)
|
|||
menu_numcachepics++;
|
||||
strcpy (pic->name, path);
|
||||
|
||||
if (strcmp("lmp", COM_FileGetExtension(path)))
|
||||
{
|
||||
char npath[MAX_QPATH];
|
||||
COM_StripExtension(path, npath, sizeof(npath));
|
||||
gl.gltexture = TexMgr_LoadImage (NULL, npath, 0, 0, SRC_EXTERNAL, NULL, npath, 0, TEXPREF_ALPHA | TEXPREF_PAD | TEXPREF_NOPICMIP);
|
||||
|
||||
pic->pic.width = gl.gltexture->width;
|
||||
pic->pic.height = gl.gltexture->height;
|
||||
|
||||
gl.sl = 0;
|
||||
gl.sh = (float)pic->pic.width/(float)TexMgr_PadConditional(pic->pic.width); //johnfitz
|
||||
gl.tl = 0;
|
||||
gl.th = (float)pic->pic.height/(float)TexMgr_PadConditional(pic->pic.height); //johnfitz
|
||||
memcpy (pic->pic.data, &gl, sizeof(glpic_t));
|
||||
|
||||
return &pic->pic;
|
||||
}
|
||||
|
||||
//
|
||||
// load the pic from disk
|
||||
//
|
||||
|
@ -582,6 +600,26 @@ void Draw_SubPic (float x, float y, float w, float h, qpic_t *pic, float s1, flo
|
|||
glEnd ();
|
||||
}
|
||||
|
||||
//Spike -- this is for CSQC to do fancy drawing.
|
||||
void Draw_PicPolygon(qpic_t *pic, unsigned int numverts, polygonvert_t *verts)
|
||||
{
|
||||
glpic_t *gl;
|
||||
|
||||
if (scrap_dirty)
|
||||
Scrap_Upload ();
|
||||
gl = (glpic_t *)pic->data;
|
||||
GL_Bind (gl->gltexture);
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
while (numverts --> 0)
|
||||
{
|
||||
glColor4fv(verts->rgba);
|
||||
glTexCoord2f (gl->sl*(1-verts->st[0]) + verts->st[0]*gl->sh, gl->tl*(1-verts->st[1]) + verts->st[1]*gl->th);
|
||||
glVertex2f(verts->xy[0], verts->xy[1]);
|
||||
verts++;
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_TransPicTranslate -- johnfitz -- rewritten to use texmgr to do translation
|
||||
|
|
|
@ -1272,7 +1272,10 @@ void CalcSurfaceExtents (msurface_t *s)
|
|||
s->extents[i] = (bmaxs[i] - bmins[i]) * lmscale;
|
||||
|
||||
if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > maxextent) //johnfitz -- was 512 in glquake, 256 in winquake
|
||||
Sys_Error ("Bad surface extents");
|
||||
{
|
||||
s->extents[i] = 1;
|
||||
// Sys_Error ("Bad surface extents");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
90
Quake/keys.c
90
Quake/keys.c
|
@ -39,7 +39,8 @@ int history_line = 0;
|
|||
|
||||
keydest_t key_dest;
|
||||
|
||||
char *keybindings[MAX_KEYS];
|
||||
int key_bindmap[2] = {0,1};
|
||||
char *keybindings[MAX_BINDMAPS][MAX_KEYS];
|
||||
qboolean consolekeys[MAX_KEYS]; // if true, can't be rebound while in console
|
||||
qboolean menubound[MAX_KEYS]; // if true, can't be rebound while in menu
|
||||
qboolean keydown[MAX_KEYS];
|
||||
|
@ -919,21 +920,23 @@ const char *Key_KeynumToString (int keynum)
|
|||
Key_SetBinding
|
||||
===================
|
||||
*/
|
||||
void Key_SetBinding (int keynum, const char *binding)
|
||||
void Key_SetBinding (int keynum, const char *binding, int bindmap)
|
||||
{
|
||||
if (keynum == -1)
|
||||
return;
|
||||
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||
return;
|
||||
|
||||
// free old bindings
|
||||
if (keybindings[keynum])
|
||||
if (keybindings[bindmap][keynum])
|
||||
{
|
||||
Z_Free (keybindings[keynum]);
|
||||
keybindings[keynum] = NULL;
|
||||
Z_Free (keybindings[bindmap][keynum]);
|
||||
keybindings[bindmap][keynum] = NULL;
|
||||
}
|
||||
|
||||
// allocate memory for new binding
|
||||
if (binding)
|
||||
keybindings[keynum] = Z_Strdup(binding);
|
||||
keybindings[bindmap][keynum] = Z_Strdup(binding);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -944,31 +947,38 @@ Key_Unbind_f
|
|||
void Key_Unbind_f (void)
|
||||
{
|
||||
int b;
|
||||
int keyarg = !strcmp(Cmd_Argv(0), "in_bind")?2:1;
|
||||
int bindmap = keyarg==2?atoi(Cmd_Argv(1)):0;
|
||||
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||
bindmap = 0;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
if (Cmd_Argc() != keyarg+1)
|
||||
{
|
||||
Con_Printf ("unbind <key> : remove commands from a key\n");
|
||||
return;
|
||||
}
|
||||
|
||||
b = Key_StringToKeynum (Cmd_Argv(1));
|
||||
b = Key_StringToKeynum (Cmd_Argv(keyarg));
|
||||
if (b == -1)
|
||||
{
|
||||
Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
Key_SetBinding (b, NULL);
|
||||
Key_SetBinding (b, NULL, bindmap);
|
||||
}
|
||||
|
||||
void Key_Unbindall_f (void)
|
||||
{
|
||||
int i;
|
||||
int i, b;
|
||||
|
||||
for (i = 0; i < MAX_KEYS; i++)
|
||||
for (b = 0; b < MAX_BINDMAPS; b++)
|
||||
{
|
||||
if (keybindings[i])
|
||||
Key_SetBinding (i, NULL);
|
||||
for (i = 0; i < MAX_KEYS; i++)
|
||||
{
|
||||
if (keybindings[b][i])
|
||||
Key_SetBinding (i, NULL, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -980,13 +990,14 @@ Key_Bindlist_f -- johnfitz
|
|||
void Key_Bindlist_f (void)
|
||||
{
|
||||
int i, count;
|
||||
int bindmap = 0;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < MAX_KEYS; i++)
|
||||
{
|
||||
if (keybindings[i] && *keybindings[i])
|
||||
if (keybindings[bindmap][i] && *keybindings[bindmap][i])
|
||||
{
|
||||
Con_SafePrintf (" %s \"%s\"\n", Key_KeynumToString(i), keybindings[i]);
|
||||
Con_SafePrintf (" %s \"%s\"\n", Key_KeynumToString(i), keybindings[bindmap][i]);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
@ -1002,40 +1013,45 @@ void Key_Bind_f (void)
|
|||
{
|
||||
int i, c, b;
|
||||
char cmd[1024];
|
||||
int keyarg = !strcmp(Cmd_Argv(0), "in_bind")?2:1;
|
||||
int bindmap = keyarg==2?atoi(Cmd_Argv(1)):0;
|
||||
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||
bindmap = 0;
|
||||
|
||||
c = Cmd_Argc();
|
||||
|
||||
if (c != 2 && c != 3)
|
||||
if (c < keyarg+1 )
|
||||
{
|
||||
Con_Printf ("bind <key> [command] : attach a command to a key\n");
|
||||
return;
|
||||
}
|
||||
b = Key_StringToKeynum (Cmd_Argv(1));
|
||||
|
||||
b = Key_StringToKeynum (Cmd_Argv(keyarg));
|
||||
if (b == -1)
|
||||
{
|
||||
Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1));
|
||||
Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(keyarg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == 2)
|
||||
if (c == keyarg+1)
|
||||
{
|
||||
if (keybindings[b])
|
||||
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] );
|
||||
if (keybindings[bindmap][b])
|
||||
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(keyarg), keybindings[bindmap][b] );
|
||||
else
|
||||
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) );
|
||||
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(keyarg) );
|
||||
return;
|
||||
}
|
||||
|
||||
// copy the rest of the command line
|
||||
cmd[0] = 0;
|
||||
for (i = 2; i < c; i++)
|
||||
for (i = keyarg+1; i < c; i++)
|
||||
{
|
||||
q_strlcat (cmd, Cmd_Argv(i), sizeof(cmd));
|
||||
if (i != (c-1))
|
||||
q_strlcat (cmd, " ", sizeof(cmd));
|
||||
}
|
||||
|
||||
Key_SetBinding (b, cmd);
|
||||
Key_SetBinding (b, cmd, bindmap);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1048,14 +1064,23 @@ Writes lines containing "bind key value"
|
|||
void Key_WriteBindings (FILE *f)
|
||||
{
|
||||
int i;
|
||||
int bindmap;
|
||||
|
||||
// unbindall before loading stored bindings:
|
||||
if (cfg_unbindall.value)
|
||||
fprintf (f, "unbindall\n");
|
||||
for (i = 0; i < MAX_KEYS; i++)
|
||||
for (bindmap = 0; bindmap < MAX_BINDMAPS; bindmap++)
|
||||
{
|
||||
if (keybindings[i] && *keybindings[i])
|
||||
fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]);
|
||||
for (i = 0; i < MAX_KEYS; i++)
|
||||
{
|
||||
if (keybindings[bindmap][i] && *keybindings[bindmap][i])
|
||||
{
|
||||
if (bindmap)
|
||||
fprintf (f, "in_bind %i \"%s\" \"%s\"\n", bindmap, Key_KeynumToString(i), keybindings[bindmap][i]);
|
||||
else
|
||||
fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[bindmap][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1200,6 +1225,9 @@ void Key_Init (void)
|
|||
Cmd_AddCommand ("bind",Key_Bind_f);
|
||||
Cmd_AddCommand ("unbind",Key_Unbind_f);
|
||||
Cmd_AddCommand ("unbindall",Key_Unbindall_f);
|
||||
|
||||
Cmd_AddCommand ("in_bind",Key_Bind_f); //spike -- purely for dp compat.
|
||||
Cmd_AddCommand ("in_unbind",Key_Unbind_f); //spike -- purely for dp compat.
|
||||
}
|
||||
|
||||
static struct {
|
||||
|
@ -1359,7 +1387,9 @@ void Key_Event (int key, qboolean down)
|
|||
// downs can be matched with ups
|
||||
if (!down)
|
||||
{
|
||||
kb = keybindings[key];
|
||||
kb = keybindings[key_bindmap[0]][key];
|
||||
if (!kb)
|
||||
kb = keybindings[key_bindmap[1]][key]; //FIXME: if the qc changes the bindmap while a key is held then things will break. this is consistent with DP.
|
||||
if (kb && kb[0] == '+')
|
||||
{
|
||||
sprintf (cmd, "-%s %i\n", kb+1, key);
|
||||
|
@ -1380,7 +1410,9 @@ void Key_Event (int key, qboolean down)
|
|||
(key_dest == key_console && !consolekeys[key]) ||
|
||||
(key_dest == key_game && (!con_forcedup || !consolekeys[key])))
|
||||
{
|
||||
kb = keybindings[key];
|
||||
kb = keybindings[key_bindmap[0]][key];
|
||||
if (!kb)
|
||||
kb = keybindings[key_bindmap[1]][key];
|
||||
if (kb)
|
||||
{
|
||||
if (kb[0] == '+')
|
||||
|
|
|
@ -155,13 +155,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define K_RTRIGGER 252
|
||||
|
||||
#define MAX_KEYS 256
|
||||
#define MAX_BINDMAPS 8
|
||||
|
||||
#define MAXCMDLINE 256
|
||||
|
||||
typedef enum {key_game, key_console, key_message, key_menu} keydest_t;
|
||||
|
||||
extern keydest_t key_dest;
|
||||
extern char *keybindings[MAX_KEYS];
|
||||
extern char *keybindings[MAX_BINDMAPS][MAX_KEYS];
|
||||
|
||||
#define CMDLINES 64
|
||||
|
||||
|
@ -170,6 +171,7 @@ extern int edit_line;
|
|||
extern int key_linepos;
|
||||
extern int key_insert;
|
||||
extern double key_blinktime;
|
||||
extern int key_bindmap[2];
|
||||
|
||||
extern qboolean chat_team;
|
||||
|
||||
|
@ -185,7 +187,7 @@ void Key_Event (int key, qboolean down);
|
|||
void Char_Event (int key);
|
||||
qboolean Key_TextEntry (void);
|
||||
|
||||
void Key_SetBinding (int keynum, const char *binding);
|
||||
void Key_SetBinding (int keynum, const char *binding, int bindmap);
|
||||
const char *Key_KeynumToString (int keynum);
|
||||
int Key_StringToKeynum (const char *str);
|
||||
int Key_NativeToQC(int code);
|
||||
|
|
|
@ -1451,6 +1451,7 @@ void M_FindKeysForCommand (const char *command, int *threekeys)
|
|||
int j;
|
||||
int l;
|
||||
char *b;
|
||||
int bindmap = 0;
|
||||
|
||||
threekeys[0] = threekeys[1] = threekeys[2] = -1;
|
||||
l = strlen(command);
|
||||
|
@ -1458,7 +1459,7 @@ void M_FindKeysForCommand (const char *command, int *threekeys)
|
|||
|
||||
for (j = 0; j < MAX_KEYS; j++)
|
||||
{
|
||||
b = keybindings[j];
|
||||
b = keybindings[bindmap][j];
|
||||
if (!b)
|
||||
continue;
|
||||
if (!strncmp (b, command, l) )
|
||||
|
@ -1476,16 +1477,17 @@ void M_UnbindCommand (const char *command)
|
|||
int j;
|
||||
int l;
|
||||
char *b;
|
||||
int bindmap = 0;
|
||||
|
||||
l = strlen(command);
|
||||
|
||||
for (j = 0; j < MAX_KEYS; j++)
|
||||
{
|
||||
b = keybindings[j];
|
||||
b = keybindings[bindmap][j];
|
||||
if (!b)
|
||||
continue;
|
||||
if (!strncmp (b, command, l) )
|
||||
Key_SetBinding (j, NULL);
|
||||
Key_SetBinding (j, NULL, bindmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
147
Quake/pr_cmds.c
147
Quake/pr_cmds.c
|
@ -22,8 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
#define STRINGTEMP_BUFFERS 16
|
||||
#define STRINGTEMP_LENGTH 1024
|
||||
//#define STRINGTEMP_BUFFERS 16
|
||||
//#define STRINGTEMP_LENGTH 1024
|
||||
static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
|
||||
static byte pr_string_tempindex = 0;
|
||||
|
||||
|
@ -1826,6 +1826,137 @@ builtin_t pr_ssqcbuiltins[] =
|
|||
};
|
||||
int pr_ssqcnumbuiltins = sizeof(pr_ssqcbuiltins)/sizeof(pr_ssqcbuiltins[0]);
|
||||
|
||||
|
||||
|
||||
|
||||
static void PF_cl_sound (void)
|
||||
{
|
||||
const char *sample;
|
||||
int channel;
|
||||
edict_t *entity;
|
||||
int volume;
|
||||
float attenuation;
|
||||
int entnum;
|
||||
|
||||
entity = G_EDICT(OFS_PARM0);
|
||||
channel = G_FLOAT(OFS_PARM1);
|
||||
sample = G_STRING(OFS_PARM2);
|
||||
volume = G_FLOAT(OFS_PARM3) * 255;
|
||||
attenuation = G_FLOAT(OFS_PARM4);
|
||||
|
||||
entnum = NUM_FOR_EDICT(entity);
|
||||
//fullcsqc fixme: if (entity->v->entnum)
|
||||
entnum *= -1;
|
||||
|
||||
S_StartSound(entnum, channel, S_PrecacheSound(sample), entity->v.origin, volume, attenuation);
|
||||
}
|
||||
|
||||
static void PF_cl_precache_sound (void)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
s = G_STRING(OFS_PARM0);
|
||||
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
||||
PR_CheckEmptyString (s);
|
||||
|
||||
//precache sounds are optional in quake's sound system. NULL is a valid response so don't check.
|
||||
S_PrecacheSound(s);
|
||||
}
|
||||
|
||||
int CL_Precache_Model(const char *name)
|
||||
{
|
||||
int i;
|
||||
if (!*name)
|
||||
return 0;
|
||||
|
||||
//if the server precached the model then we don't need to do anything.
|
||||
for (i = 1; i < MAX_MODELS; i++)
|
||||
{
|
||||
if (!*cl.model_name[i])
|
||||
break; //no more
|
||||
if (!strcmp(cl.model_name[i], name))
|
||||
return i;
|
||||
}
|
||||
PR_RunError ("CL_Precache_Model: implementme");
|
||||
return 0;
|
||||
}
|
||||
static void PF_cl_precache_model (void)
|
||||
{
|
||||
const char *s;
|
||||
int i;
|
||||
|
||||
s = G_STRING(OFS_PARM0);
|
||||
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
||||
PR_CheckEmptyString (s);
|
||||
|
||||
//if the server precached the model then we don't need to do anything.
|
||||
for (i = 1; i < MAX_MODELS; i++)
|
||||
{
|
||||
if (!*cl.model_name[i])
|
||||
break; //no more
|
||||
if (!strcmp(cl.model_name[i], s))
|
||||
return;
|
||||
}
|
||||
PR_RunError ("PF_cl_precache_model: implementme");
|
||||
}
|
||||
static void PF_cl_setmodel (void)
|
||||
{
|
||||
int i;
|
||||
const char *m;
|
||||
qmodel_t *mod;
|
||||
edict_t *e;
|
||||
|
||||
e = G_EDICT(OFS_PARM0);
|
||||
m = G_STRING(OFS_PARM1);
|
||||
|
||||
i = CL_Precache_Model(m);
|
||||
|
||||
mod = qcvm->GetModel(i);
|
||||
e->v.model = mod?PR_SetEngineString(mod->name):0; //I believe this to be safe in QS.
|
||||
e->v.modelindex = i;
|
||||
if (mod)
|
||||
//johnfitz -- correct physics cullboxes for bmodels
|
||||
/* Spike -- THIS IS A HUGE CLUSTERFUCK.
|
||||
the mins/maxs sizes of models in vanilla was always set to xyz -16/+16.
|
||||
which causes issues with clientside culling.
|
||||
many engines fixed that, but not here.
|
||||
which means that setmodel-without-setsize is now fucked.
|
||||
the qc will usually do a setsize after setmodel anyway, so applying that fix here will do nothing.
|
||||
you'd need to apply the serverside version of the cull fix in SV_LinkEdict instead, which is where the pvs is calculated.
|
||||
tracebox is limited to specific hull sizes. the traces are biased such that they're aligned to the mins point of the box, rather than the center of the trace.
|
||||
so vanilla's '-16 -16 -16'/'16 16 16' is wrong for Z (which is usually corrected for with gravity anyway), but X+Y will be correctly aligned for the resulting hull.
|
||||
but traceboxes using models with -12 or -20 or whatever will be biased/offcenter in the X+Y axis (as well as Z, but that's still mostly unimportant)
|
||||
deciding whether to replicate the vanilla behaviour based upon model type sucks.
|
||||
|
||||
vanilla:
|
||||
brush - always the models size
|
||||
mdl - always [-16, -16, -16], [16, 16, 16]
|
||||
quakespasm:
|
||||
brush - always the models size
|
||||
mdl - always the models size
|
||||
quakeworld:
|
||||
*.bsp - always the models size (matched by extension rather than type)
|
||||
other - model isn't even loaded, setmodel does not do setsize at all.
|
||||
fte default (with nq mod):
|
||||
*.bsp (or sv_gameplayfix_setmodelrealbox) - always the models size (matched by extension rather than type)
|
||||
other - always [-16, -16, -16], [16, 16, 16]
|
||||
|
||||
fte's behaviour means:
|
||||
a) dedicated servers don't have to bother loading non-mdls.
|
||||
b) nq mods still work fine, where extensions are adhered to in the original qc.
|
||||
c) when replacement models are used for bsp models, things still work without them reverting to +/- 16.
|
||||
*/
|
||||
{
|
||||
if (mod->type == mod_brush || !sv_gameplayfix_setmodelrealbox.value)
|
||||
SetMinMaxSize (e, mod->clipmins, mod->clipmaxs, true);
|
||||
else
|
||||
SetMinMaxSize (e, mod->mins, mod->maxs, true);
|
||||
}
|
||||
//johnfitz
|
||||
else
|
||||
SetMinMaxSize (e, vec3_origin, vec3_origin, true);
|
||||
}
|
||||
|
||||
#define PF_NoCSQC PF_Fixme
|
||||
#define PF_CSQCToDo PF_Fixme
|
||||
builtin_t pr_csqcbuiltins[] =
|
||||
|
@ -1833,12 +1964,12 @@ builtin_t pr_csqcbuiltins[] =
|
|||
PF_Fixme,
|
||||
PF_makevectors, // void(entity e) makevectors = #1
|
||||
PF_setorigin, // void(entity e, vector o) setorigin = #2
|
||||
PF_CSQCToDo,//PF_setmodel, // void(entity e, string m) setmodel = #3
|
||||
PF_cl_setmodel, // void(entity e, string m) setmodel = #3
|
||||
PF_setsize, // void(entity e, vector min, vector max) setsize = #4
|
||||
PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5
|
||||
PF_break, // void() break = #6
|
||||
PF_random, // float() random = #7
|
||||
PF_sound, // void(entity e, float chan, string samp) sound = #8
|
||||
PF_cl_sound, // void(entity e, float chan, string samp) sound = #8
|
||||
PF_normalize, // vector(vector v) normalize = #9
|
||||
PF_error, // void(string e) error = #10
|
||||
PF_objerror, // void(string e) objerror = #11
|
||||
|
@ -1849,8 +1980,8 @@ builtin_t pr_csqcbuiltins[] =
|
|||
PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16
|
||||
PF_NoCSQC, // entity() checkclient (was: clientlist, apparently) = #17
|
||||
PF_Find, // entity(entity start, .string fld, string match) find = #18
|
||||
PF_CSQCToDo,//PF_cl_precache_sound, // void(string s) precache_sound = #19
|
||||
PF_CSQCToDo,//PF_cl_precache_model, // void(string s) precache_model = #20
|
||||
PF_cl_precache_sound, // void(string s) precache_sound = #19
|
||||
PF_cl_precache_model, // void(string s) precache_model = #20
|
||||
PF_NoCSQC, // void(entity client, string s)stuffcmd = #21
|
||||
PF_findradius, // entity(vector org, float rad) findradius = #22
|
||||
PF_NoCSQC, // void(string s) bprint = #23
|
||||
|
@ -1912,8 +2043,8 @@ builtin_t pr_csqcbuiltins[] =
|
|||
|
||||
PF_CSQCToDo,//PF_ambientsound,
|
||||
|
||||
PF_CSQCToDo,//PF_cl_precache_model,
|
||||
PF_CSQCToDo,//PF_cl_precache_sound, // precache_sound2 is different only for qcc
|
||||
PF_cl_precache_model,
|
||||
PF_cl_precache_sound,
|
||||
PF_precache_file,
|
||||
|
||||
PF_NoCSQC,//PF_setspawnparms
|
||||
|
|
|
@ -1123,7 +1123,7 @@ qboolean PR_LoadProgs (const char *filename, qboolean fatal, builtin_t *builtins
|
|||
Host_Error ("%s has wrong version number (%i should be %i)", filename, qcvm->progs->version, PROG_VERSION);
|
||||
else
|
||||
{
|
||||
Con_Printf("%s ABI set not supported", filename);
|
||||
Con_Printf("%s ABI set not supported\n", filename);
|
||||
qcvm->progs = NULL;
|
||||
return false;
|
||||
}
|
||||
|
@ -1134,7 +1134,33 @@ qboolean PR_LoadProgs (const char *filename, qboolean fatal, builtin_t *builtins
|
|||
Host_Error ("%s system vars have been modified, progdefs.h is out of date", filename);
|
||||
else
|
||||
{
|
||||
Con_Printf("%s system vars are not supported", filename);
|
||||
switch(qcvm->progs->crc)
|
||||
{
|
||||
case 22390: //full csqc
|
||||
Con_Printf("%s - full csqc is not supported\n", filename);
|
||||
break;
|
||||
case 52195: //dp csqc
|
||||
Con_Printf("%s - obsolete csqc is not supported\n", filename);
|
||||
break;
|
||||
case 54730: //quakeworld
|
||||
Con_Printf("%s - quakeworld gamecode is not supported\n", filename);
|
||||
break;
|
||||
case 26940: //prerelease
|
||||
Con_Printf("%s - prerelease gamecode is not supported\n", filename);
|
||||
break;
|
||||
case 32401: //tenebrae
|
||||
Con_Printf("%s - tenebrae gamecode is not supported\n", filename);
|
||||
break;
|
||||
case 38488: //hexen2 release
|
||||
case 26905: //hexen2 mission pack
|
||||
case 14046: //hexen2 demo
|
||||
Con_Printf("%s - hexen2 gamecode is not supported\n", filename);
|
||||
break;
|
||||
//case 5927: //nq PROGHEADER_CRC as above. shouldn't happen, obviously.
|
||||
default:
|
||||
Con_Printf("%s system vars are not supported\n", filename);
|
||||
break;
|
||||
}
|
||||
qcvm->progs = NULL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -370,7 +370,7 @@ void PR_ExecuteProgram (func_t fnum)
|
|||
{
|
||||
st++; /* next statement */
|
||||
|
||||
if (++profile > 10000000) //spike -- was 100000
|
||||
if (++profile > 0x10000000) //spike -- was decimal 100000
|
||||
{
|
||||
qcvm->xstatement = st - qcvm->statements;
|
||||
PR_RunError("runaway loop error");
|
||||
|
|
218
Quake/pr_ext.c
218
Quake/pr_ext.c
|
@ -476,6 +476,7 @@ static void PF_strzone(void)
|
|||
size_t l[8];
|
||||
int i;
|
||||
size_t id;
|
||||
|
||||
for (i = 0; i < qcvm->argc; i++)
|
||||
{
|
||||
s[i] = G_STRING(OFS_PARM0+i*3);
|
||||
|
@ -494,7 +495,6 @@ static void PF_strzone(void)
|
|||
}
|
||||
qcvm->knownzone[id>>3] |= 1u<<(id&7);
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < qcvm->argc; i++)
|
||||
{
|
||||
memcpy(buf, s[i], l[i]);
|
||||
|
@ -506,6 +506,7 @@ static void PF_strunzone(void)
|
|||
{
|
||||
size_t id;
|
||||
const char *foo = G_STRING(OFS_PARM0);
|
||||
|
||||
if (!G_INT(OFS_PARM0))
|
||||
return; //don't bug out if they gave a null string
|
||||
id = -1-G_INT(OFS_PARM0);
|
||||
|
@ -2100,10 +2101,18 @@ static void PF_getsurfacepointattribute(void)
|
|||
}
|
||||
static void PF_sv_getlight(void)
|
||||
{
|
||||
qmodel_t *om = cl.worldmodel;
|
||||
float *point = G_VECTOR(OFS_PARM0);
|
||||
|
||||
cl.worldmodel = qcvm->worldmodel; //R_LightPoint is really clientside, so if its called from ssqc then try to make things work regardless
|
||||
//FIXME: d_lightstylevalue isn't set on dedicated servers
|
||||
|
||||
//FIXME: seems like quakespasm doesn't do lits for model lighting, so we won't either.
|
||||
G_FLOAT(OFS_RETURN+0) = G_FLOAT(OFS_RETURN+1) = G_FLOAT(OFS_RETURN+2) = R_LightPoint(point) / 255.0;
|
||||
|
||||
cl.worldmodel = om;
|
||||
}
|
||||
#define PF_cl_getlight PF_sv_getlight
|
||||
|
||||
//server/client stuff
|
||||
static void PF_checkcommand(void)
|
||||
|
@ -2560,6 +2569,27 @@ static void PF_sv_pointsound(void)
|
|||
float attenuation = G_FLOAT(OFS_PARM3);
|
||||
SV_StartSound (qcvm->edicts, origin, 0, sample, volume, attenuation);
|
||||
}
|
||||
static void PF_cl_pointsound(void)
|
||||
{
|
||||
float *origin = G_VECTOR(OFS_PARM0);
|
||||
const char *sample = G_STRING(OFS_PARM1);
|
||||
float volume = G_FLOAT(OFS_PARM2);
|
||||
float attenuation = G_FLOAT(OFS_PARM3);
|
||||
S_StartSound(0, 0, S_PrecacheSound(sample), origin, volume, attenuation);
|
||||
}
|
||||
static void PF_cl_soundlength(void)
|
||||
{
|
||||
const char *sample = G_STRING(OFS_PARM0);
|
||||
sfx_t *sfx = S_PrecacheSound(sample);
|
||||
sfxcache_t *sc;
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
if (sfx)
|
||||
{
|
||||
sc = S_LoadSound (sfx);
|
||||
if (sc)
|
||||
G_FLOAT(OFS_RETURN) = (double)sc->length / sc->speed;
|
||||
}
|
||||
}
|
||||
|
||||
//file stuff
|
||||
|
||||
|
@ -2612,7 +2642,7 @@ static void PF_fopen(void)
|
|||
const char *fallback;
|
||||
FILE *file;
|
||||
size_t i;
|
||||
char name[MAX_OSPATH];
|
||||
char name[MAX_OSPATH], *sl;
|
||||
int filesize = 0;
|
||||
|
||||
G_FLOAT(OFS_RETURN) = -1; //assume failure
|
||||
|
@ -2642,7 +2672,17 @@ static void PF_fopen(void)
|
|||
break;
|
||||
case 2: //write
|
||||
q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, fname);
|
||||
Sys_mkdir (name);
|
||||
sl = name;
|
||||
while (*sl)
|
||||
{
|
||||
if (*sl == '/')
|
||||
{
|
||||
*sl = 0;
|
||||
Sys_mkdir (name); //make sure each part of the path exists.
|
||||
*sl = '/';
|
||||
}
|
||||
*sl++;
|
||||
}
|
||||
file = fopen(name, "wb");
|
||||
break;
|
||||
}
|
||||
|
@ -4587,6 +4627,33 @@ static void PF_cl_drawcharacter(void)
|
|||
glEnd ();
|
||||
}
|
||||
|
||||
static void PF_cl_drawrawstring(void)
|
||||
{
|
||||
extern gltexture_t *char_texture;
|
||||
|
||||
float *pos = G_VECTOR(OFS_PARM0);
|
||||
const char *text = G_STRING (OFS_PARM1);
|
||||
float *size = G_VECTOR(OFS_PARM2);
|
||||
float *rgb = G_VECTOR(OFS_PARM3);
|
||||
float alpha = G_FLOAT (OFS_PARM4);
|
||||
// int flags = G_FLOAT (OFS_PARM5);
|
||||
|
||||
float x = pos[0];
|
||||
int c;
|
||||
|
||||
if (!*text)
|
||||
return; //don't waste time on spaces
|
||||
|
||||
GL_Bind (char_texture);
|
||||
glColor4f (rgb[0], rgb[1], rgb[2], alpha);
|
||||
glBegin (GL_QUADS);
|
||||
while ((c = *text++))
|
||||
{
|
||||
DrawQC_CharacterQuad (x, pos[1], c, size[0], size[1]);
|
||||
x += size[0];
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
static void PF_cl_drawstring(void)
|
||||
{
|
||||
extern gltexture_t *char_texture;
|
||||
|
@ -4742,6 +4809,46 @@ static void PF_cl_drawfill(void)
|
|||
glEnable (GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
static qpic_t *polygon_pic;
|
||||
#define MAX_POLYVERTS
|
||||
polygonvert_t polygon_verts[256];
|
||||
unsigned int polygon_numverts;
|
||||
static void PF_R_PolygonBegin(void)
|
||||
{
|
||||
qpic_t *pic = DrawQC_CachePic(G_STRING(OFS_PARM0), false);
|
||||
int flags = (qcvm->argc>1)?G_FLOAT(OFS_PARM1):0;
|
||||
int is2d = (qcvm->argc>2)?G_FLOAT(OFS_PARM2):0;
|
||||
|
||||
if (!is2d)
|
||||
PR_RunError ("PF_R_PolygonBegin: scene polygons are not supported");
|
||||
|
||||
polygon_pic = pic;
|
||||
polygon_numverts = 0;
|
||||
}
|
||||
static void PF_R_PolygonVertex(void)
|
||||
{
|
||||
polygonvert_t *v = &polygon_verts[polygon_numverts];
|
||||
if (polygon_numverts == countof(polygon_verts))
|
||||
return; //panic!
|
||||
polygon_numverts++;
|
||||
|
||||
v->xy[0] = G_FLOAT(OFS_PARM0+0);
|
||||
v->xy[1] = G_FLOAT(OFS_PARM0+1);
|
||||
v->st[0] = G_FLOAT(OFS_PARM1+0);
|
||||
v->st[1] = G_FLOAT(OFS_PARM1+1);
|
||||
v->rgba[0] = G_FLOAT(OFS_PARM2+0);
|
||||
v->rgba[1] = G_FLOAT(OFS_PARM2+1);
|
||||
v->rgba[2] = G_FLOAT(OFS_PARM2+2);
|
||||
v->rgba[3] = G_FLOAT(OFS_PARM3);
|
||||
}
|
||||
static void PF_R_PolygonEnd(void)
|
||||
{
|
||||
if (polygon_pic)
|
||||
Draw_PicPolygon(polygon_pic, polygon_numverts, polygon_verts);
|
||||
polygon_numverts = 0;
|
||||
}
|
||||
|
||||
static void PF_cl_cprint(void)
|
||||
{
|
||||
const char *str = PF_VarString(0);
|
||||
|
@ -4764,18 +4871,50 @@ static void PF_cl_stringtokeynum(void)
|
|||
static void PF_cl_getkeybind(void)
|
||||
{
|
||||
int keynum = Key_QCToNative(G_FLOAT(OFS_PARM0));
|
||||
|
||||
int bindmap = (qcvm->argc<=1)?0:G_FLOAT(OFS_PARM1);
|
||||
char *s = PR_GetTempString();
|
||||
if (keynum >= 0 && keynum < MAX_KEYS)
|
||||
Q_strncpy(s, keybindings[keynum], STRINGTEMP_LENGTH);
|
||||
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||
bindmap = 0;
|
||||
if (keynum >= 0 && keynum < MAX_KEYS && keybindings[bindmap][keynum])
|
||||
Q_strncpy(s, keybindings[bindmap][keynum], STRINGTEMP_LENGTH);
|
||||
else
|
||||
Q_strncpy(s, "", STRINGTEMP_LENGTH);
|
||||
G_INT(OFS_RETURN) = PR_SetEngineString(s);
|
||||
}
|
||||
static void PF_cl_setkeybind(void)
|
||||
{
|
||||
int keynum = Key_QCToNative(G_FLOAT(OFS_PARM0));
|
||||
const char *binding = G_STRING(OFS_PARM1);
|
||||
int bindmap = (qcvm->argc<=1)?0:G_FLOAT(OFS_PARM2);
|
||||
char *s = PR_GetTempString();
|
||||
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||
bindmap = 0;
|
||||
if (keynum >= 0 && keynum < MAX_KEYS)
|
||||
Key_SetBinding(keynum, binding, bindmap);
|
||||
}
|
||||
static void PF_cl_getbindmaps(void)
|
||||
{
|
||||
G_FLOAT(OFS_RETURN+0) = key_bindmap[0];
|
||||
G_FLOAT(OFS_RETURN+1) = key_bindmap[1];
|
||||
G_FLOAT(OFS_RETURN+2) = 0;
|
||||
}
|
||||
static void PF_cl_setbindmaps(void)
|
||||
{
|
||||
float *bm = G_VECTOR(OFS_PARM0);
|
||||
key_bindmap[0] = bm[0];
|
||||
key_bindmap[1] = bm[1];
|
||||
|
||||
if (key_bindmap[0] < 0 || key_bindmap[0] >= MAX_BINDMAPS)
|
||||
key_bindmap[0] = 0;
|
||||
if (key_bindmap[1] < 0 || key_bindmap[1] >= MAX_BINDMAPS)
|
||||
key_bindmap[1] = 0;
|
||||
|
||||
G_FLOAT(OFS_RETURN) = false;
|
||||
}
|
||||
static void PF_cl_findkeysforcommand(void)
|
||||
{
|
||||
const char *command = G_STRING(OFS_PARM0);
|
||||
// float bindmap = G_FLOAT(OFS_PARM1);
|
||||
int bindmap = G_FLOAT(OFS_PARM1);
|
||||
int keys[5];
|
||||
char gah[64];
|
||||
char *s = PR_GetTempString();
|
||||
|
@ -4783,10 +4922,12 @@ static void PF_cl_findkeysforcommand(void)
|
|||
int j;
|
||||
int l = strlen(command);
|
||||
const char *b;
|
||||
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||
bindmap = 0;
|
||||
|
||||
for (j = 0; j < MAX_KEYS; j++)
|
||||
{
|
||||
b = keybindings[j];
|
||||
b = keybindings[bindmap][j];
|
||||
if (!b)
|
||||
continue;
|
||||
if (!strncmp (b, command, l) && (!b[l] || (!strchr(command, ' ') && (b[l] == ' ' || b[l] == '\t'))))
|
||||
|
@ -4817,17 +4958,19 @@ static void PF_cl_findkeysforcommand(void)
|
|||
static void PF_cl_findkeysforcommandex(void)
|
||||
{
|
||||
const char *command = G_STRING(OFS_PARM0);
|
||||
// float bindmap = G_FLOAT(OFS_PARM1);
|
||||
int bindmap = G_FLOAT(OFS_PARM1);
|
||||
int keys[16];
|
||||
char *s = PR_GetTempString();
|
||||
int count = 0;
|
||||
int j;
|
||||
int l = strlen(command);
|
||||
const char *b;
|
||||
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||
bindmap = 0;
|
||||
|
||||
for (j = 0; j < MAX_KEYS; j++)
|
||||
{
|
||||
b = keybindings[j];
|
||||
b = keybindings[bindmap][j];
|
||||
if (!b)
|
||||
continue;
|
||||
if (!strncmp (b, command, l) && (!b[l] || (!strchr(command, ' ') && (b[l] == ' ' || b[l] == '\t'))))
|
||||
|
@ -4857,13 +5000,43 @@ static void PF_cl_setcursormode(void)
|
|||
// float *hotspot = (qcvm->argc<=2)?NULL:G_VECTOR(OFS_PARM2);
|
||||
// float cursorscale = (qcvm->argc<=3)?1:G_FLOAT(OFS_PARM3);
|
||||
|
||||
/* if (absmode)
|
||||
{
|
||||
int mark = Hunk_LowMark();
|
||||
int width, height;
|
||||
qboolean malloced;
|
||||
byte *imagedata = Image_LoadImage(cursorname, &width, &height, &malloced);
|
||||
//TODO: rescale image by cursorscale
|
||||
SDL_Surface *surf = !imagedata?NULL:SDL_CreateRGBSurfaceFrom(imagedata, width, height, 32, width*4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
Hunk_FreeToLowMark(mark);
|
||||
if (malloced)
|
||||
free(imagedata);
|
||||
if (surf)
|
||||
{
|
||||
cursor = SDL_CreateColorCursor(surf, hotspot[0], hotspot[1]);
|
||||
SDL_FreeSurface(surf);
|
||||
SDL_SetCursor(cursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetCursor(SDL_GetDefaultCursor());
|
||||
cursor = NULL;
|
||||
}
|
||||
if (oldcursor)
|
||||
SDL_FreeCursor(oldcursor);
|
||||
oldcursor = cursor;
|
||||
}*/
|
||||
|
||||
cl.csqc_cursorforced = absmode;
|
||||
}
|
||||
static void PF_cl_getcursormode(void)
|
||||
{
|
||||
// qboolean effectivemode = (qcvm->argc==0)?false:G_FLOAT(OFS_PARM0);
|
||||
qboolean effectivemode = (qcvm->argc==0)?false:G_FLOAT(OFS_PARM0);
|
||||
|
||||
G_FLOAT(OFS_RETURN) = cl.csqc_cursorforced;
|
||||
// if (effectivemode)
|
||||
// G_FLOAT(OFS_RETURN) = cl.csqc_cursorforced;
|
||||
// else
|
||||
G_FLOAT(OFS_RETURN) = cl.csqc_cursorforced;
|
||||
}
|
||||
static void PF_cl_setsensitivity(void)
|
||||
{
|
||||
|
@ -5111,9 +5284,9 @@ static struct
|
|||
{"stof", PF_stof, PF_stof, 81, "float(string)"}, //81
|
||||
{"multicast", PF_multicast, PF_NoCSQC, 82, D("#define unicast(pl,reli) do{msg_entity = pl; multicast('0 0 0', reli?MULITCAST_ONE_R:MULTICAST_ONE);}while(0)\n"
|
||||
"void(vector where, float set)", "Once the MSG_MULTICAST network message buffer has been filled with data, this builtin is used to dispatch it to the given target, filtering by pvs for reduced network bandwidth.")}, //82
|
||||
{"tracebox", PF_tracebox, NULL, 90, D("void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent)", "Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values.")},
|
||||
{"tracebox", PF_tracebox, PF_tracebox, 90, D("void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent)", "Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values.")},
|
||||
{"randomvec", PF_randomvector, PF_randomvector, 91, D("vector()", "Returns a vector with random values. Each axis is independantly a value between -1 and 1 inclusive.")},
|
||||
{"getlight", PF_sv_getlight, NULL, 92, "vector(vector org)"},// (DP_QC_GETLIGHT),
|
||||
{"getlight", PF_sv_getlight, PF_cl_getlight, 92, "vector(vector org)"},// (DP_QC_GETLIGHT),
|
||||
{"registercvar", PF_registercvar, PF_registercvar, 93, D("float(string cvarname, string defaultvalue)", "Creates a new cvar on the fly. If it does not already exist, it will be given the specified value. If it does exist, this is a no-op.\nThis builtin has the limitation that it does not apply to configs or commandlines. Such configs will need to use the set or seta command causing this builtin to be a noop.\nIn engines that support it, you will generally find the autocvar feature easier and more efficient to use.")},
|
||||
{"min", PF_min, PF_min, 94, D("float(float a, float b, ...)", "Returns the lowest value of its arguments.")},// (DP_QC_MINMAXBOUND)
|
||||
{"max", PF_max, PF_max, 95, D("float(float a, float b, ...)", "Returns the highest value of its arguments.")},// (DP_QC_MINMAXBOUND)
|
||||
|
@ -5246,9 +5419,9 @@ static struct
|
|||
// {"setproperty", PF_NoSSQC, PF_FullCSQCOnly, 303, D("#define setviewprop setproperty\nfloat(float property, ...)", "Allows you to override default view properties like viewport, fov, and whether the engine hud will be drawn. Different VF_ values have slightly different arguments, some are vectors, some floats.")},// (EXT_CSQC)
|
||||
// {"renderscene", PF_NoSSQC, PF_FullCSQCOnly, 304, D("void()", "Draws all entities, polygons, and particles on the rentity list (which were added via addentities or addentity), using the various view properties set via setproperty. There is no ordering dependancy.\nThe scene must generally be cleared again before more entities are added, as entities will persist even over to the next frame.\nYou may call this builtin multiple times per frame, but should only be called from CSQC_UpdateView.")},// (EXT_CSQC)
|
||||
// {"dynamiclight_add",PF_NoSSQC, PF_FullCSQCOnly, 305, D("float(vector org, float radius, vector lightcolours, optional float style, optional string cubemapname, optional float pflags)", "Adds a temporary dlight, ready to be drawn via addscene. Cubemap orientation will be read from v_forward/v_right/v_up.")},// (EXT_CSQC)
|
||||
// {"R_BeginPolygon", PF_NoSSQC, PF_R_PolygonBegin, 306, D("void(string texturename, optional float flags, optional float is2d)", "Specifies the shader to use for the following polygons, along with optional flags.\nIf is2d, the polygon will be drawn as soon as the EndPolygon call is made, rather than waiting for renderscene. This allows complex 2d effects.")},// (EXT_CSQC_???)
|
||||
// {"R_PolygonVertex", PF_NoSSQC, PF_R_PolygonVertex, 307, D("void(vector org, vector texcoords, vector rgb, float alpha)", "Specifies a polygon vertex with its various properties.")},// (EXT_CSQC_???)
|
||||
// {"R_EndPolygon", PF_NoSSQC, PF_R_PolygonEnd, 308, D("void()", "Ends the current polygon. At least 3 verticies must have been specified. You do not need to call beginpolygon if you wish to draw another polygon with the same shader.")},
|
||||
{"R_BeginPolygon", PF_NoSSQC, PF_R_PolygonBegin, 306, D("void(string texturename, optional float flags, optional float is2d)", "Specifies the shader to use for the following polygons, along with optional flags.\nIf is2d, the polygon will be drawn as soon as the EndPolygon call is made, rather than waiting for renderscene. This allows complex 2d effects.")},// (EXT_CSQC_???)
|
||||
{"R_PolygonVertex", PF_NoSSQC, PF_R_PolygonVertex, 307, D("void(vector org, vector texcoords, vector rgb, float alpha)", "Specifies a polygon vertex with its various properties.")},// (EXT_CSQC_???)
|
||||
{"R_EndPolygon", PF_NoSSQC, PF_R_PolygonEnd, 308, D("void()", "Ends the current polygon. At least 3 verticies must have been specified. You do not need to call beginpolygon if you wish to draw another polygon with the same shader.")},
|
||||
// {"getproperty", PF_NoSSQC, PF_FullCSQCOnly, 309, D("#define getviewprop getproperty\n__variant(float property)", "Retrieve a currently-set (typically view) property, allowing you to read the current viewport or other things. Due to cheat protection, certain values may be unretrievable.")},// (EXT_CSQC_1)
|
||||
// {"unproject", PF_NoSSQC, PF_FullCSQCOnly, 310, D("vector (vector v)", "Transform a 2d screen-space point (with depth) into a 3d world-space point, according the various origin+angle+fov etc settings set via setproperty.")},// (EXT_CSQC)
|
||||
// {"project", PF_NoSSQC, PF_FullCSQCOnly, 311, D("vector (vector v)", "Transform a 3d world-space point into a 2d screen-space point, according the various origin+angle+fov etc settings set via setproperty.")},// (EXT_CSQC)
|
||||
|
@ -5261,7 +5434,7 @@ static struct
|
|||
{"drawgetimagesize",PF_NoSSQC, PF_cl_getimagesize, 318, D("#define draw_getimagesize drawgetimagesize\nvector(string picname)", "Returns the dimensions of the named image. Images specified with .lmp should give the original .lmp's dimensions even if texture replacements use a different resolution.")},// (EXT_CSQC)
|
||||
// {"freepic", PF_NoSSQC, PF_FullCSQCOnly, 319, D("void(string name)", "Tells the engine that the image is no longer needed. The image will appear to be new the next time its needed.")},// (EXT_CSQC)
|
||||
{"drawcharacter", PF_NoSSQC, PF_cl_drawcharacter,320, D("float(vector position, float character, vector size, vector rgb, float alpha, optional float drawflag)", "Draw the given quake character at the given position.\nIf flag&4, the function will consider the char to be a unicode char instead (or display as a ? if outside the 32-127 range).\nsize should normally be something like '8 8 0'.\nrgb should normally be '1 1 1'\nalpha normally 1.\nSoftware engines may assume the named defaults.\nNote that ALL text may be rescaled on the X axis due to variable width fonts. The X axis may even be ignored completely.")},// (EXT_CSQC, [EXT_CSQC_???])
|
||||
// {"drawrawstring", PF_NoSSQC, PF_FullCSQCOnly, 321, D("float(vector position, string text, vector size, vector rgb, float alpha, optional float drawflag)", "Draws the specified string without using any markup at all, even in engines that support it.\nIf UTF-8 is globally enabled in the engine, then that encoding is used (without additional markup), otherwise it is raw quake chars.\nSoftware engines may assume a size of '8 8 0', rgb='1 1 1', alpha=1, flag&3=0, but it is not an error to draw out of the screen.")},// (EXT_CSQC, [EXT_CSQC_???])
|
||||
{"drawrawstring", PF_NoSSQC, PF_cl_drawrawstring,321, D("float(vector position, string text, vector size, vector rgb, float alpha, optional float drawflag)", "Draws the specified string without using any markup at all, even in engines that support it.\nIf UTF-8 is globally enabled in the engine, then that encoding is used (without additional markup), otherwise it is raw quake chars.\nSoftware engines may assume a size of '8 8 0', rgb='1 1 1', alpha=1, flag&3=0, but it is not an error to draw out of the screen.")},// (EXT_CSQC, [EXT_CSQC_???])
|
||||
{"drawpic", PF_NoSSQC, PF_cl_drawpic, 322, D("float(vector position, string pic, vector size, vector rgb, float alpha, optional float drawflag)", "Draws an shader within the given 2d screen box. Software engines may omit support for rgb+alpha, but must support rescaling, and must clip to the screen without crashing.")},// (EXT_CSQC, [EXT_CSQC_???])
|
||||
{"drawfill", PF_NoSSQC, PF_cl_drawfill, 323, D("float(vector position, vector size, vector rgb, float alpha, optional float drawflag)", "Draws a solid block over the given 2d box, with given colour, alpha, and blend mode (specified via flags).\nflags&3=0 simple blend.\nflags&3=1 additive blend")},// (EXT_CSQC, [EXT_CSQC_???])
|
||||
{"drawsetcliparea", PF_NoSSQC, PF_cl_drawsetclip, 324, D("void(float x, float y, float width, float height)", "Specifies a 2d clipping region (aka: scissor test). 2d draw calls will all be clipped to this 2d box, the area outside will not be modified by any 2d draw call (even 2d polygons).")},// (EXT_CSQC_???)
|
||||
|
@ -5419,7 +5592,7 @@ static struct
|
|||
{"strtolower", PF_strtolower, PF_strtolower, 480, "string(string s)"}, //DP_QC_STRING_CASE_FUNCTIONS
|
||||
{"strtoupper", PF_strtoupper, PF_strtoupper, 481, "string(string s)"}, //DP_QC_STRING_CASE_FUNCTIONS
|
||||
{"cvar_defstring", PF_cvar_defstring, PF_cvar_defstring, 482, "string(string s)"}, //DP_QC_CVAR_DEFSTRING
|
||||
{"pointsound", PF_sv_pointsound, NULL, 483, "void(vector origin, string sample, float volume, float attenuation)"},//DP_SV_POINTSOUND
|
||||
{"pointsound", PF_sv_pointsound, PF_cl_pointsound, 483, "void(vector origin, string sample, float volume, float attenuation)"},//DP_SV_POINTSOUND
|
||||
{"strreplace", PF_strreplace, PF_strreplace, 484, "string(string search, string replace, string subject)"},//DP_QC_STRREPLACE
|
||||
{"strireplace", PF_strireplace, PF_strireplace, 485, "string(string search, string replace, string subject)"},//DP_QC_STRREPLACE
|
||||
{"getsurfacepointattribute",PF_getsurfacepointattribute,PF_getsurfacepointattribute, 486, "vector(entity e, float s, float n, float a)"},//DP_QC_GETSURFACEPOINTATTRIBUTE
|
||||
|
@ -5448,8 +5621,9 @@ static struct
|
|||
// {"loadfromdata", PF_loadfromdata, PF_loadfromdata, 529, D("void(string s)", "Reads a set of entities from the given string. This string should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead.")},
|
||||
// {"loadfromfile", PF_loadfromfile, PF_loadfromfile, 530, D("void(string s)", "Reads a set of entities from the named file. This file should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead.")},
|
||||
{"log", PF_Logarithm, PF_Logarithm, 532, D("float(float v, optional float base)", "Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by.")},
|
||||
{"buf_loadfile", PF_buf_loadfile, NULL, 535, D("float(string filename, strbuf bufhandle)", "Appends the named file into a string buffer (which must have been created in advance). The return value merely says whether the file was readable.")},
|
||||
{"buf_writefile", PF_buf_writefile, NULL, 536, D("float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings)", "Writes the contents of a string buffer onto the end of the supplied filehandle (you must have already used fopen). Additional optional arguments permit you to constrain the writes to a subsection of the stringbuffer.")},
|
||||
{"soundlength", PF_NoSSQC, PF_cl_soundlength, 534, D("float(string sample)", "Provides a way to query the duration of a sound sample, allowing you to set up a timer to chain samples.")},
|
||||
{"buf_loadfile", PF_buf_loadfile, PF_buf_loadfile, 535, D("float(string filename, strbuf bufhandle)", "Appends the named file into a string buffer (which must have been created in advance). The return value merely says whether the file was readable.")},
|
||||
{"buf_writefile", PF_buf_writefile, PF_buf_writefile, 536, D("float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings)", "Writes the contents of a string buffer onto the end of the supplied filehandle (you must have already used fopen). Additional optional arguments permit you to constrain the writes to a subsection of the stringbuffer.")},
|
||||
{"callfunction", PF_callfunction, PF_callfunction, 605, D("void(.../*, string funcname*/)", "Invokes the named function. The function name is always passed as the last parameter and must always be present. The others are passed to the named function as-is")},
|
||||
{"isfunction", PF_isfunction, PF_isfunction, 607, D("float(string s)", "Returns true if the named function exists and can be called with the callfunction builtin.")},
|
||||
{"parseentitydata", PF_parseentitydata, NULL, 613, D("float(entity e, string s, optional float offset)", "Reads a single entity's fields into an already-spawned entity. s should contain field pairs like in a saved game: {\"foo1\" \"bar\" \"foo2\" \"5\"}. Returns <=0 on failure, otherwise returns the offset in the string that was read to.")},
|
||||
|
@ -5457,6 +5631,8 @@ static struct
|
|||
{"sprintf", PF_sprintf, PF_sprintf, 627, "string(string fmt, ...)"},
|
||||
{"getsurfacenumtriangles",PF_getsurfacenumtriangles,PF_getsurfacenumtriangles,628,"float(entity e, float s)"},
|
||||
{"getsurfacetriangle",PF_getsurfacetriangle,PF_getsurfacetriangle,629,"vector(entity e, float s, float n)"},
|
||||
{"getbindmaps", PF_NoSSQC, PF_cl_getbindmaps, 631, "vector()", "stub."},
|
||||
{"setbindmaps", PF_NoSSQC, PF_cl_setbindmaps, 632, "float(vector bm)", "stub."},
|
||||
// {"digest_hex", PF_digest_hex, PF_digest_hex, 639, "string(string digest, string data, ...)"},
|
||||
};
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ sizebuf_t *WriteDest (void);
|
|||
char *PR_GetTempString (void);
|
||||
int PR_MakeTempString (const char *val);
|
||||
char *PF_VarString (int first);
|
||||
#define STRINGTEMP_BUFFERS 16
|
||||
#define STRINGTEMP_BUFFERS 1024
|
||||
#define STRINGTEMP_LENGTH 1024
|
||||
void PF_Fixme(void); //the 'unimplemented' builtin. woot.
|
||||
|
||||
|
|
|
@ -1003,6 +1003,7 @@ void Sbar_Draw (void)
|
|||
glDisable (GL_ALPHA_TEST); //in the finest tradition of glquake, we litter gl state calls all over the place. yay state trackers.
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
PR_SwitchQCVM(&cl.qcvm);
|
||||
pr_global_struct->frametime = host_frametime;
|
||||
if (qcvm->extglobals.cltime)
|
||||
*qcvm->extglobals.cltime = realtime;
|
||||
if (qcvm->extglobals.player_localentnum)
|
||||
|
|
|
@ -205,6 +205,7 @@ void S_Init (void)
|
|||
Con_Printf("\nSound Initialization\n");
|
||||
|
||||
Cmd_AddCommand("play", S_Play);
|
||||
Cmd_AddCommand("play2", S_Play); //Spike -- a version with attenuation 0.
|
||||
Cmd_AddCommand("playvol", S_PlayVol);
|
||||
Cmd_AddCommand("stopsound", S_StopAllSoundsC);
|
||||
Cmd_AddCommand("soundlist", S_SoundList);
|
||||
|
@ -1000,6 +1001,7 @@ static void S_Play (void)
|
|||
int i;
|
||||
char name[256];
|
||||
sfx_t *sfx;
|
||||
float attenuation = !strcmp(Cmd_Argv(0), "play2")?0:1.0;
|
||||
|
||||
i = 1;
|
||||
while (i < Cmd_Argc())
|
||||
|
@ -1010,7 +1012,7 @@ static void S_Play (void)
|
|||
q_strlcat(name, ".wav", sizeof(name));
|
||||
}
|
||||
sfx = S_PrecacheSound(name);
|
||||
S_StartSound(hash++, 0, sfx, listener_origin, 1.0, 1.0);
|
||||
S_StartSound(hash++, 0, sfx, listener_origin, 1.0, attenuation);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,6 +174,8 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
// Con_Printf ("loading %s\n",namebuffer);
|
||||
|
||||
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf), NULL);
|
||||
if (!data)
|
||||
data = COM_LoadStackFile(s->name, stackbuf, sizeof(stackbuf), NULL);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
|
|
|
@ -3104,6 +3104,8 @@ void SV_SpawnServer (const char *server)
|
|||
|
||||
sv.active = true;
|
||||
|
||||
SV_Precache_Model("progs/player.mdl"); //Spike -- SV_CreateBaseline depends on this model.
|
||||
|
||||
// all setup is completed, any further precache statements are errors
|
||||
sv.state = ss_active;
|
||||
|
||||
|
|
Loading…
Reference in a new issue