X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=progsvm.h;h=9794111c08ac435529bad883fe0ee1e38d493ecd;hp=f2fe16bc37d8247f6d0e748e0c3e1a797acedb27;hb=8c6898ab1f01b8efd78fea454b3f8654c4265ebb;hpb=631460dc33a02b110ac3b44227afbb4d19cd969d diff --git a/progsvm.h b/progsvm.h index f2fe16bc..9794111c 100644 --- a/progsvm.h +++ b/progsvm.h @@ -33,10 +33,20 @@ The code uses void pointers instead. #include "progdefs.h" // generated by program cdefs #include "clprogdefs.h" // generated by program cdefs +#ifndef DP_SMALLMEMORY +#define PROFILING +#endif + +// forward declaration of clgecko_t +struct clgecko_s; + typedef struct prvm_stack_s { int s; mfunction_t *f; + double tprofile_acc; + double profile_acc; + double builtinsprofile_acc; } prvm_stack_t; @@ -64,6 +74,8 @@ typedef struct prvm_edict_private_s { qboolean free; float freetime; + int mark; + const char *allocation_origin; } prvm_edict_private_t; typedef struct prvm_edict_s @@ -73,7 +85,7 @@ typedef struct prvm_edict_s union { prvm_edict_private_t *required; - void *vp; + vec_t *vp; // FIXME: this server pointer really means world, not server // (it is used by both server qc and client qc, but not menu qc) edict_engineprivate_t *server; @@ -97,202 +109,425 @@ typedef struct prvm_edict_s // QuakeC fields (stored in dynamically resized array) union { - void *vp; + vec_t *vp; entvars_t *server; cl_entvars_t *client; } fields; } prvm_edict_t; -#define PRVM_EDICTFIELDVALUE(ed, fieldoffset) (fieldoffset >= 0 ? (prvm_eval_t *)((int *)ed->fields.vp + fieldoffset) : NULL) -#define PRVM_GLOBALFIELDVALUE(fieldoffset) (fieldoffset >= 0 ? (prvm_eval_t *)((int *)prog->globals.generic + fieldoffset) : NULL) +extern prvm_eval_t prvm_badvalue; + +#define PRVM_alledictfloat(ed, fieldname) (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_alledictvector(ed, fieldname) (PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.fieldname)) +#define PRVM_alledictstring(ed, fieldname) (PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.fieldname)) +#define PRVM_alledictedict(ed, fieldname) (PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_alledictfunction(ed, fieldname) (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.fieldname)) +#define PRVM_allglobalfloat(fieldname) (PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.fieldname)) +#define PRVM_allglobalvector(fieldname) (PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.fieldname)) +#define PRVM_allglobalstring(fieldname) (PRVM_GLOBALFIELDSTRING(prog->globaloffsets.fieldname)) +#define PRVM_allglobaledict(fieldname) (PRVM_GLOBALFIELDEDICT(prog->globaloffsets.fieldname)) +#define PRVM_allglobalfunction(fieldname) (PRVM_GLOBALFIELDFUNCTION(prog->globaloffsets.fieldname)) +#define PRVM_allfunction(funcname) (prog->funcoffsets.funcname) + +#define PRVM_drawedictfloat(ed, fieldname) (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_drawedictvector(ed, fieldname) (PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.fieldname)) +#define PRVM_drawedictstring(ed, fieldname) (PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.fieldname)) +#define PRVM_drawedictedict(ed, fieldname) (PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_drawedictfunction(ed, fieldname) (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.fieldname)) +#define PRVM_drawglobalfloat(fieldname) (PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.fieldname)) +#define PRVM_drawglobalvector(fieldname) (PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.fieldname)) +#define PRVM_drawglobalstring(fieldname) (PRVM_GLOBALFIELDSTRING(prog->globaloffsets.fieldname)) +#define PRVM_drawglobaledict(fieldname) (PRVM_GLOBALFIELDEDICT(prog->globaloffsets.fieldname)) +#define PRVM_drawglobalfunction(fieldname) (PRVM_GLOBALFIELDFUNCTION(prog->globaloffsets.fieldname)) +#define PRVM_drawfunction(funcname) (prog->funcoffsets.funcname) + +#define PRVM_gameedictfloat(ed, fieldname) (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_gameedictvector(ed, fieldname) (PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.fieldname)) +#define PRVM_gameedictstring(ed, fieldname) (PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.fieldname)) +#define PRVM_gameedictedict(ed, fieldname) (PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_gameedictfunction(ed, fieldname) (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.fieldname)) +#define PRVM_gameglobalfloat(fieldname) (PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.fieldname)) +#define PRVM_gameglobalvector(fieldname) (PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.fieldname)) +#define PRVM_gameglobalstring(fieldname) (PRVM_GLOBALFIELDSTRING(prog->globaloffsets.fieldname)) +#define PRVM_gameglobaledict(fieldname) (PRVM_GLOBALFIELDEDICT(prog->globaloffsets.fieldname)) +#define PRVM_gameglobalfunction(fieldname) (PRVM_GLOBALFIELDFUNCTION(prog->globaloffsets.fieldname)) +#define PRVM_gamefunction(funcname) (prog->funcoffsets.funcname) + +#define PRVM_serveredictfloat(ed, fieldname) (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_serveredictvector(ed, fieldname) (PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.fieldname)) +#define PRVM_serveredictstring(ed, fieldname) (PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.fieldname)) +#define PRVM_serveredictedict(ed, fieldname) (PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_serveredictfunction(ed, fieldname) (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.fieldname)) +#define PRVM_serverglobalfloat(fieldname) (PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.fieldname)) +#define PRVM_serverglobalvector(fieldname) (PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.fieldname)) +#define PRVM_serverglobalstring(fieldname) (PRVM_GLOBALFIELDSTRING(prog->globaloffsets.fieldname)) +#define PRVM_serverglobaledict(fieldname) (PRVM_GLOBALFIELDEDICT(prog->globaloffsets.fieldname)) +#define PRVM_serverglobalfunction(fieldname) (PRVM_GLOBALFIELDFUNCTION(prog->globaloffsets.fieldname)) +#define PRVM_serverfunction(funcname) (prog->funcoffsets.funcname) + +#define PRVM_clientedictfloat(ed, fieldname) (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_clientedictvector(ed, fieldname) (PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.fieldname)) +#define PRVM_clientedictstring(ed, fieldname) (PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.fieldname)) +#define PRVM_clientedictedict(ed, fieldname) (PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_clientedictfunction(ed, fieldname) (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.fieldname)) +#define PRVM_clientglobalfloat(fieldname) (PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.fieldname)) +#define PRVM_clientglobalvector(fieldname) (PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.fieldname)) +#define PRVM_clientglobalstring(fieldname) (PRVM_GLOBALFIELDSTRING(prog->globaloffsets.fieldname)) +#define PRVM_clientglobaledict(fieldname) (PRVM_GLOBALFIELDEDICT(prog->globaloffsets.fieldname)) +#define PRVM_clientglobalfunction(fieldname) (PRVM_GLOBALFIELDFUNCTION(prog->globaloffsets.fieldname)) +#define PRVM_clientfunction(funcname) (prog->funcoffsets.funcname) + +#define PRVM_menuedictfloat(ed, fieldname) (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_menuedictvector(ed, fieldname) (PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.fieldname)) +#define PRVM_menuedictstring(ed, fieldname) (PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.fieldname)) +#define PRVM_menuedictedict(ed, fieldname) (PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.fieldname)) +#define PRVM_menuedictfunction(ed, fieldname) (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.fieldname)) +#define PRVM_menuglobalfloat(fieldname) (PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.fieldname)) +#define PRVM_menuglobalvector(fieldname) (PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.fieldname)) +#define PRVM_menuglobalstring(fieldname) (PRVM_GLOBALFIELDSTRING(prog->globaloffsets.fieldname)) +#define PRVM_menuglobaledict(fieldname) (PRVM_GLOBALFIELDEDICT(prog->globaloffsets.fieldname)) +#define PRVM_menuglobalfunction(fieldname) (PRVM_GLOBALFIELDFUNCTION(prog->globaloffsets.fieldname)) +#define PRVM_menufunction(funcname) (prog->funcoffsets.funcname) + +#if 1 +#define PRVM_EDICTFIELDVALUE(ed, fieldoffset) (fieldoffset < 0 ? Con_Printf("Invalid fieldoffset at %s:%i\n", __FILE__, __LINE__), &prvm_badvalue : (prvm_eval_t *)((int *)ed->fields.vp + fieldoffset)) +#define PRVM_EDICTFIELDFLOAT(ed, fieldoffset) (PRVM_EDICTFIELDVALUE(ed, fieldoffset)->_float) +#define PRVM_EDICTFIELDVECTOR(ed, fieldoffset) (PRVM_EDICTFIELDVALUE(ed, fieldoffset)->vector) +#define PRVM_EDICTFIELDSTRING(ed, fieldoffset) (PRVM_EDICTFIELDVALUE(ed, fieldoffset)->string) +#define PRVM_EDICTFIELDEDICT(ed, fieldoffset) (PRVM_EDICTFIELDVALUE(ed, fieldoffset)->edict) +#define PRVM_EDICTFIELDFUNCTION(ed, fieldoffset) (PRVM_EDICTFIELDVALUE(ed, fieldoffset)->function) +#define PRVM_GLOBALFIELDVALUE(fieldoffset) (fieldoffset < 0 ? Con_Printf("Invalid fieldoffset at %s:%i\n", __FILE__, __LINE__), &prvm_badvalue : (prvm_eval_t *)((int *)prog->globals.generic + fieldoffset)) +#define PRVM_GLOBALFIELDFLOAT(fieldoffset) (PRVM_GLOBALFIELDVALUE(fieldoffset)->_float) +#define PRVM_GLOBALFIELDVECTOR(fieldoffset) (PRVM_GLOBALFIELDVALUE(fieldoffset)->vector) +#define PRVM_GLOBALFIELDSTRING(fieldoffset) (PRVM_GLOBALFIELDVALUE(fieldoffset)->string) +#define PRVM_GLOBALFIELDEDICT(fieldoffset) (PRVM_GLOBALFIELDVALUE(fieldoffset)->edict) +#define PRVM_GLOBALFIELDFUNCTION(fieldoffset) (PRVM_GLOBALFIELDVALUE(fieldoffset)->function) +#else +#define PRVM_EDICTFIELDVALUE(ed, fieldoffset) ((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset)) +#define PRVM_EDICTFIELDFLOAT(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->_float) +#define PRVM_EDICTFIELDVECTOR(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->vector) +#define PRVM_EDICTFIELDSTRING(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->string) +#define PRVM_EDICTFIELDEDICT(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->edict) +#define PRVM_EDICTFIELDFUNCTION(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->function) +#define PRVM_GLOBALFIELDVALUE(fieldoffset) ((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset)) +#define PRVM_GLOBALFIELDFLOAT(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->_float) +#define PRVM_GLOBALFIELDVECTOR(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->vector) +#define PRVM_GLOBALFIELDSTRING(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->string) +#define PRVM_GLOBALFIELDEDICT(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->edict) +#define PRVM_GLOBALFIELDFUNCTION(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->function) +#endif //============================================================================ #define PRVM_OP_STATE 1 +#ifdef DP_SMALLMEMORY +#define PRVM_MAX_STACK_DEPTH 128 +#define PRVM_LOCALSTACK_SIZE 2048 + +#define PRVM_MAX_OPENFILES 16 +#define PRVM_MAX_OPENSEARCHES 8 +#define PRVM_MAX_GECKOINSTANCES 1 +#else #define PRVM_MAX_STACK_DEPTH 1024 #define PRVM_LOCALSTACK_SIZE 16384 #define PRVM_MAX_OPENFILES 256 #define PRVM_MAX_OPENSEARCHES 128 +#define PRVM_MAX_GECKOINSTANCES 32 +#endif typedef void (*prvm_builtin_t) (void); // NOTE: field offsets use -1 for NULL typedef struct prvm_prog_fieldoffsets_s { - // server and client use a lot of similar fields, so this is combined - int SendEntity; // ssqc - int Version; // ssqc - int alpha; // ssqc / csqc - int ammo_cells1; // ssqc - Dissolution of Eternity mission pack - int ammo_lava_nails; // ssqc - Dissolution of Eternity mission pack - int ammo_multi_rockets; // ssqc - Dissolution of Eternity mission pack - int ammo_nails1; // ssqc - Dissolution of Eternity mission pack - int ammo_plasma; // ssqc - Dissolution of Eternity mission pack - int ammo_rockets1; // ssqc - Dissolution of Eternity mission pack - int ammo_shells1; // ssqc - Dissolution of Eternity mission pack - int angles; // common - used by changeyaw/changepitch - int button3; // ssqc - int button4; // ssqc - int button5; // ssqc - int button6; // ssqc - int button7; // ssqc - int button8; // ssqc - int button9; // ssqc - int button10; // ssqc - int button11; // ssqc - int button12; // ssqc - int button13; // ssqc - int button14; // ssqc - int button15; // ssqc - int button16; // ssqc - int buttonchat; // ssqc - int buttonuse; // ssqc - int chain; // common - used by find builtins - int classname; // common - int clientcolors; // ssqc - int color; // ssqc - int colormod; // ssqc / csqc - int contentstransition; // ssqc - int cursor_active; // ssqc - int cursor_screen; // ssqc - int cursor_trace_endpos; // ssqc - int cursor_trace_ent; // ssqc - int cursor_trace_start; // ssqc - int customizeentityforclient; // ssqc - int dimension_hit; // ssqc / csqc - int dimension_solid; // ssqc / csqc - int disableclientprediction; // ssqc - int dphitcontentsmask; // ssqc / csqc - int drawonlytoclient; // ssqc - int effects; // ssqc / csqc - int exteriormodeltoclient; // ssqc - int fatness; // ssqc / csqc - int forceshader; // csqc - int frame1time; // csqc - int frame2; // csqc - int frame2time; // csqc - int frame; // common - used by OP_STATE - int fullbright; // ssqc - Nehahra support - int glow_color; // ssqc - int glow_size; // ssqc - int glow_trail; // ssqc - int gravity; // ssqc - int groundentity; // ssqc / csqc - int hull; // ssqc / csqc - int ideal_yaw; // ssqc / csqc - int idealpitch; // ssqc / csqc - int items2; // ssqc - int lerpfrac; // csqc - int light_lev; // ssqc - int modelflags; // ssqc - int movement; // ssqc - int nextthink; // common - used by OP_STATE - int netaddress; // ssqc - int nodrawtoclient; // ssqc - int pflags; // ssqc - int ping; // ssqc - int pitch_speed; // ssqc / csqc - int playermodel; // ssqc - int playerskin; // ssqc - int pmodel; // ssqc - int punchvector; // ssqc - int renderamt; // ssqc - HalfLife support - int renderflags; // csqc - int rendermode; // ssqc - HalfLife support - int scale; // ssqc / csqc - int style; // ssqc - int tag_entity; // ssqc / csqc - int tag_index; // ssqc / csqc - int think; // common - used by OP_STATE - int viewmodelforclient; // ssqc - int viewzoom; // ssqc - int yaw_speed; // ssqc / csqc +#define PRVM_DECLARE_serverglobalfloat(x) +#define PRVM_DECLARE_serverglobalvector(x) +#define PRVM_DECLARE_serverglobalstring(x) +#define PRVM_DECLARE_serverglobaledict(x) +#define PRVM_DECLARE_serverglobalfunction(x) +#define PRVM_DECLARE_clientglobalfloat(x) +#define PRVM_DECLARE_clientglobalvector(x) +#define PRVM_DECLARE_clientglobalstring(x) +#define PRVM_DECLARE_clientglobaledict(x) +#define PRVM_DECLARE_clientglobalfunction(x) +#define PRVM_DECLARE_menuglobalfloat(x) +#define PRVM_DECLARE_menuglobalvector(x) +#define PRVM_DECLARE_menuglobalstring(x) +#define PRVM_DECLARE_menuglobaledict(x) +#define PRVM_DECLARE_menuglobalfunction(x) +#define PRVM_DECLARE_serverfieldfloat(x) +#define PRVM_DECLARE_serverfieldvector(x) +#define PRVM_DECLARE_serverfieldstring(x) +#define PRVM_DECLARE_serverfieldedict(x) +#define PRVM_DECLARE_serverfieldfunction(x) +#define PRVM_DECLARE_clientfieldfloat(x) +#define PRVM_DECLARE_clientfieldvector(x) +#define PRVM_DECLARE_clientfieldstring(x) +#define PRVM_DECLARE_clientfieldedict(x) +#define PRVM_DECLARE_clientfieldfunction(x) +#define PRVM_DECLARE_menufieldfloat(x) +#define PRVM_DECLARE_menufieldvector(x) +#define PRVM_DECLARE_menufieldstring(x) +#define PRVM_DECLARE_menufieldedict(x) +#define PRVM_DECLARE_menufieldfunction(x) +#define PRVM_DECLARE_serverfunction(x) +#define PRVM_DECLARE_clientfunction(x) +#define PRVM_DECLARE_menufunction(x) +#define PRVM_DECLARE_field(x) int x; +#define PRVM_DECLARE_global(x) +#define PRVM_DECLARE_function(x) +#include "prvm_offsets.h" +#undef PRVM_DECLARE_serverglobalfloat +#undef PRVM_DECLARE_serverglobalvector +#undef PRVM_DECLARE_serverglobalstring +#undef PRVM_DECLARE_serverglobaledict +#undef PRVM_DECLARE_serverglobalfunction +#undef PRVM_DECLARE_clientglobalfloat +#undef PRVM_DECLARE_clientglobalvector +#undef PRVM_DECLARE_clientglobalstring +#undef PRVM_DECLARE_clientglobaledict +#undef PRVM_DECLARE_clientglobalfunction +#undef PRVM_DECLARE_menuglobalfloat +#undef PRVM_DECLARE_menuglobalvector +#undef PRVM_DECLARE_menuglobalstring +#undef PRVM_DECLARE_menuglobaledict +#undef PRVM_DECLARE_menuglobalfunction +#undef PRVM_DECLARE_serverfieldfloat +#undef PRVM_DECLARE_serverfieldvector +#undef PRVM_DECLARE_serverfieldstring +#undef PRVM_DECLARE_serverfieldedict +#undef PRVM_DECLARE_serverfieldfunction +#undef PRVM_DECLARE_clientfieldfloat +#undef PRVM_DECLARE_clientfieldvector +#undef PRVM_DECLARE_clientfieldstring +#undef PRVM_DECLARE_clientfieldedict +#undef PRVM_DECLARE_clientfieldfunction +#undef PRVM_DECLARE_menufieldfloat +#undef PRVM_DECLARE_menufieldvector +#undef PRVM_DECLARE_menufieldstring +#undef PRVM_DECLARE_menufieldedict +#undef PRVM_DECLARE_menufieldfunction +#undef PRVM_DECLARE_serverfunction +#undef PRVM_DECLARE_clientfunction +#undef PRVM_DECLARE_menufunction +#undef PRVM_DECLARE_field +#undef PRVM_DECLARE_global +#undef PRVM_DECLARE_function } prvm_prog_fieldoffsets_t; // NOTE: global offsets use -1 for NULL typedef struct prvm_prog_globaloffsets_s { - // server and client use a lot of similar globals, so this is combined - int SV_InitCmd; // ssqc - int self; // common - int time; // ssqc / csqc - int v_forward; // ssqc / csqc - int v_right; // ssqc / csqc - int v_up; // ssqc / csqc - int view_angles; // csqc - int trace_allsolid; // ssqc / csqc - int trace_startsolid; // ssqc / csqc - int trace_fraction; // ssqc / csqc - int trace_inwater; // ssqc / csqc - int trace_inopen; // ssqc / csqc - int trace_endpos; // ssqc / csqc - int trace_plane_normal; // ssqc / csqc - int trace_plane_dist; // ssqc / csqc - int trace_ent; // ssqc / csqc - int trace_dphitcontents; // ssqc / csqc - int trace_dphitq3surfaceflags; // ssqc / csqc - int trace_dphittexturename; // ssqc / csqc - int trace_dpstartcontents; // ssqc / csqc +#define PRVM_DECLARE_serverglobalfloat(x) +#define PRVM_DECLARE_serverglobalvector(x) +#define PRVM_DECLARE_serverglobalstring(x) +#define PRVM_DECLARE_serverglobaledict(x) +#define PRVM_DECLARE_serverglobalfunction(x) +#define PRVM_DECLARE_clientglobalfloat(x) +#define PRVM_DECLARE_clientglobalvector(x) +#define PRVM_DECLARE_clientglobalstring(x) +#define PRVM_DECLARE_clientglobaledict(x) +#define PRVM_DECLARE_clientglobalfunction(x) +#define PRVM_DECLARE_menuglobalfloat(x) +#define PRVM_DECLARE_menuglobalvector(x) +#define PRVM_DECLARE_menuglobalstring(x) +#define PRVM_DECLARE_menuglobaledict(x) +#define PRVM_DECLARE_menuglobalfunction(x) +#define PRVM_DECLARE_serverfieldfloat(x) +#define PRVM_DECLARE_serverfieldvector(x) +#define PRVM_DECLARE_serverfieldstring(x) +#define PRVM_DECLARE_serverfieldedict(x) +#define PRVM_DECLARE_serverfieldfunction(x) +#define PRVM_DECLARE_clientfieldfloat(x) +#define PRVM_DECLARE_clientfieldvector(x) +#define PRVM_DECLARE_clientfieldstring(x) +#define PRVM_DECLARE_clientfieldedict(x) +#define PRVM_DECLARE_clientfieldfunction(x) +#define PRVM_DECLARE_menufieldfloat(x) +#define PRVM_DECLARE_menufieldvector(x) +#define PRVM_DECLARE_menufieldstring(x) +#define PRVM_DECLARE_menufieldedict(x) +#define PRVM_DECLARE_menufieldfunction(x) +#define PRVM_DECLARE_serverfunction(x) +#define PRVM_DECLARE_clientfunction(x) +#define PRVM_DECLARE_menufunction(x) +#define PRVM_DECLARE_field(x) +#define PRVM_DECLARE_global(x) int x; +#define PRVM_DECLARE_function(x) +#include "prvm_offsets.h" +#undef PRVM_DECLARE_serverglobalfloat +#undef PRVM_DECLARE_serverglobalvector +#undef PRVM_DECLARE_serverglobalstring +#undef PRVM_DECLARE_serverglobaledict +#undef PRVM_DECLARE_serverglobalfunction +#undef PRVM_DECLARE_clientglobalfloat +#undef PRVM_DECLARE_clientglobalvector +#undef PRVM_DECLARE_clientglobalstring +#undef PRVM_DECLARE_clientglobaledict +#undef PRVM_DECLARE_clientglobalfunction +#undef PRVM_DECLARE_menuglobalfloat +#undef PRVM_DECLARE_menuglobalvector +#undef PRVM_DECLARE_menuglobalstring +#undef PRVM_DECLARE_menuglobaledict +#undef PRVM_DECLARE_menuglobalfunction +#undef PRVM_DECLARE_serverfieldfloat +#undef PRVM_DECLARE_serverfieldvector +#undef PRVM_DECLARE_serverfieldstring +#undef PRVM_DECLARE_serverfieldedict +#undef PRVM_DECLARE_serverfieldfunction +#undef PRVM_DECLARE_clientfieldfloat +#undef PRVM_DECLARE_clientfieldvector +#undef PRVM_DECLARE_clientfieldstring +#undef PRVM_DECLARE_clientfieldedict +#undef PRVM_DECLARE_clientfieldfunction +#undef PRVM_DECLARE_menufieldfloat +#undef PRVM_DECLARE_menufieldvector +#undef PRVM_DECLARE_menufieldstring +#undef PRVM_DECLARE_menufieldedict +#undef PRVM_DECLARE_menufieldfunction +#undef PRVM_DECLARE_serverfunction +#undef PRVM_DECLARE_clientfunction +#undef PRVM_DECLARE_menufunction +#undef PRVM_DECLARE_field +#undef PRVM_DECLARE_global +#undef PRVM_DECLARE_function } prvm_prog_globaloffsets_t; -// these are initialized using PRVM_ED_FindFunction // NOTE: function offsets use 0 for NULL typedef struct prvm_prog_funcoffsets_s { - func_t CSQC_ConsoleCommand; // csqc - func_t CSQC_Ent_Remove; // csqc - func_t CSQC_Ent_Update; // csqc - func_t CSQC_Event; // csqc [515]: engine call this for its own needs so csqc can do some things according to what engine it's running on. example: to say about edicts increase, whatever... - func_t CSQC_Init; // csqc - func_t CSQC_InputEvent; // csqc - func_t CSQC_Parse_CenterPrint; // csqc - func_t CSQC_Parse_Print; // csqc - func_t CSQC_Parse_StuffCmd; // csqc - func_t CSQC_Parse_TempEntity; // csqc [515]: very helpfull when you want to create your own particles/decals/etc for effects that already exist - func_t CSQC_Shutdown; // csqc - func_t CSQC_UpdateView; // csqc - func_t EndFrame; // ssqc - func_t RestoreGame; // ssqc - func_t SV_ChangeTeam; // ssqc - func_t SV_ParseClientCommand; // ssqc - func_t SV_PlayerPhysics; // ssqc - func_t GameCommand; // any - - // menu qc only uses some functions, nothing else - func_t m_display; // mqc - func_t m_draw; // mqc - func_t m_hide; // mqc - func_t m_init; // mqc - func_t m_keydown; // mqc - func_t m_keyup; // mqc - func_t m_shutdown; // mqc - func_t m_toggle; // mqc +#define PRVM_DECLARE_serverglobalfloat(x) +#define PRVM_DECLARE_serverglobalvector(x) +#define PRVM_DECLARE_serverglobalstring(x) +#define PRVM_DECLARE_serverglobaledict(x) +#define PRVM_DECLARE_serverglobalfunction(x) +#define PRVM_DECLARE_clientglobalfloat(x) +#define PRVM_DECLARE_clientglobalvector(x) +#define PRVM_DECLARE_clientglobalstring(x) +#define PRVM_DECLARE_clientglobaledict(x) +#define PRVM_DECLARE_clientglobalfunction(x) +#define PRVM_DECLARE_menuglobalfloat(x) +#define PRVM_DECLARE_menuglobalvector(x) +#define PRVM_DECLARE_menuglobalstring(x) +#define PRVM_DECLARE_menuglobaledict(x) +#define PRVM_DECLARE_menuglobalfunction(x) +#define PRVM_DECLARE_serverfieldfloat(x) +#define PRVM_DECLARE_serverfieldvector(x) +#define PRVM_DECLARE_serverfieldstring(x) +#define PRVM_DECLARE_serverfieldedict(x) +#define PRVM_DECLARE_serverfieldfunction(x) +#define PRVM_DECLARE_clientfieldfloat(x) +#define PRVM_DECLARE_clientfieldvector(x) +#define PRVM_DECLARE_clientfieldstring(x) +#define PRVM_DECLARE_clientfieldedict(x) +#define PRVM_DECLARE_clientfieldfunction(x) +#define PRVM_DECLARE_menufieldfloat(x) +#define PRVM_DECLARE_menufieldvector(x) +#define PRVM_DECLARE_menufieldstring(x) +#define PRVM_DECLARE_menufieldedict(x) +#define PRVM_DECLARE_menufieldfunction(x) +#define PRVM_DECLARE_serverfunction(x) +#define PRVM_DECLARE_clientfunction(x) +#define PRVM_DECLARE_menufunction(x) +#define PRVM_DECLARE_field(x) +#define PRVM_DECLARE_global(x) +#define PRVM_DECLARE_function(x) int x; +#include "prvm_offsets.h" +#undef PRVM_DECLARE_serverglobalfloat +#undef PRVM_DECLARE_serverglobalvector +#undef PRVM_DECLARE_serverglobalstring +#undef PRVM_DECLARE_serverglobaledict +#undef PRVM_DECLARE_serverglobalfunction +#undef PRVM_DECLARE_clientglobalfloat +#undef PRVM_DECLARE_clientglobalvector +#undef PRVM_DECLARE_clientglobalstring +#undef PRVM_DECLARE_clientglobaledict +#undef PRVM_DECLARE_clientglobalfunction +#undef PRVM_DECLARE_menuglobalfloat +#undef PRVM_DECLARE_menuglobalvector +#undef PRVM_DECLARE_menuglobalstring +#undef PRVM_DECLARE_menuglobaledict +#undef PRVM_DECLARE_menuglobalfunction +#undef PRVM_DECLARE_serverfieldfloat +#undef PRVM_DECLARE_serverfieldvector +#undef PRVM_DECLARE_serverfieldstring +#undef PRVM_DECLARE_serverfieldedict +#undef PRVM_DECLARE_serverfieldfunction +#undef PRVM_DECLARE_clientfieldfloat +#undef PRVM_DECLARE_clientfieldvector +#undef PRVM_DECLARE_clientfieldstring +#undef PRVM_DECLARE_clientfieldedict +#undef PRVM_DECLARE_clientfieldfunction +#undef PRVM_DECLARE_menufieldfloat +#undef PRVM_DECLARE_menufieldvector +#undef PRVM_DECLARE_menufieldstring +#undef PRVM_DECLARE_menufieldedict +#undef PRVM_DECLARE_menufieldfunction +#undef PRVM_DECLARE_serverfunction +#undef PRVM_DECLARE_clientfunction +#undef PRVM_DECLARE_menufunction +#undef PRVM_DECLARE_field +#undef PRVM_DECLARE_global +#undef PRVM_DECLARE_function } prvm_prog_funcoffsets_t; +// stringbuffer flags +#define STRINGBUFFER_SAVED 1 // saved in savegames + +typedef struct prvm_stringbuffer_s +{ + int max_strings; + int num_strings; + char **strings; + const char *origin; + unsigned char flags; +} +prvm_stringbuffer_t; + // [INIT] variables flagged with this token can be initialized by 'you' // NOTE: external code has to create and free the mempools but everything else is done by prvm ! typedef struct prvm_prog_s { - dprograms_t *progs; + double starttime; + unsigned int id; // increasing unique id of progs instance mfunction_t *functions; char *strings; int stringssize; ddef_t *fielddefs; ddef_t *globaldefs; - dstatement_t *statements; - int edict_size; // in bytes - int edictareasize; // LordHavoc: in bytes (for bound checking) + mstatement_t *statements; + int entityfields; // number of vec_t fields in progs (some variables are 3) + int entityfieldsarea; // LordHavoc: equal to max_edicts * entityfields (for bounds checking) + + // loaded values from the disk format + int progs_version; + int progs_crc; + int progs_numstatements; + int progs_numglobaldefs; + int progs_numfielddefs; + int progs_numfunctions; + int progs_numstrings; + int progs_numglobals; + int progs_entityfields; + + // real values in memory (some modified by loader) + int numstatements; + int numglobaldefs; + int numfielddefs; + int numfunctions; + int numstrings; + int numglobals; int *statement_linenums; // NULL if not available double *statement_profile; // only incremented if prvm_statementprofiling is on union { - float *generic; + vec_t *generic; globalvars_t *server; cl_globalvars_t *client; } globals; @@ -303,9 +538,12 @@ typedef struct prvm_prog_s // (simple optimization of the free string search) int firstfreeknownstring; const char **knownstrings; - unsigned char *knownstrings_freeable; + unsigned char *knownstrings_freeable; + const char **knownstrings_origin; const char ***stringshash; + memexpandablearray_t stringbuffersarray; + // all memory allocations related to this vm_prog (code, edicts, strings) mempool_t *progs_mempool; // [INIT] @@ -327,6 +565,7 @@ typedef struct prvm_prog_s int localstack_used; unsigned short headercrc; // [INIT] + unsigned short headercrc2; // [INIT] alternate CRC for tenebrae progs.dat unsigned short filecrc; @@ -334,7 +573,11 @@ typedef struct prvm_prog_s // until this point everything also exists (with the pr_ prefix) in the old vm qfile_t *openfiles[PRVM_MAX_OPENFILES]; + const char * openfiles_origin[PRVM_MAX_OPENFILES]; fssearch_t *opensearches[PRVM_MAX_OPENSEARCHES]; + const char * opensearches_origin[PRVM_MAX_OPENSEARCHES]; + struct clgecko_s *opengeckoinstances[PRVM_MAX_GECKOINSTANCES]; + skeleton_t *skeletons[MAX_EDICTS]; // copies of some vars that were former read from sv int num_edicts; @@ -347,32 +590,39 @@ typedef struct prvm_prog_s int reserved_edicts; // [INIT] prvm_edict_t *edicts; - void *edictsfields; - void *edictprivate; + vec_t *edictsfields; + void *edictprivate; // size of the engine private struct int edictprivate_size; // [INIT] prvm_prog_fieldoffsets_t fieldoffsets; prvm_prog_globaloffsets_t globaloffsets; - prvm_prog_funcoffsets_t funcoffsets; + prvm_prog_funcoffsets_t funcoffsets; // allow writing to world entity fields, this is set by server init and // cleared before first server frame qboolean allowworldwrites; // name of the prog, e.g. "Server", "Client" or "Menu" (used for text output) - char *name; // [INIT] + const char *name; // [INIT] // flag - used to store general flags like PRVM_GE_SELF, etc. - int flag; + int flag; - char *extensionstring; // [INIT] + const char *extensionstring; // [INIT] qboolean loadintoworld; // [INIT] // used to indicate whether a prog is loaded qboolean loaded; + qboolean leaktest_active; + + // translation buffer (only needs to be freed on unloading progs, type is private to prvm_edict.c) + void *po; + + // printed together with backtraces + const char *statestring; // prvm_builtin_mem_t *mem_list; @@ -402,6 +652,7 @@ typedef struct prvm_prog_s void (*error_cmd)(const char *format, ...) DP_FUNC_PRINTF(1); // [INIT] + void (*ExecuteProgram)(func_t fnum, const char *errormessage); // pointer to one of the *VM_ExecuteProgram functions } prvm_prog_t; extern prvm_prog_t * prog; @@ -424,8 +675,8 @@ extern const int vm_sv_numbuiltins; extern const int vm_cl_numbuiltins; extern const int vm_m_numbuiltins; -extern char * vm_sv_extensions; // client also uses this -extern char * vm_m_extensions; +extern const char * vm_sv_extensions; // client also uses this +extern const char * vm_m_extensions; void VM_SV_Cmd_Init(void); void VM_SV_Cmd_Reset(void); @@ -442,7 +693,16 @@ void VM_Cmd_Reset(void); void PRVM_Init (void); -void PRVM_ExecuteProgram (func_t fnum, const char *errormessage); +#ifdef PROFILING +void MVM_ExecuteProgram (func_t fnum, const char *errormessage); +void CLVM_ExecuteProgram (func_t fnum, const char *errormessage); +void SVVM_ExecuteProgram (func_t fnum, const char *errormessage); +#else +#define MVM_ExecuteProgram SVVM_ExecuteProgram +#define CLVM_ExecuteProgram SVVM_ExecuteProgram +void SVVM_ExecuteProgram (func_t fnum, const char *errormessage); +#endif +#define PRVM_ExecuteProgram prog->ExecuteProgram #define PRVM_Alloc(buffersize) _PRVM_Alloc(buffersize, __FILE__, __LINE__) #define PRVM_Free(buffer) _PRVM_Free(buffer, __FILE__, __LINE__) @@ -451,13 +711,17 @@ void *_PRVM_Alloc (size_t buffersize, const char *filename, int fileline); void _PRVM_Free (void *buffer, const char *filename, int fileline); void _PRVM_FreeAll (const char *filename, int fileline); -void PRVM_Profile (int maxfunctions, int mininstructions); +void PRVM_Profile (int maxfunctions, double mintime, int sortby); void PRVM_Profile_f (void); +void PRVM_ChildProfile_f (void); +void PRVM_CallProfile_f (void); void PRVM_PrintFunction_f (void); void PRVM_PrintState(void); void PRVM_CrashAll (void); void PRVM_Crash (void); +void PRVM_ShortStackTrace(char *buf, size_t bufsize); +const char *PRVM_AllocationOrigin(void); ddef_t *PRVM_ED_FindField(const char *name); ddef_t *PRVM_ED_FindGlobal(const char *name); @@ -471,6 +735,7 @@ func_t PRVM_ED_FindFunctionOffset(const char *name); void PRVM_MEM_IncreaseEdicts(void); +qboolean PRVM_ED_CanAlloc(prvm_edict_t *e); prvm_edict_t *PRVM_ED_Alloc (void); void PRVM_ED_Free (prvm_edict_t *ed); void PRVM_ED_ClearEdict (prvm_edict_t *e); @@ -485,8 +750,9 @@ void PRVM_ED_ParseGlobals (const char *data); void PRVM_ED_LoadFromFile (const char *data); -prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline); -#define PRVM_EDICT_NUM(n) (((unsigned)(n) < (unsigned int)prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__)) +unsigned int PRVM_EDICT_NUM_ERROR(unsigned int n, const char *filename, int fileline); +#define PRVM_EDICT(n) (((unsigned)(n) < (unsigned int)prog->max_edicts) ? (unsigned int)(n) : PRVM_EDICT_NUM_ERROR((unsigned int)(n), __FILE__, __LINE__)) +#define PRVM_EDICT_NUM(n) (prog->edicts + PRVM_EDICT(n)) //int NUM_FOR_EDICT_ERROR(prvm_edict_t *e); #define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts)) @@ -525,6 +791,7 @@ void PRVM_ED_PrintNum (int ent, const char *wildcard_fieldname); const char *PRVM_GetString(int num); int PRVM_SetEngineString(const char *s); +const char *PRVM_ChangeEngineString(int i, const char *s); int PRVM_SetTempString(const char *s); int PRVM_AllocString(size_t bufferlength, char **pointer); void PRVM_FreeString(int num); @@ -566,7 +833,7 @@ Load a program with LoadProgs */ void PRVM_InitProg(int prognr); // LoadProgs expects to be called right after InitProg -void PRVM_LoadProgs (const char *filename, int numrequiredfunc, char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, char **required_global); +void PRVM_LoadProgs (const char *filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global); void PRVM_ResetProg(void); qboolean PRVM_ProgLoaded(int prognr); @@ -578,4 +845,9 @@ void VM_Warning(const char *fmt, ...) DP_FUNC_PRINTF(1); // TODO: fill in the params //void PRVM_Create(); +void VM_GenerateFrameGroupBlend(framegroupblend_t *framegroupblend, const prvm_edict_t *ed); +void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroupblend_t *framegroupblend, const dp_model_t *model); +void VM_UpdateEdictSkeleton(prvm_edict_t *ed, const dp_model_t *edmodel, const frameblend_t *frameblend); +void VM_RemoveEdictSkeleton(prvm_edict_t *ed); + #endif