]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/source/fteqcc-src/progslib.h
Latest fteqcc and netradiant sources
[voretournament/voretournament.git] / misc / source / fteqcc-src / progslib.h
1
2 #ifndef PROGSLIB_H
3 #define PROGSLIB_H
4 #ifdef _MSC_VER
5         #define VARGS __cdecl
6 #endif
7 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
8         #define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
9 #endif
10 #ifndef LIKEPRINTF
11         #define LIKEPRINTF(x)
12 #endif
13 #ifndef VARGS
14         #define VARGS
15 #endif
16
17 #if defined(_M_IX86) || defined(__i386__)
18 //#define QCJIT
19 #endif
20
21 #ifdef QCJIT
22 #define ASMCALL VARGS
23 #else
24 #define ASMCALL
25 #endif
26 #define QCBUILTIN ASMCALL
27
28
29 struct edict_s;
30 struct entvars_s;
31 struct globalvars_s;
32 struct qcthread_s;
33 typedef struct progfuncs_s progfuncs_t;
34 typedef void (ASMCALL *builtin_t) (progfuncs_t *prinst, struct globalvars_s *gvars);
35
36 //used by progs engine. All nulls is reset.
37 typedef struct {
38         char *varname;
39         struct fdef_s *ofs32;
40
41         int spare[2];
42 } evalc_t;
43 #define sizeofevalc sizeof(evalc_t)
44 typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer, ev_integer, ev_variant, ev_struct, ev_union} etype_t;
45
46 //the number of pointers to variables (as opposed to functions - those are fine) in these structures is excessive.
47 //Many of the functions are also obsolete.
48 struct progfuncs_s {
49         int progsversion;       //PROGSTRUCT_VERSION
50
51
52         void    (*Configure)                            (progfuncs_t *prinst, int addressablesize, int max_progs);              //configure buffers and memory. Used to reset and must be called first. Flushes a running VM.
53         progsnum_t      (*LoadProgs)                    (progfuncs_t *prinst, char *s, int headercrc, builtin_t *builtins, int numbuiltins);    //load a progs
54         int             (*InitEnts)                                     (progfuncs_t *prinst, int max_ents);    //returns size of edicts for use with nextedict macro
55         void    (*ExecuteProgram)                       (progfuncs_t *prinst, func_t fnum);     //start execution
56         pbool   (*SwitchProgs)                          (progfuncs_t *prinst, progsnum_t num);  //switch to a different progs - this should be obsolete.
57         struct globalvars_s     *(*globals)             (progfuncs_t *prinst, progsnum_t num);  //get the globals of a progs
58         struct entvars_s        *(*entvars)             (progfuncs_t *prinst, struct edict_s *ent);     //return a pointer to the entvars of an ent. can be achieved via the edict_t structure instead, so obsolete.
59
60         void    (VARGS *RunError)                       (progfuncs_t *prinst, char *msg, ...) LIKEPRINTF(2);            //builtins call this to say there was a problem
61         void    (*PrintEdict)                           (progfuncs_t *prinst, struct edict_s *ed);      //get a listing of all vars on an edict (sent back via 'print')
62
63         struct edict_s  *(*EntAlloc)            (progfuncs_t *prinst);
64         void    (*EntFree)                                      (progfuncs_t *prinst, struct edict_s *ed);
65
66         struct edict_s  *(*EDICT_NUM)           (progfuncs_t *prinst, unsigned int n);          //get the nth edict
67         unsigned int            (*NUM_FOR_EDICT)                        (progfuncs_t *prinst, struct edict_s *e);       //so you can find out what that 'n' will be
68
69         void    (*SetGlobalEdict)                       (progfuncs_t *prinst, struct edict_s *ed, int ofs);     //set a global to an edict (partially obsolete)
70
71         char    *(*VarString)                           (progfuncs_t *prinst, int       first); //returns a string made up of multiple arguments
72
73         struct progstate_s **progstate; //internal to the library.
74
75         func_t  (*FindFunction)                         (progfuncs_t *prinst, char *funcname, progsnum_t num);
76
77         int             (*StartCompile)                         (progfuncs_t *prinst, int argv, char **argc);   //1 if can compile, 0 if failed to compile
78         int             (*ContinueCompile)                      (progfuncs_t *prinst);  //2 if finished, 1 if more to go, 0 if failed
79
80         char    *(*filefromprogs)                       (progfuncs_t *prinst, progsnum_t prnum, char *fname, int *size, char *buffer);  //reveals encoded/added files from already loaded progs
81         char    *(*filefromnewprogs)            (progfuncs_t *prinst, char *prname, char *fname, int *size, char *buffer);      //reveals encoded/added files from a progs on the disk somewhere
82
83         char    *(*save_ents)                           (progfuncs_t *prinst, char *buf, int *size, int mode);  //dump the entire progs info into one big self allocated string
84         int             (*load_ents)                            (progfuncs_t *prinst, char *s, float killonspawnflags); //restore the entire progs state (or just add some more ents) (returns edicts ize)
85
86         char    *(*saveent)                                     (progfuncs_t *prinst, char *buf, int *size, struct edict_s *ed);        //will save just one entities vars
87         struct edict_s  *(*restoreent)          (progfuncs_t *prinst, char *buf, int *size, struct edict_s *ed);        //will restore the entity that had it's values saved (can use NULL for ed)
88
89         union eval_s    *(*FindGlobal)          (progfuncs_t *prinst, char *name, progsnum_t num, etype_t *type);       //find a pointer to the globals value
90         char    *(*AddString)                           (progfuncs_t *prinst, char *val, int minlength);        //dump a string into the progs memory (for setting globals and whatnot)
91         void    *(*Tempmem)                                     (progfuncs_t *prinst, int ammount, char *whatfor);      //grab some mem for as long as the progs stays loaded
92
93         union eval_s    *(*GetEdictFieldValue)  (progfuncs_t *prinst, struct edict_s *ent, char *name, evalc_t *s); //get an entityvar (cache it) and return the possible values
94         struct edict_s  *(*ProgsToEdict)        (progfuncs_t *prinst, int progs);       //edicts are stored as ints and need to be adjusted
95         int             (*EdictToProgs)                         (progfuncs_t *prinst, struct edict_s *ed);              //edicts are stored as ints and need to be adjusted
96
97         char    *(*EvaluateDebugString)         (progfuncs_t *prinst, char *key);       //evaluate a string and return it's value (according to current progs) (expands edict vars)
98
99         int             *pr_trace;      //start calling the editor for each line executed       
100
101         void    (*StackTrace)                           (progfuncs_t *prinst);
102         
103         int             (*ToggleBreak)                          (progfuncs_t *prinst, char *filename, int linenum, int mode);
104
105         int             numprogs;
106
107         struct  progexterns_s *parms;   //these are the initial parms, they may be changed
108
109         pbool   (*Decompile)                            (progfuncs_t *prinst, char *fname);
110
111
112         struct prinst_s *prinst;        //internal variables. Leave alone.
113
114         int             *callargc;      //number of args of built-in call
115         void    (*RegisterBuiltin)                      (progfuncs_t *prinst, char *, builtin_t);
116
117         char *stringtable;      //qc strings are all relative. add to a qc string. this is required for support of frikqcc progs that strip string immediates.
118         int fieldadjust;        //FrikQCC style arrays can cause problems due to field remapping. This causes us to leave gaps but offsets identical.
119
120         struct qcthread_s *(*Fork)                      (progfuncs_t *prinst);  //returns a pointer to a thread which can be resumed via RunThread.
121         void    (*RunThread)                            (progfuncs_t *prinst, struct qcthread_s *thread);
122         void    (*AbortStack)                           (progfuncs_t *prinst);  //annigilates the current stack, positioning on a return statement. It is expected that this is only used via a builtin!
123
124         int lastcalledbuiltinnumber;                    //useful with non-implemented opcodes.
125
126         int (*RegisterFieldVar)                         (progfuncs_t *prinst, unsigned int type, char *name, signed long requestedpos, signed long originalofs);
127
128         char    *tempstringbase;                                //for engine's use. Store your base tempstring pointer here.
129         int             tempstringnum;                  //for engine's use.
130
131         string_t (*TempString)                          (progfuncs_t *prinst, char *str);
132
133         string_t (*StringToProgs)                       (progfuncs_t *prinst, char *str);
134         char *(ASMCALL *StringToNative)                         (progfuncs_t *prinst, string_t str);
135         int stringtablesize;
136
137         int (*QueryField)                                       (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache);       //find info on a field definition at an offset
138
139         void (*EntClear)                                        (progfuncs_t *progfuncs, struct edict_s *e);
140         void (*FindPrefixGlobals)                       (progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) );
141 };
142
143 typedef struct progexterns_s {
144         int progsversion;       //PROGSTRUCT_VERSION
145
146         unsigned char *(*ReadFile) (const char *fname, void *buffer, int len);
147         int (*FileSize) (const char *fname);    //-1 if file does not exist
148         pbool (*WriteFile) (const char *name, void *data, int len);
149         int (VARGS *printf) (const char *, ...) LIKEPRINTF(1);
150         void (VARGS *Sys_Error) (const char *, ...) LIKEPRINTF(1);
151         void (VARGS *Abort) (char *, ...) LIKEPRINTF(1);
152         int edictsize;  //size of edict_t
153
154         void (*entspawn) (struct edict_s *ent, int loading);    //ent has been spawned, but may not have all the extra variables (that may need to be set) set
155         pbool (*entcanfree) (struct edict_s *ent);      //return true to stop ent from being freed
156         void (ASMCALL *stateop) (progfuncs_t *prinst, float var, func_t func);  //what to do on qc's state opcode.
157         void (ASMCALL *cstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc);             //a hexen2 opcode.
158         void (ASMCALL *cwstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc);    //a hexen2 opcode.
159         void (ASMCALL *thinktimeop) (progfuncs_t *prinst, struct edict_s *ent, float varb);                     //a hexen2 opcode.
160
161
162         //used when loading a game
163         builtin_t *(*builtinsfor) (int num, int headercrc);     //must return a pointer to the builtins that were used before the state was saved.
164         void (*loadcompleate) (int edictsize);  //notification to reset any pointers.
165         pbool (*badfield)(progfuncs_t *prinst, struct edict_s *ent, const char *keyname, const char *value);    //called for any fields that are not registered
166
167         void *(VARGS *memalloc) (int size);     //small string allocation       malloced and freed randomly by the executor. (use malloc if you want)
168         void (VARGS *memfree) (void * mem);
169
170
171         builtin_t *globalbuiltins;      //these are available to all progs
172         int numglobalbuiltins;
173
174         enum {PR_NOCOMPILE, PR_COMPILENEXIST, PR_COMPILEEXISTANDCHANGED, PR_COMPILECHANGED, PR_COMPILEALWAYS, PR_COMPILEIGNORE} autocompile;
175
176         double *gametime;       //used to prevent the vm from reusing an entity faster than 2 secs.
177
178         struct edict_s **sv_edicts;     //pointer to the engine's reference to world.
179         unsigned int *sv_num_edicts;            //pointer to the engine's edict count.
180
181         int (*useeditor) (progfuncs_t *prinst, char *filename, int line, int nump, char **parms);       //called on syntax errors or step-by-step debugging.
182 } progparms_t, progexterns_t;
183
184 //FIXMEs
185 void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size);
186 void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *relstringtable);
187 void ED_Print(progfuncs_t *progfuncs, struct edict_s *ed);
188 char *PR_RemoveProgsString(progfuncs_t *progfuncs, string_t str);
189 int PR_GetFuncArgCount(progfuncs_t *progfuncs, func_t func);
190
191 #if defined(QCLIBDLL_EXPORTS)
192 __declspec(dllexport)
193 #endif
194 progfuncs_t * InitProgs(progparms_t *ext);
195 #if defined(QCLIBDLL_EXPORTS)
196 __declspec(dllexport)
197 #endif
198 void CloseProgs(progfuncs_t *inst);
199
200 #ifndef COMPILER
201 typedef union eval_s
202 {
203         string_t                string;
204         float                   _float;
205         float                   _vector[3];
206         func_t                  function;
207         int                             _int;
208         int                             edict;
209         progsnum_t              prog;   //so it can easily be changed
210 } eval_t;
211 #endif
212
213 #define PR_CURRENT      -1
214 #define PR_ANY  -2      //not always valid. Use for finding funcs
215 #define PR_ANYBACK -3
216 #define PROGSTRUCT_VERSION 2
217
218
219 #ifndef DLL_PROG
220 #define PR_Configure(pf, memsize, max_progs)                            (*pf->Configure)                        (pf, memsize, max_progs)
221 #define PR_LoadProgs(pf, s, headercrc, builtins, numb)          (*pf->LoadProgs)                        (pf, s, headercrc, builtins, numb)
222 #define PR_InitEnts(pf, maxents)                                                        (*pf->InitEnts)                         (pf, maxents)
223 #define PR_ExecuteProgram(pf, fnum)                                                     (*pf->ExecuteProgram)           (pf, fnum)
224 #define PR_SwitchProgs(pf, num)                                                         (*pf->SwitchProgs)                      (pf, num)
225 #define PR_globals(pf, num)                                                                     (*pf->globals)                          (pf, num)
226 #define PR_entvars(pf, ent)                                                                     (*pf->entvars)                          (pf, ent)
227
228 #define PR_RegisterFieldVar(pf,type,name,reqofs,qcofs)          (*pf->RegisterFieldVar)         (pf,type,name,reqofs,qcofs)
229
230 #define ED_Alloc(pf)                                                                            (*pf->EntAlloc)                         (pf)
231 #define ED_Free(pf, ed)                                                                         (*pf->EntFree)                          (pf, ed)
232 #define ED_Clear(pf, ed)                                                                        (*pf->EntClear)                         (pf, ed)
233
234 #define PR_LoadEnts(pf, s, kf)                                                          (*pf->load_ents)                        (pf, s, kf)
235 #define PR_SaveEnts(pf, buf, size, mode)                                        (*pf->save_ents)                        (pf, buf, size, mode)
236
237 #define EDICT_NUM(pf, num)                                                                      (*pf->EDICT_NUM)                        (pf, num)
238 #define NUM_FOR_EDICT(pf, e)                                                            (*pf->NUM_FOR_EDICT)            (pf, e)
239 #define SetGlobalEdict(pf, ed, ofs)                                                     (*pf->SetGlobalEdict)           (pf, ed, ofs)
240 #define PR_VarString(pf,first)                                                          (*pf->VarString)                        (pf,first)
241
242 #define PR_StartCompile(pf,argc,argv)                                           (*pf->StartCompile)                     (pf,argc,argv)
243 #define PR_ContinueCompile(pf)                                                          (*pf->ContinueCompile)          (pf)
244
245 #define PR_StackTrace(pf)                                                                       (*pf->StackTrace)                       (pf)
246 #define PR_AbortStack(pf)                                                                       (*pf->AbortStack)                       (pf)
247
248 #define PR_RunError(pf,str)                                                                     (*pf->RunError)                         (pf,str)
249
250 #define PR_PrintEdict(pf,ed)                                                            (*pf->PrintEdict)                       (pf, ed)
251
252 #define PR_FindFunction(pf, name, num)                                          (*pf->FindFunction)                     (pf, name, num)
253 #define PR_FindGlobal(pf, name, progs, type)                            (*pf->FindGlobal)                       (pf, name, progs, type)
254 #define PR_AddString(pf, ed, len)                                                       (*pf->AddString)                        (pf, ed, len)
255 #define PR_Alloc(pf,size)                                                                       (*pf->Tempmem)                          (pf, size)
256
257 #define PROG_TO_EDICT(pf, ed)                                                           (*pf->ProgsToEdict)                     (pf, ed)
258 #define EDICT_TO_PROG(pf, ed)                                                           (*pf->EdictToProgs)                     (pf, (struct edict_s*)ed)
259
260 #define PR_RegisterBuiltin(pf, name, func)                                      (*pf->RegisterBuiltin)          (pf, name, func)
261
262 #define PR_GetString(pf,s)                                                                      (*pf->StringToNative)           (pf, s)
263 #define PR_GetStringOfs(pf,o)                                                           (*pf->StringToNative)           (pf, G_INT(o))
264 #define PR_SetString(pf, s)                                                                     (*pf->StringToProgs)            (pf, s)
265
266 #define NEXT_EDICT(pf,o)                EDICT_NUM(pf, NUM_FOR_EDICT(pf, o)+1)
267 #define RETURN_EDICT(pf, e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(pf, e))
268
269
270 //builtin funcs (which operate on globals)
271 //To use these outside of builtins, you will likly have to use the 'globals' method.
272 #define G_FLOAT(o) (((float *)pr_globals)[o])
273 #define G_FLOAT2(o) (((float *)pr_globals)[OFS_PARM0 + o*3])
274 #define G_INT(o) (((int *)pr_globals)[o])
275 #define G_EDICT(pf, o) PROG_TO_EDICT(pf, G_INT(o)) //((edict_t *)((char *) sv.edicts+ *(int *)&((float *)pr_globals)[o]))
276 #define G_EDICTNUM(pf, o) NUM_FOR_EDICT(pf, G_EDICT(pf, o))
277 #define G_VECTOR(o) (&((float *)pr_globals)[o])
278 #define G_FUNCTION(o) (*(func_t *)&((float *)pr_globals)[o])
279
280 /*
281 #define PR_GetString(p,s) (s?s + p->stringtable:"")
282 #define PR_GetStringOfs(p,o) (G_INT(o)?G_INT(o) + p->stringtable:"")
283 #define PR_SetStringOfs(p,o,s) (G_INT(o) = s - p->stringtable)
284 */
285 //#define PR_SetString(p, s) ((s&&*s)?(s - p->stringtable):0)
286 #define PR_NewString(p, s, l) PR_SetString(p, PR_AddString(p, s, l))
287 /**/
288
289 #define ev_prog ev_integer
290
291 #define E_STRING(o) (char *)(((int *)((char *)ed) + progparms.edictsize)[o])
292
293 //#define pr_global_struct pr_globals
294
295 #endif
296
297
298 #define OFS_NULL                0
299 #define OFS_RETURN              1
300 #define OFS_PARM0               4               // leave 3 ofs for each parm to hold vectors
301 #define OFS_PARM1               7
302 #define OFS_PARM2               10
303 #define OFS_PARM3               13
304 #define OFS_PARM4               16
305 #define OFS_PARM5               19
306 #define OFS_PARM6               22
307 #define OFS_PARM7               25
308 #define RESERVED_OFS    28
309
310
311 #undef edict_t
312 #undef globalvars_t
313
314 #endif //PROGSLIB_H