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