X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=progsvm.h;h=e389f0f0516203f212daed08234b817db9c6eed3;hp=2bd376a4f88a7b671d756b3604a06871b0acecf7;hb=d191d2aae518b7fe21132a6c159554a350966978;hpb=e11263d3ea167699c332c40802df925881d8a58d diff --git a/progsvm.h b/progsvm.h index 2bd376a4..e389f0f0 100644 --- a/progsvm.h +++ b/progsvm.h @@ -30,7 +30,7 @@ The code uses void pointers instead. #define PROGSVM_H #include "pr_comp.h" // defs shared with qcc -//#include "progdefs.h" // generated by program cdefs +#include "progdefs.h" // generated by program cdefs /* typedef union vm_eval_s @@ -152,6 +152,13 @@ typedef union prvm_eval_s int edict; } prvm_eval_t; +typedef struct prvm_required_field_s +{ + int type; + const char *name; +} prvm_required_field_t; + + /*typedef struct prvm_link_s { int entitynumber; @@ -170,13 +177,37 @@ typedef struct prvm_edict_s { // engine-private fields (stored in dynamically resized array) //edict_engineprivate_t *e; - prvm_edict_private_t *e; + union + { + prvm_edict_private_t *required; + void *vp; + edict_engineprivate_t *server; + // add other private structs as you desire + // new structs have to start with the elements of prvm_edit_private_t + // e.g. a new struct has to either look like this: + // typedef struct server_edict_private_s { + // prvm_edict_private_t base; + // vec3_t moved_from; + // vec3_t moved_fromangles; + // ... } server_edict_private_t; + // or: + // typedef struct server_edict_private_s { + // qboolean free; + // float freetime; + // vec3_t moved_from; + // vec3_t moved_fromangles; + // ... } server_edict_private_t; + // However, the first one should be preferred. + } priv; // QuakeC fields (stored in dynamically resized array) - //entvars_t *v; - void *v; + union + { + void *vp; + entvars_t *server; + } fields; } prvm_edict_t; - -#define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((qbyte *)ed->v + fieldoffset) : NULL) + +#define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((qbyte *)ed->fields.vp + fieldoffset) : NULL) /*// this struct is the basic requirement for a qc prog typedef struct prvm_pr_globalvars_s @@ -216,28 +247,37 @@ typedef struct prvm_builtin_mem_s typedef void (*prvm_builtin_t) (void); +// [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 vm_prog_s +typedef struct prvm_prog_s { dprograms_t *progs; mfunction_t *functions; char *strings; + int stringssize; ddef_t *fielddefs; ddef_t *globaldefs; dstatement_t *statements; - //prvm_pr_globalvars_t*pr_global_struct; - float *globals; // same as pr_global_struct int edict_size; // in bytes int edictareasize; // LordHavoc: in bytes (for bound checking) - - mempool_t *progs_mempool; - mempool_t *edictstring_mempool; - prvm_builtin_t *builtins; - int numbuiltins; - + union { + float *generic; + globalvars_t *server; + } globals; + + int maxknownstrings; + int numknownstrings; + const char **knownstrings; + + // all memory allocations related to this vm_prog (code, edicts, strings) + mempool_t *progs_mempool; // [INIT] + + prvm_builtin_t *builtins; // [INIT] + int numbuiltins; // [INIT] + int argc; - + int trace; mfunction_t *xfunction; int xstatement; @@ -246,79 +286,83 @@ typedef struct vm_prog_s // thus increase the array, so depth wont be overwritten prvm_stack_t stack[PRVM_MAX_STACK_DEPTH+1]; int depth; - + int localstack[PRVM_LOCALSTACK_SIZE]; int localstack_used; - unsigned short crc; + unsigned short headercrc; // [INIT] + + unsigned short filecrc; //============================================================================ // until this point everything also exists (with the pr_ prefix) in the old vm // copies of some vars that were former read from sv int num_edicts; - int max_edicts; + // number of edicts for which space has been (should be) allocated + int max_edicts; // [INIT] + // used instead of the constant MAX_EDICTS + int limit_edicts; // [INIT] + + // number of reserved edicts (allocated from 1) + int reserved_edicts; // [INIT] + prvm_edict_t *edicts; void *edictsfields; void *edictprivate; // size of the engine private struct - int edictprivate_size; + int edictprivate_size; // [INIT] - // instead of sv_editcts_mempool - mempool_t *edicts_mempool; - // has to be updated every frame - so the vm time is up-to-date // AK changed so time will point to the time field (if there is one) else it points to _time // actually should be double, but qc doesnt support it float *time; float _time; - // name of the prog, e.g. "Server", "Client" or "Menu" (used in for text output) - char *name; + // name of the prog, e.g. "Server", "Client" or "Menu" (used for text output) + char *name; // [INIT] // flag - used to store general flags like PRVM_GE_SELF, etc. int flag; - char *extensionstring; + char *extensionstring; // [INIT] + + qboolean loadintoworld; // [INIT] // used to indicate whether a prog is loaded qboolean loaded; - // used instead of the constant MAX_EDICTS - int limit_edicts; - // prvm_builtin_mem_t *mem_list; // now passes as parameter of PRVM_LoadProgs -// char **required_func; +// char **required_func; // int numrequiredfunc; //============================================================================ - + ddef_t *self; // if self != 0 then there is a global self - + //============================================================================ // function pointers - - void (*begin_increase_edicts)(void); // used by PRVM_MEM_Increase_Edicts - void (*end_increase_edicts)(void); - - void (*init_edict)(int num); // used by PRVM_ED_ClearEdict - void (*free_edict)(prvm_edict_t *ed); // used by PRVM_ED_Free - void (*count_edicts)(void); // used by PRVM_ED_Count_f + void (*begin_increase_edicts)(void); // [INIT] used by PRVM_MEM_Increase_Edicts + void (*end_increase_edicts)(void); // [INIT] - qboolean (*load_edict)(prvm_edict_t *ent); // used by PRVM_ED_LoadFromFile + void (*init_edict)(prvm_edict_t *edict); // [INIT] used by PRVM_ED_ClearEdict + void (*free_edict)(prvm_edict_t *ed); // [INIT] used by PRVM_ED_Free - void (*init_cmd)(void); // used by PRVM_InitProg - void (*reset_cmd)(void); // used by PRVM_ResetProg + void (*count_edicts)(void); // [INIT] used by PRVM_ED_Count_f - void (*error_cmd)(void); + qboolean (*load_edict)(prvm_edict_t *ent); // [INIT] used by PRVM_ED_LoadFromFile -} prvm_prog_t; + void (*init_cmd)(void); // [INIT] used by PRVM_InitProg + void (*reset_cmd)(void); // [INIT] used by PRVM_ResetProg + + void (*error_cmd)(const char *format, ...); // [INIT] +} prvm_prog_t; extern prvm_prog_t * prog; @@ -332,25 +376,25 @@ extern prvm_prog_t prvm_prog_list[PRVM_MAXPROGS]; //============================================================================ // prvm_cmds part -extern prvm_builtin_t vm_sv_builtins[]; -extern prvm_builtin_t vm_cl_builtins[]; -extern prvm_builtin_t vm_m_builtins[]; +extern prvm_builtin_t vm_sv_builtins[]; +extern prvm_builtin_t vm_cl_builtins[]; +extern prvm_builtin_t vm_m_builtins[]; extern const int vm_sv_numbuiltins; extern const int vm_cl_numbuiltins; extern const int vm_m_numbuiltins; -extern char * vm_sv_extensions; -extern char * vm_cl_extensions; -extern char * vm_m_extensions; +extern char * vm_sv_extensions; +extern char * vm_cl_extensions; +extern char * vm_m_extensions; -void VM_SV_Cmd_Init(void); -void VM_SV_Cmd_Reset(void); +void VM_SV_Cmd_Init(void); +void VM_SV_Cmd_Reset(void); -void VM_CL_Cmd_Init(void); -void VM_CL_Cmd_Reset(void); +void VM_CL_Cmd_Init(void); +void VM_CL_Cmd_Reset(void); -void VM_M_Cmd_Init(void); +void VM_M_Cmd_Init(void); void VM_M_Cmd_Reset(void); void VM_Cmd_Init(void); @@ -360,7 +404,13 @@ void VM_Cmd_Reset(void); void PRVM_Init (void); void PRVM_ExecuteProgram (func_t fnum, const char *errormessage); -void PRVM_LoadProgs (const char *filename, int numrequiredfunc, char **required_func); + +#define PRVM_Alloc(buffersize) _PRVM_Alloc(buffersize, __FILE__, __LINE__) +#define PRVM_Free(buffer) _PRVM_Free(buffer, __FILE__, __LINE__) +#define PRVM_FreeAll() _PRVM_FreeAll(__FILE__, __LINE__) +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_f (void); @@ -368,14 +418,17 @@ void PRVM_PrintState(void); void PRVM_CrashAll (void); void PRVM_Crash (void); +int PRVM_ED_FindFieldOffset(const char *field); +ddef_t *PRVM_ED_FindField (const char *name); +mfunction_t *PRVM_ED_FindFunction (const char *name); + +void PRVM_MEM_IncreaseEdicts(void); + prvm_edict_t *PRVM_ED_Alloc (void); void PRVM_ED_Free (prvm_edict_t *ed); void PRVM_ED_ClearEdict (prvm_edict_t *e); -char *PRVM_ED_NewString (const char *string); -// returns a copy of the string allocated from the server's string heap - -void PRVM_ED_Print (prvm_edict_t *ed); +void PRVM_ED_Print(prvm_edict_t *ed); void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed); const char *PRVM_ED_ParseEdict (const char *data, prvm_edict_t *ent); @@ -386,33 +439,34 @@ 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) (((n) >= 0 && (n) < prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__)) +#define PRVM_EDICT_NUM_UNSIGNED(n) (((n) < prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__)) -//int NUM_FOR_EDICT_ERROR(edict_t *e); -#define PRVM_NUM_FOR_EDICT(e) ((prvm_edict_t *)(e) - prog->edicts) -//int NUM_FOR_EDICT(edict_t *e); +//int NUM_FOR_EDICT_ERROR(prvm_edict_t *e); +#define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts)) +//int PRVM_NUM_FOR_EDICT(prvm_edict_t *e); #define PRVM_NEXT_EDICT(e) ((e) + 1) #define PRVM_EDICT_TO_PROG(e) (PRVM_NUM_FOR_EDICT(e)) -//int PRVM_EDICT_TO_PROG(edict_t *e); +//int PRVM_EDICT_TO_PROG(prvm_edict_t *e); #define PRVM_PROG_TO_EDICT(n) (PRVM_EDICT_NUM(n)) -//edict_t *PRVM_PROG_TO_EDICT(int n); +//prvm_edict_t *PRVM_PROG_TO_EDICT(int n); //============================================================================ -#define PRVM_G_FLOAT(o) (prog->globals[o]) -#define PRVM_G_INT(o) (*(int *)&prog->globals[o]) -#define PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals[o])) +#define PRVM_G_FLOAT(o) (prog->globals.generic[o]) +#define PRVM_G_INT(o) (*(int *)&prog->globals.generic[o]) +#define PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals.generic[o])) #define PRVM_G_EDICTNUM(o) PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(o)) -#define PRVM_G_VECTOR(o) (&prog->globals[o]) -#define PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&prog->globals[o])) -//#define PRVM_G_FUNCTION(o) (*(func_t *)&prog->globals[o]) +#define PRVM_G_VECTOR(o) (&prog->globals.generic[o]) +#define PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&prog->globals.generic[o])) +//#define PRVM_G_FUNCTION(o) (*(func_t *)&prog->globals.generic[o]) // FIXME: make these go away? -#define PRVM_E_FLOAT(e,o) (((float*)e->v)[o]) -//#define PRVM_E_INT(e,o) (((int*)e->v)[o]) -//#define PRVM_E_VECTOR(e,o) (&((float*)e->v)[o]) -#define PRVM_E_STRING(e,o) (PRVM_GetString(*(string_t *)&((float*)e->v)[o])) +#define PRVM_E_FLOAT(e,o) (((float*)e->fields.vp)[o]) +#define PRVM_E_INT(e,o) (((int*)e->fields.vp)[o]) +//#define PRVM_E_VECTOR(e,o) (&((float*)e->fields.vp)[o]) +#define PRVM_E_STRING(e,o) (PRVM_GetString(*(string_t *)&((float*)e->fields.vp)[o])) extern int prvm_type_size[8]; // for consistency : I think a goal of this sub-project is to // make the new vm mostly independent from the old one, thus if it's necessary, I copy everything @@ -422,8 +476,11 @@ void PRVM_Init_Exec(void); void PRVM_ED_PrintEdicts_f (void); void PRVM_ED_PrintNum (int ent); -#define PRVM_GetString(num) (prog->strings + num) -#define PRVM_SetString(s) ((int) (s) ? (s - prog->strings) : 0) +const char *PRVM_GetString(int num); +int PRVM_SetQCString(const char *s); +int PRVM_SetEngineString(const char *s); +int PRVM_AllocString(int bufferlength, char **pointer); +void PRVM_FreeString(int num); //============================================================================ @@ -434,7 +491,7 @@ void PRVM_ED_PrintNum (int ent); #define PRVM_Begin if(prog != 0) Con_Printf("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__) #define PRVM_End prog = 0 #else -#define PRVM_Begin +#define PRVM_Begin #define PRVM_End prog = 0 #endif @@ -449,19 +506,27 @@ void PRVM_ED_PrintNum (int ent); // helper macro to make function pointer calls easier #define PRVM_GCALL(func) if(prog->func) prog->func -#define PRVM_ERROR Host_Error +#define PRVM_ERROR prog->error_cmd // other prog handling functions qboolean PRVM_SetProgFromString(const char *str); -void PRVM_SetProg(int prognr); +void PRVM_SetProg(int prognr); -void PRVM_InitProg(int prognr); -void PRVM_ResetProg(void); +/* +Initializing a vm: +Call InitProg with the num +Set up the fields marked with [INIT] in the prog struct +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); +void PRVM_ResetProg(void); qboolean PRVM_ProgLoaded(int prognr); -int PRVM_GetProgNr(void); - +int PRVM_GetProgNr(void); + // TODO: fill in the params //void PRVM_Create();