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