while not 100% complete (sv is still referred to as well as r_skyname), the

progs engine no longer refers to any global vars. This alows for multiple progs
being loaded (NOTE: NOT multiple mods, but (eg) for various protocol
extensions) and, once the last couple of issues are taken care of, CSQC.
This commit is contained in:
Bill Currie 2000-12-31 07:43:09 +00:00
parent 76a11bd74a
commit b6c832d900
17 changed files with 1106 additions and 1200 deletions

View file

@ -63,83 +63,69 @@ typedef struct edict_s
} edict_t; } edict_t;
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) #define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
//============================================================================ struct progs_s;
extern dprograms_t *progs;
extern dfunction_t *pr_functions;
extern char *pr_strings;
extern ddef_t *pr_globaldefs;
extern ddef_t *pr_fielddefs;
extern dstatement_t *pr_statements;
extern globalvars_t *pr_global_struct;
extern float *pr_globals; // same as pr_global_struct
extern int pr_edict_size; // in bytes
extern int pr_edictareasize; // LordHavoc: for bounds checking
//============================================================================ //============================================================================
void PR_Init (void); void PR_Init (void);
void PR_ExecuteProgram (func_t fnum); void PR_ExecuteProgram (struct progs_s *pr, func_t fnum);
void PR_LoadProgs (void); void PR_LoadProgs (struct progs_s *pr);
void PR_Profile_f (void); void PR_Profile_f (void);
edict_t *ED_Alloc (void); edict_t *ED_Alloc (struct progs_s *pr);
void ED_Free (edict_t *ed); void ED_Free (struct progs_s *pr, edict_t *ed);
char *ED_NewString (char *string); char *ED_NewString (struct progs_s *pr, char *string);
// returns a copy of the string allocated from the server's string heap // returns a copy of the string allocated from the server's string heap
void ED_Print (edict_t *ed); void ED_Print (struct progs_s *pr, edict_t *ed);
void ED_Write (QFile *f, edict_t *ed); void ED_Write (struct progs_s *pr, QFile *f, edict_t *ed);
char *ED_ParseEdict (char *data, edict_t *ent); char *ED_ParseEdict (struct progs_s *pr, char *data, edict_t *ent);
void ED_WriteGlobals (QFile *f); void ED_WriteGlobals (struct progs_s *pr, QFile *f);
void ED_ParseGlobals (char *data); void ED_ParseGlobals (struct progs_s *pr, char *data);
void ED_LoadFromFile (char *data); void ED_LoadFromFile (struct progs_s *pr, char *data);
ddef_t *ED_FindField (char *name); ddef_t *ED_FindField (struct progs_s *pr, char *name);
dfunction_t *ED_FindFunction (struct progs_s *pr, char *name);
//define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size))
//define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size)
edict_t *EDICT_NUM(int n); //define EDICT_NUM(p,n) ((edict_t *)(sv.edicts+ (n)*(p)->pr_edict_size))
int NUM_FOR_EDICT(edict_t *e); //define NUM_FOR_EDICT(p,e) (((byte *)(e) - sv.edicts)/(p)->pr_edict_size)
#define NEXT_EDICT(e) ((edict_t *)( (byte *)e + pr_edict_size)) edict_t *EDICT_NUM(struct progs_s *pr, int n);
int NUM_FOR_EDICT(struct progs_s *pr, edict_t *e);
#define NEXT_EDICT(p,e) ((edict_t *)( (byte *)e + (p)->pr_edict_size))
#define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts) #define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts)
#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e)) #define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e))
//============================================================================ //============================================================================
#define G_FLOAT(o) (pr_globals[o]) #define G_FLOAT(p,o) ((p)->pr_globals[o])
#define G_INT(o) (*(int *)&pr_globals[o]) #define G_INT(p,o) (*(int *)&(p)->pr_globals[o])
#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o])) #define G_EDICT(p,o) ((edict_t *)((byte *)sv.edicts+ *(int *)&(p)->pr_globals[o]))
#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o)) #define G_EDICTNUM(p,o) NUM_FOR_EDICT(p,G_EDICT(p, o))
#define G_VECTOR(o) (&pr_globals[o]) #define G_VECTOR(p,o) (&(p)->pr_globals[o])
#define G_STRING(o) (PR_GetString(*(string_t *)&pr_globals[o])) #define G_STRING(p,o) (PR_GetString(pr,*(string_t *)&(p)->pr_globals[o]))
#define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) #define G_FUNCTION(p,o) (*(func_t *)&(p)->pr_globals[o])
#define E_FLOAT(e,o) (((float*)&e->v)[o]) #define E_FLOAT(e,o) (((float*)&e->v)[o])
#define E_INT(e,o) (*(int *)&((float*)&e->v)[o]) #define E_INT(e,o) (*(int *)&((float*)&e->v)[o])
#define E_VECTOR(e,o) (&((float*)&e->v)[o]) #define E_VECTOR(e,o) (&((float*)&e->v)[o])
#define E_STRING(e,o) (PR_GetString(*(string_t *)&((float*)&e->v)[o])) #define E_STRING(e,o) (PR_GetString(pr,*(string_t *)&((float*)&e->v)[o]))
extern int type_size[8]; extern int type_size[8];
typedef void (*builtin_t) (void); typedef void (*builtin_t) (struct progs_s *pr);
extern builtin_t *pr_builtins; extern builtin_t *pr_builtins;
extern int pr_numbuiltins; extern int pr_numbuiltins;
extern int pr_argc; int FindFieldOffset (struct progs_s *pr, char *field);
extern qboolean pr_trace;
extern dfunction_t *pr_xfunction;
extern int pr_xstatement;
extern func_t EndFrame; // 2000-01-02 EndFrame function by Maddes/FrikaC extern func_t EndFrame; // 2000-01-02 EndFrame function by Maddes/FrikaC
@ -147,22 +133,58 @@ extern func_t SpectatorConnect;
extern func_t SpectatorThink; extern func_t SpectatorThink;
extern func_t SpectatorDisconnect; extern func_t SpectatorDisconnect;
void PR_RunError (char *error, ...) __attribute__((format(printf,1,2))); void PR_RunError (struct progs_s *pr, char *error, ...) __attribute__((format(printf,2,3)));
void ED_PrintEdicts (void); void ED_PrintEdicts (struct progs_s *pr);
void ED_PrintNum (int ent); void ED_PrintNum (struct progs_s *pr, int ent);
eval_t *GetEdictFieldValue(edict_t *ed, char *field); eval_t *GetEdictFieldValue(struct progs_s *pr, edict_t *ed, char *field);
// //
// PR STrings stuff // PR STrings stuff
// //
#define MAX_PRSTR 1024 #define MAX_PRSTR 1024
extern char *pr_strtbl[MAX_PRSTR]; char *PR_GetString(struct progs_s *pr, int num);
extern int num_prstr; int PR_SetString(struct progs_s *pr, char *s);
char *PR_GetString(int num); //============================================================================
int PR_SetString(char *s);
#define MAX_STACK_DEPTH 32
#define LOCALSTACK_SIZE 2048
typedef struct {
int s;
dfunction_t *f;
} prstack_t;
typedef struct progs_s {
dprograms_t *progs;
dfunction_t *pr_functions;
char *pr_strings;
ddef_t *pr_globaldefs;
ddef_t *pr_fielddefs;
dstatement_t *pr_statements;
globalvars_t *pr_global_struct;
float *pr_globals; // same as pr_global_struct
int pr_edict_size; // in bytes
int pr_edictareasize; // LordHavoc: for bounds checking
int pr_argc;
qboolean pr_trace;
dfunction_t *pr_xfunction;
int pr_xstatement;
char *pr_strtbl[MAX_PRSTR];
int num_prstr;
prstack_t pr_stack[MAX_STACK_DEPTH];
int pr_depth;
int localstack[LOCALSTACK_SIZE];
int localstack_used;
} progs_t;
#endif // _PROGS_H #endif // _PROGS_H

View file

@ -397,6 +397,8 @@ extern QFile *sv_fraglogfile;
extern double sv_frametime; extern double sv_frametime;
extern progs_t sv_progs;
//=========================================================== //===========================================================
// FIXME: declare exported functions in their own relevant .h // FIXME: declare exported functions in their own relevant .h
@ -423,7 +425,8 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink);
void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg); void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg);
void SV_MoveToGoal (void); struct progs_s;
void SV_MoveToGoal (struct progs_s *pr);
void SV_SaveSpawnparms (void); void SV_SaveSpawnparms (void);

View file

