mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 12:10:48 +00:00
PF_VarString return a plain char * and make it easier to add "at load" init
functions
This commit is contained in:
parent
14c65d48c7
commit
5f5662a063
8 changed files with 129 additions and 73 deletions
|
@ -70,10 +70,10 @@ void PR_ExecuteProgram (progs_t *pr, func_t fnum);
|
|||
void PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts,
|
||||
int zone);
|
||||
void PR_LoadProgs (progs_t *pr, const char *progsname, int edicts, int zone);
|
||||
void PR_LoadStrings (progs_t *pr);
|
||||
void PR_LoadDebug (progs_t *pr);
|
||||
int PR_LoadStrings (progs_t *pr);
|
||||
int PR_LoadDebug (progs_t *pr);
|
||||
edict_t *PR_InitEdicts (progs_t *pr, int num_edicts);
|
||||
void PR_Check_Opcodes (progs_t *pr);
|
||||
int PR_Check_Opcodes (progs_t *pr);
|
||||
|
||||
void PR_Profile_f (void);
|
||||
|
||||
|
@ -206,11 +206,15 @@ builtin_t *PR_FindBuiltin (progs_t *pr, const char *name);
|
|||
int PR_RelocateBuiltins (progs_t *pr);
|
||||
int PR_ResolveGlobals (progs_t *pr);
|
||||
|
||||
typedef int pr_load_func_t (progs_t *);
|
||||
void PR_AddLoadFunc (progs_t *pr, pr_load_func_t *func);
|
||||
int PR_RunLoadFuncs (progs_t *pr);
|
||||
|
||||
//
|
||||
// PR Obj stuff
|
||||
//
|
||||
void PR_Obj_Progs_Init (progs_t *pr);
|
||||
void PR_InitRuntime (progs_t *pr);
|
||||
int PR_InitRuntime (progs_t *pr);
|
||||
|
||||
//
|
||||
// PR Strings stuff
|
||||
|
@ -268,7 +272,7 @@ extern const char *pr_gametype;
|
|||
// PR Cmds stuff
|
||||
//
|
||||
|
||||
const char *PF_VarString (progs_t *pr, int first);
|
||||
char *PF_VarString (progs_t *pr, int first);
|
||||
void PR_Cmds_Init (progs_t *pr);
|
||||
|
||||
//============================================================================
|
||||
|
@ -300,6 +304,10 @@ struct progs_s {
|
|||
struct hashtab_s *global_hash;
|
||||
struct hashtab_s *field_hash;
|
||||
|
||||
int num_load_funcs;
|
||||
int max_load_funcs;
|
||||
pr_load_func_t **load_funcs;
|
||||
|
||||
// garbage collected strings
|
||||
strref_t *static_strings;
|
||||
strref_t **dynamic_strings;
|
||||
|
|
|
@ -61,7 +61,7 @@ const char *pr_gametype = "";
|
|||
// FIXME: Hunk_TempAlloc, Sys_Printf, Cvar_*, PR_SetString, PR_RunError, ED_PrintEdicts, PF_traceon, PF_traceoff, ED_PrintNum, PR_FindBuiltin isn't threadsafe/reentrant
|
||||
|
||||
|
||||
const char *
|
||||
char *
|
||||
PF_VarString (progs_t *pr, int first)
|
||||
{
|
||||
char *out;
|
||||
|
|
|
@ -185,7 +185,7 @@ PR_Load_Source_File (progs_t *pr, const char *fname)
|
|||
return f;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
PR_LoadDebug (progs_t *pr)
|
||||
{
|
||||
char *sym_path;
|
||||
|
@ -202,7 +202,7 @@ PR_LoadDebug (progs_t *pr)
|
|||
pr->local_defs = 0;
|
||||
|
||||
if (!pr_debug->int_val)
|
||||
return;
|
||||
return 1;
|
||||
|
||||
def = PR_FindGlobal (pr, ".debug_file");
|
||||
if (def)
|
||||
|
@ -210,7 +210,7 @@ PR_LoadDebug (progs_t *pr)
|
|||
|
||||
Hash_FlushTable (file_hash);
|
||||
if (!str)
|
||||
return;
|
||||
return 1;
|
||||
pr->debugfile = PR_GetString (pr, str->string_var);
|
||||
sym_file = QFS_SkipPath (pr->debugfile);
|
||||
path_end = QFS_SkipPath (pr->progs_name);
|
||||
|
@ -221,7 +221,7 @@ PR_LoadDebug (progs_t *pr)
|
|||
pr->debug = pr->load_file (pr, sym_path);
|
||||
if (!pr->debug) {
|
||||
Sys_Printf ("can't load %s for debug info\n", sym_path);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
pr->debug->version = LittleLong (pr->debug->version);
|
||||
if (pr->debug->version != PROG_DEBUG_VERSION) {
|
||||
|
@ -232,7 +232,7 @@ PR_LoadDebug (progs_t *pr)
|
|||
pr->debug->version & 0xfff);
|
||||
Hunk_FreeToLowMark (start);
|
||||
pr->debug = 0;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
pr->debug->crc = LittleShort (pr->debug->crc);
|
||||
if (pr->debug->crc != pr->crc) {
|
||||
|
@ -244,7 +244,7 @@ PR_LoadDebug (progs_t *pr)
|
|||
pr->crc);
|
||||
Hunk_FreeToLowMark (start);
|
||||
pr->debug = 0;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
pr->debug->you_tell_me_and_we_will_both_know = LittleShort
|
||||
(pr->debug->you_tell_me_and_we_will_both_know);
|
||||
|
@ -287,6 +287,7 @@ PR_LoadDebug (progs_t *pr)
|
|||
pr->local_defs[i].ofs = LittleShort (pr->local_defs[i].ofs);
|
||||
pr->local_defs[i].s_name = LittleLong (pr->local_defs[i].s_name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
pr_auxfunction_t *
|
||||
|
|
|
@ -265,6 +265,42 @@ PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts, int zone)
|
|||
((int *) pr->pr_globals)[i] = LittleLong (((int *) pr->pr_globals)[i]);
|
||||
}
|
||||
|
||||
void
|
||||
PR_AddLoadFunc (progs_t *pr, int (*func)(progs_t *))
|
||||
{
|
||||
if (pr->num_load_funcs == pr->max_load_funcs) {
|
||||
int n;
|
||||
pr->max_load_funcs += 8;
|
||||
n = pr->max_load_funcs;
|
||||
pr->load_funcs = realloc (pr->load_funcs,
|
||||
n * sizeof (pr_load_func_t *));
|
||||
SYS_CHECKMEM (pr->load_funcs);
|
||||
}
|
||||
pr->load_funcs[pr->num_load_funcs++] = func;
|
||||
}
|
||||
|
||||
static int (*load_funcs[])(progs_t *) = {
|
||||
PR_ResolveGlobals,
|
||||
PR_Check_Opcodes,
|
||||
PR_LoadStrings,
|
||||
PR_LoadDebug,
|
||||
};
|
||||
|
||||
int
|
||||
PR_RunLoadFuncs (progs_t *pr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof (load_funcs) / sizeof (load_funcs[0]); i++)
|
||||
if (!load_funcs[i](pr))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < pr->num_load_funcs; i++)
|
||||
if (!pr->load_funcs[i](pr))
|
||||
return 0;
|
||||
return PR_InitRuntime (pr);
|
||||
}
|
||||
|
||||
/*
|
||||
PR_LoadProgs
|
||||
*/
|
||||
|
@ -282,20 +318,8 @@ PR_LoadProgs (progs_t *pr, const char *progsname, int edicts, int zone)
|
|||
if (!pr->progs)
|
||||
return;
|
||||
|
||||
if (!PR_RelocateBuiltins (pr))
|
||||
if (!PR_RunLoadFuncs (pr))
|
||||
PR_Error (pr, "unable to load %s", progsname);
|
||||
|
||||
if (!PR_ResolveGlobals (pr))
|
||||
PR_Error (pr, "unable to load %s", progsname);
|
||||
|
||||
// initialise the strings managment code
|
||||
PR_LoadStrings (pr);
|
||||
|
||||
PR_LoadDebug (pr);
|
||||
|
||||
PR_Check_Opcodes (pr);
|
||||
|
||||
PR_InitRuntime (pr);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -965,7 +965,7 @@ PR_Obj_Progs_Init (progs_t *pr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
PR_InitRuntime (progs_t *pr)
|
||||
{
|
||||
int fnum;
|
||||
|
@ -1019,4 +1019,5 @@ PR_InitRuntime (progs_t *pr)
|
|||
finish_category (pr, *category);
|
||||
}
|
||||
free (category_list);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1057,43 +1057,71 @@ error:
|
|||
(long)(st - pr->pr_statements), op->opname);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
PR_Check_Opcodes (progs_t *pr)
|
||||
{
|
||||
opcode_t *op;
|
||||
dstatement_t *st;
|
||||
int state_ok = 0;
|
||||
unsigned i;
|
||||
|
||||
if (!pr_boundscheck->int_val)
|
||||
return;
|
||||
for (st = pr->pr_statements;
|
||||
(unsigned long) (st - pr->pr_statements) < pr->progs->numstatements;
|
||||
st++) {
|
||||
op = PR_Opcode (st->op);
|
||||
if (!op) {
|
||||
PR_Error (pr,
|
||||
"PR_Check_Opcodes: unknown opcode %d at statement %ld",
|
||||
st->op, (long)(st - pr->pr_statements));
|
||||
if (pr->globals.time && pr->globals.self && pr->fields.nextthink != -1
|
||||
&& pr->fields.think != -1 && pr->fields.frame != -1)
|
||||
state_ok = 1;
|
||||
|
||||
if (!pr_boundscheck->int_val) {
|
||||
for (i = 0, st = pr->pr_statements; i < pr->progs->numstatements;
|
||||
st++, i++) {
|
||||
op = PR_Opcode (st->op);
|
||||
if (!op) {
|
||||
PR_Error (pr, "PR_Check_Opcodes: unknown opcode %d at "
|
||||
"statement %ld", st->op,
|
||||
(long)(st - pr->pr_statements));
|
||||
}
|
||||
if (st->op == OP_STATE && !state_ok) {
|
||||
PR_Error (pr, "PR_Check_Opcodes: %s used with missing fields "
|
||||
"or globals", op->opname);
|
||||
}
|
||||
}
|
||||
switch (st->op) {
|
||||
case OP_IF:
|
||||
case OP_IFNOT:
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_branch (pr, st, op, st->b);
|
||||
break;
|
||||
case OP_GOTO:
|
||||
check_branch (pr, st, op, st->a);
|
||||
break;
|
||||
case OP_DONE:
|
||||
case OP_RETURN:
|
||||
check_global (pr, st, op, ev_integer, st->a);
|
||||
check_global (pr, st, op, ev_void, st->b);
|
||||
check_global (pr, st, op, ev_void, st->c);
|
||||
break;
|
||||
default:
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_global (pr, st, op, op->type_b, st->b);
|
||||
check_global (pr, st, op, op->type_c, st->c);
|
||||
break;
|
||||
} else {
|
||||
for (i = 0, st = pr->pr_statements; i < pr->progs->numstatements;
|
||||
st++, i++) {
|
||||
op = PR_Opcode (st->op);
|
||||
if (!op) {
|
||||
PR_Error (pr, "PR_Check_Opcodes: unknown opcode %d at "
|
||||
"statement %ld", st->op,
|
||||
(long)(st - pr->pr_statements));
|
||||
}
|
||||
switch (st->op) {
|
||||
case OP_IF:
|
||||
case OP_IFNOT:
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_branch (pr, st, op, st->b);
|
||||
break;
|
||||
case OP_GOTO:
|
||||
check_branch (pr, st, op, st->a);
|
||||
break;
|
||||
case OP_DONE:
|
||||
case OP_RETURN:
|
||||
check_global (pr, st, op, ev_integer, st->a);
|
||||
check_global (pr, st, op, ev_void, st->b);
|
||||
check_global (pr, st, op, ev_void, st->c);
|
||||
break;
|
||||
case OP_STATE:
|
||||
if (!state_ok) {
|
||||
PR_Error (pr, "PR_Check_Opcodes: %s used with missing "
|
||||
"fields or globals", op->opname);
|
||||
}
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_global (pr, st, op, op->type_b, st->b);
|
||||
break;
|
||||
default:
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_global (pr, st, op, op->type_b, st->b);
|
||||
check_global (pr, st, op, op->type_c, st->c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -190,21 +190,14 @@ PR_ResolveGlobals (progs_t *pr)
|
|||
goto error;
|
||||
pr->pr_param_size = G_INT (pr, def->ofs);
|
||||
}
|
||||
if (!(def = PR_FindGlobal (pr, sym = "time")))
|
||||
goto error;
|
||||
pr->globals.time = &G_FLOAT (pr, def->ofs);
|
||||
if (!(def = PR_FindGlobal (pr, ".self")))
|
||||
if (!(def = PR_FindGlobal (pr, "self"))) {
|
||||
sym = "self";
|
||||
goto error;
|
||||
}
|
||||
pr->globals.self = &G_INT (pr, def->ofs);
|
||||
if ((pr->fields.nextthink = ED_GetFieldIndex (pr, sym = "nextthink")) == -1)
|
||||
goto error;
|
||||
if ((pr->fields.frame = ED_GetFieldIndex (pr, sym = "frame")) == -1)
|
||||
goto error;
|
||||
if ((pr->fields.think = ED_GetFieldIndex (pr, sym = "think")) == -1)
|
||||
goto error;
|
||||
if ((def = PR_FindGlobal (pr, "time")))
|
||||
pr->globals.time = &G_FLOAT (pr, def->ofs);
|
||||
if ((def = PR_FindGlobal (pr, ".self"))
|
||||
|| (def = PR_FindGlobal (pr, "self")))
|
||||
pr->globals.self = &G_INT (pr, def->ofs);
|
||||
pr->fields.nextthink = ED_GetFieldIndex (pr, sym = "nextthink");
|
||||
pr->fields.frame = ED_GetFieldIndex (pr, sym = "frame");
|
||||
pr->fields.think = ED_GetFieldIndex (pr, sym = "think");
|
||||
return 1;
|
||||
error:
|
||||
Sys_Printf ("%s: undefined symbol: %s\n", pr->progs_name, sym);
|
||||
|
|
|
@ -115,7 +115,7 @@ strref_free (void *_sr, void *_pr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
PR_LoadStrings (progs_t *pr)
|
||||
{
|
||||
char *end = pr->pr_strings + pr->pr_stringsize;
|
||||
|
@ -148,6 +148,7 @@ PR_LoadStrings (progs_t *pr)
|
|||
count++;
|
||||
}
|
||||
pr->num_strings = count;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue