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