@ -69,7 +69,7 @@ endif
server_SOURCES= pr_cmds.c pr_edict.c pr_exec.c pr_offs.c sv_ccmds.c sv_cvar.c \ server_SOURCES= pr_cmds.c pr_edict.c pr_exec.c pr_offs.c sv_ccmds.c sv_cvar.c \
sv_ents.c sv_init.c sv_main.c sv_misc.c sv_model.c \ sv_ents.c sv_init.c sv_main.c sv_misc.c sv_model.c \
sv_move.c sv_nchan.c sv_phys.c sv_send.c sv_user.c \ sv_move.c sv_nchan.c sv_phys.c sv_progs.c sv_send.c sv_user.c \
ver_check.c world.c $(world_ASM) ver_check.c world.c $(world_ASM)
qf_server_SOURCES= $(common_SOURCES) $(server_SOURCES) qf_server_SOURCES= $(common_SOURCES) $(server_SOURCES)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -38,27 +38,6 @@
#include "server.h" #include "server.h"
#include "sys.h" #include "sys.h"
typedef struct {
int s;
dfunction_t *f;
} prstack_t;
#define MAX_STACK_DEPTH 32
prstack_t pr_stack[MAX_STACK_DEPTH];
int pr_depth;
#define LOCALSTACK_SIZE 2048
int localstack[LOCALSTACK_SIZE];
int localstack_used;
qboolean pr_trace;
dfunction_t *pr_xfunction;
int pr_xstatement;
int pr_argc;
char *pr_opnames[] = { char *pr_opnames[] = {
"DONE", "DONE",
@ -157,7 +136,7 @@ char *PR_GlobalStringNoContents (int ofs);
PR_PrintStatement PR_PrintStatement
*/ */
void void
PR_PrintStatement (dstatement_t *s) PR_PrintStatement (progs_t *pr, dstatement_t *s)
{ {
int i; int i;
@ -192,34 +171,34 @@ PR_PrintStatement (dstatement_t *s)
PR_StackTrace PR_StackTrace
*/ */
void void
PR_StackTrace (void) PR_StackTrace (progs_t *pr)
{ {
dfunction_t *f; dfunction_t *f;
int i; int i;
if (pr_depth == 0) { if (pr->pr_depth == 0) {
Con_Printf ("<NO STACK>\n"); Con_Printf ("<NO STACK>\n");
return; return;
} }
pr_stack[pr_depth].f = pr_xfunction; pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
for (i = pr_depth; i >= 0; i--) { for (i = pr->pr_depth; i >= 0; i--) {
f = pr_stack[i].f; f = pr->pr_stack[i].f;
if (!f) { if (!f) {
Con_Printf ("<NO FUNCTION>\n"); Con_Printf ("<NO FUNCTION>\n");
} else } else
Con_Printf ("%12s : %s\n", PR_GetString (f->s_file), Con_Printf ("%12s : %s\n", PR_GetString (pr, f->s_file),
PR_GetString (f->s_name)); PR_GetString (pr, f->s_name));
} }
} }
/* /*
PR_Profile_f PR_Profile
*/ */
void void
PR_Profile_f (void) PR_Profile (progs_t *pr)
{ {
dfunction_t *f, *best; dfunction_t *f, *best;
int max; int max;
@ -230,8 +209,8 @@ PR_Profile_f (void)
do { do {
max = 0; max = 0;
best = NULL; best = NULL;
for (i = 0; i < progs->numfunctions; i++) { for (i = 0; i < pr->progs->numfunctions; i++) {
f = &pr_functions[i]; f = &pr->pr_functions[i];
if (f->profile > max) { if (f->profile > max) {
max = f->profile; max = f->profile;
best = f; best = f;
@ -240,13 +219,18 @@ PR_Profile_f (void)
if (best) { if (best) {
if (num < 10) if (num < 10)
Con_Printf ("%7i %s\n", best->profile, Con_Printf ("%7i %s\n", best->profile,
PR_GetString (best->s_name)); PR_GetString (pr, best->s_name));
num++; num++;
best->profile = 0; best->profile = 0;
} }
} while (best); } while (best);
} }
void
PR_Profile_f (void)
{
}
/* /*
PR_RunError PR_RunError
@ -254,7 +238,7 @@ PR_Profile_f (void)
Aborts the currently executing function Aborts the currently executing function
*/ */
void void
PR_RunError (char *error, ...) PR_RunError (progs_t *pr, char *error, ...)
{ {
va_list argptr; va_list argptr;
char string[1024]; char string[1024];
@ -263,11 +247,11 @@ PR_RunError (char *error, ...)
vsnprintf (string, sizeof (string), error, argptr); vsnprintf (string, sizeof (string), error, argptr);
va_end (argptr); va_end (argptr);
PR_PrintStatement (pr_statements + pr_xstatement); PR_PrintStatement (pr, pr->pr_statements + pr->pr_xstatement);
PR_StackTrace (); PR_StackTrace (pr);
Con_Printf ("%s\n", string); Con_Printf ("%s\n", string);
pr_depth = 0; // dump the stack so SV_Error can pr->pr_depth = 0; // dump the stack so SV_Error can
// shutdown functions // shutdown functions
SV_Error ("Program error"); SV_Error ("Program error");
@ -285,36 +269,36 @@ PR_RunError (char *error, ...)
Returns the new program statement counter Returns the new program statement counter
*/ */
int int
PR_EnterFunction (dfunction_t *f) PR_EnterFunction (progs_t *pr, dfunction_t *f)
{ {
int i, j, c, o; int i, j, c, o;
pr_stack[pr_depth].s = pr_xstatement; pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement;
pr_stack[pr_depth].f = pr_xfunction; pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
pr_depth++; pr->pr_depth++;
if (pr_depth >= MAX_STACK_DEPTH) if (pr->pr_depth >= MAX_STACK_DEPTH)
PR_RunError ("stack overflow"); PR_RunError (pr, "stack overflow");
// save off any locals that the new function steps on // save off any locals that the new function steps on
c = f->locals; c = f->locals;
if (localstack_used + c > LOCALSTACK_SIZE) if (pr->localstack_used + c > LOCALSTACK_SIZE)
PR_RunError ("PR_ExecuteProgram: locals stack overflow\n"); PR_RunError (pr, "PR_ExecuteProgram: locals stack overflow\n");
for (i = 0; i < c; i++) for (i = 0; i < c; i++)
localstack[localstack_used + i] = pr->localstack[pr->localstack_used + i] =
((int *) pr_globals)[f->parm_start + i]; ((int *) pr->pr_globals)[f->parm_start + i];
localstack_used += c; pr->localstack_used += c;
// copy parameters // copy parameters
o = f->parm_start; o = f->parm_start;
for (i = 0; i < f->numparms; i++) { for (i = 0; i < f->numparms; i++) {
for (j = 0; j < f->parm_size[i]; j++) { for (j = 0; j < f->parm_size[i]; j++) {
((int *) pr_globals)[o] = ((int *) pr_globals)[OFS_PARM0 + i * 3 + j]; ((int *) pr->pr_globals)[o] = ((int *) pr->pr_globals)[OFS_PARM0 + i * 3 + j];
o++; o++;
} }
} }
pr_xfunction = f; pr->pr_xfunction = f;
return f->first_statement - 1; // offset the s++ return f->first_statement - 1; // offset the s++
} }
@ -322,28 +306,28 @@ PR_EnterFunction (dfunction_t *f)
PR_LeaveFunction PR_LeaveFunction
*/ */
int int
PR_LeaveFunction (void) PR_LeaveFunction (progs_t *pr)
{ {
int i, c; int i, c;
if (pr_depth <= 0) if (pr->pr_depth <= 0)
SV_Error ("prog stack underflow"); SV_Error ("prog stack underflow");
// restore locals from the stack // restore locals from the stack
c = pr_xfunction->locals; c = pr->pr_xfunction->locals;
localstack_used -= c; pr->localstack_used -= c;
if (localstack_used < 0) if (pr->localstack_used < 0)
PR_RunError ("PR_ExecuteProgram: locals stack underflow\n"); PR_RunError (pr, "PR_ExecuteProgram: locals stack underflow\n");
for (i = 0; i < c; i++) for (i = 0; i < c; i++)
((int *) pr_globals)[pr_xfunction->parm_start + i] = ((int *) pr->pr_globals)[pr->pr_xfunction->parm_start + i] =
localstack[localstack_used + i]; pr->localstack[pr->localstack_used + i];
// up stack // up stack
pr_depth--; pr->pr_depth--;
pr_xfunction = pr_stack[pr_depth].f; pr->pr_xfunction = pr->pr_stack[pr->pr_depth].f;
return pr_stack[pr_depth].s; return pr->pr_stack[pr->pr_depth].s;
} }
@ -351,14 +335,14 @@ PR_LeaveFunction (void)
PR_ExecuteProgram PR_ExecuteProgram
*/ */
// LordHavoc: optimized // LordHavoc: optimized
#define OPA ((eval_t *)&pr_globals[(unsigned short) st->a]) #define OPA ((eval_t *)&pr->pr_globals[(unsigned short) st->a])
#define OPB ((eval_t *)&pr_globals[(unsigned short) st->b]) #define OPB ((eval_t *)&pr->pr_globals[(unsigned short) st->b])
#define OPC ((eval_t *)&pr_globals[(unsigned short) st->c]) #define OPC ((eval_t *)&pr->pr_globals[(unsigned short) st->c])
extern cvar_t *pr_boundscheck; extern cvar_t *pr_boundscheck;
void void
PR_ExecuteProgram (func_t fnum) PR_ExecuteProgram (progs_t *pr, func_t fnum)
{ {
dstatement_t *st; dstatement_t *st;
dfunction_t *f, *newf; dfunction_t *f, *newf;
@ -367,20 +351,20 @@ PR_ExecuteProgram (func_t fnum)
eval_t *ptr; eval_t *ptr;
int profile, startprofile; int profile, startprofile;
if (!fnum || fnum >= progs->numfunctions) { if (!fnum || fnum >= pr->progs->numfunctions) {
if (pr_global_struct->self) if (pr->pr_global_struct->self)
ED_Print (PROG_TO_EDICT (pr_global_struct->self)); ED_Print (pr, PROG_TO_EDICT (pr->pr_global_struct->self));
SV_Error ("PR_ExecuteProgram: NULL function"); SV_Error ("PR_ExecuteProgram: NULL function");
} }
f = &pr_functions[fnum]; f = &pr->pr_functions[fnum];
pr_trace = false; pr->pr_trace = false;
// make a stack frame // make a stack frame
exitdepth = pr_depth; exitdepth = pr->pr_depth;
st = &pr_statements[PR_EnterFunction (f)]; st = &pr->pr_statements[PR_EnterFunction (pr, f)];
startprofile = profile = 0; startprofile = profile = 0;
while (1) { while (1) {
@ -388,12 +372,12 @@ PR_ExecuteProgram (func_t fnum)
if (++profile > 1000000) // LordHavoc: increased runaway loop if (++profile > 1000000) // LordHavoc: increased runaway loop
// limit 10x // limit 10x
{ {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError ("runaway loop error"); PR_RunError (pr, "runaway loop error");
} }
if (pr_trace) if (pr->pr_trace)
PR_PrintStatement (st); PR_PrintStatement (pr, st);
switch (st->op) { switch (st->op) {
case OP_ADD_F: case OP_ADD_F:
@ -466,7 +450,7 @@ PR_ExecuteProgram (func_t fnum)
&& !OPA->vector[2]; && !OPA->vector[2];
break; break;
case OP_NOT_S: case OP_NOT_S:
OPC->_float = !OPA->string || !*PR_GetString (OPA->string); OPC->_float = !OPA->string || !*PR_GetString (pr, OPA->string);
break; break;
case OP_NOT_FNC: case OP_NOT_FNC:
OPC->_float = !OPA->function; OPC->_float = !OPA->function;
@ -484,8 +468,8 @@ PR_ExecuteProgram (func_t fnum)
break; break;
case OP_EQ_S: case OP_EQ_S:
OPC->_float = OPC->_float =
!strcmp (PR_GetString (OPA->string), !strcmp (PR_GetString (pr, OPA->string),
PR_GetString (OPB->string)); PR_GetString (pr, OPB->string));
break; break;
case OP_EQ_E: case OP_EQ_E:
OPC->_float = OPA->_int == OPB->_int; OPC->_float = OPA->_int == OPB->_int;
@ -503,8 +487,8 @@ PR_ExecuteProgram (func_t fnum)
break; break;
case OP_NE_S: case OP_NE_S:
OPC->_float = OPC->_float =
strcmp (PR_GetString (OPA->string), strcmp (PR_GetString (pr, OPA->string),
PR_GetString (OPB->string)); PR_GetString (pr, OPB->string));
break; break;
case OP_NE_E: case OP_NE_E:
OPC->_float = OPA->_int != OPB->_int; OPC->_float = OPA->_int != OPB->_int;
@ -533,18 +517,18 @@ PR_ExecuteProgram (func_t fnum)
case OP_STOREP_S: case OP_STOREP_S:
case OP_STOREP_FNC: // pointers case OP_STOREP_FNC: // pointers
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)) { && (OPB->_int < 0 || OPB->_int + 4 > pr->pr_edictareasize)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to write to an out of bounds edict\n"); (pr, "Progs attempted to write to an out of bounds edict\n");
return; return;
} }
if (pr_boundscheck->int_val && (OPB->_int % pr_edict_size < if (pr_boundscheck->int_val && (OPB->_int % pr->pr_edict_size <
((byte *) & sv.edicts->v - ((byte *) & sv.edicts->v -
(byte *) sv.edicts))) { (byte *) sv.edicts))) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to write to an engine edict field\n"); (pr, "Progs attempted to write to an engine edict field\n");
return; return;
} }
ptr = (eval_t *) ((byte *) sv.edicts + OPB->_int); ptr = (eval_t *) ((byte *) sv.edicts + OPB->_int);
@ -552,10 +536,10 @@ PR_ExecuteProgram (func_t fnum)
break; break;
case OP_STOREP_V: case OP_STOREP_V:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 12 > pr_edictareasize)) { && (OPB->_int < 0 || OPB->_int + 12 > pr->pr_edictareasize)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to write to an out of bounds edict\n"); (pr, "Progs attempted to write to an out of bounds edict\n");
return; return;
} }
ptr = (eval_t *) ((byte *) sv.edicts + OPB->_int); ptr = (eval_t *) ((byte *) sv.edicts + OPB->_int);
@ -565,23 +549,23 @@ PR_ExecuteProgram (func_t fnum)
break; break;
case OP_ADDRESS: case OP_ADDRESS:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr_edictareasize)) { && (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to address an out of bounds edict\n"); (pr, "Progs attempted to address an out of bounds edict\n");
return; return;
} }
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPA->edict == 0 && sv.state == ss_active)) { && (OPA->edict == 0 && sv.state == ss_active)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError ("assignment to world entity"); PR_RunError (pr, "assignment to world entity");
return; return;
} }
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= progs->entityfields)) { && (OPB->_int < 0 || OPB->_int >= pr->progs->entityfields)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to address an invalid field in an edict\n"); (pr, "Progs attempted to address an invalid field in an edict\n");
return; return;
} }
ed = PROG_TO_EDICT (OPA->edict); ed = PROG_TO_EDICT (OPA->edict);
@ -594,17 +578,17 @@ PR_ExecuteProgram (func_t fnum)
case OP_LOAD_S: case OP_LOAD_S:
case OP_LOAD_FNC: case OP_LOAD_FNC:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr_edictareasize)) { && (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an out of bounds edict number\n"); (pr, "Progs attempted to read an out of bounds edict number\n");
return; return;
} }
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= progs->entityfields)) { && (OPB->_int < 0 || OPB->_int >= pr->progs->entityfields)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an invalid field in an edict\n"); (pr, "Progs attempted to read an invalid field in an edict\n");
return; return;
} }
ed = PROG_TO_EDICT (OPA->edict); ed = PROG_TO_EDICT (OPA->edict);
@ -612,17 +596,17 @@ PR_ExecuteProgram (func_t fnum)
break; break;
case OP_LOAD_V: case OP_LOAD_V:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr_edictareasize)) { && (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an out of bounds edict number\n"); (pr, "Progs attempted to read an out of bounds edict number\n");
return; return;
} }
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 2 >= progs->entityfields)) { && (OPB->_int < 0 || OPB->_int + 2 >= pr->progs->entityfields)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an invalid field in an edict\n"); (pr, "Progs attempted to read an invalid field in an edict\n");
return; return;
} }
ed = PROG_TO_EDICT (OPA->edict); ed = PROG_TO_EDICT (OPA->edict);
@ -654,40 +638,40 @@ PR_ExecuteProgram (func_t fnum)
case OP_CALL6: case OP_CALL6:
case OP_CALL7: case OP_CALL7:
case OP_CALL8: case OP_CALL8:
pr_xfunction->profile += profile - startprofile; pr->pr_xfunction->profile += profile - startprofile;
startprofile = profile; startprofile = profile;
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
pr_argc = st->op - OP_CALL0; pr->pr_argc = st->op - OP_CALL0;
if (!OPA->function) if (!OPA->function)
PR_RunError ("NULL function"); PR_RunError (pr, "NULL function");
newf = &pr_functions[OPA->function]; newf = &pr->pr_functions[OPA->function];
if (newf->first_statement < 0) { // negative if (newf->first_statement < 0) { // negative
// statements are // statements are
// built in functions // built in functions
int i = -newf->first_statement; int i = -newf->first_statement;
if (i >= pr_numbuiltins) if (i >= pr_numbuiltins)
PR_RunError ("Bad builtin call number"); PR_RunError (pr, "Bad builtin call number");
pr_builtins[i] (); pr_builtins[i] (pr);
break; break;
} }
st = &pr_statements[PR_EnterFunction (newf)]; st = &pr->pr_statements[PR_EnterFunction (pr, newf)];
break; break;
case OP_DONE: case OP_DONE:
case OP_RETURN: case OP_RETURN:
pr_globals[OFS_RETURN] = pr_globals[(unsigned short) st->a]; pr->pr_globals[OFS_RETURN] = pr->pr_globals[(unsigned short) st->a];
pr_globals[OFS_RETURN + 1] = pr->pr_globals[OFS_RETURN + 1] =
pr_globals[(unsigned short) st->a + 1]; pr->pr_globals[(unsigned short) st->a + 1];
pr_globals[OFS_RETURN + 2] = pr->pr_globals[OFS_RETURN + 2] =
pr_globals[(unsigned short) st->a + 2]; pr->pr_globals[(unsigned short) st->a + 2];
st = &pr_statements[PR_LeaveFunction ()]; st = &pr->pr_statements[PR_LeaveFunction (pr)];
if (pr_depth == exitdepth) if (pr->pr_depth == exitdepth)
return; // all done return; // all done
break; break;
case OP_STATE: case OP_STATE:
ed = PROG_TO_EDICT (pr_global_struct->self); ed = PROG_TO_EDICT (pr->pr_global_struct->self);
ed->v.nextthink = pr_global_struct->time + 0.1; ed->v.nextthink = pr->pr_global_struct->time + 0.1;
ed->v.frame = OPA->_float; ed->v.frame = OPA->_float;
ed->v.think = OPB->function; ed->v.think = OPB->function;
break; break;
@ -847,18 +831,18 @@ PR_ExecuteProgram (func_t fnum)
break; break;
case OP_STOREP_I: case OP_STOREP_I:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)) { && (OPB->_int < 0 || OPB->_int + 4 > pr->pr_edictareasize)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to write to an out of bounds edict\n"); (pr, "Progs attempted to write to an out of bounds edict\n");
return; return;
} }
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int % pr_edict_size < && (OPB->_int % pr->pr_edict_size <
((byte *) & sv.edicts->v - (byte *) sv.edicts))) { ((byte *) & sv.edicts->v - (byte *) sv.edicts))) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to write to an engine edict field\n"); (pr, "Progs attempted to write to an engine edict field\n");
return; return;
} }
ptr = (eval_t *) ((byte *) sv.edicts + OPB->_int); ptr = (eval_t *) ((byte *) sv.edicts + OPB->_int);
@ -866,17 +850,17 @@ PR_ExecuteProgram (func_t fnum)
break; break;
case OP_LOAD_I: case OP_LOAD_I:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr_edictareasize)) { && (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an out of bounds edict number\n"); (pr, "Progs attempted to read an out of bounds edict number\n");
return; return;
} }
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= progs->entityfields)) { && (OPB->_int < 0 || OPB->_int >= pr->progs->entityfields)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an invalid field in an edict\n"); (pr, "Progs attempted to read an invalid field in an edict\n");
return; return;
} }
ed = PROG_TO_EDICT (OPA->edict); ed = PROG_TO_EDICT (OPA->edict);
@ -890,37 +874,37 @@ PR_ExecuteProgram (func_t fnum)
case OP_GSTOREP_S: case OP_GSTOREP_S:
case OP_GSTOREP_FNC: // pointers case OP_GSTOREP_FNC: // pointers
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= pr_globaldefs)) { && (OPB->_int < 0 || OPB->_int >= pr->pr_globaldefs)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to write to an invalid indexed global\n"); (pr, "Progs attempted to write to an invalid indexed global\n");
return; return;
} }
pr_globals[OPB->_int] = OPA->_float; pr->pr_globals[OPB->_int] = OPA->_float;
break; break;
case OP_GSTOREP_V: case OP_GSTOREP_V:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)) { && (OPB->_int < 0 || OPB->_int + 2 >= pr->pr_globaldefs)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to write to an invalid indexed global\n"); (pr, "Progs attempted to write to an invalid indexed global\n");
return; return;
} }
pr_globals[OPB->_int] = OPA->vector[0]; pr->pr_globals[OPB->_int] = OPA->vector[0];
pr_globals[OPB->_int + 1] = OPA->vector[1]; pr->pr_globals[OPB->_int + 1] = OPA->vector[1];
pr_globals[OPB->_int + 2] = OPA->vector[2]; pr->pr_globals[OPB->_int + 2] = OPA->vector[2];
break; break;
case OP_GADDRESS: case OP_GADDRESS:
i = OPA->_int + (int) OPB->_float; i = OPA->_int + (int) OPB->_float;
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (i < 0 || i >= pr_globaldefs)) { && (i < 0 || i >= pr->pr_globaldefs)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to address an out of bounds global\n"); (pr, "Progs attempted to address an out of bounds global\n");
return; return;
} }
OPC->_float = pr_globals[i]; OPC->_float = pr->pr_globals[i];
break; break;
case OP_GLOAD_I: case OP_GLOAD_I:
@ -930,33 +914,33 @@ PR_ExecuteProgram (func_t fnum)
case OP_GLOAD_S: case OP_GLOAD_S:
case OP_GLOAD_FNC: case OP_GLOAD_FNC:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPA->_int < 0 || OPA->_int >= pr_globaldefs)) { && (OPA->_int < 0 || OPA->_int >= pr->pr_globaldefs)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an invalid indexed global\n"); (pr, "Progs attempted to read an invalid indexed global\n");
return; return;
} }
OPC->_float = pr_globals[OPA->_int]; OPC->_float = pr->pr_globals[OPA->_int];
break; break;
case OP_GLOAD_V: case OP_GLOAD_V:
if (pr_boundscheck->int_val if (pr_boundscheck->int_val
&& (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)) { && (OPA->_int < 0 || OPA->_int + 2 >= pr->pr_globaldefs)) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs attempted to read an invalid indexed global\n"); (pr, "Progs attempted to read an invalid indexed global\n");
return; return;
} }
OPC->vector[0] = pr_globals[OPA->_int]; OPC->vector[0] = pr->pr_globals[OPA->_int];
OPC->vector[1] = pr_globals[OPA->_int + 1]; OPC->vector[1] = pr->pr_globals[OPA->_int + 1];
OPC->vector[2] = pr_globals[OPA->_int + 2]; OPC->vector[2] = pr->pr_globals[OPA->_int + 2];
break; break;
case OP_BOUNDCHECK: case OP_BOUNDCHECK:
if (OPA->_int < 0 || OPA->_int >= st->b) { if (OPA->_int < 0 || OPA->_int >= st->b) {
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError PR_RunError
("Progs boundcheck failed at line number %d, value is < 0 or >= %d\n", (pr, "Progs boundcheck failed at line number %d, value is < 0 or >= %d\n",
st->b, st->c); st->b, st->c);
return; return;
} }
@ -964,41 +948,39 @@ PR_ExecuteProgram (func_t fnum)
*/ */
default: default:
pr_xstatement = st - pr_statements; pr->pr_xstatement = st - pr->pr_statements;
PR_RunError ("Bad opcode %i", st->op); PR_RunError (pr, "Bad opcode %i", st->op);
} }
} }
} }
char *pr_strtbl[MAX_PRSTR];
int num_prstr;
char * char *
PR_GetString (int num) PR_GetString (progs_t *pr, int num)
{ {
if (num < 0) { if (num < 0) {
// Con_DPrintf("GET:%d == %s\n", num, pr_strtbl[-num]); // Con_DPrintf("GET:%d == %s\n", num, pr->pr_strtbl[-num]);
return pr_strtbl[-num]; return pr->pr_strtbl[-num];
} }
return pr_strings + num; return pr->pr_strings + num;
} }
int int
PR_SetString (char *s) PR_SetString (progs_t *pr, char *s)
{ {
int i; int i;
if (s - pr_strings < 0) { if (s - pr->pr_strings < 0) {
for (i = 0; i <= num_prstr; i++) for (i = 0; i <= pr->num_prstr; i++)
if (pr_strtbl[i] == s) if (pr->pr_strtbl[i] == s)
break; break;
if (i < num_prstr) if (i < pr->num_prstr)
return -i; return -i;
if (num_prstr == MAX_PRSTR - 1) if (pr->num_prstr == MAX_PRSTR - 1)
Sys_Error ("MAX_PRSTR"); Sys_Error ("MAX_PRSTR");
num_prstr++; pr->num_prstr++;
pr_strtbl[num_prstr] = s; pr->pr_strtbl[pr->num_prstr] = s;
// Con_DPrintf("SET:%d == %s\n", -num_prstr, s); // Con_DPrintf("SET:%d == %s\n", -pr->num_prstr, s);
return -num_prstr; return -pr->num_prstr;
} }
return (int) (s - pr_strings); return (int) (s - pr->pr_strings);
} }

