]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/mediasource/extra/fteqcc-src/pr_edict.c
fteqcc source
[voretournament/voretournament.git] / misc / mediasource / extra / fteqcc-src / pr_edict.c
1
2
3 #define PROGSUSED
4 struct edict_s;
5 #include "progsint.h"
6 //#include "crc.h"
7
8 /*int maxedicts;
9
10 evalc_t spawnflagscache;
11 */
12
13 #ifdef _WIN32
14 //this is windows  all files are written with this endian standard. we do this to try to get a little more speed.
15 #define NOENDIAN
16 #endif
17
18
19 vec3_t vec3_origin;
20
21 //edictrun_t *sv_edicts;
22 //int sv_num_edicts;
23
24 //int                           pr_edict_size;  // in bytes
25 //int                           pr_max_edict_size;
26
27 //unsigned short                pr_crc;
28
29 fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs);
30 pbool   ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, int bits);
31
32
33
34 /*
35 #define MAX_FIELD_LEN   64
36 #define GEFV_CACHESIZE  5
37
38 typedef struct {
39         ddef_t  *pcache;
40         char    field[MAX_FIELD_LEN];
41 } gefv_cache;
42
43 static gefv_cache       gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
44 */
45
46 /*
47 =================
48 QC_ClearEdict
49
50 Sets everything to NULL
51 =================
52 */
53 void QC_ClearEdict (progfuncs_t *progfuncs, struct edict_s *ed)
54 {
55         edictrun_t *e = (edictrun_t *)ed;
56         int num = e->entnum;
57         memset (e->fields, 0, fields_size);
58         e->isfree = false;
59         e->entnum = num;
60 }
61
62 edictrun_t *ED_AllocIntoTable (progfuncs_t *progfuncs, int num)
63 {
64         edictrun_t *e;
65
66         prinst->edicttable[num] = *(struct edict_s **)&e = (void*)memalloc(externs->edictsize);
67         memset(e, 0, externs->edictsize);
68         e->fields = PRAddressableAlloc(progfuncs, fields_size);
69         e->entnum = num;
70         QC_ClearEdict(progfuncs, (struct edict_s*)e);
71
72         return e;
73 }
74
75 /*
76 =================
77 ED_Alloc
78
79 Either finds a free edict, or allocates a new one.
80 Try to avoid reusing an entity that was recently freed, because it
81 can cause the client to think the entity morphed into something else
82 instead of being removed and recreated, which can cause interpolated
83 angles and bad trails.
84 =================
85 */
86 struct edict_s *ED_Alloc (progfuncs_t *progfuncs)
87 {
88         unsigned int                    i;
89         edictrun_t              *e;
90
91         for ( i=0 ; i<sv_num_edicts ; i++)
92         {
93                 e = (edictrun_t*)EDICT_NUM(progfuncs, i);
94                 // the first couple seconds of server time can involve a lot of
95                 // freeing and allocating, so relax the replacement policy
96                 if (!e || (e->isfree && ( e->freetime < 2 || *externs->gametime - e->freetime > 0.5 ) ))
97                 {
98                         if (!e)
99                                 e = ED_AllocIntoTable(progfuncs, i);
100                         else
101                                 QC_ClearEdict (progfuncs, (struct edict_s*)e);
102
103                         if (externs->entspawn)
104                                 externs->entspawn((struct edict_s *) e, false);
105                         return (struct edict_s *)e;
106                 }
107         }
108
109         if (i >= maxedicts-1)   //try again, but use timed out ents.
110         {
111                 for ( i=0 ; i<sv_num_edicts ; i++)
112                 {
113                         e = (edictrun_t*)EDICT_NUM(progfuncs, i);
114                         // the first couple seconds of server time can involve a lot of
115                         // freeing and allocating, so relax the replacement policy
116                         if (!e || (e->isfree))
117                         {
118                                 if (!e)
119                                         e = ED_AllocIntoTable(progfuncs, i);
120                                 else
121                                         QC_ClearEdict (progfuncs, (struct edict_s*)e);
122
123                                 if (externs->entspawn)
124                                         externs->entspawn((struct edict_s *) e, false);
125                                 return (struct edict_s *)e;
126                         }
127                 }
128
129                 if (i >= maxedicts-2)
130                 {
131                         printf("Running out of edicts\n");
132                         pr_trace = 1;   //trip the debugger whilst it's still valid
133                 }
134                 if (i >= maxedicts-1)
135                 {
136                         int size;
137                         char *buf;
138                         buf = progfuncs->save_ents(progfuncs, NULL, &size, 0);
139                         progfuncs->parms->WriteFile("edalloc.dump", buf, size);
140                         Sys_Error ("ED_Alloc: no free edicts");
141                 }
142         }
143
144         sv_num_edicts++;
145         e = (edictrun_t*)EDICT_NUM(progfuncs, i);
146
147         if (!e)
148                 e = ED_AllocIntoTable(progfuncs, i);
149         else
150                 QC_ClearEdict (progfuncs, (struct edict_s*)e);
151
152         if (externs->entspawn)
153                 externs->entspawn((struct edict_s *) e, false);
154
155         return (struct edict_s *)e;
156 }
157
158 /*
159 =================
160 ED_Free
161
162 Marks the edict as free
163 FIXME: walk all entities and NULL out references to this entity
164 =================
165 */
166 void ED_Free (progfuncs_t *progfuncs, struct edict_s *ed)
167 {
168         edictrun_t *e = (edictrun_t *)ed;
169 //      SV_UnlinkEdict (ed);            // unlink from world bsp
170
171         if (e->isfree)  //this happens on start.bsp where an onlyregistered trigger killtargets itself (when all of this sort die after 1 trigger anyway).
172         {
173                 if (pr_depth)
174                         printf("Tried to free free entity within %s\n", pr_xfunction->s_name+progfuncs->stringtable);
175                 else
176                         printf("Engine tried to free free entity\n");
177 //              if (developer.value == 1)
178 //                      pr_trace = true;
179                 return;
180         }
181
182         if (externs->entcanfree)
183                 if (!externs->entcanfree(ed))   //can stop an ent from being freed.
184                         return;
185
186         e->isfree = true;
187         e->freetime = (float)*externs->gametime;
188
189 /*
190         ed->v.model = 0;
191         ed->v.takedamage = 0;
192         ed->v.modelindex = 0;
193         ed->v.colormap = 0;
194         ed->v.skin = 0;
195         ed->v.frame = 0;
196         VectorCopy (vec3_origin, ed->v.origin);
197         VectorCopy (vec3_origin, ed->v.angles);
198         ed->v.nextthink = -1;
199         ed->v.solid = 0;
200 */
201 }
202
203 //===========================================================================
204
205 /*
206 ============
207 ED_GlobalAtOfs
208 ============
209 */
210 ddef16_t *ED_GlobalAtOfs16 (progfuncs_t *progfuncs, int ofs)
211 {
212         ddef16_t                *def;
213         unsigned int                    i;
214
215         for (i=0 ; i<pr_progs->numglobaldefs ; i++)
216         {
217                 def = &pr_globaldefs16[i];
218                 if (def->ofs == ofs)
219                         return def;
220         }
221         return NULL;
222 }
223 ddef32_t *ED_GlobalAtOfs32 (progfuncs_t *progfuncs, unsigned int ofs)
224 {
225         ddef32_t                *def;
226         unsigned int                    i;
227
228         for (i=0 ; i<pr_progs->numglobaldefs ; i++)
229         {
230                 def = &pr_globaldefs32[i];
231                 if (def->ofs == ofs)
232                         return def;
233         }
234         return NULL;
235 }
236
237 /*
238 ============
239 ED_FieldAtOfs
240 ============
241 */
242 fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs)
243 {
244 //      ddef_t          *def;
245         unsigned int                    i;
246
247         for (i=0 ; i<numfields ; i++)
248         {
249                 if (field[i].ofs == ofs)
250                         return &field[i];
251         }
252         return NULL;
253 }
254 /*
255 ============
256 ED_FindField
257 ============
258 */
259 fdef_t *ED_FindField (progfuncs_t *progfuncs, char *name)
260 {
261         unsigned int                    i;
262
263         for (i=0 ; i<numfields ; i++)
264         {
265                 if (!strcmp(field[i].name, name) )
266                         return &field[i];
267         }
268         return NULL;
269 }
270
271
272 /*
273 ============
274 ED_FindGlobal
275 ============
276 */
277 ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, char *name)
278 {
279         ddef16_t                *def;
280         unsigned int                    i;
281
282         for (i=1 ; i<pr_progs->numglobaldefs ; i++)
283         {
284                 def = &pr_globaldefs16[i];
285                 if (!strcmp(def->s_name+progfuncs->stringtable,name) )
286                         return def;
287         }
288         return NULL;
289 }
290 ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name)
291 {
292         ddef32_t                *def;
293         unsigned int                    i;
294
295         for (i=1 ; i<pr_progs->numglobaldefs ; i++)
296         {
297                 def = &pr_globaldefs32[i];
298                 if (!strcmp(def->s_name+progfuncs->stringtable,name) )
299                         return def;
300         }
301         return NULL;
302 }
303
304 unsigned int ED_FindGlobalOfs (progfuncs_t *progfuncs, char *name)
305 {
306         ddef16_t *d16;
307         ddef32_t *d32;
308         switch(current_progstate->intsize)
309         {
310         case 24:
311         case 16:
312                 d16 = ED_FindGlobal16(progfuncs, name);
313                 return d16?d16->ofs:0;
314         case 32:
315                 d32 = ED_FindGlobal32(progfuncs, name);
316                 return d32?d32->ofs:0;
317         }
318         Sys_Error("ED_FindGlobalOfs - bad intsize");
319         return 0;
320 }
321
322 ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum_t prnum)
323 {
324         ddef16_t                *def;
325         unsigned int                    i;
326
327         for (i=1 ; i<pr_progstate[prnum].progs->numglobaldefs ; i++)
328         {
329                 def = &pr_progstate[prnum].globaldefs16[i];
330                 if (!strcmp(def->s_name+progfuncs->stringtable,name) )
331                         return def;
332         }
333         return NULL;
334 }
335 ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum_t prnum)
336 {
337         ddef32_t                *def;
338         unsigned int                    i;
339
340         for (i=1 ; i<pr_progstate[prnum].progs->numglobaldefs ; i++)
341         {
342                 def = &pr_progstate[prnum].globaldefs32[i];
343                 if (!strcmp(def->s_name+progfuncs->stringtable,name) )
344                         return def;
345         }
346         return NULL;
347 }
348
349 ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type)
350 {
351         ddef16_t                *def;
352         unsigned int                    i;
353
354         for (i=1 ; i<pr_progstate[prnum].progs->numglobaldefs ; i++)
355         {
356                 def = &pr_progstate[prnum].globaldefs16[i];
357                 if (!strcmp(def->s_name+progfuncs->stringtable,name) )
358                 {
359                         if (pr_progstate[prnum].types)
360                         {
361                                 if (pr_progstate[prnum].types[def->type&~DEF_SAVEGLOBAL].type != type)
362                                         continue;
363                         }
364                         else if ((def->type&(~DEF_SAVEGLOBAL)) != type)
365                                 continue;
366                         return def;
367                 }
368         }
369         return NULL;
370 }
371
372
373 ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type)
374 {
375         ddef32_t                *def;
376         unsigned int                    i;
377
378         for (i=1 ; i<pr_progstate[prnum].progs->numglobaldefs ; i++)
379         {
380                 def = &pr_progstate[prnum].globaldefs32[i];
381                 if (!strcmp(def->s_name+progfuncs->stringtable,name) )
382                 {
383                         if (pr_progstate[prnum].types)
384                         {
385                                 if (pr_progstate[prnum].types[def->type&~DEF_SAVEGLOBAL].type != type)
386                                         continue;
387                         }
388                         else if ((def->type&(~DEF_SAVEGLOBAL)) != (unsigned)type)
389                                 continue;
390                         return def;
391                 }
392         }
393         return NULL;
394 }
395
396 unsigned int *ED_FindGlobalOfsFromProgs (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type)
397 {
398         ddef16_t                *def16;
399         ddef32_t                *def32;
400         static unsigned int pos;
401         switch(pr_progstate[prnum].intsize)
402         {
403         case 16:
404         case 24:
405                 def16 = ED_FindTypeGlobalFromProgs16(progfuncs, name, prnum, type);
406                 if (!def16)
407                         return NULL;
408                 pos = def16->ofs;
409                 return &pos;
410         case 32:
411                 def32 = ED_FindTypeGlobalFromProgs32(progfuncs, name, prnum, type);
412                 if (!def32)
413                         return NULL;
414                 return &def32->ofs;
415         }
416         Sys_Error("ED_FindGlobalOfsFromProgs - bad intsize");
417         return 0;
418 }
419
420 /*
421 ============
422 ED_FindFunction
423 ============
424 */
425 dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, char *name, progsnum_t *prnum, progsnum_t fromprogs)
426 {
427         dfunction_t             *func;
428         unsigned int                            i;
429         char *sep;
430
431         progsnum_t pnum;
432
433         if (prnum)
434         {
435                 sep = strchr(name, ':');
436                 if (sep)
437                 {
438                         pnum = atoi(name);
439                         name = sep+1;
440                 }
441                 else
442                 {
443                         if (fromprogs>=0)
444                                 pnum = fromprogs;
445                         else
446                                 pnum = pr_typecurrent;
447                 }
448                 *prnum = pnum;
449         }
450         else
451                 pnum = pr_typecurrent;
452
453         if ((unsigned)pnum > (unsigned)maxprogs)
454         {
455                 printf("Progsnum %i out of bounds\n", pnum);
456                 return NULL;
457         }
458
459         if (!pr_progstate[pnum].progs)
460                 return NULL;
461
462         for (i=1 ; i<pr_progstate[pnum].progs->numfunctions ; i++)
463         {
464                 func = &pr_progstate[pnum].functions[i];
465                 if (!strcmp(func->s_name+progfuncs->stringtable,name) )
466                         return func;
467         }
468         return NULL;
469 }
470
471 /*
472 ============
473 PR_ValueString
474
475 Returns a string describing *data in a type specific manner
476 =============
477 */
478 char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
479 {
480         static char     line[256];
481         fdef_t                  *fielddef;
482         dfunction_t     *f;
483
484 #ifdef DEF_SAVEGLOBAL
485         type &= ~DEF_SAVEGLOBAL;
486 #endif
487
488         if (pr_types)
489                 type = pr_types[type].type;
490
491         switch (type)
492         {
493         case ev_struct:
494                 sprintf (line, "struct");
495                 break;
496         case ev_union:
497                 sprintf (line, "union");
498                 break;
499         case ev_string:
500                 sprintf (line, "%s", PR_StringToNative(progfuncs, val->string));
501                 break;
502         case ev_entity:
503                 sprintf (line, "entity %i", NUM_FOR_EDICT(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, val->edict)) );
504                 break;
505         case ev_function:
506                 if (!val->function)
507                         sprintf (line, "NULL function");
508                 else
509                 {
510                         if ((val->function & 0xff000000)>>24 >= (unsigned)maxprogs || !pr_progstate[(val->function & 0xff000000)>>24].functions)
511                                 sprintf (line, "Bad function");
512                         else
513                         {
514                                 f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000);
515                                 sprintf (line, "%i:%s()", (val->function & 0xff000000)>>24, f->s_name+progfuncs->stringtable);
516                         }
517                 }
518                 break;
519         case ev_field:
520                 fielddef = ED_FieldAtOfs (progfuncs,  val->_int );
521                 if (!fielddef)
522                         sprintf (line, ".??? (%i)", val->_int);
523                 else
524                         sprintf (line, ".%s (%i)", fielddef->name, val->_int);
525                 break;
526         case ev_void:
527                 sprintf (line, "void type");
528                 break;
529         case ev_float:
530                 sprintf (line, "%5.1f", val->_float);
531                 break;
532         case ev_integer:
533                 sprintf (line, "%i", val->_int);
534                 break;
535         case ev_vector:
536                 sprintf (line, "'%5.1f %5.1f %5.1f'", val->_vector[0], val->_vector[1], val->_vector[2]);
537                 break;
538         case ev_pointer:
539                 sprintf (line, "pointer");
540                 {
541 //                      int entnum;
542 //                      int valofs;
543                         if (val->_int == 0)
544                         {
545                                 sprintf (line, "NULL pointer");
546                                 break;
547                         }
548                 //FIXME: :/
549                         sprintf(line, "UNKNOWN");
550 //                      entnum = ((qbyte *)val->edict - (qbyte *)sv_edicts) / pr_edict_size;
551 //                      valofs = (int *)val->edict - (int *)edvars(EDICT_NUM(progfuncs, entnum));
552 //                      fielddef = ED_FieldAtOfs (progfuncs, valofs );
553 //                      if (!fielddef)
554 //                              sprintf(line, "ent%i.%s", entnum, "UNKNOWN");
555 //                      else
556 //                              sprintf(line, "ent%i.%s", entnum, fielddef->s_name);
557                 }
558                 break;
559         default:
560                 sprintf (line, "bad type %i", type);
561                 break;
562         }
563
564         return line;
565 }
566
567 /*
568 ============
569 PR_UglyValueString
570
571 Returns a string describing *data in a type specific manner
572 Easier to parse than PR_ValueString
573 =============
574 */
575 char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
576 {
577         static char     line[256];
578         fdef_t          *fielddef;
579         dfunction_t     *f;
580         int i, j;
581
582 #ifdef DEF_SAVEGLOBAL
583         type &= ~DEF_SAVEGLOBAL;
584 #endif
585
586         if (pr_types)
587                 type = pr_types[type].type;
588
589         switch (type)
590         {
591         case ev_struct:
592                 sprintf (line, "structures cannot yet be saved");
593                 break;
594         case ev_union:
595                 sprintf (line, "unions cannot yet be saved");
596                 break;
597         case ev_string:
598                 {
599                         char *outs = line;
600                         int outb = sizeof(line)-2;
601                         char *ins = PR_StringToNative(progfuncs, val->string);
602                         //markup the output string.
603                         while(*ins && outb > 0)
604                         {
605                                 switch(*ins)
606                                 {
607                                 case '\n':
608                                         *outs++ = '\\';
609                                         *outs++ = 'n';
610                                         ins++;
611                                         outb-=2;
612                                         break;
613                                 case '\"':
614                                         *outs++ = '\\';
615                                         *outs++ = '"';
616                                         ins++;
617                                         outb-=2;
618                                         break;
619                                 case '\\':
620                                         *outs++ = '\\';
621                                         *outs++ = '\\';
622                                         ins++;
623                                         outb-=2;
624                                         break;
625                                 default:
626                                         *outs++ = *ins++;
627                                         outb--;
628                                         break;
629                                 }
630                         }
631                         *outs = 0;
632                 }
633                 break;
634         case ev_entity:
635                 sprintf (line, "%i", val->_int);
636                 break;
637         case ev_function:
638                 i = (val->function & 0xff000000)>>24;   //progs number
639                 if ((unsigned)i >= maxprogs || !pr_progstate[(unsigned)i].progs)
640                         sprintf (line, "BAD FUNCTION INDEX: %i", val->function);
641                 else
642                 {
643                         j = (val->function & ~0xff000000);      //function number
644                         if ((unsigned)j >= pr_progstate[(unsigned)i].progs->numfunctions)
645                                 sprintf(line, "%i:%s", i, "CORRUPT FUNCTION POINTER");
646                         else
647                         {
648                                 f = pr_progstate[(unsigned)i].functions + j;
649                                 sprintf (line, "%i:%s", i, f->s_name+progfuncs->stringtable);
650                         }
651                 }
652                 break;
653         case ev_field:
654                 fielddef = ED_FieldAtOfs (progfuncs, val->_int );
655                 sprintf (line, "%s", fielddef->name);
656                 break;
657         case ev_void:
658                 sprintf (line, "void");
659                 break;
660         case ev_float:
661                 if (val->_float == (int)val->_float)
662                         sprintf (line, "%i", (int)val->_float); //an attempt to cut down on the number of .000000 vars..
663                 else
664                         sprintf (line, "%f", val->_float);
665                 break;
666         case ev_integer:
667                 sprintf (line, "%i", val->_int);
668                 break;
669         case ev_vector:
670                 if (val->_vector[0] == (int)val->_vector[0] && val->_vector[1] == (int)val->_vector[1] && val->_vector[2] == (int)val->_vector[2])
671                         sprintf (line, "%i %i %i", (int)val->_vector[0], (int)val->_vector[1], (int)val->_vector[2]);
672                 else
673                         sprintf (line, "%f %f %f", val->_vector[0], val->_vector[1], val->_vector[2]);
674                 break;
675         default:
676                 sprintf (line, "bad type %i", type);
677                 break;
678         }
679
680         return line;
681 }
682
683 //compatible with Q1 (for savegames)
684 char *PR_UglyOldValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
685 {
686         static char     line[256];
687         fdef_t          *fielddef;
688         dfunction_t     *f;
689
690 #ifdef DEF_SAVEGLOBAL
691         type &= ~DEF_SAVEGLOBAL;
692 #endif
693
694         if (pr_types)
695                 type = pr_types[type].type;
696
697         switch (type)
698         {
699         case ev_struct:
700                 sprintf (line, "structures cannot yet be saved");
701                 break;
702         case ev_union:
703                 sprintf (line, "unions cannot yet be saved");
704                 break;
705         case ev_string:
706                 sprintf (line, "%s", PR_StringToNative(progfuncs, val->string));
707                 break;
708         case ev_entity:
709                 sprintf (line, "%i", NUM_FOR_EDICT(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, val->edict)));
710                 break;
711         case ev_function:
712                 f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000);
713                 sprintf (line, "%s", f->s_name+progfuncs->stringtable);
714                 break;
715         case ev_field:
716                 fielddef = ED_FieldAtOfs (progfuncs, val->_int );
717                 sprintf (line, "%s", fielddef->name);
718                 break;
719         case ev_void:
720                 sprintf (line, "void");
721                 break;
722         case ev_float:
723                 if (val->_float == (int)val->_float)
724                         sprintf (line, "%i", (int)val->_float); //an attempt to cut down on the number of .000000 vars..
725                 else
726                         sprintf (line, "%f", val->_float);
727                 break;
728         case ev_integer:
729                 sprintf (line, "%i", val->_int);
730                 break;
731         case ev_vector:
732                 if (val->_vector[0] == (int)val->_vector[0] && val->_vector[1] == (int)val->_vector[1] && val->_vector[2] == (int)val->_vector[2])
733                         sprintf (line, "%i %i %i", (int)val->_vector[0], (int)val->_vector[1], (int)val->_vector[2]);
734                 else
735                         sprintf (line, "%f %f %f", val->_vector[0], val->_vector[1], val->_vector[2]);
736                 break;
737                 break;
738         default:
739                 sprintf (line, "bad type %i", type);
740                 break;
741         }
742
743         return line;
744 }
745
746 char *PR_TypeString(progfuncs_t *progfuncs, etype_t type)
747 {
748 #ifdef DEF_SAVEGLOBAL
749         type &= ~DEF_SAVEGLOBAL;
750 #endif
751
752         if (pr_types)
753                 type = pr_types[type].type;
754
755         switch (type)
756         {
757         case ev_struct:
758                 return "struct";
759         case ev_union:
760                 return "union";
761         case ev_string:
762                 return "string";
763         case ev_entity:
764                 return "entity";
765         case ev_function:
766                 return "function";
767         case ev_field:
768                 return "field";
769         case ev_void:
770                 return "void";
771         case ev_float:
772                 return "float";
773         case ev_vector:
774                 return "vector";
775         case ev_integer:
776                 return "integer";
777         default:
778                 return "BAD TYPE";
779         }
780 }
781
782 /*
783 ============
784 PR_GlobalString
785
786 Returns a string with a description and the contents of a global,
787 padded to 20 field width
788 ============
789 */
790 char *PR_GlobalString (progfuncs_t *progfuncs, int ofs)
791 {
792         char    *s;
793         int             i;
794         ddef16_t        *def16;
795         ddef32_t        *def32;
796         void    *val;
797         static char     line[128];
798
799         switch (current_progstate->intsize)
800         {
801         case 16:
802         case 24:
803                 val = (void *)&pr_globals[ofs];
804                 def16 = ED_GlobalAtOfs16(progfuncs, ofs);
805                 if (!def16)
806                         sprintf (line,"%i(?""?""?)", ofs);
807                 else
808                 {
809                         s = PR_ValueString (progfuncs, def16->type, val);
810                         sprintf (line,"%i(%s)%s", ofs, def16->s_name+progfuncs->stringtable, s);
811                 }
812
813                 i = strlen(line);
814                 for ( ; i<20 ; i++)
815                         strcat (line," ");
816                 strcat (line," ");
817                 return line;
818         case 32:
819                 val = (void *)&pr_globals[ofs];
820                 def32 = ED_GlobalAtOfs32(progfuncs, ofs);
821                 if (!def32)
822                         sprintf (line,"%i(?""?""?)", ofs);
823                 else
824                 {
825                         s = PR_ValueString (progfuncs, def32->type, val);
826                         sprintf (line,"%i(%s)%s", ofs, def32->s_name+progfuncs->stringtable, s);
827                 }
828
829                 i = strlen(line);
830                 for ( ; i<20 ; i++)
831                         strcat (line," ");
832                 strcat (line," ");
833                 return line;
834         }
835         Sys_Error("Bad offset size in PR_GlobalString");
836         return "";
837 }
838
839 char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs)
840 {
841         int             i;
842         ddef16_t        *def16;
843         ddef32_t        *def32;
844         static char     line[128];
845
846         switch (current_progstate->intsize)
847         {
848         case 16:
849         case 24:
850                 def16 = ED_GlobalAtOfs16(progfuncs, ofs);
851                 if (!def16)
852                         sprintf (line,"%i(?""?""?)", ofs);
853                 else
854                         sprintf (line,"%i(%s)", ofs, def16->s_name+progfuncs->stringtable);
855                 break;
856         case 32:
857                 def32 = ED_GlobalAtOfs32(progfuncs, ofs);
858                 if (!def32)
859                         sprintf (line,"%i(?""?""?)", ofs);
860                 else
861                         sprintf (line,"%i(%s)", ofs, def32->s_name+progfuncs->stringtable);
862                 break;
863         default:
864                 Sys_Error("Bad offset size in PR_GlobalStringNoContents");
865         }
866
867         i = strlen(line);
868         for ( ; i<20 ; i++)
869                 strcat (line," ");
870         strcat (line," ");
871
872         return line;
873 }
874
875
876 /*
877 =============
878 ED_Print
879
880 For debugging
881 =============
882 */
883 void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed)
884 {
885         int             l;
886         fdef_t  *d;
887         int             *v;
888         unsigned int            i;unsigned int j;
889         char    *name;
890         int             type;
891
892         if (((edictrun_t *)ed)->isfree)
893         {
894                 printf ("FREE\n");
895                 return;
896         }
897
898         printf("\nEDICT %i:\n", NUM_FOR_EDICT(progfuncs, (struct edict_s *)ed));
899         for (i=1 ; i<numfields ; i++)
900         {
901                 d = &field[i];
902                 name = d->name;
903                 l = strlen(name);
904                 if (l >= 2 && name[l-2] == '_')
905                         continue;       // skip _x, _y, _z vars
906
907                 v = (int *)((char *)edvars(ed) + d->ofs*4);
908
909         // if the value is still all 0, skip the field
910 #ifdef DEF_SAVEGLOBAL
911                 type = d->type & ~DEF_SAVEGLOBAL;
912 #else
913                 type = d->type;
914 #endif
915
916                 for (j=0 ; j<type_size[type] ; j++)
917                         if (v[j])
918                                 break;
919                 if (j == type_size[type])
920                         continue;
921
922                 printf ("%s",name);
923                 l = strlen (name);
924                 while (l++ < 15)
925                         printf (" ");
926
927                 printf ("%s\n", PR_ValueString(progfuncs, d->type, (eval_t *)v));
928         }
929 }
930
931 void ED_PrintNum (progfuncs_t *progfuncs, int ent)
932 {
933         ED_Print (progfuncs, EDICT_NUM(progfuncs, ent));
934 }
935
936 /*
937 =============
938 ED_PrintEdicts
939
940 For debugging, prints all the entities in the current server
941 =============
942 */
943 void ED_PrintEdicts (progfuncs_t *progfuncs)
944 {
945         unsigned int            i;
946
947         printf ("%i entities\n", sv_num_edicts);
948         for (i=0 ; i<sv_num_edicts ; i++)
949                 ED_PrintNum (progfuncs, i);
950 }
951
952 /*
953 =============
954 ED_Count
955
956 For debugging
957 =============
958 */
959 void ED_Count (progfuncs_t *progfuncs)
960 {
961         unsigned int            i;
962         edictrun_t      *ent;
963         unsigned int            active, models, solid, step;
964
965         active = models = solid = step = 0;
966         for (i=0 ; i<sv_num_edicts ; i++)
967         {
968                 ent = (edictrun_t *)EDICT_NUM(progfuncs, i);
969                 if (ent->isfree)
970                         continue;
971                 active++;
972 //              if (ent->v.solid)
973 //                      solid++;
974 //              if (ent->v.model)
975 //                      models++;
976 //              if (ent->v.movetype == MOVETYPE_STEP)
977 //                      step++;
978         }
979
980         printf ("num_edicts:%3i\n", sv_num_edicts);
981         printf ("active    :%3i\n", active);
982 //      Con_Printf ("view      :%3i\n", models);
983 //      Con_Printf ("touch     :%3i\n", solid);
984 //      Con_Printf ("step      :%3i\n", step);
985
986 }
987
988
989
990 //============================================================================
991
992
993 /*
994 =============
995 ED_NewString
996 =============
997 */
998 char *ED_NewString (progfuncs_t *progfuncs, char *string, int minlength)
999 {
1000         char    *newc, *new_p;
1001         int             i,l;
1002
1003         minlength++;
1004
1005         l = strlen(string) + 1;
1006
1007         newc = PRAddressableAlloc (progfuncs, l<minlength?minlength:l);
1008         new_p = newc;
1009
1010         for (i=0 ; i< l ; i++)
1011         {
1012                 if (string[i] == '\\' && i < l-1 && string[i+1] != 0)
1013                 {
1014                         i++;
1015                         if (string[i] == 'n')
1016                                 *new_p++ = '\n';
1017                         else
1018                                 *new_p++ = '\\';
1019                 }
1020                 else
1021                         *new_p++ = string[i];
1022         }
1023
1024         return newc;
1025 }
1026
1027
1028 /*
1029 =============
1030 ED_ParseEval
1031
1032 Can parse either fields or globals
1033 returns false if error
1034 =============
1035 */
1036 pbool   ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, int bits)
1037 {
1038         int             i;
1039         char    string[128];
1040         fdef_t  *def;
1041         char    *v, *w;
1042         void    *d;
1043         string_t st;
1044         dfunction_t     *func;
1045
1046         int type;
1047
1048         switch(bits)
1049         {
1050         case 16:
1051                 d = (void *)((int *)base + ((ddef16_t*)key)->ofs);
1052
1053                 if (pr_types)
1054                         type = pr_types[((ddef16_t*)key)->type & ~DEF_SAVEGLOBAL].type;
1055                 else
1056                         type = ((ddef16_t*)key)->type & ~DEF_SAVEGLOBAL;
1057                 break;
1058         case 32:
1059                 d = (void *)((int *)base + ((ddef32_t*)key)->ofs);
1060
1061                 if (pr_types)
1062                         type = pr_types[((ddef32_t*)key)->type & ~DEF_SAVEGLOBAL].type;
1063                 else
1064                         type = ((ddef32_t*)key)->type & ~DEF_SAVEGLOBAL;
1065                 break;
1066         default:
1067                 Sys_Error("Bad bits in ED_ParseEpair");
1068                 d = 0;
1069         }
1070
1071         switch (type)
1072         {
1073         case ev_string:
1074                 st = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, s, 0));
1075                 *(string_t *)d = st;
1076                 break;
1077
1078         case ev_float:
1079                 *(float *)d = (float)atof (s);
1080                 break;
1081
1082         case ev_integer:
1083                 *(int *)d = atoi (s);
1084                 break;
1085
1086         case ev_vector:
1087                 strcpy (string, s);
1088                 v = string;
1089                 w = string;
1090                 for (i=0 ; i<3 ; i++)
1091                 {
1092                         while (*v && *v != ' ')
1093                                 v++;
1094                         *v = 0;
1095                         ((float *)d)[i] = (float)atof (w);
1096                         w = v = v+1;
1097                 }
1098                 break;
1099
1100         case ev_entity:
1101                 *(int *)d = atoi (s);
1102                 break;
1103
1104         case ev_field:
1105                 def = ED_FindField (progfuncs, s);
1106                 if (!def)
1107                 {
1108                         printf ("Can't find field %s\n", s);
1109                         return false;
1110                 }
1111                 *(int *)d = def->ofs;
1112                 break;
1113
1114         case ev_function:
1115                 if (s[1]==':'&&s[2]=='\0')
1116                 {
1117                         *(func_t *)d = 0;
1118                         return true;
1119                 }
1120                 func = ED_FindFunction (progfuncs, s, &i, -1);
1121                 if (!func)
1122                 {
1123                         printf ("Can't find function %s\n", s);
1124                         return false;
1125                 }
1126                 *(func_t *)d = (func - pr_progstate[i].functions) | (i<<24);
1127                 break;
1128
1129         default:
1130                 break;
1131         }
1132         return true;
1133 }
1134
1135 /*
1136 ====================
1137 ED_ParseEdict
1138
1139 Parses an edict out of the given string, returning the new position
1140 ed should be a properly initialized empty edict.
1141 Used for initial level load and for savegames.
1142 ====================
1143 */
1144 #if 1
1145 char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent)
1146 {
1147         fdef_t          *key;
1148         pbool   init;
1149         char            keyname[256];
1150         int                     n;
1151
1152 //      eval_t          *val;
1153
1154         init = false;
1155
1156 // clear it
1157 //      if (ent != (edictrun_t *)sv_edicts)     // hack
1158 //              memset (ent+1, 0, pr_edict_size - sizeof(edictrun_t));
1159
1160 // go through all the dictionary pairs
1161         while (1)
1162         {
1163         // parse key
1164                 data = QCC_COM_Parse (data);
1165                 if (qcc_token[0] == '}')
1166                         break;
1167                 if (!data)
1168                 {
1169                         printf ("ED_ParseEntity: EOF without closing brace\n");
1170                         return NULL;
1171                 }
1172
1173                 strncpy (keyname, qcc_token, sizeof(keyname)-1);
1174                 keyname[sizeof(keyname)-1] = 0;
1175
1176                 // another hack to fix heynames with trailing spaces
1177                 n = strlen(keyname);
1178                 while (n && keyname[n-1] == ' ')
1179                 {
1180                         keyname[n-1] = 0;
1181                         n--;
1182                 }
1183
1184         // parse value
1185                 data = QCC_COM_Parse (data);
1186                 if (!data)
1187                 {
1188                         printf ("ED_ParseEntity: EOF without closing brace\n");
1189                         return NULL; 
1190                 }
1191
1192                 if (qcc_token[0] == '}')
1193                 {
1194                         printf ("ED_ParseEntity: closing brace without data\n");
1195                         return NULL;
1196                 }
1197
1198                 init = true;
1199
1200 // keynames with a leading underscore are used for utility comments,
1201 // and are immediately discarded by quake
1202                 if (keyname[0] == '_')
1203                         continue;
1204
1205                 key = ED_FindField (progfuncs, keyname);
1206                 if (!key)
1207                 {
1208                         if (!strcmp(keyname, "angle"))  //Quake anglehack - we've got to leave it in cos it doesn't work for quake otherwise, and this is a QuakeC lib!
1209                         {
1210                                 if ((key = ED_FindField (progfuncs, "angles")))
1211                                 {
1212                                         sprintf (qcc_token, "0 %f 0", atof(qcc_token)); //change it from yaw to 3d angle
1213                                         goto cont;
1214                                 }
1215                         }
1216                         if (!strcmp(keyname, "light"))  //Quake lighthack - allows a field name and a classname to go by the same thing in the level editor
1217                                 if ((key = ED_FindField (progfuncs, "light_lev")))
1218                                         goto cont;
1219                         printf ("'%s' is not a field\n", keyname);
1220                         continue;
1221                 }
1222
1223 cont:
1224                 if (!ED_ParseEpair (progfuncs, ent->fields, (ddefXX_t*)key, qcc_token, 32))
1225                 {
1226                         continue;
1227 //                      Sys_Error ("ED_ParseEdict: parse error on entities");
1228                 }
1229         }
1230
1231         if (!init)
1232                 ent->isfree = true;
1233
1234         return data;
1235 }
1236 #endif
1237
1238 /*
1239 ================
1240 ED_LoadFromFile
1241
1242 The entities are directly placed in the array, rather than allocated with
1243 ED_Alloc, because otherwise an error loading the map would have entity
1244 number references out of order.
1245
1246 Creates a server's entity / program execution context by
1247 parsing textual entity definitions out of an ent file.
1248
1249 Used for both fresh maps and savegame loads.  A fresh map would also need
1250 to call ED_CallSpawnFunctions () to let the objects initialize themselves.
1251 ================
1252 */
1253
1254 char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer)     //switch first.
1255 {
1256 #define AddS(str) strcpy(buffer, str);buffer+=strlen(str);
1257         int             *v;
1258         ddef32_t                *def32;
1259         ddef16_t                *def16;
1260         unsigned int                    i;
1261         unsigned int j;
1262         char    *name;
1263         int                     type;
1264         int curprogs = pr_typecurrent;
1265         int len;
1266         switch(current_progstate->intsize)
1267         {
1268         case 16:
1269         case 24:
1270                 for (i=0 ; i<pr_progs->numglobaldefs ; i++)
1271                 {
1272                         def16 = &pr_globaldefs16[i];
1273                         name = def16->s_name + progfuncs->stringtable;
1274                         len = strlen(name);
1275                         if (!*name)
1276                                 continue;
1277                         if (name[len-2] == '_' && (name[len-1] == 'x' || name[len-1] == 'y' || name[len-1] == 'z'))
1278                                 continue;       // skip _x, _y, _z vars (vector components, which are saved as one vector not 3 floats)
1279
1280                         type = def16->type;
1281
1282 #ifdef DEF_SAVEGLOBAL
1283                         if ( !(def16->type & DEF_SAVEGLOBAL) )
1284                                 continue;
1285                         type &= ~DEF_SAVEGLOBAL;
1286 #endif
1287                         if (current_progstate->types)
1288                                 type = current_progstate->types[type].type;
1289                         if (type == ev_function)
1290                         {
1291                                 v = (int *)&current_progstate->globals[def16->ofs];
1292                                 if ((v[0]&0xff000000)>>24 == (unsigned)curprogs)        //same progs
1293                                 {
1294                                         if (!progfuncs->stringtable[current_progstate->functions[v[0]&0x00ffffff].s_name])
1295                                                 continue;
1296                                         else if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name))   //names match. Assume function is at initial value.
1297                                                 continue;
1298                                 }
1299
1300                                 if (curprogs!=0)
1301                                 if ((v[0]&0xff000000)>>24 == 0)
1302                                         if (!ED_FindFunction(progfuncs, name, NULL, curprogs))  //defined as extern
1303                                         {
1304                                                 if (!progfuncs->stringtable[pr_progstate[0].functions[v[0]&0x00ffffff].s_name])
1305                                                         continue;
1306                                                 else if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name + progfuncs->stringtable, name))     //same name.
1307                                                         continue;
1308                                         }
1309
1310                                 //else function has been redirected externally.
1311                                 goto add16;
1312                         }
1313                         else if (type != ev_string      //anything other than these is not saved
1314                         && type != ev_float
1315                         && type != ev_integer
1316                         && type != ev_entity
1317                         && type != ev_vector)
1318                                 continue;
1319
1320                         v = (int *)&current_progstate->globals[def16->ofs];
1321
1322                         // make sure the value is not null, where there's no point in saving
1323                         for (j=0 ; j<type_size[type] ; j++)
1324                                 if (v[j])
1325                                         break;
1326                         if (j == type_size[type])
1327                                 continue;
1328
1329  add16:
1330                         AddS (qcva("\"%s\" ", name));
1331                         AddS (qcva("\"%s\"\n", PR_UglyValueString(progfuncs, def16->type&~DEF_SAVEGLOBAL, (eval_t *)v)));
1332                 }
1333                 break;
1334         case 32:
1335                 for (i=0 ; i<pr_progs->numglobaldefs ; i++)
1336                 {
1337                         def32 = &pr_globaldefs32[i];
1338                         name = def32->s_name + progfuncs->stringtable;
1339                         if (name[strlen(name)-2] == '_')
1340                                 continue;       // skip _x, _y, _z vars (vector components, which are saved as one vector not 3 floats)
1341
1342                         type = def32->type;
1343
1344 #ifdef DEF_SAVEGLOBAL
1345                         if ( !(def32->type & DEF_SAVEGLOBAL) )
1346                                 continue;
1347                         type &= ~DEF_SAVEGLOBAL;
1348 #endif
1349                         if (current_progstate->types)
1350                                 type = current_progstate->types[type].type;
1351                         if (type == ev_function)
1352                         {
1353                                 v = (int *)&current_progstate->globals[def32->ofs];
1354                                 if ((v[0]&0xff000000)>>24 == (unsigned)curprogs)        //same progs
1355                                         if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name))        //names match. Assume function is at initial value.
1356                                                 continue;
1357
1358                                 if (curprogs!=0)
1359                                 if ((v[0]&0xff000000)>>24 == 0)
1360                                         if (!ED_FindFunction(progfuncs, name, NULL, curprogs))  //defined as extern
1361                                                 if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name))   //same name.
1362                                                         continue;
1363
1364                                 //else function has been redirected externally.
1365                                 goto add32;
1366                         }
1367                         else if (type != ev_string      //anything other than these is not saved
1368                         && type != ev_float
1369                         && type != ev_integer
1370                         && type != ev_entity
1371                         && type != ev_vector)
1372                                 continue;
1373
1374                         v = (int *)&current_progstate->globals[def32->ofs];
1375
1376                         // make sure the value is not null, where there's no point in saving
1377                         for (j=0 ; j<type_size[type] ; j++)
1378                                 if (v[j])
1379                                         break;
1380                         if (j == type_size[type])
1381                                 continue;
1382 add32:
1383                         AddS (qcva("\"%s\" ", name));
1384                         AddS (qcva("\"%s\"\n", PR_UglyValueString(progfuncs, def32->type&~DEF_SAVEGLOBAL, (eval_t *)v)));
1385                 }
1386                 break;
1387         default:
1388                 Sys_Error("Bad number of bits in SaveEnts");
1389         }
1390
1391         return buffer;
1392 }
1393
1394 char *ED_WriteEdict(progfuncs_t *progfuncs, edictrun_t *ed, char *buffer, pbool q1compatible)
1395 {
1396         fdef_t  *d;
1397
1398         int             *v;
1399         unsigned int            i;unsigned int j;
1400         char    *name;
1401         int             type;
1402         int len;
1403
1404         for (i=0 ; i<numfields ; i++)
1405         {
1406                 d = &field[i];
1407                 name = d->name;
1408                 len = strlen(name);
1409                 if (len>4 && (name[len-2] == '_' && (name[len-1] == 'x' || name[len-1] == 'y' || name[len-1] == 'z')))
1410                         continue;       // skip _x, _y, _z vars
1411
1412                 v = (int *)((char*)ed->fields + d->ofs*4);
1413
1414         // if the value is still all 0, skip the field
1415 #ifdef DEF_SAVEGLOBAL
1416                 type = d->type & ~DEF_SAVEGLOBAL;
1417 #else
1418                 type = d->type;
1419 #endif
1420
1421                 for (j=0 ; j<type_size[type] ; j++)
1422                         if (v[j])
1423                                 break;
1424                 if (j == type_size[type])
1425                         continue;
1426
1427                 //add it to the file
1428                 AddS (qcva("\"%s\" ",name));
1429                 AddS (qcva("\"%s\"\n", (q1compatible?PR_UglyOldValueString:PR_UglyValueString)(progfuncs, d->type, (eval_t *)v)));
1430         }
1431
1432         return buffer;
1433 #undef AddS
1434 }
1435
1436 char *SaveCallStack (progfuncs_t *progfuncs, char *s)
1437 {
1438 #define AddS(str) strcpy(s, str);s+=strlen(str);
1439         char buffer[8192];
1440         dfunction_t     *f;
1441         int                     i;
1442         int progs;
1443
1444         int arg;
1445         int *globalbase;
1446
1447         progs = -1;
1448
1449         if (pr_depth == 0)
1450         {
1451                 AddS ("<NO STACK>\n");
1452                 return s;
1453         }
1454
1455         globalbase = (int *)pr_globals + pr_xfunction->parm_start + pr_xfunction->locals;
1456
1457         pr_stack[pr_depth].f = pr_xfunction;
1458         for (i=pr_depth ; i>0 ; i--)
1459         {
1460                 f = pr_stack[i].f;
1461
1462                 if (!f)
1463                 {
1464                         AddS ("<NO FUNCTION>\n");
1465                 }
1466                 else
1467                 {
1468                         if (pr_stack[i].progsnum != progs)
1469                         {
1470                                 progs = pr_stack[i].progsnum;
1471
1472                                 sprintf(buffer, "//%i %s\n", progs, pr_progstate[progs].filename);
1473                                 AddS (buffer);
1474                         }
1475                         if (!f->s_file)
1476                                 sprintf(buffer, "\t\"%i:%s\"\n", progs, f->s_name+progfuncs->stringtable);
1477                         else
1478                                 sprintf(buffer, "\t\"%i:%s\" //%s\n", progs, f->s_name+progfuncs->stringtable, f->s_file+progfuncs->stringtable);
1479                         AddS (buffer);
1480
1481                         AddS ("\t{\n");
1482                         for (arg = 0; arg < f->locals; arg++)
1483                         {
1484                                 ddef16_t *local;
1485                                 local = ED_GlobalAtOfs16(progfuncs, f->parm_start+arg);
1486                                 if (!local)
1487                                         sprintf(buffer, "\t\tofs%i %i // %f\n", f->parm_start+arg, *(int *)(globalbase - f->locals+arg), *(float *)(globalbase - f->locals+arg) );
1488                                 else
1489                                 {
1490                                         if (local->type == ev_entity)
1491                                         {
1492                                                 sprintf(buffer, "\t\t\"%s\" \"entity %i\"\n", local->s_name+progfuncs->stringtable, ((eval_t*)(globalbase - f->locals+arg))->edict);
1493                                         }
1494                                         else
1495                                                 sprintf(buffer, "\t\t\"%s\"\t\"%s\"\n", local->s_name+progfuncs->stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg)));
1496
1497                                         if (local->type == ev_vector)
1498                                                 arg+=2;
1499                                 }
1500                                 AddS (buffer);
1501                         }
1502                         AddS ("\t}\n");
1503
1504                         if (i == pr_depth)
1505                                 globalbase = localstack + localstack_used - f->locals;
1506                         else
1507                                 globalbase -= f->locals;
1508                 }
1509         }
1510         return s;
1511 #undef AddS
1512 }
1513
1514 //there are two ways of saving everything.
1515 //0 is to save just the entities.
1516 //1 is to save the entites, and all the progs info so that all the variables are saved off, and it can be reloaded to exactly how it was (provided no files or data has been changed outside, like the progs.dat for example)
1517 char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *len, int alldata)
1518 {
1519 #define AddS(str) strcpy(s, str);s+=strlen(str);
1520         char *s, *os;
1521         unsigned int a;
1522         int oldprogs;
1523
1524         if (mem)
1525         {
1526                 os = s = mem;
1527         }
1528         else
1529                 os = s = memalloc(5*1024*1024);
1530
1531         if (alldata == 2)
1532         {       //special Q1 savegame compatability mode.
1533                 //engine will need to store references to progs type and will need to preload the progs and inti the ents itself before loading.
1534
1535                 //Make sure there is only 1 progs loaded.
1536                 for (a = 1; a < maxprogs; a++)
1537                 {
1538                         if (pr_progstate[a].progs)
1539                                 break;
1540                 }
1541                 if (!pr_progstate[0].progs || a != maxprogs)    //the state of the progs wasn't Q1 compatible.
1542                 {
1543                         memfree(os);
1544                         return NULL;
1545                 }
1546
1547                 //write the globals
1548                 AddS ("{\n");
1549
1550                 oldprogs = pr_typecurrent;
1551                 PR_SwitchProgs(progfuncs, 0);
1552
1553                 s = ED_WriteGlobals(progfuncs, s);
1554
1555                 PR_SwitchProgs(progfuncs, oldprogs);
1556
1557                 AddS ("}\n");
1558
1559
1560                 //write the ents
1561                 for (a = 0; a < sv_num_edicts; a++)
1562                 {
1563                         edictrun_t *ed = (edictrun_t *)EDICT_NUM(progfuncs, a);
1564
1565                         AddS ("{\n");
1566
1567                         if (!ed->isfree)
1568                                 s = ED_WriteEdict(progfuncs, ed, s, true);
1569
1570                         AddS ("}\n");
1571                 }
1572
1573                 *len = s - os;
1574                 return os;
1575         }
1576
1577         if (alldata)
1578         {
1579                 AddS("general {\n");
1580                 AddS(qcva("\"maxprogs\" \"%i\"\n", maxprogs));
1581 //              AddS(qcva("\"maxentities\" \"%i\"\n", maxedicts));
1582 //              AddS(qcva("\"mem\" \"%i\"\n", hunksize));
1583 //              AddS(qcva("\"crc\" \"%i\"\n", header_crc));
1584                 AddS(qcva("\"numentities\" \"%i\"\n", sv_num_edicts));
1585                 AddS("}\n");
1586
1587                 oldprogs = pr_typecurrent;
1588
1589                 for (a = 0; a < maxprogs; a++)
1590                 {
1591                         if (!pr_progstate[a].progs)
1592                                 continue;
1593                         PR_SwitchProgs(progfuncs, a);
1594                         {
1595                                 AddS (qcva("progs %i {\n", a));
1596                                 AddS (qcva("\"filename\" \"%s\"\n", pr_progstate[a].filename));
1597                                 AddS (qcva("\"crc\" \"%i\"\n", pr_progs->crc));
1598                                 AddS (qcva("\"numbuiltins\" \"%i\"\n", current_progstate->numbuiltins));
1599                                 AddS ("}\n");
1600                         }
1601                 }
1602
1603                 if (alldata == 3)
1604                 {
1605                         //include callstack
1606                         AddS("stacktrace {\n");
1607                         s = SaveCallStack(progfuncs, s);
1608                         AddS("}\n");
1609                 }
1610
1611                 for (a = 0; a < maxprogs; a++)  //I would mix, but external functions rely on other progs being loaded
1612                 {
1613                         if (!pr_progstate[a].progs)
1614                                 continue;
1615
1616                         AddS (qcva("globals %i {\n", a));
1617
1618                         PR_SwitchProgs(progfuncs, a);
1619
1620                         s = ED_WriteGlobals(progfuncs, s);
1621
1622                         AddS ("}\n");
1623                 }
1624                 PR_SwitchProgs(progfuncs, oldprogs);
1625         }
1626         for (a = 0; a < sv_num_edicts; a++)
1627         {
1628                 edictrun_t *ed = (edictrun_t *)EDICT_NUM(progfuncs, a);
1629
1630                 if (ed->isfree)
1631                         continue;
1632
1633                 AddS (qcva("entity %i{\n", a));
1634
1635                 s = ED_WriteEdict(progfuncs, ed, s, false);
1636
1637                 AddS ("}\n");
1638         }
1639
1640         *len = s - os;
1641         return os;
1642
1643 #undef AddS
1644 }
1645
1646 int header_crc;
1647
1648 //if 'general' block is found, this is a compleate state, otherwise, we should spawn entities like
1649 int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
1650 {
1651         eval_t *fulldata;       //this is part of FTE_FULLSPAWNDATA
1652         char *datastart;
1653
1654         eval_t *var;
1655
1656         char filename[128];
1657         int num;
1658         int numbuiltins;
1659         edictrun_t *ed=NULL;
1660         ddef16_t *d16;
1661         ddef32_t *d32;
1662         func_t CheckSpawn=0;
1663
1664         extern edictrun_t tempedict;
1665
1666         int crc = 1;
1667         int entsize = 0;
1668         int numents = 0;
1669
1670         pbool resethunk=0;
1671         pbool isloadgame;
1672         if (!strncmp(file, "loadgame", 8))
1673         {
1674                 isloadgame = true;
1675                 numents = -1;
1676                 file+=8;
1677                 fulldata = NULL;
1678         }
1679         else
1680         {
1681                 isloadgame = false;
1682
1683                 if (pr_typecurrent>=0)
1684                         num = ED_FindGlobalOfs(progfuncs, "__fullspawndata");
1685                 else
1686                         num = 0;
1687                 if (num)
1688                         fulldata = (eval_t *)((int *)pr_globals + num);
1689                 else
1690                         fulldata = NULL;
1691         }
1692
1693         while(1)
1694         {
1695                 datastart = file;
1696                 file = QCC_COM_Parse(file);
1697                 if (file == NULL)
1698                         break;  //finished reading file
1699                 else if (!strcmp(qcc_token, "entity"))
1700                 {
1701                         if (entsize == 0 && resethunk)  //edicts have not yet been initialized, and this is a compleate load (memsize has been set)
1702                         {
1703                                 entsize = PR_InitEnts(progfuncs, maxedicts);
1704 //                              sv_num_edicts = numents;
1705
1706                                 for (num = 0; num < numents; num++)
1707                                 {
1708                                         ed = (edictrun_t *)EDICT_NUM(progfuncs, num);
1709
1710                                         if (!ed)
1711                                         {
1712                                                 ed = ED_AllocIntoTable(progfuncs, num);
1713                                                 ed->isfree = true;
1714                                                 if (externs->entspawn)
1715                                                         externs->entspawn((struct edict_s *) ed, true);
1716                                         }
1717                                 }
1718                         }
1719
1720                         file = QCC_COM_Parse(file);
1721                         num = atoi(qcc_token);
1722                         file = QCC_COM_Parse(file);
1723                         if (qcc_token[0] != '{')
1724                                 Sys_Error("Progs loading found %s, not '{'", qcc_token);
1725                         if (!resethunk)
1726                                 ed = (edictrun_t *)ED_Alloc(progfuncs);
1727                         else
1728                         {
1729                                 ed = (edictrun_t *)EDICT_NUM(progfuncs, num);
1730
1731                                 if (!ed)
1732                                 {
1733                                         Sys_Error("Edict was not allocated\n");
1734                                         ed = ED_AllocIntoTable(progfuncs, num);
1735                                 }
1736                         }
1737                         ed->isfree = false;
1738                         if (externs->entspawn)
1739                                 externs->entspawn((struct edict_s *) ed, true);
1740                         file = ED_ParseEdict(progfuncs, file, ed);
1741
1742                         if (killonspawnflags)
1743                         {
1744                                 var = GetEdictFieldValue (progfuncs, (struct edict_s *)&ed, "spawnflags", &spawnflagscache);
1745                                 if (var)
1746                                 {
1747                                         if ((int)var->_float & (int)killonspawnflags)
1748                                         {
1749                                                 ed->isfree = true;
1750                                                 continue;
1751                                         }
1752                                 }
1753                         }
1754
1755                         if (!resethunk)
1756                         {
1757                                 dfunction_t *f;
1758                                 if ((var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "classname", NULL)))
1759                                 {
1760                                         f = ED_FindFunction(progfuncs, var->string + progfuncs->stringtable, NULL, -1);
1761                                         if (f)
1762                                         {
1763                                                 var = (eval_t *)((int *)pr_globals + ED_FindGlobalOfs(progfuncs, "self"));
1764                                                 var->edict = EDICT_TO_PROG(progfuncs, ed);
1765                                                 PR_ExecuteProgram(progfuncs, f-pr_functions);
1766                                         }
1767                                 }
1768                         }
1769                 }
1770                 else if (!strcmp(qcc_token, "progs"))
1771                 {
1772                         file = QCC_COM_Parse(file);
1773                         num = atoi(qcc_token);
1774                         file = QCC_COM_Parse(file);
1775                         if (qcc_token[0] != '{')
1776                                 Sys_Error("Progs loading found %s, not '{'", qcc_token);
1777
1778
1779                         filename[0] = '\0';
1780                         header_crc = 0;
1781                         numbuiltins = 0;
1782
1783                         while(1)
1784                         {
1785                                 file = QCC_COM_Parse(file);     //read the key
1786                                 if (!file)
1787                                         Sys_Error("EOF in progs block");
1788
1789                                 if (!strcmp("filename", qcc_token))     //check key get and save values
1790                                         {file = QCC_COM_Parse(file); strcpy(filename, qcc_token);}
1791                                 else if (!strcmp("crc", qcc_token))
1792                                         {file = QCC_COM_Parse(file); header_crc = atoi(qcc_token);}
1793                                 else if (!strcmp("numbuiltins", qcc_token))
1794                                         {file = QCC_COM_Parse(file); numbuiltins = atoi(qcc_token);}
1795                                 else if (qcc_token[0] == '}')   //end of block
1796                                         break;
1797                                 else
1798                                         Sys_Error("Bad key \"%s\" in progs block", qcc_token);
1799                         }
1800
1801                         PR_ReallyLoadProgs(progfuncs, filename, header_crc, &pr_progstate[num], true);
1802                         if (!externs->builtinsfor)
1803                         {
1804                         //      Sys_Error("Couldn't reset the builtin functions");
1805                                 current_progstate->builtins = NULL;     //these are specific, we assume the global ones were set via pr_configure
1806                                 current_progstate->numbuiltins = 0;
1807                         }
1808                         else
1809                         {
1810                                 current_progstate->builtins = externs->builtinsfor(num, header_crc);
1811                                 current_progstate->numbuiltins = numbuiltins;
1812                         }
1813                 }
1814                 else if (!strcmp(qcc_token, "globals"))
1815                 {
1816                         if (entsize == 0 && resethunk)  //by the time we parse some globals, we MUST have loaded all progs
1817                         {
1818                                 entsize = PR_InitEnts(progfuncs, maxedicts);
1819 //                              sv_num_edicts = numents;
1820
1821                                 for (num = 0; num < numents; num++)
1822                                 {
1823                                         ed = (edictrun_t *)EDICT_NUM(progfuncs, num);
1824
1825                                         if (!ed)
1826                                         {
1827                                                 ed = ED_AllocIntoTable(progfuncs, num);
1828                                                 ed->isfree = true;
1829                                         }
1830
1831                                         if (externs->entspawn)
1832                                                 externs->entspawn((struct edict_s *) ed, true);
1833                                 }
1834                         }
1835
1836                         file = QCC_COM_Parse(file);
1837                         num = atoi(qcc_token);
1838
1839                         file = QCC_COM_Parse(file);
1840                         if (qcc_token[0] != '{')
1841                                 Sys_Error("Globals loading found \'%s\', not '{'", qcc_token);
1842
1843                         PR_SwitchProgs(progfuncs, num);
1844                         while (1)
1845                         {
1846                                 file = QCC_COM_Parse(file);
1847                                 if (qcc_token[0] == '}')
1848                                         break;
1849                                 else if (!qcc_token[0] || !file)
1850                                         Sys_Error("EOF when parsing global values");
1851
1852                                 switch(current_progstate->intsize)
1853                                 {
1854                                 case 16:
1855                                 case 24:
1856                                         if (!(d16 = ED_FindGlobal16(progfuncs, qcc_token)))
1857                                         {
1858                                                 file = QCC_COM_Parse(file);
1859                                                 printf("global value %s not found", qcc_token);
1860                                         }
1861                                         else
1862                                         {
1863                                                 file = QCC_COM_Parse(file);
1864                                                 ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, 16);
1865                                         }
1866                                         break;
1867                                 case 32:
1868                                         if (!(d32 = ED_FindGlobal32(progfuncs, qcc_token)))
1869                                         {
1870                                                 file = QCC_COM_Parse(file);
1871                                                 printf("global value %s not found", qcc_token);
1872                                         }
1873                                         else
1874                                         {
1875                                                 file = QCC_COM_Parse(file);
1876                                                 ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, 32);
1877                                         }
1878                                         break;
1879                                 default:
1880                                         Sys_Error("Bad intsize in LoadEnts");
1881                                 }
1882                         }
1883
1884 //                      file = QCC_COM_Parse(file);
1885 //                      if (com_token[0] != '}')
1886 //                              Sys_Error("Progs loading found %s, not '}'", qcc_token);
1887                 }
1888                 else if (!strcmp(qcc_token, "general"))
1889                 {
1890                         QC_StartShares(progfuncs);
1891 //                      QC_InitShares();        //forget stuff
1892 //                      pr_edict_size = 0;
1893                         max_fields_size=0;
1894
1895                         file = QCC_COM_Parse(file);
1896                         if (qcc_token[0] != '{')
1897                                 Sys_Error("Progs loading found %s, not '{'", qcc_token);
1898
1899                         while(1)
1900                         {
1901                                 file = QCC_COM_Parse(file);     //read the key
1902                                 if (!file)
1903                                         Sys_Error("EOF in general block");
1904
1905                                 if (!strcmp("maxprogs", qcc_token))     //check key get and save values
1906                                         {file = QCC_COM_Parse(file); maxprogs = atoi(qcc_token);}
1907 //                              else if (!strcmp("maxentities", com_token))
1908 //                                      {file = QCC_COM_Parse(file); maxedicts = atoi(qcc_token);}
1909 //                              else if (!strcmp("mem", com_token))
1910 //                                      {file = QCC_COM_Parse(file); memsize = atoi(qcc_token);}
1911 //                              else if (!strcmp("crc", com_token))
1912 //                                      {file = QCC_COM_Parse(file); crc = atoi(qcc_token);}
1913                                 else if (!strcmp("numentities", qcc_token))
1914                                         {file = QCC_COM_Parse(file); numents = atoi(qcc_token);}
1915                                 else if (qcc_token[0] == '}')   //end of block
1916                                         break;
1917                                 else
1918                                         Sys_Error("Bad key \"%s\" in general block", qcc_token);
1919                         }
1920
1921                         PRAddressableFlush(progfuncs, -1);
1922                         resethunk=true;
1923
1924                         pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * maxprogs);
1925                         pr_typecurrent=0;
1926
1927                         sv_num_edicts = 1;      //set up a safty buffer so things won't go horribly wrong too often
1928                         sv_edicts=(struct edict_s *)&tempedict;
1929                         prinst->edicttable = &sv_edicts;
1930
1931
1932                         sv_num_edicts = numents;        //should be fine
1933
1934 //                      PR_Configure(crc, NULL, memsize, maxedicts, maxprogs);
1935                 }
1936                 else if (!strcmp(qcc_token, "{"))
1937                 {
1938                         if (isloadgame)
1939                         {
1940                                 if (numents == -1)      //globals
1941                                 {
1942                                         while (1)
1943                                         {
1944                                                 file = QCC_COM_Parse(file);
1945                                                 if (qcc_token[0] == '}')
1946                                                         break;
1947                                                 else if (!qcc_token[0] || !file)
1948                                                         Sys_Error("EOF when parsing global values");
1949
1950                                                 switch(current_progstate->intsize)
1951                                                 {
1952                                                 case 16:
1953                                                 case 24:
1954                                                         if (!(d16 = ED_FindGlobal16(progfuncs, qcc_token)))
1955                                                         {
1956                                                                 file = QCC_COM_Parse(file);
1957                                                                 printf("global value %s not found", qcc_token);
1958                                                         }
1959                                                         else
1960                                                         {
1961                                                                 file = QCC_COM_Parse(file);
1962                                                                 ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d16, qcc_token, 16);
1963                                                         }
1964                                                         break;
1965                                                 case 32:
1966                                                         if (!(d32 = ED_FindGlobal32(progfuncs, qcc_token)))
1967                                                         {
1968                                                                 file = QCC_COM_Parse(file);
1969                                                                 printf("global value %s not found", qcc_token);
1970                                                         }
1971                                                         else
1972                                                         {
1973                                                                 file = QCC_COM_Parse(file);
1974                                                                 ED_ParseEpair(progfuncs, pr_globals, (ddefXX_t*)d32, qcc_token, 32);
1975                                                         }
1976                                                         break;
1977                                                 default:
1978                                                         Sys_Error("Bad intsize in LoadEnts");
1979                                                 }
1980                                         }
1981                                 }
1982                                 else
1983                                 {
1984                                         ed = (edictrun_t *)EDICT_NUM(progfuncs, numents);
1985                                         if (!ed)
1986                                                 ed = ED_AllocIntoTable(progfuncs, numents);
1987
1988                                         if (externs->entspawn)
1989                                                 externs->entspawn((struct edict_s *) ed, true);
1990
1991                                         sv_num_edicts = numents;
1992                                         ed->isfree = false;
1993                                         file = ED_ParseEdict (progfuncs, file, ed);
1994                                 }
1995                                 numents++;
1996                                 continue;
1997                         }
1998
1999                         if (entsize == 0 && resethunk)  //edicts have not yet been initialized, and this is a compleate load (memsize has been set)
2000                         {
2001                                 entsize = PR_InitEnts(progfuncs, maxedicts);
2002 //                              sv_num_edicts = numents;
2003
2004                                 for (num = 0; num < numents; num++)
2005                                 {
2006                                         ed = (edictrun_t *)EDICT_NUM(progfuncs, num);
2007
2008                                         if (!ed)
2009                                         {
2010                                                 ed = ED_AllocIntoTable(progfuncs, num);
2011                                                 ed->isfree = true;
2012                                         }
2013                                 }
2014                         }
2015
2016                         if (!ed)        //first entity
2017                                 ed = (edictrun_t *)EDICT_NUM(progfuncs, 0);
2018                         else
2019                                 ed = (edictrun_t *)ED_Alloc(progfuncs);
2020                         ed->isfree = false;
2021                         if (externs->entspawn)
2022                                 externs->entspawn((struct edict_s *) ed, true);
2023                         file = ED_ParseEdict(progfuncs, file, ed);
2024
2025                         if (killonspawnflags)
2026                         {
2027                                 var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "spawnflags", &spawnflagscache);
2028                                 if (var)
2029                                 {
2030                                         if ((int)var->_float & (int)killonspawnflags)
2031                                         {
2032                                                 ed->isfree = true;
2033                                                 ed->freetime = 0;
2034                                                 continue;
2035                                         }
2036                                 }
2037                         }
2038
2039                         if (!resethunk)
2040                         {
2041                                 char *eclassname;
2042                                 func_t f;
2043                                 if (!CheckSpawn)
2044                                         CheckSpawn = PR_FindFunc(progfuncs, "CheckSpawn", -2);
2045
2046                                 var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "classname", NULL);
2047                                 if (!var || !var->string || !*PR_StringToNative(progfuncs, var->string))
2048                                 {
2049                                         printf("No classname\n");
2050                                         ED_Free(progfuncs, (struct edict_s *)ed);
2051                                 }
2052                                 else
2053                                 {
2054                                         eval_t *selfvar;
2055
2056                                         //added by request of Mercury.
2057                                         if (fulldata)   //this is a vital part of HL map support!!!
2058                                         {       //essentually, it passes the ent's spawn info to the ent.
2059                                                 char *nl;       //otherwise it sees only the named fields of
2060                                                 char *spawndata;//a standard quake ent.
2061                                                 spawndata = PRHunkAlloc(progfuncs, file - datastart +1);
2062                                                 strncpy(spawndata, datastart, file - datastart);
2063                                                 spawndata[file - datastart] = '\0';
2064                                                 for (nl = spawndata; *nl; nl++)
2065                                                         if (*nl == '\n')
2066                                                                 *nl = '\t';
2067                                                 fulldata->string = PR_StringToProgs(progfuncs, spawndata);
2068                                         }
2069
2070                                         selfvar = (eval_t *)((int *)pr_globals + ED_FindGlobalOfs(progfuncs, "self"));
2071                                         selfvar->edict = EDICT_TO_PROG(progfuncs, ed);
2072
2073                                         //DP_SV_SPAWNFUNC_PREFIX support
2074                                         eclassname = PR_StringToNative(progfuncs, var->string);
2075 #ifdef _WIN32
2076                                         _snprintf(filename, sizeof(filename), "spawnfunc_%s", eclassname);
2077                                         filename[sizeof(filename)-1] = 0;
2078 #else
2079                                         snprintf(filename, sizeof(filename), "spawnfunc_%s", eclassname);
2080 #endif
2081                                         f = PR_FindFunc(progfuncs, filename, PR_ANYBACK);
2082                                         if (!f)
2083                                                 f = PR_FindFunc(progfuncs, eclassname, PR_ANYBACK);
2084                                         if (f)
2085                                         {
2086                                                 if (CheckSpawn)
2087                                                 {
2088                                                         G_INT(OFS_PARM0) = f;
2089                                                         PR_ExecuteProgram(progfuncs, CheckSpawn);
2090                                                         //call the spawn func or remove.
2091                                                 }
2092                                                 else
2093                                                         PR_ExecuteProgram(progfuncs, f);
2094                                         }
2095                                         else if (CheckSpawn)
2096                                         {
2097                                                 G_INT(OFS_PARM0) = 0;
2098                                                 PR_ExecuteProgram(progfuncs, CheckSpawn);
2099                                                 //the mod is responsible for freeing unrecognised ents.
2100                                         }
2101                                         else
2102                                         {
2103                                                 printf("Couldn't find spawn function %s\n", PR_StringToNative(progfuncs, var->string));
2104                                                 ED_Free(progfuncs, (struct edict_s *)ed);
2105                                         }
2106                                 }
2107                         }
2108                 }
2109                 else
2110                         Sys_Error("Command %s not recognised", qcc_token);
2111         }
2112         if (resethunk)
2113         {
2114                 header_crc = crc;
2115                 if (externs->loadcompleate)
2116                         externs->loadcompleate(entsize);
2117
2118                 sv_num_edicts = numents;
2119         }
2120
2121         if (resethunk)
2122         {
2123                 return entsize;
2124         }
2125         else
2126                 return max_fields_size;
2127 }
2128
2129 #define AddS(str) strcpy(s, str);s+=strlen(str);
2130
2131 char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed)
2132 {
2133         fdef_t  *d;
2134         int             *v;
2135         unsigned int            i;unsigned int j;
2136         char    *name;
2137         int             type;
2138
2139         char *s = buf;
2140
2141 //      if (ed->free)
2142 //              continue;
2143
2144         AddS ("{\n");
2145
2146
2147         for (i=0 ; i<numfields ; i++)
2148         {
2149                 int len;
2150
2151                 d = &field[i];
2152                 name = d->name;
2153                 len = strlen(name); // should we skip vars with no name?
2154                 if (len > 2 && name[len-2] == '_')
2155                         continue;       // skip _x, _y, _z vars
2156
2157                 v = (int*)((edictrun_t*)ed)->fields + d->ofs;
2158
2159         // if the value is still all 0, skip the field
2160                 type = d->type & ~DEF_SAVEGLOBAL;
2161                 for (j=0 ; j<type_size[type] ; j++)
2162                         if (v[j])
2163                                 break;
2164                 if (j == type_size[type])
2165                         continue;
2166
2167                 //add it to the file
2168                 AddS (qcva("\"%s\" ",name));
2169                 AddS (qcva("\"%s\"\n", PR_UglyValueString(progfuncs, d->type, (eval_t *)v)));
2170         }
2171
2172         AddS ("}\n");
2173
2174         *size = s - buf;
2175
2176         return buf;
2177 }
2178 struct edict_s *RestoreEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed)
2179 {
2180         edictrun_t *ent;
2181         char *start = buf;
2182
2183         buf = QCC_COM_Parse(buf);       //read the key
2184         if (!buf || !*qcc_token)
2185                 return NULL;
2186
2187         if (strcmp(qcc_token, "{"))
2188                 Sys_Error("Restore Ent with no opening brace");
2189
2190         if (!ed)
2191                 ent = (edictrun_t *)ED_Alloc(progfuncs);
2192         else
2193                 ent = (edictrun_t *)ed;
2194         ent->isfree = false;
2195
2196         if (externs->entspawn)
2197                 externs->entspawn((struct edict_s *) ent, false);
2198
2199         buf = ED_ParseEdict(progfuncs, buf, ent);
2200
2201         *size = buf - start;
2202
2203         return (struct edict_s *)ent;
2204 }
2205
2206 #define Host_Error Sys_Error
2207
2208 //return true if pr_progs needs recompiling (source files have changed)
2209 pbool PR_TestRecompile(progfuncs_t *progfuncs)
2210 {
2211         int newsize;
2212         int num, found=0, lost=0, changed=0;
2213         includeddatafile_t *s;
2214         if (!pr_progs->ofsfiles)
2215                 return false;
2216
2217         num = *(int*)((char *)pr_progs + pr_progs->ofsfiles);
2218         s = (includeddatafile_t *)((char *)pr_progs + pr_progs->ofsfiles+4);
2219         while(num>0)
2220         {
2221                 newsize = externs->FileSize(s->filename);
2222                 if (newsize == -1)      //ignore now missing files. - the referencer must have changed...
2223                         lost++;
2224                 else if (s->size != newsize)    //file
2225                         changed++;
2226                 else
2227                         found++;
2228
2229                 s++;
2230                 num--;
2231         }
2232         if (lost > found+changed)
2233                 return false;
2234         if (changed)
2235                 return true;
2236         return false;
2237 }
2238 /*
2239 #ifdef _DEBUG
2240 //this is for debugging.
2241 //I'm using this to detect incorrect string types while converting 32bit string pointers with bias to bound indexes.
2242 void PR_TestForWierdness(progfuncs_t *progfuncs)
2243 {
2244         unsigned int i;
2245         int e;
2246         edictrun_t *ed;
2247         for (i = 0; i < pr_progs->numglobaldefs; i++)
2248         {
2249                 if ((pr_globaldefs16[i].type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_string)
2250                 {
2251                         if (G_INT(pr_globaldefs16[i].ofs) < 0 || G_INT(pr_globaldefs16[i].ofs) >= addressableused)
2252                                 printf("String type irregularity on \"%s\" \"%s\"\n", pr_globaldefs16[i].s_name+progfuncs->stringtable, G_INT(pr_globaldefs16[i].ofs)+progfuncs->stringtable);
2253                 }
2254         }
2255
2256         for (i = 0; i < numfields; i++)
2257         {
2258                 if ((field[i].type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_string)
2259                 {
2260                         for (e = 0; e < sv_num_edicts; e++)
2261                         {
2262                                 ed = (edictrun_t*)EDICT_NUM(progfuncs, e);
2263                                 if (ed->isfree)
2264                                         continue;
2265                                 if (((int *)ed->fields)[field[i].ofs] < 0 || ((int *)ed->fields)[field[i].ofs] >= addressableused)
2266                                         printf("String type irregularity \"%s\" \"%s\"\n", field[i].name, ((int *)ed->fields)[field[i].ofs]+progfuncs->stringtable);
2267                         }
2268                 }
2269         }
2270 }
2271 #endif
2272 */
2273 char *decode(int complen, int len, int method, char *info, char *buffer);
2274 /*
2275 ===============
2276 PR_LoadProgs
2277 ===============
2278 */
2279 int PR_ReallyLoadProgs (progfuncs_t *progfuncs, char *filename, int headercrc, progstate_t *progstate, pbool complain)
2280 {
2281         unsigned int            i, type;
2282 //      extensionbuiltin_t *eb;
2283 //      float   fl;
2284         int len;
2285 //      int num;
2286 //      dfunction_t *f, *f2;
2287         ddef16_t *d16;
2288         ddef32_t *d32;
2289         int *d2;
2290         eval_t *eval;
2291         char *s;
2292         int progstype;
2293         int trysleft = 2;
2294 //      bool qfhack = false;
2295         pbool isfriked = false; //all imediate values were stripped, which causes problems with strings.
2296         pbool hexencalling = false;     //hexen style calling convention. The opcodes themselves are used as part of passing the arguments;
2297         ddef16_t *gd16, *fld16;
2298         float *glob;
2299         dfunction_t *fnc;
2300         dstatement16_t *st16;
2301
2302         int hmark=0xffffffff;
2303
2304         int reorg = prinst->reorganisefields || numfields;
2305
2306         int stringadjust;
2307
2308         current_progstate = progstate;
2309
2310         strcpy(current_progstate->filename, filename);
2311
2312
2313 // flush the non-C variable lookup cache
2314 //      for (i=0 ; i<GEFV_CACHESIZE ; i++)
2315 //              gefvCache[i].field[0] = 0;
2316
2317         memset(&spawnflagscache, 0, sizeof(evalc_t));
2318
2319         if (externs->autocompile == PR_COMPILEALWAYS)   //always compile before loading
2320         {
2321                 printf("Forcing compile of progs %s\n", filename);
2322                 if (!CompileFile(progfuncs, filename))
2323                         return false;
2324         }
2325
2326 //      CRC_Init (&pr_crc);
2327
2328 retry:
2329         if ((len=externs->FileSize(filename))<=0)
2330         {
2331                 if (externs->autocompile == PR_COMPILENEXIST || externs->autocompile == PR_COMPILECHANGED)      //compile if file is not found (if 2, we have already tried, so don't bother)
2332                 {
2333                         if (hmark==0xffffffff)  //first try
2334                         {
2335                                 printf("couldn't open progs %s. Attempting to compile.\n", filename);
2336                                 CompileFile(progfuncs, filename);
2337                         }
2338                         if ((len=externs->FileSize(filename))<0)
2339                         {
2340                                 printf("Couldn't find or compile file %s\n", filename);
2341                                 return false;
2342                         }
2343                 }
2344                 else if (externs->autocompile == PR_COMPILEIGNORE)
2345                         return false;
2346                 else
2347                 {
2348                         printf("Couldn't find file %s\n", filename);
2349                         return false;
2350                 }
2351         }
2352
2353         hmark = PRHunkMark(progfuncs);
2354         pr_progs = PRHunkAlloc(progfuncs, len+1);
2355         if (!externs->ReadFile(filename, pr_progs, len+1))
2356         {
2357                 if (!complain)
2358                         return false;
2359                 printf("Failed to open %s", filename);
2360                 return false;
2361         }
2362
2363 //      for (i=0 ; i<len ; i++)
2364 //              CRC_ProcessByte (&pr_crc, ((byte *)pr_progs)[i]);
2365
2366 // byte swap the header
2367 #ifndef NOENDIAN
2368         for (i=0 ; i<standard_dprograms_t_size/sizeof(int); i++)
2369                 ((int *)pr_progs)[i] = PRLittleLong ( ((int *)pr_progs)[i] );
2370 #endif
2371
2372         if (pr_progs->version == PROG_VERSION)
2373         {
2374 //              printf("Opening standard progs file \"%s\"\n", filename);
2375                 current_progstate->intsize = 16;
2376         }
2377         else if (pr_progs->version == PROG_EXTENDEDVERSION)
2378         {
2379 #ifndef NOENDIAN
2380                 for (i = standard_dprograms_t_size/sizeof(int); i < sizeof(dprograms_t)/sizeof(int); i++)
2381                         ((int *)pr_progs)[i] = PRLittleLong ( ((int *)pr_progs)[i] );
2382 #endif
2383                 if (pr_progs->secondaryversion == PROG_SECONDARYVERSION16)
2384                 {
2385 //                      printf("Opening 16bit fte progs file \"%s\"\n", filename);
2386                         current_progstate->intsize = 16;
2387                 }
2388                 else if (pr_progs->secondaryversion == PROG_SECONDARYVERSION32)
2389                 {
2390 //                      printf("Opening 32bit fte progs file \"%s\"\n", filename);
2391                         current_progstate->intsize = 32;
2392                 }
2393                 else
2394                 {
2395 //                      printf("Opening KK7 progs file \"%s\"\n", filename);
2396                         current_progstate->intsize = 24;        //KK progs. Yuck. Disabling saving would be a VERY good idea.
2397                         pr_progs->version = PROG_VERSION;       //not fte.
2398                 }
2399 /*              else
2400                 {
2401                         printf ("Progs extensions are not compatible\nTry recompiling with the FTE compiler\n");
2402                         HunkFree(hmark);
2403                         pr_progs=NULL;
2404                         return false;
2405                 }
2406 */      }
2407         else
2408         {
2409                 printf ("%s has wrong version number (%i should be %i)\n", filename, pr_progs->version, PROG_VERSION);
2410                 PRHunkFree(progfuncs, hmark);
2411                 pr_progs=NULL;
2412                 return false;
2413         }
2414
2415 //progs contains enough info for use to recompile it.
2416         if (trysleft && (externs->autocompile == PR_COMPILECHANGED  || externs->autocompile == PR_COMPILEEXISTANDCHANGED) && pr_progs->version == PROG_EXTENDEDVERSION)
2417         {
2418                 if (PR_TestRecompile(progfuncs))
2419                 {
2420                         printf("Source file has changed\nRecompiling.\n");
2421                         if (CompileFile(progfuncs, filename))
2422                         {
2423                                 PRHunkFree(progfuncs, hmark);
2424                                 pr_progs=NULL;
2425
2426                                 trysleft--;
2427                                 goto retry;
2428                         }
2429                 }
2430         }
2431         if (!trysleft)  //the progs exists, let's just be happy about it.
2432                 printf("Progs is out of date and uncompilable\n");
2433
2434         if (headercrc != -1 && headercrc != 0)
2435         if (pr_progs->crc != headercrc && pr_progs->crc != 0)   //This shouldn't affect us. However, it does adjust expectations and usage of builtins.
2436         {
2437 //              printf ("%s system vars have been modified, progdefs.h is out of date\n", filename);
2438                 PRHunkFree(progfuncs, hmark);
2439                 pr_progs=NULL;
2440                 return false;
2441         }
2442
2443         if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->blockscompressed && !QC_decodeMethodSupported(2))
2444         {
2445                 printf ("%s uses compression\n", filename);
2446                 PRHunkFree(progfuncs, hmark);
2447                 pr_progs=NULL;
2448                 return false;
2449         }
2450
2451         fnc = pr_functions = (dfunction_t *)((qbyte *)pr_progs + pr_progs->ofs_functions);
2452         pr_strings = ((char *)pr_progs + pr_progs->ofs_strings);
2453         current_progstate->globaldefs = *(void**)&gd16 = (void *)((qbyte *)pr_progs + pr_progs->ofs_globaldefs);
2454         current_progstate->fielddefs = *(void**)&fld16 = (void *)((qbyte *)pr_progs + pr_progs->ofs_fielddefs);
2455         current_progstate->statements = (void *)((qbyte *)pr_progs + pr_progs->ofs_statements);
2456
2457         glob = pr_globals = (void *)((qbyte *)pr_progs + pr_progs->ofs_globals);
2458
2459         pr_linenums=NULL;
2460         pr_types=NULL;
2461         if (pr_progs->version == PROG_EXTENDEDVERSION)
2462         {
2463                 if (pr_progs->ofslinenums)
2464                         pr_linenums = (int *)((qbyte *)pr_progs + pr_progs->ofslinenums);
2465                 if (pr_progs->ofs_types)
2466                         pr_types = (typeinfo_t *)((qbyte *)pr_progs + pr_progs->ofs_types);
2467
2468                 //start decompressing stuff...
2469                 if (pr_progs->blockscompressed & 1)     //statements
2470                 {
2471                         switch(current_progstate->intsize)
2472                         {
2473                         case 16:
2474                                 len=sizeof(dstatement16_t)*pr_progs->numstatements;
2475                                 break;
2476                         case 32:
2477                                 len=sizeof(dstatement32_t)*pr_progs->numstatements;
2478                                 break;
2479                         default:
2480                                 Sys_Error("Bad intsize");
2481                         }
2482                         s = PRHunkAlloc(progfuncs, len);
2483                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_statements16), len, 2, (char *)(((int *)pr_statements16)+1), s);
2484
2485                         current_progstate->statements = (dstatement16_t *)s;
2486                 }
2487                 if (pr_progs->blockscompressed & 2)     //global defs
2488                 {
2489                         switch(current_progstate->intsize)
2490                         {
2491                         case 16:
2492                                 len=sizeof(ddef16_t)*pr_progs->numglobaldefs;
2493                                 break;
2494                         case 32:
2495                                 len=sizeof(ddef32_t)*pr_progs->numglobaldefs;
2496                                 break;
2497                         default:
2498                                 Sys_Error("Bad intsize");
2499                         }
2500                         s = PRHunkAlloc(progfuncs, len);
2501                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_globaldefs16), len, 2, (char *)(((int *)pr_globaldefs16)+1), s);
2502
2503                         gd16 = *(ddef16_t**)&current_progstate->globaldefs = (ddef16_t *)s;
2504                 }
2505                 if (pr_progs->blockscompressed & 4)     //fields
2506                 {
2507                         switch(current_progstate->intsize)
2508                         {
2509                         case 16:
2510                                 len=sizeof(ddef16_t)*pr_progs->numglobaldefs;
2511                                 break;
2512                         case 32:
2513                                 len=sizeof(ddef32_t)*pr_progs->numglobaldefs;
2514                                 break;
2515                         default:
2516                                 Sys_Error("Bad intsize");
2517                         }
2518                         s = PRHunkAlloc(progfuncs, len);
2519                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_fielddefs16), len, 2, (char *)(((int *)pr_fielddefs16)+1), s);
2520
2521                         *(ddef16_t**)&current_progstate->fielddefs = (ddef16_t *)s;
2522                 }
2523                 if (pr_progs->blockscompressed & 8)     //functions
2524                 {
2525                         len=sizeof(dfunction_t)*pr_progs->numfunctions;
2526                         s = PRHunkAlloc(progfuncs, len);
2527                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_functions), len, 2, (char *)(((int *)pr_functions)+1), s);
2528
2529                         fnc = pr_functions = (dfunction_t *)s;
2530                 }
2531                 if (pr_progs->blockscompressed & 16)    //string table
2532                 {
2533                         len=sizeof(char)*pr_progs->numstrings;
2534                         s = PRHunkAlloc(progfuncs, len);
2535                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_strings), len, 2, (char *)(((int *)pr_strings)+1), s);
2536
2537                         pr_strings = (char *)s;
2538                 }
2539                 if (pr_progs->blockscompressed & 32)    //globals
2540                 {
2541                         len=sizeof(float)*pr_progs->numglobals;
2542                         s = PRHunkAlloc(progfuncs, len);
2543                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_globals), len, 2, (char *)(((int *)pr_globals)+1), s);
2544
2545                         glob = pr_globals = (float *)s;
2546                 }
2547                 if (pr_linenums && pr_progs->blockscompressed & 64)     //line numbers
2548                 {
2549                         len=sizeof(int)*pr_progs->numstatements;
2550                         s = PRHunkAlloc(progfuncs, len);
2551                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_linenums), len, 2, (char *)(((int *)pr_linenums)+1), s);
2552
2553                         pr_linenums = (int *)s;
2554                 }
2555                 if (pr_types && pr_progs->blockscompressed & 128)       //types
2556                 {
2557                         len=sizeof(typeinfo_t)*pr_progs->numtypes;
2558                         s = PRHunkAlloc(progfuncs, len);
2559                         QC_decode(progfuncs, PRLittleLong(*(int *)pr_types), len, 2, (char *)(((int *)pr_types)+1), s);
2560
2561                         pr_types = (typeinfo_t *)s;
2562                 }
2563         }
2564
2565         len=sizeof(char)*pr_progs->numstrings;
2566         s = PRAddressableAlloc(progfuncs, len);
2567         memcpy(s, pr_strings, len);
2568         pr_strings = (char *)s;
2569
2570         len=sizeof(float)*pr_progs->numglobals;
2571         s = PRAddressableAlloc(progfuncs, len);
2572         memcpy(s, pr_globals, len);
2573         glob = pr_globals = (float *)s;
2574
2575         if (progfuncs->stringtable)
2576                 stringadjust = pr_strings - progfuncs->stringtable;
2577         else
2578                 stringadjust = 0;
2579
2580         if (!pr_linenums)
2581         {
2582                 unsigned int lnotype = *(unsigned int*)"LNOF";
2583                 unsigned int version = 1;
2584                 int ohm;
2585                 unsigned int *file;
2586                 char lnoname[128];
2587                 ohm = PRHunkMark(progfuncs);
2588
2589                 strcpy(lnoname, filename);
2590                 StripExtension(lnoname);
2591                 strcat(lnoname, ".lno");
2592                 if ((len=externs->FileSize(lnoname))>0)
2593                 {
2594                         file = PRHunkAlloc(progfuncs, len+1);
2595                         if (externs->ReadFile(lnoname, file, len+1))
2596                         {
2597                                 if (    file[0] != lnotype
2598                                         ||      file[1] != version
2599                                         ||      file[2] != pr_progs->numglobaldefs
2600                                         ||      file[3] != pr_progs->numglobals
2601                                         ||      file[4] != pr_progs->numfielddefs
2602                                         ||      file[5] != pr_progs->numstatements
2603                                         )
2604                                 {
2605                                         PRHunkFree(progfuncs, ohm);     //whoops: old progs or incompatible
2606                                 }
2607                                 else
2608                                         pr_linenums = file + 6;
2609                         }
2610                 }
2611         }
2612
2613         pr_functions = fnc;
2614 //      pr_strings = ((char *)pr_progs + pr_progs->ofs_strings);
2615         gd16 = *(ddef16_t**)&current_progstate->globaldefs = (ddef16_t *)((qbyte *)pr_progs + pr_progs->ofs_globaldefs);
2616         fld16 = (ddef16_t *)((qbyte *)pr_progs + pr_progs->ofs_fielddefs);
2617 //      pr_statements16 = (dstatement16_t *)((qbyte *)pr_progs + pr_progs->ofs_statements);
2618         pr_globals = glob;
2619         st16 = pr_statements16;
2620 #undef pr_globals
2621 #undef pr_globaldefs16
2622 #undef pr_functions
2623 #undef pr_statements16
2624 #undef pr_fielddefs16
2625
2626
2627         current_progstate->edict_size = pr_progs->entityfields * 4 + externs->edictsize;
2628
2629 // byte swap the lumps
2630         for (i=0 ; i<pr_progs->numfunctions; i++)
2631         {
2632 #ifndef NOENDIAN
2633                 fnc[i].first_statement  = PRLittleLong (fnc[i].first_statement);
2634                 fnc[i].parm_start       = PRLittleLong (fnc[i].parm_start);
2635                 fnc[i].s_name   = (string_t)PRLittleLong ((long)fnc[i].s_name);
2636                 fnc[i].s_file   = (string_t)PRLittleLong ((long)fnc[i].s_file);
2637                 fnc[i].numparms = PRLittleLong (fnc[i].numparms);
2638                 fnc[i].locals   = PRLittleLong (fnc[i].locals);
2639 #endif
2640 /*              if (!strncmp(fnc[i].s_name+pr_strings, "ext_", 4))
2641                 {
2642                         for (eb = extensionbuiltin; eb; eb = eb->prev)
2643                         {
2644                                 if (*eb->name == '_')
2645                                 {
2646                                         if (!strncmp(fnc[i].s_name+pr_strings+4, eb->name+1, strlen(eb->name+1)))
2647                                         {
2648                                                 fnc[i].first_statement = -0x7fffffff;
2649                                                 *(void**)&fnc[i].profile = (void*)eb->func;
2650                                                 break;
2651                                         }
2652                                 }
2653                                 else if (!strcmp(fnc[i].s_name+4, eb->name))
2654                                 {
2655                                         fnc[i].first_statement = -0x7fffffff;
2656                                         *(void**)&fnc[i].profile = (void*)eb->func;
2657                                         break;
2658                                 }
2659                         }
2660                 }
2661 */
2662                 fnc[i].s_name += stringadjust;
2663                 fnc[i].s_file += stringadjust;
2664         }
2665
2666         //actual global values
2667 #ifndef NOENDIAN
2668         for (i=0 ; i<pr_progs->numglobals ; i++)
2669                 ((int *)glob)[i] = PRLittleLong (((int *)glob)[i]);
2670 #endif
2671
2672         if (pr_types)
2673         {
2674                 for (i=0 ; i<pr_progs->numtypes ; i++)
2675                 {
2676 #ifndef NOENDIAN
2677                         pr_types[i].type = PRLittleLong(current_progstate->types[i].type);
2678                         pr_types[i].next = PRLittleLong(current_progstate->types[i].next);
2679                         pr_types[i].aux_type = PRLittleLong(current_progstate->types[i].aux_type);
2680                         pr_types[i].num_parms = PRLittleLong(current_progstate->types[i].num_parms);
2681                         pr_types[i].ofs = PRLittleLong(current_progstate->types[i].ofs);
2682                         pr_types[i].size = PRLittleLong(current_progstate->types[i].size);
2683                         pr_types[i].name = (char *)PRLittleLong((long)current_progstate->types[i].name);
2684 #endif
2685                         pr_types[i].name += stringadjust;
2686                 }
2687         }
2688
2689         if (reorg)
2690                 reorg = (headercrc != -1);
2691
2692         QC_FlushProgsOffsets(progfuncs);
2693         switch(current_progstate->intsize)
2694         {
2695         case 24:
2696         case 16:
2697                 //byteswap the globals and fix name offsets
2698                 for (i=0 ; i<pr_progs->numglobaldefs ; i++)
2699                 {
2700 #ifndef NOENDIAN
2701                         gd16[i].type = PRLittleShort (gd16[i].type);
2702                         gd16[i].ofs = PRLittleShort (gd16[i].ofs);
2703                         gd16[i].s_name = (string_t)PRLittleLong ((long)gd16[i].s_name);
2704 #endif
2705                         gd16[i].s_name += stringadjust;
2706                 }
2707
2708                 //byteswap fields and fix name offets. Also register the fields (which will result in some offset adjustments in the globals segment).
2709                 for (i=0 ; i<pr_progs->numfielddefs ; i++)
2710                 {
2711 #ifndef NOENDIAN
2712                         fld16[i].type = PRLittleShort (fld16[i].type);
2713                         fld16[i].ofs = PRLittleShort (fld16[i].ofs);
2714                         fld16[i].s_name = (string_t)PRLittleLong ((long)fld16[i].s_name);
2715 #endif
2716                         if (reorg)
2717                         {
2718                                 if (pr_types)
2719                                         type = pr_types[fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
2720                                 else
2721                                         type = fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
2722
2723                                 if (progfuncs->fieldadjust && !pr_typecurrent)  //we need to make sure all fields appear in their original place.
2724                                         QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1);
2725                                 else if (type == ev_vector)     //emit vector vars early, so their fields cannot be alocated before the vector itself. (useful against scramblers)
2726                                 {
2727                                         QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, -1, fld16[i].ofs);
2728                                 }
2729                         }
2730                         else
2731                         {
2732                                 fdef_t *nf;
2733                                 if (numfields+1>maxfields)
2734                                 {
2735                                         i = maxfields;
2736                                         maxfields += 32;
2737                                         nf = memalloc(sizeof(fdef_t) * maxfields);
2738                                         memcpy(nf, field, sizeof(fdef_t) * i);
2739                                         memfree(field);
2740                                         field = nf;
2741                                 }
2742                                 nf = &field[numfields];
2743                                 nf->name = fld16[i].s_name+pr_strings;
2744                                 nf->type = fld16[i].type;
2745                                 nf->progsofs = fld16[i].ofs;
2746                                 nf->ofs = fld16[i].ofs;
2747
2748                                 if (fields_size < (nf->ofs+type_size[nf->type])*4)
2749                                         fields_size = (nf->ofs+type_size[nf->type])*4;
2750
2751                                 numfields++;
2752                         }
2753                         fld16[i].s_name += stringadjust;
2754                 }
2755                 if (reorg && !(progfuncs->fieldadjust && !pr_typecurrent))
2756                 for (i=0 ; i<pr_progs->numfielddefs ; i++)
2757                 {
2758                         if (pr_types)
2759                                 type = pr_types[fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
2760                         else
2761                                 type = fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
2762                         if (type != ev_vector)
2763                                 QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings-stringadjust, -1, fld16[i].ofs);
2764                 }
2765
2766                 break;
2767         case 32:
2768                 for (i=0 ; i<pr_progs->numglobaldefs ; i++)
2769                 {
2770 #ifndef NOENDIAN
2771                         pr_globaldefs32[i].type = PRLittleLong (pr_globaldefs32[i].type);
2772                         pr_globaldefs32[i].ofs = PRLittleLong (pr_globaldefs32[i].ofs);
2773                         pr_globaldefs32[i].s_name = (string_t)PRLittleLong ((long)pr_globaldefs32[i].s_name);
2774 #endif
2775                         pr_globaldefs32[i].s_name += stringadjust;
2776                 }
2777
2778                 for (i=0 ; i<pr_progs->numfielddefs ; i++)
2779                 {
2780         #ifndef NOENDIAN
2781                         pr_fielddefs32[i].type = PRLittleLong (pr_fielddefs32[i].type);
2782                         pr_fielddefs32[i].ofs = PRLittleLong (pr_fielddefs32[i].ofs);
2783                         pr_fielddefs32[i].s_name = (string_t)PRLittleLong ((long)pr_fielddefs32[i].s_name);
2784         #endif
2785
2786                         if (reorg)
2787                         {
2788                                 if (pr_types)
2789                                         type = pr_types[pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
2790                                 else
2791                                         type = pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
2792                                 if (progfuncs->fieldadjust && !pr_typecurrent)  //we need to make sure all fields appear in their original place.
2793                                         QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1);
2794                                 else if (type == ev_vector)
2795                                         QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings, -1, pr_fielddefs32[i].ofs);
2796                         }
2797                         pr_fielddefs32[i].s_name += stringadjust;
2798                 }
2799                 if (reorg && !(progfuncs->fieldadjust && !pr_typecurrent))
2800                 for (i=0 ; i<pr_progs->numfielddefs ; i++)
2801                 {
2802                         if (pr_types)
2803                                 type = pr_types[pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
2804                         else
2805                                 type = pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
2806                         if (type != ev_vector)
2807                                 QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings-stringadjust, -1, pr_fielddefs32[i].ofs);
2808                 }
2809                 break;
2810         default:
2811                 Sys_Error("Bad int size");
2812         }
2813
2814 //ifstring fixes arn't performed anymore.
2815 //the following switch just fixes endian and hexen2 calling conventions (by using different opcodes).
2816         switch(current_progstate->intsize)
2817         {
2818         case 16:
2819                 for (i=0 ; i<pr_progs->numstatements ; i++)
2820                 {
2821 #ifndef NOENDIAN
2822                         st16[i].op = PRLittleShort(st16[i].op);
2823                         st16[i].a = PRLittleShort(st16[i].a);
2824                         st16[i].b = PRLittleShort(st16[i].b);
2825                         st16[i].c = PRLittleShort(st16[i].c);
2826 #endif
2827                         if (st16[i].op >= OP_CALL1 && st16[i].op <= OP_CALL8)
2828                         {
2829                                 if (st16[i].b)
2830                                         hexencalling = true;
2831
2832                         }
2833                 }
2834                 if (hexencalling)
2835                 {
2836                         for (i=0 ; i<pr_progs->numstatements ; i++)
2837                         {
2838                                 if (st16[i].op >= OP_CALL1 && st16[i].op <= OP_CALL8)
2839                                         st16[i].op += OP_CALL1H - OP_CALL1;
2840                         }
2841                 }
2842                 break;
2843
2844         case 24:        //24 sucks. Guess why.
2845                 for (i=0 ; i<pr_progs->numstatements ; i++)
2846                 {
2847 #ifndef NOENDIAN
2848                         pr_statements32[i].op = PRLittleLong(pr_statements32[i].op);
2849                         pr_statements32[i].a = PRLittleLong(pr_statements32[i].a);
2850                         pr_statements32[i].b = PRLittleLong(pr_statements32[i].b);
2851                         pr_statements32[i].c = PRLittleLong(pr_statements32[i].c);
2852 #endif
2853                         if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
2854                         {
2855                                 if (pr_statements32[i].b)
2856                                         hexencalling = true;
2857
2858                         }
2859                 }
2860                 if (hexencalling)
2861                 {
2862                         for (i=0 ; i<pr_progs->numstatements ; i++)
2863                         {
2864                                 if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
2865                                         pr_statements32[i].op += OP_CALL1H - OP_CALL1;
2866                         }
2867                 }
2868                 break;
2869         case 32:
2870                 for (i=0 ; i<pr_progs->numstatements ; i++)
2871                 {
2872 #ifndef NOENDIAN
2873                         pr_statements32[i].op = PRLittleLong(pr_statements32[i].op);
2874                         pr_statements32[i].a = PRLittleLong(pr_statements32[i].a);
2875                         pr_statements32[i].b = PRLittleLong(pr_statements32[i].b);
2876                         pr_statements32[i].c = PRLittleLong(pr_statements32[i].c);
2877 #endif
2878                         if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
2879                         {
2880                                 if (pr_statements32[i].b)
2881                                         hexencalling = true;
2882
2883                         }
2884                 }
2885                 if (hexencalling)
2886                 {
2887                         for (i=0 ; i<pr_progs->numstatements ; i++)
2888                         {
2889                                 if (pr_statements32[i].op >= OP_CALL1 && pr_statements32[i].op <= OP_CALL8)
2890                                         pr_statements32[i].op += OP_CALL1H - OP_CALL1;
2891                         }
2892                 }
2893                 break;
2894         }
2895
2896
2897         if (headercrc == -1)
2898         {
2899                 isfriked = true;
2900                 if (current_progstate->intsize != 16)
2901                         Sys_Error("Decompiling a bigprogs");
2902                 return true;
2903         }
2904
2905         progstype = current_progstate-pr_progstate;
2906
2907 //      QC_StartShares(progfuncs);
2908
2909         isfriked = true;
2910         if (!pr_typecurrent)    //progs 0 always acts as string stripped.
2911                 isfriked = -1;          //partly to avoid some bad progs.
2912
2913 //      len = 0;
2914         switch(current_progstate->intsize)
2915         {
2916         case 24:
2917         case 16:
2918                 for (i=0 ; i<pr_progs->numglobaldefs ; i++)
2919                 {
2920                         if (pr_types)
2921                                 type = pr_types[gd16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
2922                         else
2923                                 type = gd16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
2924
2925                         if (gd16[i].type & DEF_SHARED)
2926                         {
2927                                 gd16[i].type &= ~DEF_SHARED;
2928                                 if (pr_types)
2929                                         QC_AddSharedVar(progfuncs, gd16[i].ofs, pr_types[gd16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].size);
2930                                 else
2931                                         QC_AddSharedVar(progfuncs, gd16[i].ofs, type_size[type]);
2932                         }
2933                         switch(type)
2934                         {
2935                         case ev_field:
2936                                 if (reorg)
2937                                         QC_AddSharedFieldVar(progfuncs, i, pr_strings - stringadjust);
2938                                 break;
2939                         case ev_string:
2940                                 if (((unsigned int *)glob)[gd16[i].ofs]>=progstate->progs->numstrings)
2941                                         printf("Insane value\n");
2942                                 else if (isfriked != -1)
2943                                 {
2944                                         if (pr_strings[((int *)glob)[gd16[i].ofs]])     //quakec uses string tables. 0 must remain null, or 'if (s)' can break.
2945                                         {
2946                                                 ((int *)glob)[gd16[i].ofs] += stringadjust;
2947                                                 isfriked = false;
2948                                         }
2949                                         else
2950                                                 ((int *)glob)[gd16[i].ofs] = 0;
2951                                 }
2952                                 break;
2953                         case ev_function:
2954                                 if (((int *)glob)[gd16[i].ofs]) //don't change null funcs
2955                                 {
2956 //                                      if (fnc[((int *)glob)[gd16[i].ofs]].first_statement>=0) //this is a hack. Make all builtins switch to the main progs first. Allows builtin funcs to cache vars from just the main progs.
2957                                                 ((int *)glob)[gd16[i].ofs] |= progstype << 24;
2958                                 }
2959                                 break;
2960                         }
2961                 }
2962                 break;
2963         case 32:
2964                 for (i=0 ; i<pr_progs->numglobaldefs ; i++)
2965                 {
2966                         if (pr_types)
2967                                 type = pr_types[pr_globaldefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type;
2968                         else
2969                                 type = pr_globaldefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL);
2970
2971                         if (pr_globaldefs32[i].type & DEF_SHARED)
2972                         {
2973                                 pr_globaldefs32[i].type &= ~DEF_SHARED;
2974                                 if (pr_types)
2975                                         QC_AddSharedVar(progfuncs, pr_globaldefs32[i].ofs, pr_types[pr_globaldefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].size);
2976                                 else
2977                                         QC_AddSharedVar(progfuncs, pr_globaldefs32[i].ofs, type_size[type]);
2978                         }
2979                         switch(type)
2980                         {
2981                         case ev_field:
2982                                 QC_AddSharedFieldVar(progfuncs, i, pr_strings - stringadjust);
2983                                 break;
2984                         case ev_string:
2985                                 if (pr_strings[((int *)glob)[pr_globaldefs32[i].ofs]])  //quakec uses string tables. 0 must remain null, or 'if (s)' can break.
2986                                 {
2987                                         ((int *)glob)[pr_globaldefs32[i].ofs] += stringadjust;
2988                                         isfriked = false;
2989                                 }
2990                                 break;
2991                         case ev_function:
2992                                 if (((int *)glob)[pr_globaldefs32[i].ofs])      //don't change null funcs
2993                                         ((int *)glob)[pr_globaldefs32[i].ofs] |= progstype << 24;
2994                                 break;
2995                         }
2996                 }
2997
2998                 if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->numbodylessfuncs)
2999                 {
3000                         s = &((char *)pr_progs)[pr_progs->ofsbodylessfuncs];
3001                         for (i = 0; i < pr_progs->numbodylessfuncs; i++)
3002                         {
3003                                 d32 = ED_FindGlobal32(progfuncs, s);
3004                                 d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
3005                                 if (!d2)
3006                                         Sys_Error("Runtime-linked function %s was not found in existing progs", s);
3007                                 if (!d32)
3008                                         Sys_Error("Couldn't find def for \"%s\"", s);
3009                                 ((int *)glob)[d32->ofs] = (*(func_t *)&pr_progstate[0].globals[*d2]);
3010
3011                                 s+=strlen(s)+1;
3012                         }
3013                 }
3014                 break;
3015         default:
3016                 Sys_Error("Bad int size");
3017         }
3018
3019         if ((isfriked && pr_typecurrent))       //friked progs only allow one file.
3020         {
3021                 printf("You are trying to load a string-stripped progs as an addon.\nThis behaviour is not supported. Try removing some optimizations.");
3022                 PRHunkFree(progfuncs, hmark);
3023                 pr_progs=NULL;
3024                 return false;
3025         }
3026
3027         pr_strings+=stringadjust;
3028         if (!progfuncs->stringtable)
3029                 progfuncs->stringtable = pr_strings;
3030
3031         if (progfuncs->stringtablesize + progfuncs->stringtable < pr_strings + pr_progs->numstrings)
3032                 progfuncs->stringtablesize = (pr_strings + pr_progs->numstrings) - progfuncs->stringtable;
3033
3034         eval = PR_FindGlobal(progfuncs, "thisprogs", progstype);
3035         if (eval)
3036                 eval->prog = progstype;
3037
3038         switch(current_progstate->intsize)
3039         {
3040         case 16:
3041                 if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->numbodylessfuncs)
3042                 {
3043                         s = &((char *)pr_progs)[pr_progs->ofsbodylessfuncs];
3044                         for (i = 0; i < pr_progs->numbodylessfuncs; i++)
3045                         {
3046                                 d16 = ED_FindGlobal16(progfuncs, s);
3047                                 if (!d16)
3048                                 {
3049                                         printf("Progs requires \"%s\" the external function \"%s\", but the definition was stripped", filename, s);
3050                                         PRHunkFree(progfuncs, hmark);
3051                                         pr_progs=NULL;
3052                                         return false;
3053                                 }
3054
3055                                 ((int *)glob)[d16->ofs] = PR_FindFunc(progfuncs, s, PR_ANY);
3056                                 if (!((int *)glob)[d16->ofs])
3057                                         printf("Warning: Runtime-linked function %s was not found in primary progs (loading %s)", s, filename);
3058                                 /*
3059                                 d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
3060                                 if (!d2)
3061                                         Sys_Error("Runtime-linked function %s was not found in primary progs (loading %s)", s, filename);
3062                                 ((int *)glob)[d16->ofs] = (*(func_t *)&pr_progstate[0].globals[*d2]);
3063                                 */
3064                                 s+=strlen(s)+1;
3065                         }
3066                 }
3067                 break;
3068         case 24:
3069                 break;  //cannot happen anyway.
3070         case 32:
3071                 if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->numbodylessfuncs)
3072                 {
3073                         s = &((char *)pr_progs)[pr_progs->ofsbodylessfuncs];
3074                         for (i = 0; i < pr_progs->numbodylessfuncs; i++)
3075                         {
3076                                 d32 = ED_FindGlobal32(progfuncs, s);
3077                                 d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
3078                                 if (!d2)
3079                                         printf("Warning: Runtime-linked function %s was not found in existing progs", s);
3080                                 if (!d32)
3081                                 {
3082                                         printf("Couldn't find def for \"%s\"", s);
3083                                         PRHunkFree(progfuncs, hmark);
3084                                         pr_progs=NULL;
3085                                         return false;
3086                                 }
3087                                 ((int *)glob)[d32->ofs] = (*(func_t *)&pr_progstate[0].globals[*d2]);
3088
3089                                 s+=strlen(s)+1;
3090                         }
3091                 }
3092                 break;
3093         }
3094
3095         eval = PR_FindGlobal(progfuncs, "__ext__fasttrackarrays", PR_CURRENT);
3096         if (eval)       //we support these opcodes
3097                 eval->_float = true;
3098
3099         return true;
3100 }
3101
3102
3103
3104 struct edict_s *EDICT_NUM(progfuncs_t *progfuncs, unsigned int n)
3105 {
3106         if (n >= maxedicts)
3107                 Sys_Error ("QCLIB: EDICT_NUM: bad number %i", n);
3108
3109         return prinst->edicttable[n];
3110 }
3111
3112 unsigned int NUM_FOR_EDICT(progfuncs_t *progfuncs, struct edict_s *e)
3113 {
3114         edictrun_t *er = (edictrun_t*)e;
3115         if (er->entnum >= maxedicts)
3116                 Sys_Error ("QCLIB: NUM_FOR_EDICT: bad pointer (%p)", e);
3117         return er->entnum;
3118 }