]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - progsvm.h
374
[xonotic/darkplaces.git] / progsvm.h
index 4f51861bf7941f6656da980a52e9c41c2bade6b9..077058bc4de8090225b5e0126e87a93383ab9d48 100644 (file)
--- 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;
@@ -173,7 +180,8 @@ typedef struct prvm_edict_s
        union
        {
                prvm_edict_private_t *required;
-               void                             *vp;
+               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:
@@ -192,14 +200,14 @@ typedef struct prvm_edict_s
                // However, the first one should be preferred.
        } priv;
        // QuakeC fields (stored in dynamically resized array)
-       //entvars_t *v;
-       union 
+       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
@@ -241,7 +249,7 @@ 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;
@@ -250,14 +258,23 @@ typedef struct vm_prog_s
        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)
 
+       int                                     *statement_linenums; // NULL if not available
+
+       union {
+               float *generic;
+               globalvars_t *server;
+       } globals;
+
        int                                     maxknownstrings;
        int                                     numknownstrings;
+       // this is updated whenever a string is removed or added
+       // (simple optimization of the free string search)
+       int                                     firstfreeknownstring;
        const char                      **knownstrings;
+       const char                      ***stringshash;
 
        // all memory allocations related to this vm_prog (code, edicts, strings)
        mempool_t                       *progs_mempool; // [INIT]
@@ -279,14 +296,23 @@ typedef struct vm_prog_s
        int                                     localstack[PRVM_LOCALSTACK_SIZE];
        int                                     localstack_used;
 
-       unsigned short          crc; // [INIT]
+       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;
@@ -309,12 +335,11 @@ typedef struct vm_prog_s
 
        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; // [INIT]
-
 //     prvm_builtin_mem_t  *mem_list;
 
 // now passes as parameter of PRVM_LoadProgs
@@ -331,7 +356,7 @@ typedef struct vm_prog_s
        void                            (*begin_increase_edicts)(void); // [INIT] used by PRVM_MEM_Increase_Edicts
        void                            (*end_increase_edicts)(void); // [INIT]
 
-       void                            (*init_edict)(int num); // [INIT] used by PRVM_ED_ClearEdict
+       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                            (*count_edicts)(void); // [INIT] used by PRVM_ED_Count_f
@@ -341,11 +366,10 @@ typedef struct vm_prog_s
        void                            (*init_cmd)(void); // [INIT] used by PRVM_InitProg
        void                            (*reset_cmd)(void); // [INIT] used by PRVM_ResetProg
 
-       void                            (*error_cmd)(void); // [INIT]
+       void                            (*error_cmd)(const char *format, ...); // [INIT]
 
 } prvm_prog_t;
 
-
 extern prvm_prog_t * prog;
 
 #define PRVM_MAXPROGS 3
@@ -386,7 +410,6 @@ 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__)
@@ -401,6 +424,12 @@ 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);
@@ -416,27 +445,28 @@ 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);
+//int NUM_FOR_EDICT_ERROR(prvm_edict_t *e);
 #define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts))
-//int NUM_FOR_EDICT(edict_t *e);
+//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->fields.vp)[o])
@@ -453,10 +483,9 @@ void PRVM_ED_PrintEdicts_f (void);
 void PRVM_ED_PrintNum (int ent);
 
 const char *PRVM_GetString(int num);
-int PRVM_SetQCString(const char *s);
 int PRVM_SetEngineString(const char *s);
-char *PRVM_AllocString(int bufferlength);
-void PRVM_FreeString(char *s);
+int PRVM_AllocString(int bufferlength, char **pointer);
+void PRVM_FreeString(int num);
 
 //============================================================================
 
@@ -482,18 +511,26 @@ void PRVM_FreeString(char *s);
 // 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