fixed ED_Print so that it can not cause buffer overflows on large entities
[xonotic/darkplaces.git] / pr_edict.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // sv_edict.c -- entity dictionary
21
22 #include "quakedef.h"
23
24 dprograms_t             *progs;
25 dfunction_t             *pr_functions;
26 char                    *pr_strings;
27 ddef_t                  *pr_fielddefs;
28 ddef_t                  *pr_globaldefs;
29 dstatement_t    *pr_statements;
30 globalvars_t    *pr_global_struct;
31 float                   *pr_globals;                    // same as pr_global_struct
32 int                             pr_edict_size;                  // in bytes
33 int                             pr_edictareasize;               // LordHavoc: in bytes
34
35 unsigned short          pr_crc;
36
37 int             type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
38
39 ddef_t *ED_FieldAtOfs (int ofs);
40 qboolean        ED_ParseEpair (void *base, ddef_t *key, char *s);
41
42 cvar_t  pr_checkextension = {0, "pr_checkextension", "1"};
43 cvar_t  nomonsters = {0, "nomonsters", "0"};
44 cvar_t  gamecfg = {0, "gamecfg", "0"};
45 cvar_t  scratch1 = {0, "scratch1", "0"};
46 cvar_t  scratch2 = {0,"scratch2", "0"};
47 cvar_t  scratch3 = {0, "scratch3", "0"};
48 cvar_t  scratch4 = {0, "scratch4", "0"};
49 cvar_t  savedgamecfg = {CVAR_SAVE, "savedgamecfg", "0"};
50 cvar_t  saved1 = {CVAR_SAVE, "saved1", "0"};
51 cvar_t  saved2 = {CVAR_SAVE, "saved2", "0"};
52 cvar_t  saved3 = {CVAR_SAVE, "saved3", "0"};
53 cvar_t  saved4 = {CVAR_SAVE, "saved4", "0"};
54 cvar_t  decors = {0, "decors", "0"};
55 cvar_t  nehx00 = {0, "nehx00", "0"};cvar_t      nehx01 = {0, "nehx01", "0"};
56 cvar_t  nehx02 = {0, "nehx02", "0"};cvar_t      nehx03 = {0, "nehx03", "0"};
57 cvar_t  nehx04 = {0, "nehx04", "0"};cvar_t      nehx05 = {0, "nehx05", "0"};
58 cvar_t  nehx06 = {0, "nehx06", "0"};cvar_t      nehx07 = {0, "nehx07", "0"};
59 cvar_t  nehx08 = {0, "nehx08", "0"};cvar_t      nehx09 = {0, "nehx09", "0"};
60 cvar_t  nehx10 = {0, "nehx10", "0"};cvar_t      nehx11 = {0, "nehx11", "0"};
61 cvar_t  nehx12 = {0, "nehx12", "0"};cvar_t      nehx13 = {0, "nehx13", "0"};
62 cvar_t  nehx14 = {0, "nehx14", "0"};cvar_t      nehx15 = {0, "nehx15", "0"};
63 cvar_t  nehx16 = {0, "nehx16", "0"};cvar_t      nehx17 = {0, "nehx17", "0"};
64 cvar_t  nehx18 = {0, "nehx18", "0"};cvar_t      nehx19 = {0, "nehx19", "0"};
65 cvar_t  cutscene = {0, "cutscene", "1"};
66 // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
67 cvar_t  pr_boundscheck = {0, "pr_boundscheck", "1"};
68
69 #define MAX_FIELD_LEN   64
70 #define GEFV_CACHESIZE  2
71
72 typedef struct {
73         ddef_t  *pcache;
74         char    field[MAX_FIELD_LEN];
75 } gefv_cache;
76
77 static gefv_cache       gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
78
79 ddef_t *ED_FindField (char *name);
80 dfunction_t *ED_FindFunction (char *name);
81
82 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  these are defined as externs in progs.h
83 int eval_gravity;
84 int eval_button3;
85 int eval_button4;
86 int eval_button5;
87 int eval_button6;
88 int eval_button7;
89 int eval_button8;
90 int eval_glow_size;
91 int eval_glow_trail;
92 int eval_glow_color;
93 int eval_items2;
94 int eval_scale;
95 int eval_alpha;
96 int eval_renderamt; // HalfLife support
97 int eval_rendermode; // HalfLife support
98 int eval_fullbright;
99 int eval_ammo_shells1;
100 int eval_ammo_nails1;
101 int eval_ammo_lava_nails;
102 int eval_ammo_rockets1;
103 int eval_ammo_multi_rockets;
104 int eval_ammo_cells1;
105 int eval_ammo_plasma;
106 int eval_idealpitch;
107 int eval_pitch_speed;
108 int eval_viewmodelforclient;
109 int eval_nodrawtoclient;
110 int eval_exteriormodeltoclient;
111 int eval_drawonlytoclient;
112 int eval_colormod;
113 int eval_ping;
114 int eval_movement;
115 int eval_pmodel;
116 int eval_punchvector;
117
118 dfunction_t *SV_PlayerPhysicsQC;
119 dfunction_t *EndFrameQC;
120
121 int FindFieldOffset(char *field)
122 {
123         ddef_t *d;
124         d = ED_FindField(field);
125         if (!d)
126                 return 0;
127         return d->ofs*4;
128 }
129
130 void FindEdictFieldOffsets(void)
131 {
132         eval_gravity = FindFieldOffset("gravity");
133         eval_button3 = FindFieldOffset("button3");
134         eval_button4 = FindFieldOffset("button4");
135         eval_button5 = FindFieldOffset("button5");
136         eval_button6 = FindFieldOffset("button6");
137         eval_button7 = FindFieldOffset("button7");
138         eval_button8 = FindFieldOffset("button8");
139         eval_glow_size = FindFieldOffset("glow_size");
140         eval_glow_trail = FindFieldOffset("glow_trail");
141         eval_glow_color = FindFieldOffset("glow_color");
142         eval_items2 = FindFieldOffset("items2");
143         eval_scale = FindFieldOffset("scale");
144         eval_alpha = FindFieldOffset("alpha");
145         eval_renderamt = FindFieldOffset("renderamt"); // HalfLife support
146         eval_rendermode = FindFieldOffset("rendermode"); // HalfLife support
147         eval_fullbright = FindFieldOffset("fullbright");
148         eval_ammo_shells1 = FindFieldOffset("ammo_shells1");
149         eval_ammo_nails1 = FindFieldOffset("ammo_nails1");
150         eval_ammo_lava_nails = FindFieldOffset("ammo_lava_nails");
151         eval_ammo_rockets1 = FindFieldOffset("ammo_rockets1");
152         eval_ammo_multi_rockets = FindFieldOffset("ammo_multi_rockets");
153         eval_ammo_cells1 = FindFieldOffset("ammo_cells1");
154         eval_ammo_plasma = FindFieldOffset("ammo_plasma");
155         eval_idealpitch = FindFieldOffset("idealpitch");
156         eval_pitch_speed = FindFieldOffset("pitch_speed");
157         eval_viewmodelforclient = FindFieldOffset("viewmodelforclient");
158         eval_nodrawtoclient = FindFieldOffset("nodrawtoclient");
159         eval_exteriormodeltoclient = FindFieldOffset("exteriormodeltoclient");
160         eval_drawonlytoclient = FindFieldOffset("drawonlytoclient");
161         eval_colormod = FindFieldOffset("colormod");
162         eval_ping = FindFieldOffset("ping");
163         eval_movement = FindFieldOffset("movement");
164         eval_pmodel = FindFieldOffset("pmodel");
165         eval_punchvector = FindFieldOffset("punchvector");
166
167         // LordHavoc: allowing QuakeC to override the player movement code
168         SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
169         // LordHavoc: support for endframe
170         EndFrameQC = ED_FindFunction ("EndFrame");
171 };
172
173 /*
174 =================
175 ED_ClearEdict
176
177 Sets everything to NULL
178 =================
179 */
180 void ED_ClearEdict (edict_t *e)
181 {
182         memset (&e->v, 0, progs->entityfields * 4);
183         e->free = false;
184 }
185
186 /*
187 =================
188 ED_Alloc
189
190 Either finds a free edict, or allocates a new one.
191 Try to avoid reusing an entity that was recently freed, because it
192 can cause the client to think the entity morphed into something else
193 instead of being removed and recreated, which can cause interpolated
194 angles and bad trails.
195 =================
196 */
197 edict_t *ED_Alloc (void)
198 {
199         int                     i;
200         edict_t         *e;
201
202         for ( i=svs.maxclients+1 ; i<sv.num_edicts ; i++)
203         {
204                 e = EDICT_NUM(i);
205                 // the first couple seconds of server time can involve a lot of
206                 // freeing and allocating, so relax the replacement policy
207                 if (e->free && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) )
208                 {
209                         ED_ClearEdict (e);
210                         return e;
211                 }
212         }
213         
214         if (i == MAX_EDICTS)
215                 Host_Error ("ED_Alloc: no free edicts");
216                 
217         sv.num_edicts++;
218         e = EDICT_NUM(i);
219         ED_ClearEdict (e);
220
221         return e;
222 }
223
224 /*
225 =================
226 ED_Free
227
228 Marks the edict as free
229 FIXME: walk all entities and NULL out references to this entity
230 =================
231 */
232 void ED_Free (edict_t *ed)
233 {
234         SV_UnlinkEdict (ed);            // unlink from world bsp
235
236         ed->free = true;
237         ed->v.model = 0;
238         ed->v.takedamage = 0;
239         ed->v.modelindex = 0;
240         ed->v.colormap = 0;
241         ed->v.skin = 0;
242         ed->v.frame = 0;
243         VectorClear(ed->v.origin);
244         VectorClear(ed->v.angles);
245         ed->v.nextthink = -1;
246         ed->v.solid = 0;
247         
248         ed->freetime = sv.time;
249 }
250
251 //===========================================================================
252
253 /*
254 ============
255 ED_GlobalAtOfs
256 ============
257 */
258 ddef_t *ED_GlobalAtOfs (int ofs)
259 {
260         ddef_t          *def;
261         int                     i;
262         
263         for (i=0 ; i<progs->numglobaldefs ; i++)
264         {
265                 def = &pr_globaldefs[i];
266                 if (def->ofs == ofs)
267                         return def;
268         }
269         return NULL;
270 }
271
272 /*
273 ============
274 ED_FieldAtOfs
275 ============
276 */
277 ddef_t *ED_FieldAtOfs (int ofs)
278 {
279         ddef_t          *def;
280         int                     i;
281         
282         for (i=0 ; i<progs->numfielddefs ; i++)
283         {
284                 def = &pr_fielddefs[i];
285                 if (def->ofs == ofs)
286                         return def;
287         }
288         return NULL;
289 }
290
291 /*
292 ============
293 ED_FindField
294 ============
295 */
296 ddef_t *ED_FindField (char *name)
297 {
298         ddef_t          *def;
299         int                     i;
300         
301         for (i=0 ; i<progs->numfielddefs ; i++)
302         {
303                 def = &pr_fielddefs[i];
304                 if (!strcmp(pr_strings + def->s_name,name) )
305                         return def;
306         }
307         return NULL;
308 }
309
310 /*
311 ============
312 ED_FindGlobal
313 ============
314 */
315 ddef_t *ED_FindGlobal (char *name)
316 {
317         ddef_t          *def;
318         int                     i;
319         
320         for (i=0 ; i<progs->numglobaldefs ; i++)
321         {
322                 def = &pr_globaldefs[i];
323                 if (!strcmp(pr_strings + def->s_name,name) )
324                         return def;
325         }
326         return NULL;
327 }
328
329
330 /*
331 ============
332 ED_FindFunction
333 ============
334 */
335 dfunction_t *ED_FindFunction (char *name)
336 {
337         dfunction_t             *func;
338         int                             i;
339         
340         for (i=0 ; i<progs->numfunctions ; i++)
341         {
342                 func = &pr_functions[i];
343                 if (!strcmp(pr_strings + func->s_name,name) )
344                         return func;
345         }
346         return NULL;
347 }
348
349
350 /*
351 eval_t *GetEdictFieldValue(edict_t *ed, char *field)
352 {
353         ddef_t                  *def = NULL;
354         int                             i;
355         static int              rep = 0;
356
357         for (i=0 ; i<GEFV_CACHESIZE ; i++)
358         {
359                 if (!strcmp(field, gefvCache[i].field))
360                 {
361                         def = gefvCache[i].pcache;
362                         goto Done;
363                 }
364         }
365
366         def = ED_FindField (field);
367
368         if (strlen(field) < MAX_FIELD_LEN)
369         {
370                 gefvCache[rep].pcache = def;
371                 strcpy (gefvCache[rep].field, field);
372                 rep ^= 1;
373         }
374
375 Done:
376         if (!def)
377                 return NULL;
378
379         return (eval_t *)((char *)&ed->v + def->ofs*4);
380 }
381 */
382
383 /*
384 ============
385 PR_ValueString
386
387 Returns a string describing *data in a type specific manner
388 =============
389 */
390 char *PR_ValueString (etype_t type, eval_t *val)
391 {
392         static char     line[1024]; // LordHavoc: enlarged a bit (was 256)
393         ddef_t          *def;
394         dfunction_t     *f;
395         
396         type &= ~DEF_SAVEGLOBAL;
397
398         switch (type)
399         {
400         case ev_string:
401                 sprintf (line, "%s", pr_strings + val->string);
402                 break;
403         case ev_entity: 
404                 sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
405                 break;
406         case ev_function:
407                 f = pr_functions + val->function;
408                 sprintf (line, "%s()", pr_strings + f->s_name);
409                 break;
410         case ev_field:
411                 def = ED_FieldAtOfs ( val->_int );
412                 sprintf (line, ".%s", pr_strings + def->s_name);
413                 break;
414         case ev_void:
415                 sprintf (line, "void");
416                 break;
417         case ev_float:
418                 // LordHavoc: changed from %5.1f to %10.4f
419                 sprintf (line, "%10.4f", val->_float);
420                 break;
421         case ev_vector:
422                 // LordHavoc: changed from %5.1f to %10.4f
423                 sprintf (line, "'%10.4f %10.4f %10.4f'", val->vector[0], val->vector[1], val->vector[2]);
424                 break;
425         case ev_pointer:
426                 sprintf (line, "pointer");
427                 break;
428         default:
429                 sprintf (line, "bad type %i", type);
430                 break;
431         }
432         
433         return line;
434 }
435
436 /*
437 ============
438 PR_UglyValueString
439
440 Returns a string describing *data in a type specific manner
441 Easier to parse than PR_ValueString
442 =============
443 */
444 char *PR_UglyValueString (etype_t type, eval_t *val)
445 {
446         static char     line[256];
447         ddef_t          *def;
448         dfunction_t     *f;
449         
450         type &= ~DEF_SAVEGLOBAL;
451
452         switch (type)
453         {
454         case ev_string:
455                 sprintf (line, "%s", pr_strings + val->string);
456                 break;
457         case ev_entity: 
458                 sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
459                 break;
460         case ev_function:
461                 f = pr_functions + val->function;
462                 sprintf (line, "%s", pr_strings + f->s_name);
463                 break;
464         case ev_field:
465                 def = ED_FieldAtOfs ( val->_int );
466                 sprintf (line, "%s", pr_strings + def->s_name);
467                 break;
468         case ev_void:
469                 sprintf (line, "void");
470                 break;
471         case ev_float:
472                 sprintf (line, "%f", val->_float);
473                 break;
474         case ev_vector:
475                 sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
476                 break;
477         default:
478                 sprintf (line, "bad type %i", type);
479                 break;
480         }
481         
482         return line;
483 }
484
485 /*
486 ============
487 PR_GlobalString
488
489 Returns a string with a description and the contents of a global,
490 padded to 20 field width
491 ============
492 */
493 char *PR_GlobalString (int ofs)
494 {
495         char    *s;
496         int             i;
497         ddef_t  *def;
498         void    *val;
499         static char     line[128];
500         
501         val = (void *)&pr_globals[ofs];
502         def = ED_GlobalAtOfs(ofs);
503         if (!def)
504                 sprintf (line,"%i(???)", ofs);
505         else
506         {
507                 s = PR_ValueString (def->type, val);
508                 sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s);
509         }
510         
511         i = strlen(line);
512         for ( ; i<20 ; i++)
513                 strcat (line," ");
514         strcat (line," ");
515                 
516         return line;
517 }
518
519 char *PR_GlobalStringNoContents (int ofs)
520 {
521         int             i;
522         ddef_t  *def;
523         static char     line[128];
524         
525         def = ED_GlobalAtOfs(ofs);
526         if (!def)
527                 sprintf (line,"%i(???)", ofs);
528         else
529                 sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name);
530         
531         i = strlen(line);
532         for ( ; i<20 ; i++)
533                 strcat (line," ");
534         strcat (line," ");
535                 
536         return line;
537 }
538
539
540 /*
541 =============
542 ED_Print
543
544 For debugging
545 =============
546 */
547 // LordHavoc: optimized this to print out much more quickly (tempstring)
548 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
549 void ED_Print (edict_t *ed)
550 {
551         int             l;
552         ddef_t  *d;
553         int             *v;
554         int             i, j;
555         char    *name;
556         int             type;
557         char    tempstring[8192], tempstring2[260]; // temporary string buffers
558
559         if (ed->free)
560         {
561                 Con_Printf ("FREE\n");
562                 return;
563         }
564
565         tempstring[0] = 0;
566         sprintf(tempstring, "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
567         for (i=1 ; i<progs->numfielddefs ; i++)
568         {
569                 d = &pr_fielddefs[i];
570                 name = pr_strings + d->s_name;
571                 if (name[strlen(name)-2] == '_')
572                         continue;       // skip _x, _y, _z vars
573                         
574                 v = (int *)((char *)&ed->v + d->ofs*4);
575
576         // if the value is still all 0, skip the field
577                 type = d->type & ~DEF_SAVEGLOBAL;
578                 
579                 for (j=0 ; j<type_size[type] ; j++)
580                         if (v[j])
581                                 break;
582                 if (j == type_size[type])
583                         continue;
584
585                 if (strlen(name) > 256)
586                 {
587                         strncpy(tempstring2, name, 256);
588                         tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
589                         tempstring2[259] = 0;
590                         name = tempstring2;
591                 }
592                 strcat(tempstring, name);
593                 for (l = strlen(name);l < 14;l++)
594                         strcat(tempstring, " ");
595                 strcat(tempstring, " ");
596
597                 name = PR_ValueString(d->type, (eval_t *)v);
598                 if (strlen(name) > 256)
599                 {
600                         strncpy(tempstring2, name, 256);
601                         tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
602                         tempstring2[259] = 0;
603                         name = tempstring2;
604                 }
605                 strcat(tempstring, name);
606                 strcat(tempstring, "\n");
607                 if (strlen(tempstring) >= 4096)
608                 {
609                         Con_Printf("%s", tempstring);
610                         tempstring[0] = 0;
611                 }
612         }
613         if (tempstring[0])
614                 Con_Printf("%s", tempstring);
615 }
616
617 /*
618 =============
619 ED_Write
620
621 For savegames
622 =============
623 */
624 void ED_Write (QFile *f, edict_t *ed)
625 {
626         ddef_t  *d;
627         int             *v;
628         int             i, j;
629         char    *name;
630         int             type;
631
632         Qprintf (f, "{\n");
633
634         if (ed->free)
635         {
636                 Qprintf (f, "}\n");
637                 return;
638         }
639         
640         for (i=1 ; i<progs->numfielddefs ; i++)
641         {
642                 d = &pr_fielddefs[i];
643                 name = pr_strings + d->s_name;
644                 if (name[strlen(name)-2] == '_')
645                         continue;       // skip _x, _y, _z vars
646                         
647                 v = (int *)((char *)&ed->v + d->ofs*4);
648
649         // if the value is still all 0, skip the field
650                 type = d->type & ~DEF_SAVEGLOBAL;
651                 for (j=0 ; j<type_size[type] ; j++)
652                         if (v[j])
653                                 break;
654                 if (j == type_size[type])
655                         continue;
656         
657                 Qprintf (f,"\"%s\" ",name);
658                 Qprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));               
659         }
660
661         Qprintf (f, "}\n");
662 }
663
664 void ED_PrintNum (int ent)
665 {
666         ED_Print (EDICT_NUM(ent));
667 }
668
669 /*
670 =============
671 ED_PrintEdicts
672
673 For debugging, prints all the entities in the current server
674 =============
675 */
676 void ED_PrintEdicts (void)
677 {
678         int             i;
679         
680         Con_Printf ("%i entities\n", sv.num_edicts);
681         for (i=0 ; i<sv.num_edicts ; i++)
682                 ED_PrintNum (i);
683 }
684
685 /*
686 =============
687 ED_PrintEdict_f
688
689 For debugging, prints a single edicy
690 =============
691 */
692 void ED_PrintEdict_f (void)
693 {
694         int             i;
695         
696         i = atoi (Cmd_Argv(1));
697         if (i >= sv.num_edicts)
698         {
699                 Con_Printf("Bad edict number\n");
700                 return;
701         }
702         ED_PrintNum (i);
703 }
704
705 /*
706 =============
707 ED_Count
708
709 For debugging
710 =============
711 */
712 void ED_Count (void)
713 {
714         int             i;
715         edict_t *ent;
716         int             active, models, solid, step;
717
718         active = models = solid = step = 0;
719         for (i=0 ; i<sv.num_edicts ; i++)
720         {
721                 ent = EDICT_NUM(i);
722                 if (ent->free)
723                         continue;
724                 active++;
725                 if (ent->v.solid)
726                         solid++;
727                 if (ent->v.model)
728                         models++;
729                 if (ent->v.movetype == MOVETYPE_STEP)
730                         step++;
731         }
732
733         Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
734         Con_Printf ("active    :%3i\n", active);
735         Con_Printf ("view      :%3i\n", models);
736         Con_Printf ("touch     :%3i\n", solid);
737         Con_Printf ("step      :%3i\n", step);
738
739 }
740
741 /*
742 ==============================================================================
743
744                                         ARCHIVING GLOBALS
745
746 FIXME: need to tag constants, doesn't really work
747 ==============================================================================
748 */
749
750 /*
751 =============
752 ED_WriteGlobals
753 =============
754 */
755 void ED_WriteGlobals (QFile *f)
756 {
757         ddef_t          *def;
758         int                     i;
759         char            *name;
760         int                     type;
761
762         Qprintf (f,"{\n");
763         for (i=0 ; i<progs->numglobaldefs ; i++)
764         {
765                 def = &pr_globaldefs[i];
766                 type = def->type;
767                 if ( !(def->type & DEF_SAVEGLOBAL) )
768                         continue;
769                 type &= ~DEF_SAVEGLOBAL;
770
771                 if (type != ev_string && type != ev_float && type != ev_entity)
772                         continue;
773
774                 name = pr_strings + def->s_name;                
775                 Qprintf (f,"\"%s\" ", name);
776                 Qprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));              
777         }
778         Qprintf (f,"}\n");
779 }
780
781 /*
782 =============
783 ED_ParseGlobals
784 =============
785 */
786 void ED_ParseGlobals (char *data)
787 {
788         char    keyname[1024]; // LordHavoc: good idea? bad idea?  was 64
789         ddef_t  *key;
790
791         while (1)
792         {       
793         // parse key
794                 data = COM_Parse (data);
795                 if (com_token[0] == '}')
796                         break;
797                 if (!data)
798                         Host_Error ("ED_ParseEntity: EOF without closing brace");
799
800                 strcpy (keyname, com_token);
801
802         // parse value  
803                 data = COM_Parse (data);
804                 if (!data)
805                         Host_Error ("ED_ParseEntity: EOF without closing brace");
806
807                 if (com_token[0] == '}')
808                         Host_Error ("ED_ParseEntity: closing brace without data");
809
810                 key = ED_FindGlobal (keyname);
811                 if (!key)
812                 {
813                         Con_DPrintf ("'%s' is not a global\n", keyname);
814                         continue;
815                 }
816
817                 if (!ED_ParseEpair ((void *)pr_globals, key, com_token))
818                         Host_Error ("ED_ParseGlobals: parse error");
819         }
820 }
821
822 //============================================================================
823
824
825 /*
826 =============
827 ED_NewString
828 =============
829 */
830 char *ED_NewString (char *string)
831 {
832         char    *new, *new_p;
833         int             i,l;
834         
835         l = strlen(string) + 1;
836         new = Hunk_AllocName (l, "edict string");
837         new_p = new;
838
839         for (i=0 ; i< l ; i++)
840         {
841                 if (string[i] == '\\' && i < l-1)
842                 {
843                         i++;
844                         if (string[i] == 'n')
845                                 *new_p++ = '\n';
846                         else
847                                 *new_p++ = '\\';
848                 }
849                 else
850                         *new_p++ = string[i];
851         }
852         
853         return new;
854 }
855
856
857 /*
858 =============
859 ED_ParseEval
860
861 Can parse either fields or globals
862 returns false if error
863 =============
864 */
865 qboolean        ED_ParseEpair (void *base, ddef_t *key, char *s)
866 {
867         int             i;
868         char    string[128];
869         ddef_t  *def;
870         char    *v, *w;
871         void    *d;
872         dfunction_t     *func;
873         
874         d = (void *)((int *)base + key->ofs);
875         
876         switch (key->type & ~DEF_SAVEGLOBAL)
877         {
878         case ev_string:
879                 *(string_t *)d = ED_NewString (s) - pr_strings;
880                 break;
881                 
882         case ev_float:
883                 *(float *)d = atof (s);
884                 break;
885                 
886         case ev_vector:
887                 strcpy (string, s);
888                 v = string;
889                 w = string;
890                 for (i=0 ; i<3 ; i++)
891                 {
892                         while (*v && *v != ' ')
893                                 v++;
894                         *v = 0;
895                         ((float *)d)[i] = atof (w);
896                         w = v = v+1;
897                 }
898                 break;
899                 
900         case ev_entity:
901                 *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s)));
902                 break;
903                 
904         case ev_field:
905                 def = ED_FindField (s);
906                 if (!def)
907                 {
908                         // LordHavoc: don't warn about worldspawn sky/fog fields because they don't require mod support
909                         if (strcmp(s, "sky") && strcmp(s, "fog") && strncmp(s, "fog_", 4) && strcmp(s, "farclip"))
910                                 Con_DPrintf ("Can't find field %s\n", s);
911                         return false;
912                 }
913                 *(int *)d = G_INT(def->ofs);
914                 break;
915         
916         case ev_function:
917                 func = ED_FindFunction (s);
918                 if (!func)
919                 {
920                         Con_DPrintf ("Can't find function %s\n", s);
921                         return false;
922                 }
923                 *(func_t *)d = func - pr_functions;
924                 break;
925                 
926         default:
927                 break;
928         }
929         return true;
930 }
931
932 /*
933 ====================
934 ED_ParseEdict
935
936 Parses an edict out of the given string, returning the new position
937 ed should be a properly initialized empty edict.
938 Used for initial level load and for savegames.
939 ====================
940 */
941 char *ED_ParseEdict (char *data, edict_t *ent)
942 {
943         ddef_t          *key;
944         qboolean        anglehack;
945         qboolean        init;
946         char            keyname[256];
947         int                     n;
948
949         init = false;
950
951 // clear it
952         if (ent != sv.edicts)   // hack
953                 memset (&ent->v, 0, progs->entityfields * 4);
954
955 // go through all the dictionary pairs
956         while (1)
957         {       
958         // parse key
959                 data = COM_Parse (data);
960                 if (com_token[0] == '}')
961                         break;
962                 if (!data)
963                         Host_Error ("ED_ParseEntity: EOF without closing brace");
964                 
965 // anglehack is to allow QuakeEd to write single scalar angles
966 // and allow them to be turned into vectors. (FIXME...)
967 if (!strcmp(com_token, "angle"))
968 {
969         strcpy (com_token, "angles");
970         anglehack = true;
971 }
972 else
973         anglehack = false;
974
975 // FIXME: change light to _light to get rid of this hack
976 if (!strcmp(com_token, "light"))
977         strcpy (com_token, "light_lev");        // hack for single light def
978
979                 strcpy (keyname, com_token);
980
981                 // another hack to fix heynames with trailing spaces
982                 n = strlen(keyname);
983                 while (n && keyname[n-1] == ' ')
984                 {
985                         keyname[n-1] = 0;
986                         n--;
987                 }
988
989         // parse value  
990                 data = COM_Parse (data);
991                 if (!data)
992                         Host_Error ("ED_ParseEntity: EOF without closing brace");
993
994                 if (com_token[0] == '}')
995                         Host_Error ("ED_ParseEntity: closing brace without data");
996
997                 init = true;    
998
999 // keynames with a leading underscore are used for utility comments,
1000 // and are immediately discarded by quake
1001                 if (keyname[0] == '_')
1002                         continue;
1003                 
1004                 key = ED_FindField (keyname);
1005                 if (!key)
1006                 {
1007                         Con_DPrintf ("'%s' is not a field\n", keyname);
1008                         continue;
1009                 }
1010
1011 if (anglehack)
1012 {
1013 char    temp[32];
1014 strcpy (temp, com_token);
1015 sprintf (com_token, "0 %s 0", temp);
1016 }
1017
1018                 if (!ED_ParseEpair ((void *)&ent->v, key, com_token))
1019                         Host_Error ("ED_ParseEdict: parse error");
1020         }
1021
1022         if (!init)
1023                 ent->free = true;
1024
1025         return data;
1026 }
1027
1028
1029 /*
1030 ================
1031 ED_LoadFromFile
1032
1033 The entities are directly placed in the array, rather than allocated with
1034 ED_Alloc, because otherwise an error loading the map would have entity
1035 number references out of order.
1036
1037 Creates a server's entity / program execution context by
1038 parsing textual entity definitions out of an ent file.
1039
1040 Used for both fresh maps and savegame loads.  A fresh map would also need
1041 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1042 ================
1043 */
1044 void ED_LoadFromFile (char *data)
1045 {       
1046         edict_t         *ent;
1047         int                     inhibit;
1048         dfunction_t     *func;
1049         
1050         ent = NULL;
1051         inhibit = 0;
1052         pr_global_struct->time = sv.time;
1053         
1054 // parse ents
1055         while (1)
1056         {
1057 // parse the opening brace      
1058                 data = COM_Parse (data);
1059                 if (!data)
1060                         break;
1061                 if (com_token[0] != '{')
1062                         Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
1063
1064                 if (!ent)
1065                         ent = EDICT_NUM(0);
1066                 else
1067                         ent = ED_Alloc ();
1068                 data = ED_ParseEdict (data, ent);
1069
1070 // remove things from different skill levels or deathmatch
1071                 if (deathmatch.value)
1072                 {
1073                         if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
1074                         {
1075                                 ED_Free (ent);  
1076                                 inhibit++;
1077                                 continue;
1078                         }
1079                 }
1080                 else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY  ))
1081                           || (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
1082                           || (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD  )))
1083                 {
1084                         ED_Free (ent);  
1085                         inhibit++;
1086                         continue;
1087                 }
1088
1089 //
1090 // immediately call spawn function
1091 //
1092                 if (!ent->v.classname)
1093                 {
1094                         Con_Printf ("No classname for:\n");
1095                         ED_Print (ent);
1096                         ED_Free (ent);
1097                         continue;
1098                 }
1099
1100         // look for the spawn function
1101                 func = ED_FindFunction ( pr_strings + ent->v.classname );
1102
1103                 if (!func)
1104                 {
1105                         if (developer.value) // don't confuse non-developers with errors
1106                         {
1107                                 Con_Printf ("No spawn function for:\n");
1108                                 ED_Print (ent);
1109                         }
1110                         ED_Free (ent);
1111                         continue;
1112                 }
1113
1114                 pr_global_struct->self = EDICT_TO_PROG(ent);
1115                 PR_ExecuteProgram (func - pr_functions, "");
1116         }       
1117
1118         Con_DPrintf ("%i entities inhibited\n", inhibit);
1119 }
1120
1121
1122 /*
1123 ===============
1124 PR_LoadProgs
1125 ===============
1126 */
1127 void PR_LoadProgs (void)
1128 {
1129         int             i;
1130         dstatement_t *st;
1131
1132 // flush the non-C variable lookup cache
1133         for (i=0 ; i<GEFV_CACHESIZE ; i++)
1134                 gefvCache[i].field[0] = 0;
1135
1136         progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat", false);
1137         if (!progs)
1138                 Host_Error ("PR_LoadProgs: couldn't load progs.dat");
1139         Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
1140
1141         pr_crc = CRC_Block((byte *)progs, com_filesize);
1142
1143 // byte swap the header
1144         for (i=0 ; i<sizeof(*progs)/4 ; i++)
1145                 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );           
1146
1147         if (progs->version != PROG_VERSION)
1148                 Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1149         if (progs->crc != PROGHEADER_CRC)
1150                 Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1151
1152         pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
1153         pr_strings = (char *)progs + progs->ofs_strings;
1154         pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
1155         pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
1156         pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
1157
1158         pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
1159         pr_globals = (float *)pr_global_struct;
1160         
1161         pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
1162
1163         pr_edictareasize = pr_edict_size * MAX_EDICTS;
1164
1165 // byte swap the lumps
1166         for (i=0 ; i<progs->numstatements ; i++)
1167         {
1168                 pr_statements[i].op = LittleShort(pr_statements[i].op);
1169                 pr_statements[i].a = LittleShort(pr_statements[i].a);
1170                 pr_statements[i].b = LittleShort(pr_statements[i].b);
1171                 pr_statements[i].c = LittleShort(pr_statements[i].c);
1172         }
1173
1174         for (i=0 ; i<progs->numfunctions; i++)
1175         {
1176                 pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
1177                 pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
1178                 pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
1179                 pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
1180                 pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
1181                 pr_functions[i].locals = LittleLong (pr_functions[i].locals);
1182         }       
1183
1184         for (i=0 ; i<progs->numglobaldefs ; i++)
1185         {
1186                 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1187                 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1188                 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1189         }
1190
1191         for (i=0 ; i<progs->numfielddefs ; i++)
1192         {
1193                 pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
1194                 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1195                         Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1196                 pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
1197                 pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
1198         }
1199
1200         for (i=0 ; i<progs->numglobals ; i++)
1201                 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1202
1203         // LordHavoc: bounds check anything static
1204         for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
1205         {
1206                 switch (st->op)
1207                 {
1208                 case OP_IF:
1209                 case OP_IFNOT:
1210                         if ((unsigned short) st->a >= progs->numglobals || st->b + i < 0 || st->b + i >= progs->numstatements)
1211                                 Host_Error("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n", i);
1212                         break;
1213                 case OP_GOTO:
1214                         if (st->a + i < 0 || st->a + i >= progs->numstatements)
1215                                 Host_Error("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i);
1216                         break;
1217                 // global global global
1218                 case OP_ADD_F:
1219                 case OP_ADD_V:
1220                 case OP_SUB_F:
1221                 case OP_SUB_V:
1222                 case OP_MUL_F:
1223                 case OP_MUL_V:
1224                 case OP_MUL_FV:
1225                 case OP_MUL_VF:
1226                 case OP_DIV_F:
1227                 case OP_BITAND:
1228                 case OP_BITOR:
1229                 case OP_GE:
1230                 case OP_LE:
1231                 case OP_GT:
1232                 case OP_LT:
1233                 case OP_AND:
1234                 case OP_OR:
1235                 case OP_EQ_F:
1236                 case OP_EQ_V:
1237                 case OP_EQ_S:
1238                 case OP_EQ_E:
1239                 case OP_EQ_FNC:
1240                 case OP_NE_F:
1241                 case OP_NE_V:
1242                 case OP_NE_S:
1243                 case OP_NE_E:
1244                 case OP_NE_FNC:
1245                 case OP_ADDRESS:
1246                 case OP_LOAD_F:
1247                 case OP_LOAD_FLD:
1248                 case OP_LOAD_ENT:
1249                 case OP_LOAD_S:
1250                 case OP_LOAD_FNC:
1251                 case OP_LOAD_V:
1252                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1253                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1254                         break;
1255                 // global none global
1256                 case OP_NOT_F:
1257                 case OP_NOT_V:
1258                 case OP_NOT_S:
1259                 case OP_NOT_FNC:
1260                 case OP_NOT_ENT:
1261                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->c >= progs->numglobals)
1262                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1263                         break;
1264                 // 2 globals
1265                 case OP_STOREP_F:
1266                 case OP_STOREP_ENT:
1267                 case OP_STOREP_FLD:
1268                 case OP_STOREP_S:
1269                 case OP_STOREP_FNC:
1270                 case OP_STORE_F:
1271                 case OP_STORE_ENT:
1272                 case OP_STORE_FLD:
1273                 case OP_STORE_S:
1274                 case OP_STORE_FNC:
1275                 case OP_STATE:
1276                 case OP_STOREP_V:
1277                 case OP_STORE_V:
1278                         if ((unsigned short) st->a >= progs->numglobals || (unsigned short) st->b >= progs->numglobals)
1279                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1280                         break;
1281                 // 1 global
1282                 case OP_CALL0:
1283                 case OP_CALL1:
1284                 case OP_CALL2:
1285                 case OP_CALL3:
1286                 case OP_CALL4:
1287                 case OP_CALL5:
1288                 case OP_CALL6:
1289                 case OP_CALL7:
1290                 case OP_CALL8:
1291                 case OP_DONE:
1292                 case OP_RETURN:
1293                         if ((unsigned short) st->a >= progs->numglobals)
1294                                 Host_Error("PR_LoadProgs: out of bounds global index (statement %d)\n", i);
1295                         break;
1296                 default:
1297                         Host_Error("PR_LoadProgs: unknown opcode %d at statement %d\n", st->op, i);
1298                         break;
1299                 }
1300         }
1301
1302         FindEdictFieldOffsets(); // LordHavoc: update field offset list
1303 }
1304
1305
1306 void PR_Fields_f (void)
1307 {
1308         int i;
1309         if (!sv.active)
1310         {
1311                 Con_Printf("no progs loaded\n");
1312                 return;
1313         }
1314         for (i = 0;i < progs->numfielddefs;i++)
1315                 Con_Printf("%s\n", (pr_strings + pr_fielddefs[i].s_name));
1316         Con_Printf("%i entity fields, totalling %i bytes per edict, %i edicts, %i bytes total spent on edict fields\n", progs->entityfields, progs->entityfields * 4, MAX_EDICTS, progs->entityfields * 4 * MAX_EDICTS);
1317 }
1318
1319 void PR_Globals_f (void)
1320 {
1321         int i;
1322         if (!sv.active)
1323         {
1324                 Con_Printf("no progs loaded\n");
1325                 return;
1326         }
1327         for (i = 0;i < progs->numglobaldefs;i++)
1328                 Con_Printf("%s\n", (pr_strings + pr_globaldefs[i].s_name));
1329         Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
1330 }
1331
1332 /*
1333 ===============
1334 PR_Init
1335 ===============
1336 */
1337 void PR_Init (void)
1338 {
1339         Cmd_AddCommand ("edict", ED_PrintEdict_f);
1340         Cmd_AddCommand ("edicts", ED_PrintEdicts);
1341         Cmd_AddCommand ("edictcount", ED_Count);
1342         Cmd_AddCommand ("profile", PR_Profile_f);
1343         Cmd_AddCommand ("pr_fields", PR_Fields_f);
1344         Cmd_AddCommand ("pr_globals", PR_Globals_f);
1345         Cvar_RegisterVariable (&pr_checkextension);
1346         Cvar_RegisterVariable (&nomonsters);
1347         Cvar_RegisterVariable (&gamecfg);
1348         Cvar_RegisterVariable (&scratch1);
1349         Cvar_RegisterVariable (&scratch2);
1350         Cvar_RegisterVariable (&scratch3);
1351         Cvar_RegisterVariable (&scratch4);
1352         Cvar_RegisterVariable (&savedgamecfg);
1353         Cvar_RegisterVariable (&saved1);
1354         Cvar_RegisterVariable (&saved2);
1355         Cvar_RegisterVariable (&saved3);
1356         Cvar_RegisterVariable (&saved4);
1357         // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
1358         Cvar_RegisterVariable (&decors);
1359         // LordHavoc: Nehahra uses these to pass data around cutscene demos
1360         if (nehahra)
1361         {
1362                 Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
1363                 Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
1364                 Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
1365                 Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
1366                 Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
1367                 Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
1368                 Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
1369                 Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
1370                 Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
1371                 Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
1372         }
1373         Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
1374         // LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
1375         Cvar_RegisterVariable (&pr_boundscheck);
1376 }
1377
1378 // LordHavoc: turned EDICT_NUM into a #define for speed reasons
1379 edict_t *EDICT_NUM_ERROR(int n)
1380 {
1381         Host_Error ("EDICT_NUM: bad number %i", n);
1382         return NULL;
1383 }
1384 /*
1385 edict_t *EDICT_NUM(int n)
1386 {
1387         if (n < 0 || n >= sv.max_edicts)
1388                 Sys_Error ("EDICT_NUM: bad number %i", n);
1389         return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size);
1390 }
1391 */
1392
1393 int NUM_FOR_EDICT(edict_t *e)
1394 {
1395         int             b;
1396         
1397         b = (byte *)e - (byte *)sv.edicts;
1398         b = b / pr_edict_size;
1399         
1400         if (b < 0 || b >= sv.num_edicts)
1401                 Host_Error ("NUM_FOR_EDICT: bad pointer");
1402         return b;
1403 }