View file

@ -32,14 +32,12 @@
#include "progs.h" #include "progs.h"
int eval_alpha, eval_scale, eval_glowsize, eval_glowcolor, eval_colormod;
int int
FindFieldOffset (char *field) FindFieldOffset (progs_t *pr, char *field)
{ {
ddef_t *d; ddef_t *d;
d = ED_FindField (field); d = ED_FindField (pr, field);
if (!d) if (!d)
return 0; return 0;
@ -54,13 +52,3 @@ GETEDICTFIELDVALUE (edict_t *ed, int fieldoffset)
return (eval_t *) ((char *) &ed->v + fieldoffset); return (eval_t *) ((char *) &ed->v + fieldoffset);
} }
void
FindEdictFieldOffsets (void)
{
eval_alpha = FindFieldOffset ("alpha");
eval_scale = FindFieldOffset ("scale");
eval_glowsize = FindFieldOffset ("glow_size");
eval_glowcolor = FindFieldOffset ("glow_color");
eval_colormod = FindFieldOffset ("colormod");
};

View file

@ -419,7 +419,7 @@ SV_Status_f (void)
Con_Printf ("net address : %s\n", NET_AdrToString (net_local_adr)); Con_Printf ("net address : %s\n", NET_AdrToString (net_local_adr));
Con_Printf ("cpu utilization : %3i%%\n", (int) cpu); Con_Printf ("cpu utilization : %3i%%\n", (int) cpu);
Con_Printf ("avg response time: %i ms\n", (int) avg); Con_Printf ("avg response time: %i ms\n", (int) avg);
Con_Printf ("packets/frame : %5.2f (%d)\n", pak, num_prstr); Con_Printf ("packets/frame : %5.2f (%d)\n", pak, sv_progs.num_prstr);
// min fps lat drp // min fps lat drp
if (sv_redirected != RD_NONE) { if (sv_redirected != RD_NONE) {

View file

@ -373,7 +373,7 @@ SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
if (newnum < oldnum) { // this is a new entity, send it from if (newnum < oldnum) { // this is a new entity, send it from
// the baseline // the baseline
ent = EDICT_NUM (newnum); ent = EDICT_NUM (&sv_progs, newnum);
//Con_Printf ("baseline %i\n", newnum); //Con_Printf ("baseline %i\n", newnum);
SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true, SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true,
client->stdver); client->stdver);
@ -550,10 +550,10 @@ SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
numnails = 0; numnails = 0;
for (e = MAX_CLIENTS + 1, ent = EDICT_NUM (e); e < sv.num_edicts; for (e = MAX_CLIENTS + 1, ent = EDICT_NUM (&sv_progs, e); e < sv.num_edicts;
e++, ent = NEXT_EDICT (ent)) { e++, ent = NEXT_EDICT (&sv_progs, ent)) {
// ignore ents without visible models // ignore ents without visible models
if (!ent->v.modelindex || !*PR_GetString (ent->v.model)) if (!ent->v.modelindex || !*PR_GetString (&sv_progs, ent->v.model))
continue; continue;
// ignore if not touching a PV leaf // ignore if not touching a PV leaf

View file

@ -110,7 +110,7 @@ SV_CreateBaseline (void)
int entnum; int entnum;
for (entnum = 0; entnum < sv.num_edicts; entnum++) { for (entnum = 0; entnum < sv.num_edicts; entnum++) {
svent = EDICT_NUM (entnum); svent = EDICT_NUM (&sv_progs, entnum);
if (svent->free) if (svent->free)
continue; continue;
// create baselines for all player slots, // create baselines for all player slots,
@ -131,7 +131,7 @@ SV_CreateBaseline (void)
} else { } else {
svent->baseline.colormap = 0; svent->baseline.colormap = 0;
svent->baseline.modelindex = svent->baseline.modelindex =
SV_ModelIndex (PR_GetString (svent->v.model)); SV_ModelIndex (PR_GetString (&sv_progs, svent->v.model));
} }
// LordHavoc: setup baseline to include new effects // LordHavoc: setup baseline to include new effects
svent->baseline.alpha = 255; svent->baseline.alpha = 255;
@ -182,7 +182,7 @@ SV_SaveSpawnparms (void)
return; // no progs loaded yet return; // no progs loaded yet
// serverflags is the only game related thing maintained // serverflags is the only game related thing maintained
svs.serverflags = pr_global_struct->serverflags; svs.serverflags = sv_progs.pr_global_struct->serverflags;
for (i = 0, host_client = svs.clients; i < MAX_CLIENTS; i++, host_client++) { for (i = 0, host_client = svs.clients; i < MAX_CLIENTS; i++, host_client++) {
if (host_client->state != cs_spawned) if (host_client->state != cs_spawned)
@ -192,10 +192,10 @@ SV_SaveSpawnparms (void)
host_client->state = cs_connected; host_client->state = cs_connected;
// call the progs to get default spawn parms for the new client // call the progs to get default spawn parms for the new client
pr_global_struct->self = EDICT_TO_PROG (host_client->edict); sv_progs.pr_global_struct->self = EDICT_TO_PROG (host_client->edict);
PR_ExecuteProgram (pr_global_struct->SetChangeParms); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->SetChangeParms);
for (j = 0; j < NUM_SPAWN_PARMS; j++) for (j = 0; j < NUM_SPAWN_PARMS; j++)
host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j]; host_client->spawn_parms[j] = (&sv_progs.pr_global_struct->parm1)[j];
} }
} }
@ -344,15 +344,15 @@ SV_SpawnServer (char *server)
// load progs to get entity field count // load progs to get entity field count
// which determines how big each edict is // which determines how big each edict is
PR_LoadProgs (); PR_LoadProgs (&sv_progs);
// allocate edicts // allocate edicts
sv.edicts = Hunk_AllocName (MAX_EDICTS * pr_edict_size, "edicts"); sv.edicts = Hunk_AllocName (MAX_EDICTS * sv_progs.pr_edict_size, "edicts");
// leave slots at start for clients only // leave slots at start for clients only
sv.num_edicts = MAX_CLIENTS + 1; sv.num_edicts = MAX_CLIENTS + 1;
for (i = 0; i < MAX_CLIENTS; i++) { for (i = 0; i < MAX_CLIENTS; i++) {
ent = EDICT_NUM (i + 1); ent = EDICT_NUM (&sv_progs, i + 1);
svs.clients[i].edict = ent; svs.clients[i].edict = ent;
//ZOID - make sure we update frags right //ZOID - make sure we update frags right
svs.clients[i].old_frags = 0; svs.clients[i].old_frags = 0;
@ -370,9 +370,9 @@ SV_SpawnServer (char *server)
// //
SV_ClearWorld (); SV_ClearWorld ();
sv.sound_precache[0] = pr_strings; sv.sound_precache[0] = sv_progs.pr_strings;
sv.model_precache[0] = pr_strings; sv.model_precache[0] = sv_progs.pr_strings;
sv.model_precache[1] = sv.modelname; sv.model_precache[1] = sv.modelname;
sv.models[1] = sv.worldmodel; sv.models[1] = sv.worldmodel;
for (i = 1; i < sv.worldmodel->numsubmodels; i++) { for (i = 1; i < sv.worldmodel->numsubmodels; i++) {
@ -392,22 +392,22 @@ SV_SpawnServer (char *server)
// map initialization // map initialization
sv.state = ss_loading; sv.state = ss_loading;
ent = EDICT_NUM (0); ent = EDICT_NUM (&sv_progs, 0);
ent->free = false; ent->free = false;
ent->v.model = PR_SetString (sv.worldmodel->name); ent->v.model = PR_SetString (&sv_progs, sv.worldmodel->name);
ent->v.modelindex = 1; // world model ent->v.modelindex = 1; // world model
ent->v.solid = SOLID_BSP; ent->v.solid = SOLID_BSP;
ent->v.movetype = MOVETYPE_PUSH; ent->v.movetype = MOVETYPE_PUSH;
pr_global_struct->mapname = PR_SetString (sv.name); sv_progs.pr_global_struct->mapname = PR_SetString (&sv_progs, sv.name);
// serverflags are for cross level information (sigils) // serverflags are for cross level information (sigils)
pr_global_struct->serverflags = svs.serverflags; sv_progs.pr_global_struct->serverflags = svs.serverflags;
// run the frame start qc function to let progs check cvars // run the frame start qc function to let progs check cvars
SV_ProgStartFrame (); SV_ProgStartFrame ();
// load and spawn all other entities // load and spawn all other entities
ED_LoadFromFile (sv.worldmodel->entities); ED_LoadFromFile (&sv_progs, sv.worldmodel->entities);
// look up some model indexes for specialized message compression // look up some model indexes for specialized message compression
SV_FindModelNumbers (); SV_FindModelNumbers ();

View file

@ -250,13 +250,13 @@ SV_DropClient (client_t *drop)
if (!drop->spectator) { if (!drop->spectator) {
// call the prog function for removing a client // call the prog function for removing a client
// this will set the body to a dead frame, among other things // this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG (drop->edict); sv_progs.pr_global_struct->self = EDICT_TO_PROG (drop->edict);
PR_ExecuteProgram (pr_global_struct->ClientDisconnect); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->ClientDisconnect);
} else if (SpectatorDisconnect) { } else if (SpectatorDisconnect) {
// call the prog function for removing a client // call the prog function for removing a client
// this will set the body to a dead frame, among other things // this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG (drop->edict); sv_progs.pr_global_struct->self = EDICT_TO_PROG (drop->edict);
PR_ExecuteProgram (SpectatorDisconnect); PR_ExecuteProgram (&sv_progs, SpectatorDisconnect);
} }
} }
if (drop->spectator) if (drop->spectator)
@ -823,7 +823,7 @@ SVC_DirectConnect (void)
// spectator mode can ONLY be set at join time // spectator mode can ONLY be set at join time
newcl->spectator = spectator; newcl->spectator = spectator;
ent = EDICT_NUM (edictnum); ent = EDICT_NUM (&sv_progs, edictnum);
newcl->edict = ent; newcl->edict = ent;
// parse some info from the info strings // parse some info from the info strings
@ -836,9 +836,9 @@ SVC_DirectConnect (void)
newcl->lockedtill = 0; newcl->lockedtill = 0;
// call the progs to get default spawn parms for the new client // call the progs to get default spawn parms for the new client
PR_ExecuteProgram (pr_global_struct->SetNewParms); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->SetNewParms);
for (i = 0; i < NUM_SPAWN_PARMS; i++) for (i = 0; i < NUM_SPAWN_PARMS; i++)
newcl->spawn_parms[i] = (&pr_global_struct->parm1)[i]; newcl->spawn_parms[i] = (&sv_progs.pr_global_struct->parm1)[i];
if (newcl->spectator) if (newcl->spectator)
Con_Printf ("Spectator %s connected\n", newcl->name); Con_Printf ("Spectator %s connected\n", newcl->name);

