mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-06 15:51:25 +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,
|
void PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts,
|
||||||
int zone);
|
int zone);
|
||||||
void PR_LoadProgs (progs_t *pr, const char *progsname, int edicts, int zone);
|
void PR_LoadProgs (progs_t *pr, const char *progsname, int edicts, int zone);
|
||||||
void PR_LoadStrings (progs_t *pr);
|
int PR_LoadStrings (progs_t *pr);
|
||||||
void PR_LoadDebug (progs_t *pr);
|
int PR_LoadDebug (progs_t *pr);
|
||||||
edict_t *PR_InitEdicts (progs_t *pr, int num_edicts);
|
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);
|
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_RelocateBuiltins (progs_t *pr);
|
||||||
int PR_ResolveGlobals (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
|
// PR Obj stuff
|
||||||
//
|
//
|
||||||
void PR_Obj_Progs_Init (progs_t *pr);
|
void PR_Obj_Progs_Init (progs_t *pr);
|
||||||
void PR_InitRuntime (progs_t *pr);
|
int PR_InitRuntime (progs_t *pr);
|
||||||
|
|
||||||
//
|
//
|
||||||
// PR Strings stuff
|
// PR Strings stuff
|
||||||
|
@ -268,7 +272,7 @@ extern const char *pr_gametype;
|
||||||
// PR Cmds stuff
|
// 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);
|
void PR_Cmds_Init (progs_t *pr);
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -300,6 +304,10 @@ struct progs_s {
|
||||||
struct hashtab_s *global_hash;
|
struct hashtab_s *global_hash;
|
||||||
struct hashtab_s *field_hash;
|
struct hashtab_s *field_hash;
|
||||||
|
|
||||||
|
int num_load_funcs;
|
||||||
|
int max_load_funcs;
|
||||||
|
pr_load_func_t **load_funcs;
|
||||||
|
|
||||||
// garbage collected strings
|
// garbage collected strings
|
||||||
strref_t *static_strings;
|
strref_t *static_strings;
|
||||||
strref_t **dynamic_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
|
// 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)
|
PF_VarString (progs_t *pr, int first)
|
||||||
{
|
{
|
||||||
char *out;
|
char *out;
|
||||||
|
|
|
@ -185,7 +185,7 @@ PR_Load_Source_File (progs_t *pr, const char *fname)
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
PR_LoadDebug (progs_t *pr)
|
PR_LoadDebug (progs_t *pr)
|
||||||
{
|
{
|
||||||
char *sym_path;
|
char *sym_path;
|
||||||
|
@ -202,7 +202,7 @@ PR_LoadDebug (progs_t *pr)
|
||||||
pr->local_defs = 0;
|
pr->local_defs = 0;
|
||||||
|
|
||||||
if (!pr_debug->int_val)
|
if (!pr_debug->int_val)
|
||||||
return;
|
return 1;
|
||||||
|
|
||||||
def = PR_FindGlobal (pr, ".debug_file");
|
def = PR_FindGlobal (pr, ".debug_file");
|
||||||
if (def)
|
if (def)
|
||||||
|
@ -210,7 +210,7 @@ PR_LoadDebug (progs_t *pr)
|
||||||
|
|
||||||
Hash_FlushTable (file_hash);
|
Hash_FlushTable (file_hash);
|
||||||
if (!str)
|
if (!str)
|
||||||
return;
|
return 1;
|
||||||
pr->debugfile = PR_GetString (pr, str->string_var);
|
pr->debugfile = PR_GetString (pr, str->string_var);
|
||||||
sym_file = QFS_SkipPath (pr->debugfile);
|
sym_file = QFS_SkipPath (pr->debugfile);
|
||||||
path_end = QFS_SkipPath (pr->progs_name);
|
path_end = QFS_SkipPath (pr->progs_name);
|
||||||
|
@ -221,7 +221,7 @@ PR_LoadDebug (progs_t *pr)
|
||||||
pr->debug = pr->load_file (pr, sym_path);
|
pr->debug = pr->load_file (pr, sym_path);
|
||||||
if (!pr->debug) {
|
if (!pr->debug) {
|
||||||
Sys_Printf ("can't load %s for debug info\n", sym_path);
|
Sys_Printf ("can't load %s for debug info\n", sym_path);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
pr->debug->version = LittleLong (pr->debug->version);
|
pr->debug->version = LittleLong (pr->debug->version);
|
||||||
if (pr->debug->version != PROG_DEBUG_VERSION) {
|
if (pr->debug->version != PROG_DEBUG_VERSION) {
|
||||||
|
@ -232,7 +232,7 @@ PR_LoadDebug (progs_t *pr)
|
||||||
pr->debug->version & 0xfff);
|
pr->debug->version & 0xfff);
|
||||||
Hunk_FreeToLowMark (start);
|
Hunk_FreeToLowMark (start);
|
||||||
pr->debug = 0;
|
pr->debug = 0;
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
pr->debug->crc = LittleShort (pr->debug->crc);
|
pr->debug->crc = LittleShort (pr->debug->crc);
|
||||||
if (pr->debug->crc != pr->crc) {
|
if (pr->debug->crc != pr->crc) {
|
||||||
|
@ -244,7 +244,7 @@ PR_LoadDebug (progs_t *pr)
|
||||||
pr->crc);
|
pr->crc);
|
||||||
Hunk_FreeToLowMark (start);
|
Hunk_FreeToLowMark (start);
|
||||||
pr->debug = 0;
|
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 = LittleShort
|
||||||
(pr->debug->you_tell_me_and_we_will_both_know);
|
(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].ofs = LittleShort (pr->local_defs[i].ofs);
|
||||||
pr->local_defs[i].s_name = LittleLong (pr->local_defs[i].s_name);
|
pr->local_defs[i].s_name = LittleLong (pr->local_defs[i].s_name);
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_auxfunction_t *
|
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]);
|
((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
|
PR_LoadProgs
|
||||||
*/
|
*/
|
||||||
|
@ -282,20 +318,8 @@ PR_LoadProgs (progs_t *pr, const char *progsname, int edicts, int zone)
|
||||||
if (!pr->progs)
|
if (!pr->progs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!PR_RelocateBuiltins (pr))
|
if (!PR_RunLoadFuncs (pr))
|
||||||
PR_Error (pr, "unable to load %s", progsname);
|
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
|
void
|
||||||
|
|
|
@ -965,7 +965,7 @@ PR_Obj_Progs_Init (progs_t *pr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
PR_InitRuntime (progs_t *pr)
|
PR_InitRuntime (progs_t *pr)
|
||||||
{
|
{
|
||||||
int fnum;
|
int fnum;
|
||||||
|
@ -1019,4 +1019,5 @@ PR_InitRuntime (progs_t *pr)
|
||||||
finish_category (pr, *category);
|
finish_category (pr, *category);
|
||||||
}
|
}
|
||||||
free (category_list);
|
free (category_list);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1057,22 +1057,40 @@ error:
|
||||||
(long)(st - pr->pr_statements), op->opname);
|
(long)(st - pr->pr_statements), op->opname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
PR_Check_Opcodes (progs_t *pr)
|
PR_Check_Opcodes (progs_t *pr)
|
||||||
{
|
{
|
||||||
opcode_t *op;
|
opcode_t *op;
|
||||||
dstatement_t *st;
|
dstatement_t *st;
|
||||||
|
int state_ok = 0;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
if (!pr_boundscheck->int_val)
|
if (pr->globals.time && pr->globals.self && pr->fields.nextthink != -1
|
||||||
return;
|
&& pr->fields.think != -1 && pr->fields.frame != -1)
|
||||||
for (st = pr->pr_statements;
|
state_ok = 1;
|
||||||
(unsigned long) (st - pr->pr_statements) < pr->progs->numstatements;
|
|
||||||
st++) {
|
if (!pr_boundscheck->int_val) {
|
||||||
|
for (i = 0, st = pr->pr_statements; i < pr->progs->numstatements;
|
||||||
|
st++, i++) {
|
||||||
op = PR_Opcode (st->op);
|
op = PR_Opcode (st->op);
|
||||||
if (!op) {
|
if (!op) {
|
||||||
PR_Error (pr,
|
PR_Error (pr, "PR_Check_Opcodes: unknown opcode %d at "
|
||||||
"PR_Check_Opcodes: unknown opcode %d at statement %ld",
|
"statement %ld", st->op,
|
||||||
st->op, (long)(st - pr->pr_statements));
|
(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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) {
|
switch (st->op) {
|
||||||
case OP_IF:
|
case OP_IF:
|
||||||
|
@ -1089,6 +1107,14 @@ PR_Check_Opcodes (progs_t *pr)
|
||||||
check_global (pr, st, op, ev_void, st->b);
|
check_global (pr, st, op, ev_void, st->b);
|
||||||
check_global (pr, st, op, ev_void, st->c);
|
check_global (pr, st, op, ev_void, st->c);
|
||||||
break;
|
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:
|
default:
|
||||||
check_global (pr, st, op, op->type_a, st->a);
|
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_b, st->b);
|
||||||
|
@ -1096,4 +1122,6 @@ PR_Check_Opcodes (progs_t *pr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,21 +190,14 @@ PR_ResolveGlobals (progs_t *pr)
|
||||||
goto error;
|
goto error;
|
||||||
pr->pr_param_size = G_INT (pr, def->ofs);
|
pr->pr_param_size = G_INT (pr, def->ofs);
|
||||||
}
|
}
|
||||||
if (!(def = PR_FindGlobal (pr, sym = "time")))
|
if ((def = PR_FindGlobal (pr, "time")))
|
||||||
goto error;
|
|
||||||
pr->globals.time = &G_FLOAT (pr, def->ofs);
|
pr->globals.time = &G_FLOAT (pr, def->ofs);
|
||||||
if (!(def = PR_FindGlobal (pr, ".self")))
|
if ((def = PR_FindGlobal (pr, ".self"))
|
||||||
if (!(def = PR_FindGlobal (pr, "self"))) {
|
|| (def = PR_FindGlobal (pr, "self")))
|
||||||
sym = "self";
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
pr->globals.self = &G_INT (pr, def->ofs);
|
pr->globals.self = &G_INT (pr, def->ofs);
|
||||||
if ((pr->fields.nextthink = ED_GetFieldIndex (pr, sym = "nextthink")) == -1)
|
pr->fields.nextthink = ED_GetFieldIndex (pr, sym = "nextthink");
|
||||||
goto error;
|
pr->fields.frame = ED_GetFieldIndex (pr, sym = "frame");
|
||||||
if ((pr->fields.frame = ED_GetFieldIndex (pr, sym = "frame")) == -1)
|
pr->fields.think = ED_GetFieldIndex (pr, sym = "think");
|
||||||
goto error;
|
|
||||||
if ((pr->fields.think = ED_GetFieldIndex (pr, sym = "think")) == -1)
|
|
||||||
goto error;
|
|
||||||
return 1;
|
return 1;
|
||||||
error:
|
error:
|
||||||
Sys_Printf ("%s: undefined symbol: %s\n", pr->progs_name, sym);
|
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)
|
PR_LoadStrings (progs_t *pr)
|
||||||
{
|
{
|
||||||
char *end = pr->pr_strings + pr->pr_stringsize;
|
char *end = pr->pr_strings + pr->pr_stringsize;
|
||||||
|
@ -148,6 +148,7 @@ PR_LoadStrings (progs_t *pr)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
pr->num_strings = count;
|
pr->num_strings = count;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue