1 /*
2 Copyright (C) 1996-2001 Id Software, Inc.
3 Copyright (C) 2002-2009 John Fitzgibbons and others
4 Copyright (C) 2010-2014 QuakeSpasm developers
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 
21 */
22 
23 #ifndef _QUAKE_PROGS_H
24 #define _QUAKE_PROGS_H
25 
26 #include "pr_comp.h"	/* defs shared with qcc */
27 #include "progdefs.h"	/* generated by program cdefs */
28 
29 typedef union eval_s
30 {
31 	string_t	string;
32 	float		_float;
33 	float		vector[3];
34 	func_t		function;
35 	int		_int;
36 	int		edict;
37 } eval_t;
38 
39 #define	MAX_ENT_LEAFS	32
40 typedef struct edict_s
41 {
42 	qboolean	free;
43 	link_t		area;			/* linked to a division node or leaf */
44 
45 	unsigned int		num_leafs;
46 	int		leafnums[MAX_ENT_LEAFS];
47 
48 	entity_state_t	baseline;
49 	unsigned char	alpha;			/* johnfitz -- hack to support alpha since it's not part of entvars_t */
50 	qboolean	sendinterval;		/* johnfitz -- send time until nextthink to client for better lerp timing */
51 
52 	float		freetime;		/* sv.time when the object was freed */
53 	entvars_t	v;			/* C exported fields from progs */
54 
55 	/* other fields from progs come immediately after */
56 } edict_t;
57 
58 #define	EDICT_FROM_AREA(l)	STRUCT_FROM_LINK(l,edict_t,area)
59 
60 //============================================================================
61 
62 typedef void (*builtin_t) (void);
63 typedef struct qcvm_s qcvm_t;
64 
65 void PR_Init (void);
66 
67 void PR_ExecuteProgram (func_t fnum);
68 void PR_ClearProgs(qcvm_t *vm);
69 qboolean PR_LoadProgs (const char *filename, qboolean fatal, unsigned int needcrc, builtin_t *builtins, size_t numbuiltins);
70 
71 //from pr_ext.c
72 void PR_InitExtensions(void);
73 void PR_EnableExtensions(ddef_t *pr_globaldefs);	//adds in the extra builtins etc
74 void PR_AutoCvarChanged(cvar_t *var);				//updates the autocvar_ globals when their cvar is changed
75 void PR_ShutdownExtensions(void);					//nooooes!
76 void PR_ReloadPics(qboolean purge);					//for gamedir or video changes
77 func_t PR_FindExtFunction(const char *entryname);
78 void PR_DumpPlatform_f(void);						//console command: writes out a qsextensions.qc file
79 //special hacks...
80 int PF_SV_ForceParticlePrecache(const char *s);
81 int SV_Precache_Model(const char *s);
82 
83 //from pr_edict, for pr_ext. reflection is messy.
84 qboolean	ED_ParseEpair (void *base, ddef_t *key, const char *s, qboolean zoned);
85 const char *PR_UglyValueString (int type, eval_t *val);
86 ddef_t *ED_FindField (const char *name);
87 ddef_t *ED_FindGlobal (const char *name);
88 dfunction_t *ED_FindFunction (const char *fn_name);
89 
90 const char *PR_GetString (int num);
91 int PR_SetEngineString (const char *s);
92 int PR_AllocString (int bufferlength, char **ptr);
93 void PR_ClearEngineString(int num);
94 
95 void PR_Profile_f (void);
96 
97 edict_t *ED_Alloc (void);
98 void ED_Free (edict_t *ed);
99 
100 void ED_Print (edict_t *ed);
101 void ED_Write (FILE *f, edict_t *ed);
102 const char *ED_ParseEdict (const char *data, edict_t *ent);
103 
104 void ED_WriteGlobals (FILE *f);
105 const char *ED_ParseGlobals (const char *data);
106 
107 void ED_LoadFromFile (const char *data);
108 
109 /*
110 #define EDICT_NUM(n)		((edict_t *)(sv.edicts+ (n)*pr_edict_size))
111 #define NUM_FOR_EDICT(e)	(((byte *)(e) - sv.edicts) / pr_edict_size)
112 */
113 edict_t *EDICT_NUM(int n);
114 int NUM_FOR_EDICT(edict_t *e);
115 
116 #define	NEXT_EDICT(e)		((edict_t *)( (byte *)e + qcvm->edict_size))
117 
118 #define	EDICT_TO_PROG(e)	((byte *)e - (byte *)qcvm->edicts)
119 #define PROG_TO_EDICT(e)	((edict_t *)((byte *)qcvm->edicts + e))
120 
121 #define	G_FLOAT(o)		(qcvm->globals[o])
122 #define	G_INT(o)		(*(int *)&qcvm->globals[o])
123 #define	G_EDICT(o)		((edict_t *)((byte *)qcvm->edicts+ *(int *)&qcvm->globals[o]))
124 #define G_EDICTNUM(o)		NUM_FOR_EDICT(G_EDICT(o))
125 #define	G_VECTOR(o)		(&qcvm->globals[o])
126 #define	G_STRING(o)		(PR_GetString(*(string_t *)&qcvm->globals[o]))
127 #define	G_FUNCTION(o)		(*(func_t *)&qcvm->globals[o])
128 
129 #define G_VECTORSET(r,x,y,z) do{G_FLOAT((r)+0) = x; G_FLOAT((r)+1) = y;G_FLOAT((r)+2) = z;}while(0)
130 #define	E_FLOAT(e,o)		(((float*)&e->v)[o])
131 #define	E_INT(e,o)		(*(int *)&((float*)&e->v)[o])
132 #define	E_VECTOR(e,o)		(&((float*)&e->v)[o])
133 #define	E_STRING(e,o)		(PR_GetString(*(string_t *)&((float*)&e->v)[o]))
134 
135 extern	int		type_size[8];
136 
137 FUNC_NORETURN void PR_RunError (const char *error, ...) FUNC_PRINTF(1,2);
138 void PR_RunWarning (const char *error, ...) FUNC_PRINTF(1,2);
139 
140 void ED_PrintEdicts (void);
141 void ED_PrintNum (int ent);
142 
143 eval_t *GetEdictFieldValue(edict_t *ed, int fldofs);	//handles invalid offsets with a null
144 int ED_FindFieldOffset (const char *name);
145 
146 #define GetEdictFieldValid(fld) (qcvm->extfields.fld>=0)
147 #define GetEdictFieldEval(ed,fld) ((eval_t *)((char *)&ed->v + qcvm->extfields.fld*4)) //caller must validate the field first
148 
149 //from pr_cmds, no longer static so that pr_ext can use them.
150 sizebuf_t *WriteDest (void);
151 char *PR_GetTempString (void);
152 int PR_MakeTempString (const char *val);
153 char *PF_VarString (int	first);
154 #define	STRINGTEMP_BUFFERS		1024
155 #define	STRINGTEMP_LENGTH		1024
156 void PF_Fixme(void);	//the 'unimplemented' builtin. woot.
157 
158 struct pr_extfuncs_s
159 {
160 /*all vms*/
161 #define QCEXTFUNCS_COMMON \
162 	QCEXTFUNC(GameCommand,				"void(string cmdtext)")												/*obsoleted by m_consolecommand, included for dp compat.*/	\
163 /*csqc+ssqc*/
164 #define QCEXTFUNCS_GAME \
165 	QCEXTFUNC(EndFrame,					"void()")				\
166 /*ssqc*/
167 #define QCEXTFUNCS_SV \
168 	QCEXTFUNC(SV_ParseClientCommand,	"void(string cmd)")		\
169 	QCEXTFUNC(SV_RunClientCommand,		"void()")		\
170 /*csqc*/
171 #define QCEXTFUNCS_CS \
172 	QCEXTFUNC(CSQC_Init,				"void(float apilevel, string enginename, float engineversion)")	\
173 	QCEXTFUNC(CSQC_Shutdown,			"void()")	\
174 	QCEXTFUNC(CSQC_DrawHud,				"void(vector virtsize, float showscores)")							/*simple: for the simple(+limited) hud-only csqc interface.*/	\
175 	QCEXTFUNC(CSQC_DrawScores,			"void(vector virtsize, float showscores)")							/*simple: (optional) for the simple hud-only csqc interface.*/		\
176 	QCEXTFUNC(CSQC_InputEvent,			"float(float evtype, float scanx, float chary, float devid)")		\
177 	QCEXTFUNC(CSQC_ConsoleCommand,		"float(string cmdstr)")												\
178 	QCEXTFUNC(CSQC_Parse_Event,			"void()")															\
179 	QCEXTFUNC(CSQC_Parse_Damage,		"float(float save, float take, vector dir)")						\
180 	QCEXTFUNC(CSQC_Parse_CenterPrint,	"float(string msg)")												\
181 	QCEXTFUNC(CSQC_Parse_Print,			"void(string printmsg, float printlvl)")							\
182 
183 #define QCEXTFUNC(n,t) func_t n;
184 	QCEXTFUNCS_COMMON
185 	QCEXTFUNCS_GAME
186 	QCEXTFUNCS_SV
187 	QCEXTFUNCS_CS
188 #undef QCEXTFUNC
189 };
190 extern	cvar_t	pr_checkextension;	//if 0, extensions are disabled (unless they'd be fatal, but they're still spammy)
191 
192 struct pr_extglobals_s
193 {
194 #define QCEXTGLOBALS_COMMON \
195 	QCEXTGLOBAL_FLOAT(time)\
196 	QCEXTGLOBAL_FLOAT(frametime)\
197 	//end
198 #define QCEXTGLOBALS_GAME \
199 	QCEXTGLOBAL_FLOAT(input_timelength)\
200 	QCEXTGLOBAL_VECTOR(input_movevalues)\
201 	QCEXTGLOBAL_VECTOR(input_angles)\
202 	QCEXTGLOBAL_FLOAT(input_buttons)\
203 	QCEXTGLOBAL_FLOAT(input_impulse)\
204 	QCEXTGLOBAL_INT(input_weapon)\
205 	QCEXTGLOBAL_VECTOR(input_cursor_screen)\
206 	QCEXTGLOBAL_VECTOR(input_cursor_trace_start)\
207 	QCEXTGLOBAL_VECTOR(input_cursor_trace_endpos)\
208 	QCEXTGLOBAL_FLOAT(input_cursor_entitynumber)\
209 	QCEXTGLOBAL_FLOAT(physics_mode)\
210 	//end
211 #define QCEXTGLOBALS_CSQC \
212 	QCEXTGLOBAL_FLOAT(cltime)\
213 	QCEXTGLOBAL_FLOAT(clframetime)\
214 	QCEXTGLOBAL_FLOAT(maxclients)\
215 	QCEXTGLOBAL_FLOAT(intermission)\
216 	QCEXTGLOBAL_FLOAT(intermission_time)\
217 	QCEXTGLOBAL_FLOAT(player_localnum)\
218 	QCEXTGLOBAL_FLOAT(player_localentnum)\
219 	//end
220 #define QCEXTGLOBAL_FLOAT(n) float *n;
221 #define QCEXTGLOBAL_INT(n) int *n;
222 #define QCEXTGLOBAL_VECTOR(n) float *n;
223 	QCEXTGLOBALS_COMMON
224 	QCEXTGLOBALS_GAME
225 	QCEXTGLOBALS_CSQC
226 #undef QCEXTGLOBAL_FLOAT
227 #undef QCEXTGLOBAL_INT
228 #undef QCEXTGLOBAL_VECTOR
229 };
230 
231 struct pr_extfields_s
232 {	//various fields that might be wanted by the engine. -1 == invalid
233 
234 #define QCEXTFIELDS_ALL	\
235 	/*renderscene means we need a number of fields here*/	\
236 	QCEXTFIELD(alpha,					".float")				/*float*/	\
237 	QCEXTFIELD(scale,					".float")				/*float*/	\
238 	QCEXTFIELD(colormod,				".vector")			/*vector*/	\
239 	QCEXTFIELD(tag_entity,				".entity")			/*entity*/	\
240 	QCEXTFIELD(tag_index,				".float")			/*float*/	\
241 	QCEXTFIELD(modelflags,				".float")			/*float, the upper 8 bits of .effects*/	\
242 	QCEXTFIELD(origin,					".vector")				/*for menuqc's addentity builtin.*/	\
243 	QCEXTFIELD(angles,					".vector")				/*for menuqc's addentity builtin.*/	\
244 	QCEXTFIELD(frame,					".float")				/*for menuqc's addentity builtin.*/	\
245 	QCEXTFIELD(skin,					".float")				/*for menuqc's addentity builtin.*/	\
246 	/*end of list*/
247 #define QCEXTFIELDS_GAME	\
248 	/*stuff used by csqc+ssqc, but not menu*/	\
249 	QCEXTFIELD(customphysics,			".void()")/*function*/	\
250 	QCEXTFIELD(gravity,					".float")			/*float*/	\
251 	//end of list
252 #define QCEXTFIELDS_SS	\
253 	/*ssqc-only*/	\
254 	QCEXTFIELD(items2,					"//.float")				/*float*/	\
255 	QCEXTFIELD(movement,				".vector")			/*vector*/	\
256 	QCEXTFIELD(viewmodelforclient,		".entity")	/*entity*/	\
257 	QCEXTFIELD(exteriormodeltoclient,	".entity")	/*entity*/	\
258 	QCEXTFIELD(traileffectnum,			".float")		/*float*/	\
259 	QCEXTFIELD(emiteffectnum,			".float")		/*float*/	\
260 	QCEXTFIELD(button3,					".float")			/*float*/	\
261 	QCEXTFIELD(button4,					".float")			/*float*/	\
262 	QCEXTFIELD(button5,					".float")			/*float*/	\
263 	QCEXTFIELD(button6,					".float")			/*float*/	\
264 	QCEXTFIELD(button7,					".float")			/*float*/	\
265 	QCEXTFIELD(button8,					".float")			/*float*/	\
266 	QCEXTFIELD(SendEntity,				".float(entity to, float changedflags)")			/*function*/	\
267 	QCEXTFIELD(SendFlags,				".float")			/*float. :( */	\
268 	//end of list
269 
270 #define QCEXTFIELD(n,t) int n;
271 	QCEXTFIELDS_ALL
272 	QCEXTFIELDS_GAME
273 	QCEXTFIELDS_SS
274 #undef QCEXTFIELD
275 };
276 
277 typedef struct
278 {
279 	int		s;
280 	dfunction_t	*f;
281 } prstack_t;
282 
283 
284 typedef struct areanode_s
285 {
286 	int		axis;		// -1 = leaf node
287 	float	dist;
288 	struct areanode_s	*children[2];
289 	link_t	trigger_edicts;
290 	link_t	solid_edicts;
291 } areanode_t;
292 #define	AREA_DEPTH	4
293 #define	AREA_NODES	32
294 
295 struct qcvm_s
296 {
297 	dprograms_t	*progs;
298 	dfunction_t	*functions;
299 	dstatement_t	*statements;
300 	float		*globals;	/* same as pr_global_struct */
301 	ddef_t		*fielddefs;	//yay reflection.
302 
303 	int			edict_size;	/* in bytes */
304 
305 	builtin_t	builtins[1024];
306 	int			numbuiltins;
307 
308 	int			argc;
309 
310 	qboolean	trace;
311 	dfunction_t	*xfunction;
312 	int			xstatement;
313 
314 	unsigned short	progscrc;	//crc16 of the entire file
315 	unsigned int	progshash;	//folded file md4
316 	unsigned int	progssize;	//file size (bytes)
317 
318 	struct pr_extglobals_s extglobals;
319 	struct pr_extfuncs_s extfuncs;
320 	struct pr_extfields_s extfields;
321 
322 	//was static inside pr_edict
323 	char		*strings;
324 	int			stringssize;
325 	const char	**knownstrings;
326 	int			maxknownstrings;
327 	int			numknownstrings;
328 	int			freeknownstrings;
329 	ddef_t		*globaldefs;
330 
331 	unsigned char *knownzone;
332 	size_t knownzonesize;
333 
334 	//originally defined in pr_exec, but moved into the switchable qcvm struct
335 #define	MAX_STACK_DEPTH		1024 /*was 64*/	/* was 32 */
336 	prstack_t	stack[MAX_STACK_DEPTH];
337 	int			depth;
338 
339 #define	LOCALSTACK_SIZE		16384 /* was 2048*/
340 	int			localstack[LOCALSTACK_SIZE];
341 	int			localstack_used;
342 
343 	//originally part of the sv_state_t struct
344 	//FIXME: put worldmodel in here too.
345 	double		time;
346 	int			num_edicts;
347 	int			reserved_edicts;
348 	int			max_edicts;
349 	edict_t		*edicts;			// can NOT be array indexed, because edict_t is variable sized, but can be used to reference the world ent
350 	struct qmodel_s	*worldmodel;
351 	struct qmodel_s	*(*GetModel)(int modelindex);	//returns the model for the given index, or null.
352 
353 	//originally from world.c
354 	areanode_t	areanodes[AREA_NODES];
355 	int			numareanodes;
356 };
357 extern globalvars_t	*pr_global_struct;
358 
359 extern qcvm_t *qcvm;
360 void PR_SwitchQCVM(qcvm_t *nvm);
361 
362 extern builtin_t pr_ssqcbuiltins[];
363 extern int pr_ssqcnumbuiltins;
364 extern builtin_t pr_csqcbuiltins[];
365 extern int pr_csqcnumbuiltins;
366 
367 #endif	/* _QUAKE_PROGS_H */
368 
369