View file

@ -397,17 +397,17 @@ SV_MoveToGoal
====================== ======================
*/ */
void void
SV_MoveToGoal (void) SV_MoveToGoal (progs_t *pr)
{ {
edict_t *ent, *goal; edict_t *ent, *goal;
float dist; float dist;
ent = PROG_TO_EDICT (pr_global_struct->self); ent = PROG_TO_EDICT (sv_progs.pr_global_struct->self);
goal = PROG_TO_EDICT (ent->v.goalentity); goal = PROG_TO_EDICT (ent->v.goalentity);
dist = G_FLOAT (OFS_PARM0); dist = G_FLOAT (&sv_progs, OFS_PARM0);
if (!((int) ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) { if (!((int) ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
G_FLOAT (OFS_RETURN) = 0; G_FLOAT (&sv_progs, OFS_RETURN) = 0;
return; return;
} }
// if the next step hits the enemy, return immediately // if the next step hits the enemy, return immediately

View file

@ -84,8 +84,8 @@ SV_CheckAllEnts (void)
edict_t *check; edict_t *check;
// see if any solid entities are inside the final position // see if any solid entities are inside the final position
check = NEXT_EDICT (sv.edicts); check = NEXT_EDICT (&sv_progs, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_progs, check)) {
if (check->free) if (check->free)
continue; continue;
if (check->v.movetype == MOVETYPE_PUSH if (check->v.movetype == MOVETYPE_PUSH
@ -116,12 +116,12 @@ SV_CheckVelocity (edict_t *ent)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (IS_NAN (ent->v.velocity[i])) { if (IS_NAN (ent->v.velocity[i])) {
Con_Printf ("Got a NaN velocity on %s\n", Con_Printf ("Got a NaN velocity on %s\n",
PR_GetString (ent->v.classname)); PR_GetString (&sv_progs, ent->v.classname));
ent->v.velocity[i] = 0; ent->v.velocity[i] = 0;
} }
if (IS_NAN (ent->v.origin[i])) { if (IS_NAN (ent->v.origin[i])) {
Con_Printf ("Got a NaN origin on %s\n", Con_Printf ("Got a NaN origin on %s\n",
PR_GetString (ent->v.classname)); PR_GetString (&sv_progs, ent->v.classname));
ent->v.origin[i] = 0; ent->v.origin[i] = 0;
} }
} }
@ -162,10 +162,10 @@ SV_RunThink (edict_t *ent)
// it is possible to start that way // it is possible to start that way
// by a trigger with a local time. // by a trigger with a local time.
ent->v.nextthink = 0; ent->v.nextthink = 0;
pr_global_struct->time = thinktime; sv_progs.pr_global_struct->time = thinktime;
pr_global_struct->self = EDICT_TO_PROG (ent); sv_progs.pr_global_struct->self = EDICT_TO_PROG (ent);
pr_global_struct->other = EDICT_TO_PROG (sv.edicts); sv_progs.pr_global_struct->other = EDICT_TO_PROG (sv.edicts);
PR_ExecuteProgram (ent->v.think); PR_ExecuteProgram (&sv_progs, ent->v.think);
if (ent->free) if (ent->free)
return false; return false;
@ -186,24 +186,24 @@ SV_Impact (edict_t *e1, edict_t *e2)
{ {
int old_self, old_other; int old_self, old_other;
old_self = pr_global_struct->self; old_self = sv_progs.pr_global_struct->self;
old_other = pr_global_struct->other; old_other = sv_progs.pr_global_struct->other;
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
if (e1->v.touch && e1->v.solid != SOLID_NOT) { if (e1->v.touch && e1->v.solid != SOLID_NOT) {
pr_global_struct->self = EDICT_TO_PROG (e1); sv_progs.pr_global_struct->self = EDICT_TO_PROG (e1);
pr_global_struct->other = EDICT_TO_PROG (e2); sv_progs.pr_global_struct->other = EDICT_TO_PROG (e2);
PR_ExecuteProgram (e1->v.touch); PR_ExecuteProgram (&sv_progs, e1->v.touch);
} }
if (e2->v.touch && e2->v.solid != SOLID_NOT) { if (e2->v.touch && e2->v.solid != SOLID_NOT) {
pr_global_struct->self = EDICT_TO_PROG (e2); sv_progs.pr_global_struct->self = EDICT_TO_PROG (e2);
pr_global_struct->other = EDICT_TO_PROG (e1); sv_progs.pr_global_struct->other = EDICT_TO_PROG (e1);
PR_ExecuteProgram (e2->v.touch); PR_ExecuteProgram (&sv_progs, e2->v.touch);
} }
pr_global_struct->self = old_self; sv_progs.pr_global_struct->self = old_self;
pr_global_struct->other = old_other; sv_progs.pr_global_struct->other = old_other;
} }
@ -470,8 +470,8 @@ SV_Push (edict_t *pusher, vec3_t move)
// see if any solid entities are inside the final position // see if any solid entities are inside the final position
num_moved = 0; num_moved = 0;
check = NEXT_EDICT (sv.edicts); check = NEXT_EDICT (&sv_progs, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_progs, check)) {
if (check->free) if (check->free)
continue; continue;
if (check->v.movetype == MOVETYPE_PUSH if (check->v.movetype == MOVETYPE_PUSH
@ -541,9 +541,9 @@ SV_Push (edict_t *pusher, vec3_t move)
// if the pusher has a "blocked" function, call it // if the pusher has a "blocked" function, call it
// otherwise, just stay in place until the obstacle is gone // otherwise, just stay in place until the obstacle is gone
if (pusher->v.blocked) { if (pusher->v.blocked) {
pr_global_struct->self = EDICT_TO_PROG (pusher); sv_progs.pr_global_struct->self = EDICT_TO_PROG (pusher);
pr_global_struct->other = EDICT_TO_PROG (check); sv_progs.pr_global_struct->other = EDICT_TO_PROG (check);
PR_ExecuteProgram (pusher->v.blocked); PR_ExecuteProgram (&sv_progs, pusher->v.blocked);
} }
// move back any entities we already moved // move back any entities we already moved
for (i = 0; i < num_moved; i++) { for (i = 0; i < num_moved; i++) {
@ -615,10 +615,10 @@ SV_Physics_Pusher (edict_t *ent)
if (thinktime > oldltime && thinktime <= ent->v.ltime) { if (thinktime > oldltime && thinktime <= ent->v.ltime) {
VectorCopy (ent->v.origin, oldorg); VectorCopy (ent->v.origin, oldorg);
ent->v.nextthink = 0; ent->v.nextthink = 0;
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (ent); sv_progs.pr_global_struct->self = EDICT_TO_PROG (ent);
pr_global_struct->other = EDICT_TO_PROG (sv.edicts); sv_progs.pr_global_struct->other = EDICT_TO_PROG (sv.edicts);
PR_ExecuteProgram (ent->v.think); PR_ExecuteProgram (&sv_progs, ent->v.think);
if (ent->free) if (ent->free)
return; return;
VectorSubtract (ent->v.origin, oldorg, move); VectorSubtract (ent->v.origin, oldorg, move);
@ -855,8 +855,8 @@ SV_PPushMove (edict_t *pusher, float movetime) // player push
oldsolid = pusher->v.solid; oldsolid = pusher->v.solid;
check = NEXT_EDICT (sv.edicts); check = NEXT_EDICT (&sv_progs, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_progs, check)) {
if (check->free) // What entity? if (check->free) // What entity?
continue; continue;
@ -881,9 +881,9 @@ SV_PPushMove (edict_t *pusher, float movetime) // player push
// Stage 4: Yes, it must be. Fail the move. // Stage 4: Yes, it must be. Fail the move.
VectorCopy (pusher->v.origin, pusher->v.oldorigin); // Revert VectorCopy (pusher->v.origin, pusher->v.oldorigin); // Revert
if (pusher->v.blocked) { // Blocked func? if (pusher->v.blocked) { // Blocked func?
pr_global_struct->self = EDICT_TO_PROG (pusher); sv_progs.pr_global_struct->self = EDICT_TO_PROG (pusher);
pr_global_struct->other = EDICT_TO_PROG (check); sv_progs.pr_global_struct->other = EDICT_TO_PROG (check);
PR_ExecuteProgram (pusher->v.blocked); PR_ExecuteProgram (&sv_progs, pusher->v.blocked);
} }
return; return;
@ -917,10 +917,10 @@ SV_Physics_PPusher (edict_t *ent)
if (thinktime > oldltime && thinktime <= ent->v.ltime) { if (thinktime > oldltime && thinktime <= ent->v.ltime) {
ent->v.nextthink = 0; ent->v.nextthink = 0;
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (ent); sv_progs.pr_global_struct->self = EDICT_TO_PROG (ent);
pr_global_struct->other = EDICT_TO_PROG (sv.edicts); sv_progs.pr_global_struct->other = EDICT_TO_PROG (sv.edicts);
PR_ExecuteProgram (ent->v.think); PR_ExecuteProgram (&sv_progs, ent->v.think);
if (ent->free) if (ent->free)
return; return;
} }
@ -932,10 +932,10 @@ void
SV_ProgStartFrame (void) SV_ProgStartFrame (void)
{ {
// let the progs know that a new frame has started // let the progs know that a new frame has started
pr_global_struct->self = EDICT_TO_PROG (sv.edicts); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv.edicts);
pr_global_struct->other = EDICT_TO_PROG (sv.edicts); sv_progs.pr_global_struct->other = EDICT_TO_PROG (sv.edicts);
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
PR_ExecuteProgram (pr_global_struct->StartFrame); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->StartFrame);
} }
/* /*
@ -989,11 +989,11 @@ SV_RunNewmis (void)
{ {
edict_t *ent; edict_t *ent;
if (!pr_global_struct->newmis) if (!sv_progs.pr_global_struct->newmis)
return; return;
ent = PROG_TO_EDICT (pr_global_struct->newmis); ent = PROG_TO_EDICT (sv_progs.pr_global_struct->newmis);
sv_frametime = 0.05; sv_frametime = 0.05;
pr_global_struct->newmis = 0; sv_progs.pr_global_struct->newmis = 0;
SV_RunEntity (ent); SV_RunEntity (ent);
} }
@ -1019,7 +1019,7 @@ SV_Physics (void)
sv_frametime = sv_maxtic->value; sv_frametime = sv_maxtic->value;
old_time = realtime; old_time = realtime;
pr_global_struct->frametime = sv_frametime; sv_progs.pr_global_struct->frametime = sv_frametime;
SV_ProgStartFrame (); SV_ProgStartFrame ();
@ -1028,11 +1028,11 @@ SV_Physics (void)
// even the world gets a chance to think // even the world gets a chance to think
// //
ent = sv.edicts; ent = sv.edicts;
for (i = 0; i < sv.num_edicts; i++, ent = NEXT_EDICT (ent)) { for (i = 0; i < sv.num_edicts; i++, ent = NEXT_EDICT (&sv_progs, ent)) {
if (ent->free) if (ent->free)
continue; continue;
if (pr_global_struct->force_retouch) if (sv_progs.pr_global_struct->force_retouch)
SV_LinkEdict (ent, true); // force retouch even for stationary SV_LinkEdict (ent, true); // force retouch even for stationary
if (i > 0 && i <= MAX_CLIENTS) if (i > 0 && i <= MAX_CLIENTS)
@ -1043,16 +1043,16 @@ SV_Physics (void)
SV_RunNewmis (); SV_RunNewmis ();
} }
if (pr_global_struct->force_retouch) if (sv_progs.pr_global_struct->force_retouch)
pr_global_struct->force_retouch--; sv_progs.pr_global_struct->force_retouch--;
// 2000-01-02 EndFrame function by Maddes/FrikaC start // 2000-01-02 EndFrame function by Maddes/FrikaC start
if (EndFrame) { if (EndFrame) {
// let the progs know that the frame has ended // let the progs know that the frame has ended
pr_global_struct->self = EDICT_TO_PROG (sv.edicts); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv.edicts);
pr_global_struct->other = EDICT_TO_PROG (sv.edicts); sv_progs.pr_global_struct->other = EDICT_TO_PROG (sv.edicts);
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
PR_ExecuteProgram (EndFrame); PR_ExecuteProgram (&sv_progs, EndFrame);
} }
// 2000-01-02 EndFrame function by Maddes/FrikaC end // 2000-01-02 EndFrame function by Maddes/FrikaC end
} }

70
source/sv_progs.c Normal file
View file

@ -0,0 +1,70 @@
/*
sv_progs.c
Quick QuakeC server code
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "progs.h"
int eval_alpha, eval_scale, eval_glowsize, eval_glowcolor, eval_colormod;
progs_t sv_progs;
func_t EndFrame;
func_t SpectatorConnect;
func_t SpectatorDisconnect;
func_t SpectatorThink;
void
FindEdictFieldOffsets (progs_t *pr)
{
dfunction_t *f;
if (pr == &sv_progs) {
// Zoid, find the spectator functions
SpectatorConnect = SpectatorThink = SpectatorDisconnect = 0;
if ((f = ED_FindFunction (&sv_progs, "SpectatorConnect")) != NULL)
SpectatorConnect = (func_t) (f - sv_progs.pr_functions);
if ((f = ED_FindFunction (&sv_progs, "SpectatorThink")) != NULL)
SpectatorThink = (func_t) (f - sv_progs.pr_functions);
if ((f = ED_FindFunction (&sv_progs, "SpectatorDisconnect")) != NULL)
SpectatorDisconnect = (func_t) (f - sv_progs.pr_functions);
// 2000-01-02 EndFrame function by Maddes/FrikaC
EndFrame = 0;
if ((f = ED_FindFunction (&sv_progs, "EndFrame")) != NULL)
EndFrame = (func_t) (f - sv_progs.pr_functions);
eval_alpha = FindFieldOffset (&sv_progs, "alpha");
eval_scale = FindFieldOffset (&sv_progs, "scale");
eval_glowsize = FindFieldOffset (&sv_progs, "glow_size");
eval_glowcolor = FindFieldOffset (&sv_progs, "glow_color");
eval_colormod = FindFieldOffset (&sv_progs, "colormod");
}
};

View file

@ -422,7 +422,7 @@ SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
return; return;
} }
ent = NUM_FOR_EDICT (entity); ent = NUM_FOR_EDICT (&sv_progs, entity);
if ((channel & 8) || !sv_phs->int_val) // no PHS flag if ((channel & 8) || !sv_phs->int_val) // no PHS flag
{ {
@ -572,7 +572,7 @@ SV_UpdateClientStats (client_t *client)
ent = svs.clients[client->spec_track - 1].edict; ent = svs.clients[client->spec_track - 1].edict;
stats[STAT_HEALTH] = ent->v.health; stats[STAT_HEALTH] = ent->v.health;
stats[STAT_WEAPON] = SV_ModelIndex (PR_GetString (ent->v.weaponmodel)); stats[STAT_WEAPON] = SV_ModelIndex (PR_GetString (&sv_progs, ent->v.weaponmodel));
stats[STAT_AMMO] = ent->v.currentammo; stats[STAT_AMMO] = ent->v.currentammo;
stats[STAT_ARMOR] = ent->v.armorvalue; stats[STAT_ARMOR] = ent->v.armorvalue;
stats[STAT_SHELLS] = ent->v.ammo_shells; stats[STAT_SHELLS] = ent->v.ammo_shells;
@ -583,7 +583,7 @@ SV_UpdateClientStats (client_t *client)
stats[STAT_ACTIVEWEAPON] = ent->v.weapon; stats[STAT_ACTIVEWEAPON] = ent->v.weapon;
// stuff the sigil bits into the high bits of items for sbar // stuff the sigil bits into the high bits of items for sbar
stats[STAT_ITEMS] = stats[STAT_ITEMS] =
(int) ent->v.items | ((int) pr_global_struct->serverflags << 28); (int) ent->v.items | ((int) sv_progs.pr_global_struct->serverflags << 28);
// Extensions to the QW 2.40 protocol for Mega2k --KB // Extensions to the QW 2.40 protocol for Mega2k --KB
stats[STAT_VIEWHEIGHT] = (int) ent->v.view_ofs[2]; stats[STAT_VIEWHEIGHT] = (int) ent->v.view_ofs[2];
@ -693,13 +693,13 @@ SV_UpdateToReliableMessages (void)
// maxspeed/entgravity changes // maxspeed/entgravity changes
ent = host_client->edict; ent = host_client->edict;
val = GetEdictFieldValue (ent, "gravity"); val = GetEdictFieldValue (&sv_progs, ent, "gravity");
if (val && host_client->entgravity != val->_float) { if (val && host_client->entgravity != val->_float) {
host_client->entgravity = val->_float; host_client->entgravity = val->_float;
ClientReliableWrite_Begin (host_client, svc_entgravity, 5); ClientReliableWrite_Begin (host_client, svc_entgravity, 5);
ClientReliableWrite_Float (host_client, host_client->entgravity); ClientReliableWrite_Float (host_client, host_client->entgravity);
} }
val = GetEdictFieldValue (ent, "maxspeed"); val = GetEdictFieldValue (&sv_progs, ent, "maxspeed");
if (val && host_client->maxspeed != val->_float) { if (val && host_client->maxspeed != val->_float) {
host_client->maxspeed = val->_float; host_client->maxspeed = val->_float;
ClientReliableWrite_Begin (host_client, svc_maxspeed, 5); ClientReliableWrite_Begin (host_client, svc_maxspeed, 5);

View file

@ -129,14 +129,14 @@ SV_New_f (void)
MSG_WriteLong (&host_client->netchan.message, svs.spawncount); MSG_WriteLong (&host_client->netchan.message, svs.spawncount);
MSG_WriteString (&host_client->netchan.message, gamedir); MSG_WriteString (&host_client->netchan.message, gamedir);
playernum = NUM_FOR_EDICT (host_client->edict) - 1; playernum = NUM_FOR_EDICT (&sv_progs, host_client->edict) - 1;
if (host_client->spectator) if (host_client->spectator)
playernum |= 128; playernum |= 128;
MSG_WriteByte (&host_client->netchan.message, playernum); MSG_WriteByte (&host_client->netchan.message, playernum);
// send full levelname // send full levelname
MSG_WriteString (&host_client->netchan.message, MSG_WriteString (&host_client->netchan.message,
PR_GetString (sv.edicts->v.message)); PR_GetString (&sv_progs, sv.edicts->v.message));
// send the movevars // send the movevars
MSG_WriteFloat (&host_client->netchan.message, movevars.gravity); MSG_WriteFloat (&host_client->netchan.message, movevars.gravity);
@ -398,17 +398,17 @@ SV_Spawn_f (void)
// set up the edict // set up the edict
ent = host_client->edict; ent = host_client->edict;
memset (&ent->v, 0, progs->entityfields * 4); memset (&ent->v, 0, sv_progs.progs->entityfields * 4);
ent->v.colormap = NUM_FOR_EDICT (ent); ent->v.colormap = NUM_FOR_EDICT (&sv_progs, ent);
ent->v.team = 0; // FIXME ent->v.team = 0; // FIXME
ent->v.netname = PR_SetString (host_client->name); ent->v.netname = PR_SetString (&sv_progs, host_client->name);
host_client->entgravity = 1.0; host_client->entgravity = 1.0;
val = GetEdictFieldValue (ent, "gravity"); val = GetEdictFieldValue (&sv_progs, ent, "gravity");
if (val) if (val)
val->_float = 1.0; val->_float = 1.0;
host_client->maxspeed = sv_maxspeed->value; host_client->maxspeed = sv_maxspeed->value;
val = GetEdictFieldValue (ent, "maxspeed"); val = GetEdictFieldValue (&sv_progs, ent, "maxspeed");
if (val) if (val)
val->_float = sv_maxspeed->value; val->_float = sv_maxspeed->value;
@ -419,19 +419,19 @@ SV_Spawn_f (void)
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6); ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS); ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_secrets); ClientReliableWrite_Long (host_client, sv_progs.pr_global_struct->total_secrets);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6); ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS); ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->total_monsters); ClientReliableWrite_Long (host_client, sv_progs.pr_global_struct->total_monsters);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6); ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_SECRETS); ClientReliableWrite_Byte (host_client, STAT_SECRETS);
ClientReliableWrite_Long (host_client, pr_global_struct->found_secrets); ClientReliableWrite_Long (host_client, sv_progs.pr_global_struct->found_secrets);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6); ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_MONSTERS); ClientReliableWrite_Byte (host_client, STAT_MONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->killed_monsters); ClientReliableWrite_Long (host_client, sv_progs.pr_global_struct->killed_monsters);
// get the client to check and download skins // get the client to check and download skins
// when that is completed, a begin command will be issued // when that is completed, a begin command will be issued
@ -456,8 +456,8 @@ SV_SpawnSpectator (void)
// search for an info_playerstart to spawn the spectator at // search for an info_playerstart to spawn the spectator at
for (i = MAX_CLIENTS - 1; i < sv.num_edicts; i++) { for (i = MAX_CLIENTS - 1; i < sv.num_edicts; i++) {
e = EDICT_NUM (i); e = EDICT_NUM (&sv_progs, i);
if (!strcmp (PR_GetString (e->v.classname), "info_player_start")) { if (!strcmp (PR_GetString (&sv_progs, e->v.classname), "info_player_start")) {
VectorCopy (e->v.origin, sv_player->v.origin); VectorCopy (e->v.origin, sv_player->v.origin);
return; return;
} }
@ -494,27 +494,27 @@ SV_Begin_f (void)
if (SpectatorConnect) { if (SpectatorConnect) {
// copy spawn parms out of the client_t // copy spawn parms out of the client_t
for (i = 0; i < NUM_SPAWN_PARMS; i++) for (i = 0; i < NUM_SPAWN_PARMS; i++)
(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i]; (&sv_progs.pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
// call the spawn function // call the spawn function
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (SpectatorConnect); PR_ExecuteProgram (&sv_progs, SpectatorConnect);
} }
} else { } else {
// copy spawn parms out of the client_t // copy spawn parms out of the client_t
for (i = 0; i < NUM_SPAWN_PARMS; i++) for (i = 0; i < NUM_SPAWN_PARMS; i++)
(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i]; (&sv_progs.pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
// call the spawn function // call the spawn function
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (pr_global_struct->ClientConnect); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->ClientConnect);
// actually spawn the player // actually spawn the player
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (pr_global_struct->PutClientInServer); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->PutClientInServer);
} }
// clear the net statistics, because connecting gives a bogus picture // clear the net statistics, because connecting gives a bogus picture
@ -546,7 +546,7 @@ SV_Begin_f (void)
// in a state where it is expecting the client to correct the angle // in a state where it is expecting the client to correct the angle
// and it won't happen if the game was just loaded, so you wind up // and it won't happen if the game was just loaded, so you wind up
// with a permanent head tilt // with a permanent head tilt
ent = EDICT_NUM (1 + (host_client - svs.clients)); ent = EDICT_NUM (&sv_progs, 1 + (host_client - svs.clients));
MSG_WriteByte (&host_client->netchan.message, svc_setangle); MSG_WriteByte (&host_client->netchan.message, svc_setangle);
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
MSG_WriteAngle (&host_client->netchan.message, ent->v.angles[i]); MSG_WriteAngle (&host_client->netchan.message, ent->v.angles[i]);
@ -945,9 +945,9 @@ SV_Kill_f (void)
return; return;
} }
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (pr_global_struct->ClientKill); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->ClientKill);
} }
/* /*
@ -1052,8 +1052,8 @@ SV_PTrack_f (void)
if (Cmd_Argc () != 2) { if (Cmd_Argc () != 2) {
// turn off tracking // turn off tracking
host_client->spec_track = 0; host_client->spec_track = 0;
ent = EDICT_NUM (host_client - svs.clients + 1); ent = EDICT_NUM (&sv_progs, host_client - svs.clients + 1);
tent = EDICT_NUM (0); tent = EDICT_NUM (&sv_progs, 0);
ent->v.goalentity = EDICT_TO_PROG (tent); ent->v.goalentity = EDICT_TO_PROG (tent);
return; return;
} }
@ -1063,15 +1063,15 @@ SV_PTrack_f (void)
svs.clients[i].spectator) { svs.clients[i].spectator) {
SV_ClientPrintf (host_client, PRINT_HIGH, "Invalid client to track\n"); SV_ClientPrintf (host_client, PRINT_HIGH, "Invalid client to track\n");
host_client->spec_track = 0; host_client->spec_track = 0;
ent = EDICT_NUM (host_client - svs.clients + 1); ent = EDICT_NUM (&sv_progs, host_client - svs.clients + 1);
tent = EDICT_NUM (0); tent = EDICT_NUM (&sv_progs, 0);
ent->v.goalentity = EDICT_TO_PROG (tent); ent->v.goalentity = EDICT_TO_PROG (tent);
return; return;
} }
host_client->spec_track = i + 1; // now tracking host_client->spec_track = i + 1; // now tracking
ent = EDICT_NUM (host_client - svs.clients + 1); ent = EDICT_NUM (&sv_progs, host_client - svs.clients + 1);
tent = EDICT_NUM (i + 1); tent = EDICT_NUM (&sv_progs, i + 1);
ent->v.goalentity = EDICT_TO_PROG (tent); ent->v.goalentity = EDICT_TO_PROG (tent);
} }
@ -1350,7 +1350,7 @@ AddLinksToPmove (areanode_t *node)
pmove.numphysent++; pmove.numphysent++;
VectorCopy (check->v.origin, pe->origin); VectorCopy (check->v.origin, pe->origin);
pe->info = NUM_FOR_EDICT (check); pe->info = NUM_FOR_EDICT (&sv_progs, check);
if (check->v.solid == SOLID_BSP) { if (check->v.solid == SOLID_BSP) {
pe->model = sv.models[(int) (check->v.modelindex)]; pe->model = sv.models[(int) (check->v.modelindex)];
@ -1391,8 +1391,8 @@ AddAllEntsToPmove (void)
int pl; int pl;
pl = EDICT_TO_PROG (sv_player); pl = EDICT_TO_PROG (sv_player);
check = NEXT_EDICT (sv.edicts); check = NEXT_EDICT (&sv_progs, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_progs, check)) {
if (check->free) if (check->free)
continue; continue;
if (check->v.owner == pl) if (check->v.owner == pl)
@ -1531,11 +1531,11 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside)
sv_frametime = min (0.1, ucmd->msec * 0.001); sv_frametime = min (0.1, ucmd->msec * 0.001);
if (!host_client->spectator) { if (!host_client->spectator) {
pr_global_struct->frametime = sv_frametime; sv_progs.pr_global_struct->frametime = sv_frametime;
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (pr_global_struct->PlayerPreThink); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->PlayerPreThink);
SV_RunThink (sv_player); SV_RunThink (sv_player);
} }
@ -1591,7 +1591,7 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside)
if (onground != -1) { if (onground != -1) {
sv_player->v.flags = (int) sv_player->v.flags | FL_ONGROUND; sv_player->v.flags = (int) sv_player->v.flags | FL_ONGROUND;
sv_player->v.groundentity = sv_player->v.groundentity =
EDICT_TO_PROG (EDICT_NUM (pmove.physents[onground].info)); EDICT_TO_PROG (EDICT_NUM (&sv_progs, pmove.physents[onground].info));
} else { } else {
sv_player->v.flags = (int) sv_player->v.flags & ~FL_ONGROUND; sv_player->v.flags = (int) sv_player->v.flags & ~FL_ONGROUND;
} }
@ -1616,12 +1616,12 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside)
// touch other objects // touch other objects
for (i = 0; i < pmove.numtouch; i++) { for (i = 0; i < pmove.numtouch; i++) {
n = pmove.physents[pmove.touchindex[i]].info; n = pmove.physents[pmove.touchindex[i]].info;
ent = EDICT_NUM (n); ent = EDICT_NUM (&sv_progs, n);
if (!ent->v.touch || (playertouch[n / 8] & (1 << (n % 8)))) if (!ent->v.touch || (playertouch[n / 8] & (1 << (n % 8))))
continue; continue;
pr_global_struct->self = EDICT_TO_PROG (ent); sv_progs.pr_global_struct->self = EDICT_TO_PROG (ent);
pr_global_struct->other = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->other = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (ent->v.touch); PR_ExecuteProgram (&sv_progs, ent->v.touch);
playertouch[n / 8] |= 1 << (n % 8); playertouch[n / 8] |= 1 << (n % 8);
} }
} }
@ -1639,14 +1639,14 @@ SV_PostRunCmd (void)
// run post-think // run post-think
if (!host_client->spectator) { if (!host_client->spectator) {
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (pr_global_struct->PlayerPostThink); PR_ExecuteProgram (&sv_progs, sv_progs.pr_global_struct->PlayerPostThink);
SV_RunNewmis (); SV_RunNewmis ();
} else if (SpectatorThink) { } else if (SpectatorThink) {
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player); sv_progs.pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (SpectatorThink); PR_ExecuteProgram (&sv_progs, SpectatorThink);
} }
} }

View file

@ -313,16 +313,16 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
|| ent->v.absmax[2] < touch->v.absmin[2]) || ent->v.absmax[2] < touch->v.absmin[2])
continue; continue;
old_self = pr_global_struct->self; old_self = sv_progs.pr_global_struct->self;
old_other = pr_global_struct->other; old_other = sv_progs.pr_global_struct->other;
pr_global_struct->self = EDICT_TO_PROG (touch); sv_progs.pr_global_struct->self = EDICT_TO_PROG (touch);
pr_global_struct->other = EDICT_TO_PROG (ent); sv_progs.pr_global_struct->other = EDICT_TO_PROG (ent);
pr_global_struct->time = sv.time; sv_progs.pr_global_struct->time = sv.time;
PR_ExecuteProgram (touch->v.touch); PR_ExecuteProgram (&sv_progs, touch->v.touch);
pr_global_struct->self = old_self; sv_progs.pr_global_struct->self = old_self;
pr_global_struct->other = old_other; sv_progs.pr_global_struct->other = old_other;
} }
// recurse down both sides // recurse down both sides
@ -912,8 +912,8 @@ SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
VectorAdd (origin, ent->v.mins, boxmins); VectorAdd (origin, ent->v.mins, boxmins);
VectorAdd (origin, ent->v.maxs, boxmaxs); VectorAdd (origin, ent->v.maxs, boxmaxs);
check = NEXT_EDICT (sv.edicts); check = NEXT_EDICT (&sv_progs, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_progs, check)) {
if (check->free) if (check->free)
continue; continue;
if (check->v.solid != SOLID_BSP && if (check->v.solid != SOLID_BSP &&