mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-30 08:00:51 +00:00
libqfgamecode now builds. Now for the fun part: getting qw and nq to work using
the new setup.
This commit is contained in:
parent
b5d86d522d
commit
dfaf767890
6 changed files with 88 additions and 57 deletions
|
@ -30,6 +30,7 @@
|
|||
#define _PROGS_H
|
||||
|
||||
#include "link.h"
|
||||
#include "quakeio.h"
|
||||
#include "pr_comp.h"
|
||||
|
||||
typedef union eval_s
|
||||
|
@ -45,8 +46,10 @@ typedef union eval_s
|
|||
typedef union pr_type_u {
|
||||
float float_var;
|
||||
int int_var;
|
||||
string_t string_t_var;
|
||||
func_t func_t_var;
|
||||
string_t string_var;
|
||||
func_t func_var;
|
||||
int edict_var;
|
||||
float vector_var[1]; // really 3, but this structure must be 32 bits
|
||||
} pr_type_t;
|
||||
|
||||
#define MAX_ENT_LEAFS 16
|
||||
|
@ -135,7 +138,9 @@ typedef void (*builtin_t) (progs_t *pr);
|
|||
extern builtin_t *pr_builtins;
|
||||
extern int pr_numbuiltins;
|
||||
|
||||
ddef_t *PR_FindGlobal (progs_t *pr, const char *name);
|
||||
int FindFieldOffset (progs_t *pr, char *field);
|
||||
eval_t *GETEDICTFIELDVALUE (edict_t *ed, int fieldoffset);
|
||||
|
||||
extern func_t EndFrame; // 2000-01-02 EndFrame function by Maddes/FrikaC
|
||||
|
||||
|
@ -210,7 +215,7 @@ struct progs_s {
|
|||
|
||||
edict_t **edicts;
|
||||
int *num_edicts;
|
||||
int *max_edicts;
|
||||
int *reserved_edicts;
|
||||
double *time;
|
||||
int null_bad;
|
||||
|
||||
|
@ -218,6 +223,14 @@ struct progs_s {
|
|||
|
||||
void (*unlink)(edict_t *ent);
|
||||
void (*flush)(void);
|
||||
|
||||
// required globals
|
||||
float *g_time;
|
||||
int *g_self;
|
||||
// required fields (offsets into the edict)
|
||||
int f_nextthink;
|
||||
int f_frame;
|
||||
int f_think;
|
||||
};
|
||||
|
||||
#endif // _PROGS_H
|
||||
|
|
|
@ -61,7 +61,7 @@ int type_size[8] = {
|
|||
};
|
||||
|
||||
ddef_t *ED_FieldAtOfs (progs_t * pr, int ofs);
|
||||
qboolean ED_ParseEpair (progs_t * pr, void *base, ddef_t *key, char *s);
|
||||
qboolean ED_ParseEpair (progs_t * pr, pr_type_t *base, ddef_t *key, char *s);
|
||||
|
||||
#define MAX_FIELD_LEN 64
|
||||
#define GEFV_CACHESIZE 2
|
||||
|
@ -99,8 +99,9 @@ ED_Alloc (progs_t * pr)
|
|||
{
|
||||
int i;
|
||||
edict_t *e;
|
||||
int start = pr->reserved_edicts ? *pr->reserved_edicts : 0;
|
||||
|
||||
for (i = MAX_CLIENTS + 1; i < *(pr)->num_edicts; i++) {
|
||||
for (i = start + 1; i < *(pr)->num_edicts; i++) {
|
||||
e = EDICT_NUM (pr, i);
|
||||
// the first couple seconds of server time can involve a lot of
|
||||
// freeing and allocating, so relax the replacement policy
|
||||
|
@ -196,10 +197,10 @@ ED_FindField (progs_t * pr, char *name)
|
|||
|
||||
|
||||
/*
|
||||
ED_FindGlobal
|
||||
PR_FindGlobal
|
||||
*/
|
||||
ddef_t *
|
||||
ED_FindGlobal (progs_t * pr, char *name)
|
||||
PR_FindGlobal (progs_t * pr, const char *name)
|
||||
{
|
||||
ddef_t *def;
|
||||
int i;
|
||||
|
@ -545,26 +546,27 @@ ED_Count (progs_t * pr)
|
|||
int i;
|
||||
edict_t *ent;
|
||||
int active, models, solid, step;
|
||||
ddef_t *solid_def;
|
||||
ddef_t *model_def;
|
||||
|
||||
solid_def = ED_FindField (pr, "solid");
|
||||
model_def = ED_FindField (pr, "model");
|
||||
active = models = solid = step = 0;
|
||||
for (i = 0; i < *(pr)->num_edicts; i++) {
|
||||
ent = EDICT_NUM (pr, i);
|
||||
if (ent->free)
|
||||
continue;
|
||||
active++;
|
||||
if (ent->v.v.solid)
|
||||
if (solid_def && ent->v[solid_def->ofs].float_var)
|
||||
solid++;
|
||||
if (ent->v.v.model)
|
||||
if (model_def && ent->v[model_def->ofs].float_var)
|
||||
models++;
|
||||
if (ent->v.v.movetype == MOVETYPE_STEP)
|
||||
step++;
|
||||
}
|
||||
|
||||
Con_Printf ("num_edicts:%3i\n", *(pr)->num_edicts);
|
||||
Con_Printf ("active :%3i\n", active);
|
||||
Con_Printf ("view :%3i\n", models);
|
||||
Con_Printf ("touch :%3i\n", solid);
|
||||
Con_Printf ("step :%3i\n", step);
|
||||
|
||||
}
|
||||
|
||||
|
@ -632,13 +634,13 @@ ED_ParseGlobals (progs_t * pr, char *data)
|
|||
if (com_token[0] == '}')
|
||||
PR_Error (pr, "ED_ParseEntity: closing brace without data");
|
||||
|
||||
key = ED_FindGlobal (pr, keyname);
|
||||
key = PR_FindGlobal (pr, keyname);
|
||||
if (!key) {
|
||||
Con_Printf ("'%s' is not a global\n", keyname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ED_ParseEpair (pr, (void *) pr->pr_globals, key, com_token))
|
||||
if (!ED_ParseEpair (pr, pr->pr_globals, key, com_token))
|
||||
PR_Error (pr, "ED_ParseGlobals: parse error");
|
||||
}
|
||||
}
|
||||
|
@ -681,24 +683,24 @@ ED_NewString (progs_t * pr, char *string)
|
|||
returns false if error
|
||||
*/
|
||||
qboolean
|
||||
ED_ParseEpair (progs_t * pr, void *base, ddef_t *key, char *s)
|
||||
ED_ParseEpair (progs_t * pr, pr_type_t *base, ddef_t *key, char *s)
|
||||
{
|
||||
int i;
|
||||
char string[128];
|
||||
ddef_t *def;
|
||||
char *v, *w;
|
||||
void *d;
|
||||
eval_t *d;
|
||||
dfunction_t *func;
|
||||
|
||||
d = (void *) ((int *) base + key->ofs);
|
||||
d = (eval_t*)&base[key->ofs];
|
||||
|
||||
switch (key->type & ~DEF_SAVEGLOBAL) {
|
||||
case ev_string:
|
||||
*(string_t *) d = PR_SetString (pr, ED_NewString (pr, s));
|
||||
d->string = PR_SetString (pr, ED_NewString (pr, s));
|
||||
break;
|
||||
|
||||
case ev_float:
|
||||
*(float *) d = atof (s);
|
||||
d->_float = atof (s);
|
||||
break;
|
||||
|
||||
case ev_vector:
|
||||
|
@ -709,13 +711,13 @@ ED_ParseEpair (progs_t * pr, void *base, ddef_t *key, char *s)
|
|||
while (*v && *v != ' ')
|
||||
v++;
|
||||
*v = 0;
|
||||
((float *) d)[i] = atof (w);
|
||||
d->vector[i] = atof (w);
|
||||
w = v = v + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case ev_entity:
|
||||
*(int *) d = EDICT_TO_PROG (pr, EDICT_NUM (pr, atoi (s)));
|
||||
d->edict = EDICT_TO_PROG (pr, EDICT_NUM (pr, atoi (s)));
|
||||
break;
|
||||
|
||||
case ev_field:
|
||||
|
@ -724,7 +726,7 @@ ED_ParseEpair (progs_t * pr, void *base, ddef_t *key, char *s)
|
|||
Con_Printf ("Can't find field %s\n", s);
|
||||
return false;
|
||||
}
|
||||
*(int *) d = G_INT (pr, def->ofs);
|
||||
d->_int = G_INT (pr, def->ofs);
|
||||
break;
|
||||
|
||||
case ev_function:
|
||||
|
@ -733,7 +735,7 @@ ED_ParseEpair (progs_t * pr, void *base, ddef_t *key, char *s)
|
|||
Con_Printf ("Can't find function %s\n", s);
|
||||
return false;
|
||||
}
|
||||
*(func_t *) d = func - pr->pr_functions;
|
||||
d->function = func - pr->pr_functions;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -819,10 +821,9 @@ ED_ParseEdict (progs_t * pr, char *data, edict_t *ent)
|
|||
int ret;
|
||||
|
||||
if (anglehack) {
|
||||
ret = ED_ParseEpair (pr, (void *) &ent->v, key,
|
||||
va ("0 %s 0", com_token));
|
||||
ret = ED_ParseEpair (pr, ent->v, key, va ("0 %s 0", com_token));
|
||||
} else {
|
||||
ret = ED_ParseEpair (pr, (void *) &ent->v, key, com_token);
|
||||
ret = ED_ParseEpair (pr, ent->v, key, com_token);
|
||||
}
|
||||
if (!ret)
|
||||
PR_Error (pr, "ED_ParseEdict: parse error");
|
||||
|
@ -855,14 +856,16 @@ ED_LoadFromFile (progs_t * pr, char *data)
|
|||
edict_t *ent;
|
||||
int inhibit;
|
||||
dfunction_t *func;
|
||||
eval_t *classname;
|
||||
|
||||
ent = NULL;
|
||||
inhibit = 0;
|
||||
pr->pr_global_struct->time = *(pr)->time;
|
||||
|
||||
// parse ents
|
||||
*pr->g_time = *(pr)->time;
|
||||
|
||||
// parse ents
|
||||
while (1) {
|
||||
// parse the opening brace
|
||||
// parse the opening brace
|
||||
data = COM_Parse (data);
|
||||
if (!data)
|
||||
break;
|
||||
|
@ -875,23 +878,24 @@ ED_LoadFromFile (progs_t * pr, char *data)
|
|||
ent = ED_Alloc (pr);
|
||||
data = ED_ParseEdict (pr, data, ent);
|
||||
|
||||
// remove things from different skill levels or deathmatch
|
||||
// remove things from different skill levels or deathmatch
|
||||
if (ED_Prune_Edict (pr, ent)) {
|
||||
ED_Free (pr, ent);
|
||||
inhibit++;
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// immediately call spawn function
|
||||
//
|
||||
if (!ent->v.v.classname) {
|
||||
//
|
||||
// immediately call spawn function
|
||||
//
|
||||
classname = GETEDICTFIELDVALUE (ent, FindFieldOffset (pr, "classname"));
|
||||
if (classname) {
|
||||
Con_Printf ("No classname for:\n");
|
||||
ED_Print (pr, ent);
|
||||
ED_Free (pr, ent);
|
||||
continue;
|
||||
}
|
||||
// look for the spawn function
|
||||
func = ED_FindFunction (pr, PR_GetString (pr, ent->v.v.classname));
|
||||
func = ED_FindFunction (pr, PR_GetString (pr, classname->string));
|
||||
|
||||
if (!func) {
|
||||
Con_Printf ("No spawn function for:\n");
|
||||
|
@ -900,7 +904,7 @@ ED_LoadFromFile (progs_t * pr, char *data)
|
|||
continue;
|
||||
}
|
||||
|
||||
pr->pr_global_struct->self = EDICT_TO_PROG (pr, ent);
|
||||
*pr->g_self = EDICT_TO_PROG (pr, ent);
|
||||
PR_ExecuteProgram (pr, func - pr->pr_functions);
|
||||
if (pr->flush)
|
||||
pr->flush ();
|
||||
|
@ -917,6 +921,7 @@ PR_LoadProgs (progs_t * pr, char *progsname)
|
|||
{
|
||||
int i;
|
||||
dstatement_t *st;
|
||||
ddef_t *def;
|
||||
|
||||
// flush the non-C variable lookup cache
|
||||
for (i = 0; i < GEFV_CACHESIZE; i++)
|
||||
|
@ -928,18 +933,16 @@ PR_LoadProgs (progs_t * pr, char *progsname)
|
|||
|
||||
Con_DPrintf ("Programs occupy %iK.\n", com_filesize / 1024);
|
||||
|
||||
// store prog crc
|
||||
// store prog crc
|
||||
pr->crc = CRC_Block ((byte *) pr->progs, com_filesize);
|
||||
|
||||
// byte swap the header
|
||||
// byte swap the header
|
||||
for (i = 0; i < sizeof (*pr->progs) / 4; i++)
|
||||
((int *) pr->progs)[i] = LittleLong (((int *) pr->progs)[i]);
|
||||
|
||||
if (pr->progs->version != PROG_VERSION)
|
||||
PR_Error (pr, "progs.dat has wrong version number (%i should be %i)",
|
||||
pr->progs->version, PROG_VERSION);
|
||||
if (pr->progs->crc != PROGHEADER_CRC)
|
||||
PR_Error (pr, "You must have the qwprogs.dat from QuakeWorld installed");
|
||||
PR_Error (pr, "%s has wrong version number (%i should be %i)",
|
||||
progsname, pr->progs->version, PROG_VERSION);
|
||||
|
||||
pr->pr_functions =
|
||||
(dfunction_t *) ((byte *) pr->progs + pr->progs->ofs_functions);
|
||||
|
@ -999,6 +1002,21 @@ PR_LoadProgs (progs_t * pr, char *progsname)
|
|||
for (i = 0; i < pr->progs->numglobals; i++)
|
||||
((int *) pr->pr_globals)[i] = LittleLong (((int *) pr->pr_globals)[i]);
|
||||
|
||||
def = PR_FindGlobal (pr, "time");
|
||||
if (!def)
|
||||
PR_Error (pr, "%s: undefined symbol: time", progsname);
|
||||
pr->g_time = &pr->pr_globals[def->ofs].float_var;
|
||||
def = PR_FindGlobal (pr, "self");
|
||||
if (!def)
|
||||
PR_Error (pr, "%s: undefined symbol: self", progsname);
|
||||
pr->g_self = &pr->pr_globals[def->ofs].edict_var;
|
||||
if (!(pr->f_nextthink = FindFieldOffset (pr, "nextthink")))
|
||||
PR_Error (pr, "%s: undefined field: nextthink", progsname);
|
||||
if (!(pr->f_frame = FindFieldOffset (pr, "frame")))
|
||||
PR_Error (pr, "%s: undefined field: frame", progsname);
|
||||
if (!(pr->f_think = FindFieldOffset (pr, "function")))
|
||||
PR_Error (pr, "%s: undefined field: function", progsname);
|
||||
|
||||
// LordHavoc: Ender added this
|
||||
FindEdictFieldOffsets (pr);
|
||||
|
||||
|
|
|
@ -40,9 +40,7 @@
|
|||
|
||||
#include "console.h"
|
||||
#include "cvar.h"
|
||||
#include "host.h"
|
||||
#include "progs.h"
|
||||
#include "server.h"
|
||||
#include "sys.h"
|
||||
|
||||
char *pr_opnames[] = {
|
||||
|
@ -249,10 +247,10 @@ PR_RunError (progs_t * pr, char *error, ...)
|
|||
PR_StackTrace (pr);
|
||||
Con_Printf ("%s\n", string);
|
||||
|
||||
pr->pr_depth = 0; // dump the stack so SV_Error can
|
||||
// shutdown functions
|
||||
pr->pr_depth = 0; // dump the stack so PR_Error can
|
||||
// shutdown functions
|
||||
|
||||
SV_Error ("Program error");
|
||||
PR_Error (pr, "Program error");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -311,7 +309,7 @@ PR_LeaveFunction (progs_t * pr)
|
|||
int i, c;
|
||||
|
||||
if (pr->pr_depth <= 0)
|
||||
SV_Error ("prog stack underflow");
|
||||
PR_Error (pr, "prog stack underflow");
|
||||
|
||||
// restore locals from the stack
|
||||
c = pr->pr_xfunction->locals;
|
||||
|
@ -354,9 +352,9 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
int profile, startprofile;
|
||||
|
||||
if (!fnum || fnum >= pr->progs->numfunctions) {
|
||||
if (pr->pr_global_struct->self)
|
||||
ED_Print (pr, PROG_TO_EDICT (pr, pr->pr_global_struct->self));
|
||||
SV_Error ("PR_ExecuteProgram: NULL function");
|
||||
if (*pr->g_self)
|
||||
ED_Print (pr, PROG_TO_EDICT (pr, *pr->g_self));
|
||||
PR_Error (pr, "PR_ExecuteProgram: NULL function");
|
||||
}
|
||||
|
||||
f = &pr->pr_functions[fnum];
|
||||
|
@ -677,10 +675,10 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
return; // all done
|
||||
break;
|
||||
case OP_STATE:
|
||||
ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
|
||||
ed->v.v.nextthink = pr->pr_global_struct->time + 0.1;
|
||||
ed->v.v.frame = E_OPA->_float;
|
||||
ed->v.v.think = E_OPB->function;
|
||||
ed = PROG_TO_EDICT (pr, *pr->g_self);
|
||||
ed->v[pr->f_nextthink].float_var = *pr->time + 0.1;
|
||||
ed->v[pr->f_frame].float_var = E_OPA->_float;
|
||||
ed->v[pr->f_think].func_var = E_OPB->function;
|
||||
break;
|
||||
// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
|
||||
/*
|
||||
|
|
|
@ -175,6 +175,7 @@ SV_Progs_Init (void)
|
|||
sv_pr_state.edicts = &sv.edicts;
|
||||
sv_pr_state.num_edicts = &sv.num_edicts;
|
||||
sv_pr_state.time = &sv.time;
|
||||
sv_pr_state.reserved_edicts = &svs.maxclients;
|
||||
sv_pr_state.unlink = SV_UnlinkEdict;
|
||||
|
||||
Cmd_AddCommand ("edict", ED_PrintEdict_f,
|
||||
|
|
|
@ -46,8 +46,6 @@
|
|||
extern int eval_alpha, eval_scale, eval_glowsize, eval_glowcolor,
|
||||
|
||||
eval_colormod;
|
||||
// Ender Extends (QSG - End)
|
||||
extern eval_t *GETEDICTFIELDVALUE (edict_t *ed, int fieldoffset);
|
||||
|
||||
/*
|
||||
The PVS must include a small area around the client to allow head
|
||||
|
|
|
@ -52,6 +52,8 @@ func_t SpectatorConnect;
|
|||
func_t SpectatorDisconnect;
|
||||
func_t SpectatorThink;
|
||||
|
||||
static reserved_edicts = MAX_CLIENTS;
|
||||
|
||||
void
|
||||
FindEdictFieldOffsets (progs_t *pr)
|
||||
{
|
||||
|
@ -154,6 +156,7 @@ SV_Progs_Init (void)
|
|||
sv_pr_state.edicts = &sv.edicts;
|
||||
sv_pr_state.num_edicts = &sv.num_edicts;
|
||||
sv_pr_state.time = &sv.time;
|
||||
sv_pr_state.reserved_edicts = &reserved_edicts;
|
||||
sv_pr_state.unlink = SV_UnlinkEdict;
|
||||
sv_pr_state.flush = SV_FlushSignon;
|
||||
|
||||
|
|
Loading…
Reference in a new issue