mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-13 07:21:31 +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);
|
qpic_t *Draw_TryCachePic (const char *path);
|
||||||
void Draw_NewGame (void);
|
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
|
void GL_SetCanvas (canvastype newcanvas); //johnfitz
|
||||||
|
|
||||||
#endif /* _QUAKE_DRAW_H */
|
#endif /* _QUAKE_DRAW_H */
|
||||||
|
|
|
@ -314,6 +314,24 @@ qpic_t *Draw_TryCachePic (const char *path)
|
||||||
menu_numcachepics++;
|
menu_numcachepics++;
|
||||||
strcpy (pic->name, path);
|
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
|
// 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 ();
|
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
|
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;
|
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
|
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;
|
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 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 menubound[MAX_KEYS]; // if true, can't be rebound while in menu
|
||||||
qboolean keydown[MAX_KEYS];
|
qboolean keydown[MAX_KEYS];
|
||||||
|
@ -919,21 +920,23 @@ const char *Key_KeynumToString (int keynum)
|
||||||
Key_SetBinding
|
Key_SetBinding
|
||||||
===================
|
===================
|
||||||
*/
|
*/
|
||||||
void Key_SetBinding (int keynum, const char *binding)
|
void Key_SetBinding (int keynum, const char *binding, int bindmap)
|
||||||
{
|
{
|
||||||
if (keynum == -1)
|
if (keynum == -1)
|
||||||
return;
|
return;
|
||||||
|
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||||
|
return;
|
||||||
|
|
||||||
// free old bindings
|
// free old bindings
|
||||||
if (keybindings[keynum])
|
if (keybindings[bindmap][keynum])
|
||||||
{
|
{
|
||||||
Z_Free (keybindings[keynum]);
|
Z_Free (keybindings[bindmap][keynum]);
|
||||||
keybindings[keynum] = NULL;
|
keybindings[bindmap][keynum] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate memory for new binding
|
// allocate memory for new binding
|
||||||
if (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)
|
void Key_Unbind_f (void)
|
||||||
{
|
{
|
||||||
int b;
|
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");
|
Con_Printf ("unbind <key> : remove commands from a key\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
b = Key_StringToKeynum (Cmd_Argv(1));
|
b = Key_StringToKeynum (Cmd_Argv(keyarg));
|
||||||
if (b == -1)
|
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(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key_SetBinding (b, NULL);
|
Key_SetBinding (b, NULL, bindmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Key_Unbindall_f (void)
|
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])
|
for (i = 0; i < MAX_KEYS; i++)
|
||||||
Key_SetBinding (i, NULL);
|
{
|
||||||
|
if (keybindings[b][i])
|
||||||
|
Key_SetBinding (i, NULL, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,13 +990,14 @@ Key_Bindlist_f -- johnfitz
|
||||||
void Key_Bindlist_f (void)
|
void Key_Bindlist_f (void)
|
||||||
{
|
{
|
||||||
int i, count;
|
int i, count;
|
||||||
|
int bindmap = 0;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for (i = 0; i < MAX_KEYS; i++)
|
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++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1002,40 +1013,45 @@ void Key_Bind_f (void)
|
||||||
{
|
{
|
||||||
int i, c, b;
|
int i, c, b;
|
||||||
char cmd[1024];
|
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();
|
c = Cmd_Argc();
|
||||||
|
|
||||||
if (c != 2 && c != 3)
|
if (c < keyarg+1 )
|
||||||
{
|
{
|
||||||
Con_Printf ("bind <key> [command] : attach a command to a key\n");
|
Con_Printf ("bind <key> [command] : attach a command to a key\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
b = Key_StringToKeynum (Cmd_Argv(1));
|
|
||||||
|
b = Key_StringToKeynum (Cmd_Argv(keyarg));
|
||||||
if (b == -1)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == 2)
|
if (c == keyarg+1)
|
||||||
{
|
{
|
||||||
if (keybindings[b])
|
if (keybindings[bindmap][b])
|
||||||
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] );
|
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(keyarg), keybindings[bindmap][b] );
|
||||||
else
|
else
|
||||||
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) );
|
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(keyarg) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the rest of the command line
|
// copy the rest of the command line
|
||||||
cmd[0] = 0;
|
cmd[0] = 0;
|
||||||
for (i = 2; i < c; i++)
|
for (i = keyarg+1; i < c; i++)
|
||||||
{
|
{
|
||||||
q_strlcat (cmd, Cmd_Argv(i), sizeof(cmd));
|
q_strlcat (cmd, Cmd_Argv(i), sizeof(cmd));
|
||||||
if (i != (c-1))
|
if (i != (c-1))
|
||||||
q_strlcat (cmd, " ", sizeof(cmd));
|
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)
|
void Key_WriteBindings (FILE *f)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int bindmap;
|
||||||
|
|
||||||
// unbindall before loading stored bindings:
|
// unbindall before loading stored bindings:
|
||||||
if (cfg_unbindall.value)
|
if (cfg_unbindall.value)
|
||||||
fprintf (f, "unbindall\n");
|
fprintf (f, "unbindall\n");
|
||||||
for (i = 0; i < MAX_KEYS; i++)
|
for (bindmap = 0; bindmap < MAX_BINDMAPS; bindmap++)
|
||||||
{
|
{
|
||||||
if (keybindings[i] && *keybindings[i])
|
for (i = 0; i < MAX_KEYS; i++)
|
||||||
fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[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 ("bind",Key_Bind_f);
|
||||||
Cmd_AddCommand ("unbind",Key_Unbind_f);
|
Cmd_AddCommand ("unbind",Key_Unbind_f);
|
||||||
Cmd_AddCommand ("unbindall",Key_Unbindall_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 {
|
static struct {
|
||||||
|
@ -1359,7 +1387,9 @@ void Key_Event (int key, qboolean down)
|
||||||
// downs can be matched with ups
|
// downs can be matched with ups
|
||||||
if (!down)
|
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] == '+')
|
if (kb && kb[0] == '+')
|
||||||
{
|
{
|
||||||
sprintf (cmd, "-%s %i\n", kb+1, key);
|
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_console && !consolekeys[key]) ||
|
||||||
(key_dest == key_game && (!con_forcedup || !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)
|
||||||
{
|
{
|
||||||
if (kb[0] == '+')
|
if (kb[0] == '+')
|
||||||
|
|
|
@ -155,13 +155,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define K_RTRIGGER 252
|
#define K_RTRIGGER 252
|
||||||
|
|
||||||
#define MAX_KEYS 256
|
#define MAX_KEYS 256
|
||||||
|
#define MAX_BINDMAPS 8
|
||||||
|
|
||||||
#define MAXCMDLINE 256
|
#define MAXCMDLINE 256
|
||||||
|
|
||||||
typedef enum {key_game, key_console, key_message, key_menu} keydest_t;
|
typedef enum {key_game, key_console, key_message, key_menu} keydest_t;
|
||||||
|
|
||||||
extern keydest_t key_dest;
|
extern keydest_t key_dest;
|
||||||
extern char *keybindings[MAX_KEYS];
|
extern char *keybindings[MAX_BINDMAPS][MAX_KEYS];
|
||||||
|
|
||||||
#define CMDLINES 64
|
#define CMDLINES 64
|
||||||
|
|
||||||
|
@ -170,6 +171,7 @@ extern int edit_line;
|
||||||
extern int key_linepos;
|
extern int key_linepos;
|
||||||
extern int key_insert;
|
extern int key_insert;
|
||||||
extern double key_blinktime;
|
extern double key_blinktime;
|
||||||
|
extern int key_bindmap[2];
|
||||||
|
|
||||||
extern qboolean chat_team;
|
extern qboolean chat_team;
|
||||||
|
|
||||||
|
@ -185,7 +187,7 @@ void Key_Event (int key, qboolean down);
|
||||||
void Char_Event (int key);
|
void Char_Event (int key);
|
||||||
qboolean Key_TextEntry (void);
|
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);
|
const char *Key_KeynumToString (int keynum);
|
||||||
int Key_StringToKeynum (const char *str);
|
int Key_StringToKeynum (const char *str);
|
||||||
int Key_NativeToQC(int code);
|
int Key_NativeToQC(int code);
|
||||||
|
|
|
@ -1451,6 +1451,7 @@ void M_FindKeysForCommand (const char *command, int *threekeys)
|
||||||
int j;
|
int j;
|
||||||
int l;
|
int l;
|
||||||
char *b;
|
char *b;
|
||||||
|
int bindmap = 0;
|
||||||
|
|
||||||
threekeys[0] = threekeys[1] = threekeys[2] = -1;
|
threekeys[0] = threekeys[1] = threekeys[2] = -1;
|
||||||
l = strlen(command);
|
l = strlen(command);
|
||||||
|
@ -1458,7 +1459,7 @@ void M_FindKeysForCommand (const char *command, int *threekeys)
|
||||||
|
|
||||||
for (j = 0; j < MAX_KEYS; j++)
|
for (j = 0; j < MAX_KEYS; j++)
|
||||||
{
|
{
|
||||||
b = keybindings[j];
|
b = keybindings[bindmap][j];
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
if (!strncmp (b, command, l) )
|
if (!strncmp (b, command, l) )
|
||||||
|
@ -1476,16 +1477,17 @@ void M_UnbindCommand (const char *command)
|
||||||
int j;
|
int j;
|
||||||
int l;
|
int l;
|
||||||
char *b;
|
char *b;
|
||||||
|
int bindmap = 0;
|
||||||
|
|
||||||
l = strlen(command);
|
l = strlen(command);
|
||||||
|
|
||||||
for (j = 0; j < MAX_KEYS; j++)
|
for (j = 0; j < MAX_KEYS; j++)
|
||||||
{
|
{
|
||||||
b = keybindings[j];
|
b = keybindings[bindmap][j];
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
if (!strncmp (b, command, l) )
|
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"
|
#include "quakedef.h"
|
||||||
|
|
||||||
#define STRINGTEMP_BUFFERS 16
|
//#define STRINGTEMP_BUFFERS 16
|
||||||
#define STRINGTEMP_LENGTH 1024
|
//#define STRINGTEMP_LENGTH 1024
|
||||||
static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
|
static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
|
||||||
static byte pr_string_tempindex = 0;
|
static byte pr_string_tempindex = 0;
|
||||||
|
|
||||||
|
@ -1826,6 +1826,137 @@ builtin_t pr_ssqcbuiltins[] =
|
||||||
};
|
};
|
||||||
int pr_ssqcnumbuiltins = sizeof(pr_ssqcbuiltins)/sizeof(pr_ssqcbuiltins[0]);
|
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_NoCSQC PF_Fixme
|
||||||
#define PF_CSQCToDo PF_Fixme
|
#define PF_CSQCToDo PF_Fixme
|
||||||
builtin_t pr_csqcbuiltins[] =
|
builtin_t pr_csqcbuiltins[] =
|
||||||
|
@ -1833,12 +1964,12 @@ builtin_t pr_csqcbuiltins[] =
|
||||||
PF_Fixme,
|
PF_Fixme,
|
||||||
PF_makevectors, // void(entity e) makevectors = #1
|
PF_makevectors, // void(entity e) makevectors = #1
|
||||||
PF_setorigin, // void(entity e, vector o) setorigin = #2
|
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_setsize, // void(entity e, vector min, vector max) setsize = #4
|
||||||
PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5
|
PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5
|
||||||
PF_break, // void() break = #6
|
PF_break, // void() break = #6
|
||||||
PF_random, // float() random = #7
|
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_normalize, // vector(vector v) normalize = #9
|
||||||
PF_error, // void(string e) error = #10
|
PF_error, // void(string e) error = #10
|
||||||
PF_objerror, // void(string e) objerror = #11
|
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_traceline, // float(vector v1, vector v2, float tryents) traceline = #16
|
||||||
PF_NoCSQC, // entity() checkclient (was: clientlist, apparently) = #17
|
PF_NoCSQC, // entity() checkclient (was: clientlist, apparently) = #17
|
||||||
PF_Find, // entity(entity start, .string fld, string match) find = #18
|
PF_Find, // entity(entity start, .string fld, string match) find = #18
|
||||||
PF_CSQCToDo,//PF_cl_precache_sound, // void(string s) precache_sound = #19
|
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_model, // void(string s) precache_model = #20
|
||||||
PF_NoCSQC, // void(entity client, string s)stuffcmd = #21
|
PF_NoCSQC, // void(entity client, string s)stuffcmd = #21
|
||||||
PF_findradius, // entity(vector org, float rad) findradius = #22
|
PF_findradius, // entity(vector org, float rad) findradius = #22
|
||||||
PF_NoCSQC, // void(string s) bprint = #23
|
PF_NoCSQC, // void(string s) bprint = #23
|
||||||
|
@ -1912,8 +2043,8 @@ builtin_t pr_csqcbuiltins[] =
|
||||||
|
|
||||||
PF_CSQCToDo,//PF_ambientsound,
|
PF_CSQCToDo,//PF_ambientsound,
|
||||||
|
|
||||||
PF_CSQCToDo,//PF_cl_precache_model,
|
PF_cl_precache_model,
|
||||||
PF_CSQCToDo,//PF_cl_precache_sound, // precache_sound2 is different only for qcc
|
PF_cl_precache_sound,
|
||||||
PF_precache_file,
|
PF_precache_file,
|
||||||
|
|
||||||
PF_NoCSQC,//PF_setspawnparms
|
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);
|
Host_Error ("%s has wrong version number (%i should be %i)", filename, qcvm->progs->version, PROG_VERSION);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_Printf("%s ABI set not supported", filename);
|
Con_Printf("%s ABI set not supported\n", filename);
|
||||||
qcvm->progs = NULL;
|
qcvm->progs = NULL;
|
||||||
return false;
|
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);
|
Host_Error ("%s system vars have been modified, progdefs.h is out of date", filename);
|
||||||
else
|
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;
|
qcvm->progs = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,7 +370,7 @@ void PR_ExecuteProgram (func_t fnum)
|
||||||
{
|
{
|
||||||
st++; /* next statement */
|
st++; /* next statement */
|
||||||
|
|
||||||
if (++profile > 10000000) //spike -- was 100000
|
if (++profile > 0x10000000) //spike -- was decimal 100000
|
||||||
{
|
{
|
||||||
qcvm->xstatement = st - qcvm->statements;
|
qcvm->xstatement = st - qcvm->statements;
|
||||||
PR_RunError("runaway loop error");
|
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];
|
size_t l[8];
|
||||||
int i;
|
int i;
|
||||||
size_t id;
|
size_t id;
|
||||||
|
|
||||||
for (i = 0; i < qcvm->argc; i++)
|
for (i = 0; i < qcvm->argc; i++)
|
||||||
{
|
{
|
||||||
s[i] = G_STRING(OFS_PARM0+i*3);
|
s[i] = G_STRING(OFS_PARM0+i*3);
|
||||||
|
@ -494,7 +495,6 @@ static void PF_strzone(void)
|
||||||
}
|
}
|
||||||
qcvm->knownzone[id>>3] |= 1u<<(id&7);
|
qcvm->knownzone[id>>3] |= 1u<<(id&7);
|
||||||
|
|
||||||
len = 0;
|
|
||||||
for (i = 0; i < qcvm->argc; i++)
|
for (i = 0; i < qcvm->argc; i++)
|
||||||
{
|
{
|
||||||
memcpy(buf, s[i], l[i]);
|
memcpy(buf, s[i], l[i]);
|
||||||
|
@ -506,6 +506,7 @@ static void PF_strunzone(void)
|
||||||
{
|
{
|
||||||
size_t id;
|
size_t id;
|
||||||
const char *foo = G_STRING(OFS_PARM0);
|
const char *foo = G_STRING(OFS_PARM0);
|
||||||
|
|
||||||
if (!G_INT(OFS_PARM0))
|
if (!G_INT(OFS_PARM0))
|
||||||
return; //don't bug out if they gave a null string
|
return; //don't bug out if they gave a null string
|
||||||
id = -1-G_INT(OFS_PARM0);
|
id = -1-G_INT(OFS_PARM0);
|
||||||
|
@ -2100,10 +2101,18 @@ static void PF_getsurfacepointattribute(void)
|
||||||
}
|
}
|
||||||
static void PF_sv_getlight(void)
|
static void PF_sv_getlight(void)
|
||||||
{
|
{
|
||||||
|
qmodel_t *om = cl.worldmodel;
|
||||||
float *point = G_VECTOR(OFS_PARM0);
|
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.
|
//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;
|
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
|
//server/client stuff
|
||||||
static void PF_checkcommand(void)
|
static void PF_checkcommand(void)
|
||||||
|
@ -2560,6 +2569,27 @@ static void PF_sv_pointsound(void)
|
||||||
float attenuation = G_FLOAT(OFS_PARM3);
|
float attenuation = G_FLOAT(OFS_PARM3);
|
||||||
SV_StartSound (qcvm->edicts, origin, 0, sample, volume, attenuation);
|
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
|
//file stuff
|
||||||
|
|
||||||
|
@ -2612,7 +2642,7 @@ static void PF_fopen(void)
|
||||||
const char *fallback;
|
const char *fallback;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
size_t i;
|
size_t i;
|
||||||
char name[MAX_OSPATH];
|
char name[MAX_OSPATH], *sl;
|
||||||
int filesize = 0;
|
int filesize = 0;
|
||||||
|
|
||||||
G_FLOAT(OFS_RETURN) = -1; //assume failure
|
G_FLOAT(OFS_RETURN) = -1; //assume failure
|
||||||
|
@ -2642,7 +2672,17 @@ static void PF_fopen(void)
|
||||||
break;
|
break;
|
||||||
case 2: //write
|
case 2: //write
|
||||||
q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, fname);
|
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");
|
file = fopen(name, "wb");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4587,6 +4627,33 @@ static void PF_cl_drawcharacter(void)
|
||||||
glEnd ();
|
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)
|
static void PF_cl_drawstring(void)
|
||||||
{
|
{
|
||||||
extern gltexture_t *char_texture;
|
extern gltexture_t *char_texture;
|
||||||
|
@ -4742,6 +4809,46 @@ static void PF_cl_drawfill(void)
|
||||||
glEnable (GL_TEXTURE_2D);
|
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)
|
static void PF_cl_cprint(void)
|
||||||
{
|
{
|
||||||
const char *str = PF_VarString(0);
|
const char *str = PF_VarString(0);
|
||||||
|
@ -4764,18 +4871,50 @@ static void PF_cl_stringtokeynum(void)
|
||||||
static void PF_cl_getkeybind(void)
|
static void PF_cl_getkeybind(void)
|
||||||
{
|
{
|
||||||
int keynum = Key_QCToNative(G_FLOAT(OFS_PARM0));
|
int keynum = Key_QCToNative(G_FLOAT(OFS_PARM0));
|
||||||
|
int bindmap = (qcvm->argc<=1)?0:G_FLOAT(OFS_PARM1);
|
||||||
char *s = PR_GetTempString();
|
char *s = PR_GetTempString();
|
||||||
if (keynum >= 0 && keynum < MAX_KEYS)
|
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||||
Q_strncpy(s, keybindings[keynum], STRINGTEMP_LENGTH);
|
bindmap = 0;
|
||||||
|
if (keynum >= 0 && keynum < MAX_KEYS && keybindings[bindmap][keynum])
|
||||||
|
Q_strncpy(s, keybindings[bindmap][keynum], STRINGTEMP_LENGTH);
|
||||||
else
|
else
|
||||||
Q_strncpy(s, "", STRINGTEMP_LENGTH);
|
Q_strncpy(s, "", STRINGTEMP_LENGTH);
|
||||||
G_INT(OFS_RETURN) = PR_SetEngineString(s);
|
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)
|
static void PF_cl_findkeysforcommand(void)
|
||||||
{
|
{
|
||||||
const char *command = G_STRING(OFS_PARM0);
|
const char *command = G_STRING(OFS_PARM0);
|
||||||
// float bindmap = G_FLOAT(OFS_PARM1);
|
int bindmap = G_FLOAT(OFS_PARM1);
|
||||||
int keys[5];
|
int keys[5];
|
||||||
char gah[64];
|
char gah[64];
|
||||||
char *s = PR_GetTempString();
|
char *s = PR_GetTempString();
|
||||||
|
@ -4783,10 +4922,12 @@ static void PF_cl_findkeysforcommand(void)
|
||||||
int j;
|
int j;
|
||||||
int l = strlen(command);
|
int l = strlen(command);
|
||||||
const char *b;
|
const char *b;
|
||||||
|
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||||
|
bindmap = 0;
|
||||||
|
|
||||||
for (j = 0; j < MAX_KEYS; j++)
|
for (j = 0; j < MAX_KEYS; j++)
|
||||||
{
|
{
|
||||||
b = keybindings[j];
|
b = keybindings[bindmap][j];
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
if (!strncmp (b, command, l) && (!b[l] || (!strchr(command, ' ') && (b[l] == ' ' || b[l] == '\t'))))
|
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)
|
static void PF_cl_findkeysforcommandex(void)
|
||||||
{
|
{
|
||||||
const char *command = G_STRING(OFS_PARM0);
|
const char *command = G_STRING(OFS_PARM0);
|
||||||
// float bindmap = G_FLOAT(OFS_PARM1);
|
int bindmap = G_FLOAT(OFS_PARM1);
|
||||||
int keys[16];
|
int keys[16];
|
||||||
char *s = PR_GetTempString();
|
char *s = PR_GetTempString();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int j;
|
int j;
|
||||||
int l = strlen(command);
|
int l = strlen(command);
|
||||||
const char *b;
|
const char *b;
|
||||||
|
if (bindmap < 0 || bindmap >= MAX_BINDMAPS)
|
||||||
|
bindmap = 0;
|
||||||
|
|
||||||
for (j = 0; j < MAX_KEYS; j++)
|
for (j = 0; j < MAX_KEYS; j++)
|
||||||
{
|
{
|
||||||
b = keybindings[j];
|
b = keybindings[bindmap][j];
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
if (!strncmp (b, command, l) && (!b[l] || (!strchr(command, ' ') && (b[l] == ' ' || b[l] == '\t'))))
|
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 *hotspot = (qcvm->argc<=2)?NULL:G_VECTOR(OFS_PARM2);
|
||||||
// float cursorscale = (qcvm->argc<=3)?1:G_FLOAT(OFS_PARM3);
|
// 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;
|
cl.csqc_cursorforced = absmode;
|
||||||
}
|
}
|
||||||
static void PF_cl_getcursormode(void)
|
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)
|
static void PF_cl_setsensitivity(void)
|
||||||
{
|
{
|
||||||
|
@ -5111,9 +5284,9 @@ static struct
|
||||||
{"stof", PF_stof, PF_stof, 81, "float(string)"}, //81
|
{"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"
|
{"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
|
"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.")},
|
{"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.")},
|
{"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)
|
{"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)
|
{"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)
|
// {"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)
|
// {"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)
|
// {"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_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_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_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)
|
// {"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)
|
// {"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)
|
// {"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)
|
{"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)
|
// {"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_???])
|
{"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_???])
|
{"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_???])
|
{"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_???)
|
{"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
|
{"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
|
{"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
|
{"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
|
{"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
|
{"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
|
{"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.")},
|
// {"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.")},
|
// {"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.")},
|
{"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.")},
|
{"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_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.")},
|
{"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")},
|
{"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.")},
|
{"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.")},
|
{"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, ...)"},
|
{"sprintf", PF_sprintf, PF_sprintf, 627, "string(string fmt, ...)"},
|
||||||
{"getsurfacenumtriangles",PF_getsurfacenumtriangles,PF_getsurfacenumtriangles,628,"float(entity e, float s)"},
|
{"getsurfacenumtriangles",PF_getsurfacenumtriangles,PF_getsurfacenumtriangles,628,"float(entity e, float s)"},
|
||||||
{"getsurfacetriangle",PF_getsurfacetriangle,PF_getsurfacetriangle,629,"vector(entity e, float s, float n)"},
|
{"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, ...)"},
|
// {"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);
|
char *PR_GetTempString (void);
|
||||||
int PR_MakeTempString (const char *val);
|
int PR_MakeTempString (const char *val);
|
||||||
char *PF_VarString (int first);
|
char *PF_VarString (int first);
|
||||||
#define STRINGTEMP_BUFFERS 16
|
#define STRINGTEMP_BUFFERS 1024
|
||||||
#define STRINGTEMP_LENGTH 1024
|
#define STRINGTEMP_LENGTH 1024
|
||||||
void PF_Fixme(void); //the 'unimplemented' builtin. woot.
|
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.
|
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);
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
PR_SwitchQCVM(&cl.qcvm);
|
PR_SwitchQCVM(&cl.qcvm);
|
||||||
|
pr_global_struct->frametime = host_frametime;
|
||||||
if (qcvm->extglobals.cltime)
|
if (qcvm->extglobals.cltime)
|
||||||
*qcvm->extglobals.cltime = realtime;
|
*qcvm->extglobals.cltime = realtime;
|
||||||
if (qcvm->extglobals.player_localentnum)
|
if (qcvm->extglobals.player_localentnum)
|
||||||
|
|
|
@ -205,6 +205,7 @@ void S_Init (void)
|
||||||
Con_Printf("\nSound Initialization\n");
|
Con_Printf("\nSound Initialization\n");
|
||||||
|
|
||||||
Cmd_AddCommand("play", S_Play);
|
Cmd_AddCommand("play", S_Play);
|
||||||
|
Cmd_AddCommand("play2", S_Play); //Spike -- a version with attenuation 0.
|
||||||
Cmd_AddCommand("playvol", S_PlayVol);
|
Cmd_AddCommand("playvol", S_PlayVol);
|
||||||
Cmd_AddCommand("stopsound", S_StopAllSoundsC);
|
Cmd_AddCommand("stopsound", S_StopAllSoundsC);
|
||||||
Cmd_AddCommand("soundlist", S_SoundList);
|
Cmd_AddCommand("soundlist", S_SoundList);
|
||||||
|
@ -1000,6 +1001,7 @@ static void S_Play (void)
|
||||||
int i;
|
int i;
|
||||||
char name[256];
|
char name[256];
|
||||||
sfx_t *sfx;
|
sfx_t *sfx;
|
||||||
|
float attenuation = !strcmp(Cmd_Argv(0), "play2")?0:1.0;
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
while (i < Cmd_Argc())
|
while (i < Cmd_Argc())
|
||||||
|
@ -1010,7 +1012,7 @@ static void S_Play (void)
|
||||||
q_strlcat(name, ".wav", sizeof(name));
|
q_strlcat(name, ".wav", sizeof(name));
|
||||||
}
|
}
|
||||||
sfx = S_PrecacheSound(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++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,6 +174,8 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
||||||
// Con_Printf ("loading %s\n",namebuffer);
|
// Con_Printf ("loading %s\n",namebuffer);
|
||||||
|
|
||||||
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf), NULL);
|
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf), NULL);
|
||||||
|
if (!data)
|
||||||
|
data = COM_LoadStackFile(s->name, stackbuf, sizeof(stackbuf), NULL);
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3104,6 +3104,8 @@ void SV_SpawnServer (const char *server)
|
||||||
|
|
||||||
sv.active = true;
|
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
|
// all setup is completed, any further precache statements are errors
|
||||||
sv.state = ss_active;
|
sv.state = ss_active;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue