]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/source/fteqcc-src/pr_exec.c
Get VoreTournament code to compile with gmqcc. To be compiled with the same parameter...
[voretournament/voretournament.git] / misc / source / fteqcc-src / pr_exec.c
1 #define PROGSUSED
2 #include "progsint.h"
3 //#include "editor.h"
4
5 #define HunkAlloc BADGDFG sdfhhsf FHS
6
7
8 #define Host_Error Sys_Error
9
10 // I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles
11 #ifdef _WIN32
12         #if (_MSC_VER >= 1400)
13                 //with MSVC 8, use MS extensions
14                 #define snprintf linuxlike_snprintf_vc8
15                 int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
16                 #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d)
17         #else
18                 //msvc crap
19                 #define snprintf linuxlike_snprintf
20                 int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
21                 #define vsnprintf linuxlike_vsnprintf
22                 int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr);
23         #endif
24 #endif
25
26
27 //=============================================================================
28
29 /*
30 =================
31 PR_PrintStatement
32 =================
33 */
34 /*
35 void PR_PrintStatement (progfuncs_t *progfuncs, dstatement16_t *s)
36 {
37         int             i;
38 printf("PR_PrintStatement is unsupported\n");
39 return;
40         if ( (unsigned)s->op < OP_NUMOPS)
41         {
42                 printf ("%s ",  pr_opcodes[s->op].name);
43                 i = strlen(pr_opcodes[s->op].name);
44                 for ( ; i<10 ; i++)
45                         printf (" ");
46         }
47
48         if (s->op == OP_IF || s->op == OP_IFNOT)
49                 printf ("%sbranch %i",PR_GlobalString(progfuncs, s->a),s->b);
50         else if (s->op == OP_GOTO)
51         {
52                 printf ("branch %i",s->a);
53         }
54         else if ( (unsigned)(s->op - OP_STORE_F) < 6)
55         {
56                 printf ("%s",PR_GlobalString(progfuncs, s->a));
57                 printf ("%s", PR_GlobalStringNoContents(progfuncs, s->b));
58         }
59         else
60         {
61                 if (s->a)
62                         printf ("%s",PR_GlobalString(progfuncs, s->a));
63                 if (s->b)
64                         printf ("%s",PR_GlobalString(progfuncs, s->b));
65                 if (s->c)
66                         printf ("%s", PR_GlobalStringNoContents(progfuncs, s->c));
67         }
68         printf ("\n");
69 }
70 */
71
72 /*
73 ============
74 PR_StackTrace
75 ============
76 */
77 char *QC_ucase(char *str)
78 {
79         static char s[1024];
80         strcpy(s, str);
81         str = s;
82
83         while(*str)
84         {
85                 if (*str >= 'a' && *str <= 'z')
86                         *str = *str - 'a' + 'A';
87                 str++;
88         }
89         return s;
90 }
91
92 void PR_StackTrace (progfuncs_t *progfuncs)
93 {
94         dfunction_t     *f;
95         int                     i;
96         int progs;
97
98 #ifdef STACKTRACE
99         int arg;
100         int *globalbase;
101 #endif
102         progs = -1;
103
104         if (pr_depth == 0)
105         {
106                 printf ("<NO STACK>\n");
107                 return;
108         }
109
110 #ifdef STACKTRACE
111         globalbase = (int *)pr_globals + pr_xfunction->parm_start - pr_xfunction->locals;
112 #endif
113
114         pr_stack[pr_depth].f = pr_xfunction;
115         pr_stack[pr_depth].s = pr_xstatement;
116         for (i=pr_depth ; i>0 ; i--)
117         {
118                 f = pr_stack[i].f;
119
120                 if (!f)
121                 {
122                         printf ("<NO FUNCTION>\n");
123                 }
124                 else
125                 {
126                         if (pr_stack[i].progsnum != progs)
127                         {
128                                 progs = pr_stack[i].progsnum;
129
130                                 printf ("<%s>\n", pr_progstate[progs].filename);
131                         }
132                         if (!f->s_file)
133                                 printf ("stripped     : %s\n", f->s_name+progfuncs->stringtable);
134                         else
135                         {
136                                 if (pr_progstate[progs].linenums)
137                                         printf ("%12s %i : %s\n", f->s_file+progfuncs->stringtable, pr_progstate[progs].linenums[pr_stack[i].s], f->s_name+progfuncs->stringtable);
138                                 else
139                                         printf ("%12s : %s\n", f->s_file+progfuncs->stringtable, f->s_name+progfuncs->stringtable);
140                         }
141
142 #ifdef STACKTRACE
143
144                         for (arg = 0; arg < f->locals; arg++)
145                         {
146                                 ddef16_t *local;
147                                 local = ED_GlobalAtOfs16(progfuncs, f->parm_start+arg);
148                                 if (!local)
149                                 {
150                                         printf("    ofs %i: %f : %i\n", f->parm_start+arg, *(float *)(globalbase - f->locals+arg), *(int *)(globalbase - f->locals+arg) );
151                                 }
152                                 else
153                                 {
154                                         printf("    %s: %s\n", local->s_name+progfuncs->stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg)));
155                                         if (local->type == ev_vector)
156                                                 arg+=2;
157                                 }
158                         }
159
160                         if (i == pr_depth)
161                                 globalbase = localstack + localstack_used;
162                         else
163                                 globalbase -= f->locals;
164 #endif
165                 }
166         }
167 }
168
169 /*
170 ============
171 PR_Profile_f
172
173 ============
174 */
175 /*
176 void PR_Profile_f (void)
177 {
178         dfunction_t     *f, *best;
179         int                     max;
180         int                     num;
181         unsigned int                    i;
182
183         num = 0;
184         do
185         {
186                 max = 0;
187                 best = NULL;
188                 for (i=0 ; i<pr_progs->numfunctions ; i++)
189                 {
190                         f = &pr_functions[i];
191                         if (f->profile > max && f->first_statement >=0)
192                         {
193                                 max = f->profile;
194                                 best = f;
195                         }
196                 }
197                 if (best)
198                 {
199                         if (num < 10)
200                                 printf ("%7i %s\n", best->profile, best->s_name);
201                         num++;
202                         best->profile = 0;
203                 }
204         } while (best);
205 }
206 */
207
208
209 /*
210 ============
211 PR_RunError
212
213 Aborts the currently executing function
214 ============
215 */
216 void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...)
217 {
218         va_list         argptr;
219         char            string[1024];
220
221         va_start (argptr,error);
222         Q_vsnprintf (string,sizeof(string)-1, error,argptr);
223         va_end (argptr);
224
225 //      {
226 //              void SV_EndRedirect (void);
227 //              SV_EndRedirect();
228 //      }
229
230 //      PR_PrintStatement (pr_statements + pr_xstatement);
231         PR_StackTrace (progfuncs);
232         printf ("\n");
233
234 //editbadfile(pr_strings + pr_xfunction->s_file, -1);
235
236 //      pr_depth = 0;           // dump the stack so host_error can shutdown functions
237 //      prinst->exitdepth = 0;
238
239         Abort ("%s", string);
240 }
241
242 /*
243 ============================================================================
244 PR_ExecuteProgram
245
246 The interpretation main loop
247 ============================================================================
248 */
249
250 /*
251 ====================
252 PR_EnterFunction
253
254 Returns the new program statement counter
255 ====================
256 */
257 void    PR_AbortStack                   (progfuncs_t *progfuncs);
258 int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
259 {
260         int             i, j, c, o;
261
262         pr_stack[pr_depth].s = pr_xstatement;
263         pr_stack[pr_depth].f = pr_xfunction;
264         pr_stack[pr_depth].progsnum = progsnum;
265         pr_stack[pr_depth].pushed = pr_spushed;
266         pr_depth++;
267         if (pr_depth == MAX_STACK_DEPTH)
268         {
269                 pr_depth--;
270                 PR_StackTrace (progfuncs);
271
272                 printf ("stack overflow on call to %s\n", progfuncs->stringtable+f->s_name);
273
274                 //comment this out if you want the progs to try to continue anyway (could cause infinate loops)
275                 PR_AbortStack(progfuncs);
276                 Abort("Stack Overflow in %s\n", progfuncs->stringtable+f->s_name);
277                 return pr_xstatement;
278         }
279
280         localstack_used += pr_spushed;  //make sure the call doesn't hurt pushed pointers
281
282 // save off any locals that the new function steps on (to a side place, fromwhere they are restored on exit)
283         c = f->locals;
284         if (localstack_used + c > LOCALSTACK_SIZE)
285         {
286                 localstack_used -= pr_spushed;
287                 pr_depth--;
288                 PR_RunError (progfuncs, "PR_ExecuteProgram: locals stack overflow\n");
289         }
290
291         for (i=0 ; i < c ; i++)
292                 localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
293         localstack_used += c;
294
295 // copy parameters (set initial values)
296         o = f->parm_start;
297         for (i=0 ; i<f->numparms ; i++)
298         {
299                 for (j=0 ; j<f->parm_size[i] ; j++)
300                 {
301                         ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];
302                         o++;
303                 }
304         }
305
306         pr_xfunction = f;
307         return f->first_statement - 1;  // offset the s++
308 }
309
310 /*
311 ====================
312 PR_LeaveFunction
313 ====================
314 */
315 int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs)
316 {
317         int             i, c;
318
319         if (pr_depth <= 0)
320                 Sys_Error ("prog stack underflow");
321
322 // restore locals from the stack
323         c = pr_xfunction->locals;
324         localstack_used -= c;
325         if (localstack_used < 0)
326                 PR_RunError (progfuncs, "PR_ExecuteProgram: locals stack underflow\n");
327
328         for (i=0 ; i < c ; i++)
329                 ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
330
331 // up stack
332         pr_depth--;
333         PR_MoveParms(progfuncs, pr_stack[pr_depth].progsnum, pr_typecurrent);
334         PR_SwitchProgs(progfuncs, pr_stack[pr_depth].progsnum);
335         pr_xfunction = pr_stack[pr_depth].f;
336         pr_spushed = pr_stack[pr_depth].pushed;
337
338         localstack_used -= pr_spushed;
339         return pr_stack[pr_depth].s;
340 }
341
342 ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val)
343 {
344         static ddef32_t def;
345         ddef32_t *def32;
346         ddef16_t *def16;
347         int i;
348
349         if (pr_typecurrent < 0)
350                 return NULL;
351
352         switch (pr_progstate[pr_typecurrent].structtype)
353         {
354         case PST_DEFAULT:
355         case PST_KKQWSV:
356                 //this gets parms fine, but not locals
357                 if (pr_xfunction)
358                 for (i = 0; i < pr_xfunction->numparms; i++)
359                 {
360                         def16 = ED_GlobalAtOfs16(progfuncs, pr_xfunction->parm_start+i);
361                         if (!def16)
362                                 continue;
363                         if (!strcmp(def16->s_name+progfuncs->stringtable, name))
364                         {
365                                 *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i];
366
367                                 //we need something like this for functions that are not the top layer
368         //                      *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4];
369                                 def.ofs = def16->ofs;
370                                 def.s_name = def16->s_name;
371                                 def.type = def16->type;
372                                 return &def;
373                         }
374                 }
375                 def16 = ED_FindGlobal16(progfuncs, name);
376                 if (!def16)
377                         return NULL;
378                 def.ofs = def16->ofs;
379                 def.type = def16->type;
380                 def.s_name = def16->s_name;
381                 def32 = &def;
382                 break;
383         case PST_QTEST:
384         case PST_FTE32:
385                 //this gets parms fine, but not locals
386                 if (pr_xfunction)
387                 for (i = 0; i < pr_xfunction->numparms; i++)
388                 {
389                         def32 = ED_GlobalAtOfs32(progfuncs, pr_xfunction->parm_start+i);
390                         if (!def32)
391                                 continue;
392                         if (!strcmp(def32->s_name+progfuncs->stringtable, name))
393                         {
394                                 *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i];
395
396                                 //we need something like this for functions that are not the top layer
397         //                      *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4];
398                                 return def32;
399                         }
400                 }
401                 def32 = ED_FindGlobal32(progfuncs, name);
402                 if (!def32)
403                         return NULL;
404                 break;
405         default:
406                 Sys_Error("Bad struct type in ED_FindLocalOrGlobal");
407                 def32 = NULL;
408         }
409
410         *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[def32->ofs];
411         return &def;
412 }
413
414 char *COM_TrimString(char *str)
415 {
416         int i;
417         static char buffer[256];
418         while (*str <= ' ' && *str>'\0')
419                 str++;
420
421         for (i = 0; i < 255; i++)
422         {
423                 if (*str <= ' ')
424                         break;
425                 buffer[i] = *str++;
426         }
427         buffer[i] = '\0';
428         return buffer;
429 }
430
431 char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
432 {
433         static char buf[256];
434         char *c, *c2;
435         ddef32_t *def;
436         fdef_t *fdef;
437         eval_t *val;
438         char *assignment;
439         int type;
440         ddef32_t fakedef;
441         eval_t fakeval;
442         edictrun_t *ed;
443
444         assignment = strchr(key, '=');
445         if (assignment)
446                 *assignment = '\0';
447
448         c = strchr(key, '.');
449         if (c) *c = '\0';
450         def = ED_FindLocalOrGlobal(progfuncs, key, &val);
451         if (!def)
452         {
453                 if (atoi(key))
454                 {
455                         def = &fakedef;
456                         def->ofs = 0;
457                         def->type = ev_entity;
458                         val = &fakeval;
459                         val->edict = atoi(key);
460                 }
461         }
462         if (c) *c = '.';
463         if (!def)
464         {
465                 return "(Bad string)";
466         }
467         type = def->type;
468
469         //go through ent vars
470         c = strchr(key, '.');
471         while(c)
472         {
473                 c2 = c+1;
474                 c = strchr(c2, '.');
475                 type = type &~DEF_SAVEGLOBAL;
476                 if (current_progstate && current_progstate->types)
477                         type = current_progstate->types[type].type;
478                 if (type != ev_entity)
479                         return "'.' without entity";
480                 if (c)*c = '\0';
481                 fdef = ED_FindField(progfuncs, COM_TrimString(c2));
482                 if (c)*c = '.';
483                 if (!fdef)
484                         return "(Bad string)";
485                 ed = PROG_TO_EDICT(progfuncs, val->_int);
486                 if (!ed)
487                         return "(Invalid Entity)";
488                 val = (eval_t *) (((char *)ed->fields) + fdef->ofs*4);
489                 type = fdef->type;
490         }
491
492         if (assignment)
493         {
494                 assignment++;
495                 while(*assignment == ' ')
496                         assignment++;
497                 switch (type&~DEF_SAVEGLOBAL)
498                 {
499                 case ev_string:
500                         *(string_t *)val = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, assignment, 0));
501                         break;
502
503                 case ev_float:
504                         if (assignment[0] == '0' && (assignment[1] == 'x' || assignment[1] == 'X'))
505                                 *(float*)val = strtoul(assignment, NULL, 0);
506                         else
507                                 *(float *)val = (float)atof (assignment);
508                         break;
509
510                 case ev_integer:
511                         *(int *)val = atoi (assignment);
512                         break;
513
514 /*              case ev_vector:
515                         strcpy (string, assignment);
516                         v = string;
517                         w = string;
518                         for (i=0 ; i<3 ; i++)
519                         {
520                                 while (*v && *v != ' ')
521                                         v++;
522                                 *v = 0;
523                                 ((float *)d)[i] = (float)atof (w);
524                                 w = v = v+1;
525                         }
526                         break;
527 */
528                 case ev_entity:
529                         *(int *)val = EDICT_TO_PROG(progfuncs, EDICT_NUM(progfuncs, atoi (assignment)));
530                         break;
531
532                 case ev_field:
533                         fdef = ED_FindField (progfuncs, assignment);
534                         if (!fdef)
535                         {
536                                 size_t l,nl = strlen(assignment);
537                                 strcpy(buf, "Can't find field ");
538                                 l = strlen(buf);
539                                 if (nl > sizeof(buf)-l-2)
540                                         nl = sizeof(buf)-l-2;
541                                 memcpy(buf+l, assignment, nl);
542                                 assignment[l+nl+0] = '\n';
543                                 assignment[l+nl+1] = 0;
544                                 return buf;
545                         }
546                         *(int *)val = G_INT(fdef->ofs);
547                         break;
548
549                 case ev_function:
550                         {
551                                 dfunction_t *func;
552                                 int i;
553                                 int progsnum = -1;
554                                 char *s = assignment;
555                                 if (s[0] && s[1] == ':')
556                                 {
557                                         progsnum = atoi(s);
558                                         s+=2;
559                                 }
560                                 else if (s[0] && s[1] && s[2] == ':')
561                                 {
562                                         progsnum = atoi(s);
563                                         s+=3;
564                                 }
565
566                                 func = ED_FindFunction (progfuncs, s, &i, progsnum);
567                                 if (!func)
568                                 {
569                                         size_t l,nl = strlen(s);
570
571                                         assignment[-1] = '=';
572
573                                         strcpy(buf, "Can't find field ");
574                                         l = strlen(buf);
575                                         if (nl > sizeof(buf)-l-2)
576                                                 nl = sizeof(buf)-l-2;
577                                         memcpy(buf+l, assignment, nl);
578                                         assignment[l+nl+0] = '\n';
579                                         assignment[l+nl+1] = 0;
580                                         return buf;
581                                 }
582                                 *(func_t *)val = (func - pr_progstate[i].functions) | (i<<24);
583                         }
584                         break;
585
586                 default:
587                         break;
588
589                 }
590                 assignment[-1] = '=';
591         }
592         strcpy(buf, PR_ValueString(progfuncs, type, val));
593
594         return buf;
595 }
596
597 int debugstatement;
598 //int EditorHighlightLine(window_t *wnd, int line);
599 void SetExecutionToLine(progfuncs_t *progfuncs, int linenum)
600 {
601         int pn = pr_typecurrent;
602         int snum;
603         dfunction_t *f = pr_xfunction;
604
605         switch(current_progstate->structtype)
606         {
607         case PST_DEFAULT:
608         case PST_QTEST:
609                 for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++)
610                 {
611                         if (pr_statements16[snum].op == OP_DONE)
612                                 return;
613                 }
614                 break;
615         case PST_KKQWSV:
616         case PST_FTE32:
617                 for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++)
618                 {
619                         if (pr_statements32[snum].op == OP_DONE)
620                                 return;
621                 }
622                 break;
623         default:
624                 Sys_Error("Bad struct type");
625                 snum = 0;
626         }
627         debugstatement = snum;
628 //      EditorHighlightLine(editwnd, pr_progstate[pn].linenums[snum]);
629 }
630
631 //0 clear. 1 set, 2 toggle, 3 check
632 int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int flag)  //write alternate route to work by function name.
633 {
634         int ret=0;
635         unsigned int fl;
636         unsigned int i;
637         int pn = pr_typecurrent;
638         dfunction_t *f;
639         int op = 0; //warning about not being initialized before use
640
641         for (pn = 0; (unsigned)pn < maxprogs; pn++)
642         {
643                 if (!pr_progstate || !pr_progstate[pn].progs)
644                         continue;
645
646                 if (linenum)    //linenum is set means to set the breakpoint on a file and line
647                 {
648                         if (!pr_progstate[pn].linenums)
649                                 continue;
650
651                         for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++)
652                         {
653                                 if (!stricmp(f->s_file+progfuncs->stringtable, filename))
654                                 {
655                                         for (i = f->first_statement; ; i++)
656                                         {
657                                                 if (pr_progstate[pn].linenums[i] >= linenum)
658                                                 {
659                                                         fl = pr_progstate[pn].linenums[i];
660                                                         for (; ; i++)
661                                                         {
662                                                                 if ((unsigned int)pr_progstate[pn].linenums[i] > fl)
663                                                                         break;
664
665                                                                 switch(pr_progstate[pn].structtype)
666                                                                 {
667                                                                 case PST_DEFAULT:
668                                                                 case PST_QTEST:
669                                                                         op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op;
670                                                                         break;
671                                                                 case PST_KKQWSV:
672                                                                 case PST_FTE32:
673                                                                         op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op;
674                                                                         break;
675                                                                 default:
676                                                                         Sys_Error("Bad structtype");
677                                                                         op = 0;
678                                                                 }
679                                                                 switch (flag)
680                                                                 {
681                                                                 default:
682                                                                         if (op & 0x8000)
683                                                                         {
684                                                                                 op &= ~0x8000;
685                                                                                 ret = false;
686                                                                                 flag = 0;
687                                                                         }
688                                                                         else
689                                                                         {
690                                                                                 op |= 0x8000;
691                                                                                 ret = true;
692                                                                                 flag = 1;
693                                                                         }
694                                                                         break;
695                                                                 case 0:
696                                                                         op &= ~0x8000;
697                                                                         ret = false;
698                                                                         break;
699                                                                 case 1:
700                                                                         op |= 0x8000;
701                                                                         ret = true;
702                                                                         break;
703                                                                 case 3:
704                                                                         if (op & 0x8000)
705                                                                                 return true;
706                                                                 }
707                                                                 switch(pr_progstate[pn].structtype)
708                                                                 {
709                                                                 case PST_DEFAULT:
710                                                                 case PST_QTEST:
711                                                                         ((dstatement16_t*)pr_progstate[pn].statements + i)->op = op;
712                                                                         break;
713                                                                 case PST_KKQWSV:
714                                                                 case PST_FTE32:
715                                                                         ((dstatement32_t*)pr_progstate[pn].statements + i)->op = op;
716                                                                         break;
717                                                                 default:
718                                                                         Sys_Error("Bad structtype");
719                                                                         op = 0;
720                                                                 }
721                                                         }
722                                                         goto cont;
723                                                 }
724                                         }
725                                 }
726                         }
727                 }
728                 else    //set the breakpoint on the first statement of the function specified.
729                 {
730                         for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++)
731                         {
732                                 if (!strcmp(f->s_name+progfuncs->stringtable, filename))
733                                 {
734                                         i = f->first_statement;
735                                         switch(pr_progstate[pn].structtype)
736                                         {
737                                         case PST_DEFAULT:
738                                         case PST_QTEST:
739                                                 op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op;
740                                                 break;
741                                         case PST_KKQWSV:
742                                         case PST_FTE32:
743                                                 op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op;
744                                                 break;
745                                         default:
746                                                 Sys_Error("Bad structtype");
747                                         }
748                                         switch (flag)
749                                         {
750                                         default:
751                                                 if (op & 0x8000)
752                                                 {
753                                                         op &= ~0x8000;
754                                                         ret = false;
755                                                         flag = 0;
756                                                 }
757                                                 else
758                                                 {
759                                                         op |= 0x8000;
760                                                         ret = true;
761                                                         flag = 1;
762                                                 }
763                                                 break;
764                                         case 0:
765                                                 op &= ~0x8000;
766                                                 ret = false;
767                                                 break;
768                                         case 1:
769                                                 op |= 0x8000;
770                                                 ret = true;
771                                                 break;
772                                         case 3:
773                                                 if (op & 0x8000)
774                                                         return true;
775                                         }
776                                         switch(pr_progstate[pn].structtype)
777                                         {
778                                         case PST_DEFAULT:
779                                         case PST_QTEST:
780                                                 ((dstatement16_t*)pr_progstate[pn].statements + i)->op = op;
781                                                 break;
782                                         case PST_KKQWSV:
783                                         case PST_FTE32:
784                                                 ((dstatement32_t*)pr_progstate[pn].statements + i)->op = op;
785                                                 break;
786                                         default:
787                                                 Sys_Error("Bad structtype");
788                                         }
789                                         break;
790                                 }
791                         }
792                 }
793 cont:
794                 continue;
795         }
796
797         return ret;
798 }
799
800 int ShowStep(progfuncs_t *progfuncs, int statement)
801 {
802 //      return statement;
803 //      texture realcursortex;
804 static int lastline = 0;
805 static char *lastfile = 0;
806
807         int pn = pr_typecurrent;
808         int i;
809         dfunction_t *f = pr_xfunction;
810
811         if (f && pr_progstate[pn].linenums && externs->useeditor)
812         {
813                 if (lastline == pr_progstate[pn].linenums[statement] && lastfile == f->s_file+progfuncs->stringtable)
814                         return statement;       //no info/same line as last time
815
816                 lastline = pr_progstate[pn].linenums[statement];
817                 lastfile = f->s_file+progfuncs->stringtable;
818
819                 lastline = externs->useeditor(progfuncs, lastfile, lastline, 0, NULL);
820
821                 if (pr_progstate[pn].linenums[statement] != lastline)
822                 {
823                         for (i = f->first_statement; ; i++)
824                         {
825                                 if (lastline == pr_progstate[pn].linenums[i])
826                                 {
827                                         return i;
828                                 }
829                                 else if (lastline <= pr_progstate[pn].linenums[i])
830                                 {
831                                         return statement;
832                                 }
833                         }
834                 }
835         }
836         else if (f)     //annoying.
837         {
838                 if (*(f->s_file+progfuncs->stringtable))        //if we can't get the filename, then it was stripped, and debugging it like this is useless
839                         if (externs->useeditor)
840                                 externs->useeditor(progfuncs, f->s_file+progfuncs->stringtable, -1, 0, NULL);
841                 return statement;
842         }
843
844
845         return statement;
846 }
847
848 //DMW: all pointer functions are modified to be absoloute pointers from NULL not sv_edicts
849 /*
850 ====================
851 PR_ExecuteProgram
852 ====================
853 */
854 void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
855 {
856         eval_t  *t, *swtch=NULL;
857
858         int swtchtype = 0; //warning about not being initialized before use
859         dstatement16_t  *st16;
860         dstatement32_t  *st32;
861         dfunction_t     *newf;
862         int             runaway;
863         int             i;
864         edictrun_t      *ed;
865         eval_t  *ptr;
866
867         float *glob;
868
869         int fnum;
870
871         prinst->continuestatement = -1;
872 #ifdef QCJIT
873         if (current_progstate->jit)
874         {
875                 PR_EnterJIT(progfuncs, current_progstate->jit, s);
876                 return;
877         }
878 #endif
879         fnum = pr_xfunction - pr_functions;
880
881         runaway = 100000000;
882
883 #define PRBOUNDSCHECK
884 #define RUNAWAYCHECK()                                                  \
885         if (!--runaway)                                                         \
886         {                                                                                       \
887                 pr_xstatement = st-pr_statements;               \
888                 PR_StackTrace(progfuncs);                               \
889                 printf ("runaway loop error\n");                \
890                 while(pr_depth > prinst->exitdepth)             \
891                         PR_LeaveFunction(progfuncs);            \
892                 pr_spushed = 0;                                                 \
893                 return;                                                                 \
894         }
895
896 #define OPA ((eval_t *)&glob[st->a])
897 #define OPB ((eval_t *)&glob[st->b])
898 #define OPC ((eval_t *)&glob[st->c])
899
900 restart:        //jumped to when the progs might have changed.
901         glob = pr_globals;
902         switch (current_progstate->structtype)
903         {
904         case PST_DEFAULT:
905         case PST_QTEST:
906 #define INTSIZE 16
907                 st16 = &pr_statements16[s];
908                 while (pr_trace)
909                 {
910                         #define DEBUGABLE
911                         #ifdef SEPARATEINCLUDES
912                                 #include "execloop16d.h"
913                         #else
914                                 #include "execloop.h"
915                         #endif
916                         #undef DEBUGABLE
917                 }
918
919                 while(1)
920                 {
921                         #include "execloop.h"
922                 }
923 #undef INTSIZE
924                 Sys_Error("PR_ExecuteProgram - should be unreachable");
925                 break;
926         case PST_KKQWSV:
927         case PST_FTE32:
928 #define INTSIZE 32
929                 st32 = &pr_statements32[s];
930                 while (pr_trace)
931                 {
932                         #define DEBUGABLE
933                         #ifdef SEPARATEINCLUDES
934                                 #include "execloop32d.h"
935                         #else
936                                 #include "execloop.h"
937                         #endif
938                         #undef DEBUGABLE
939                 }
940
941                 while(1)
942                 {
943                         #ifdef SEPARATEINCLUDES
944                                 #include "execloop32.h"
945                         #else
946                                 #include "execloop.h"
947                         #endif
948                 }
949 #undef INTSIZE
950                 Sys_Error("PR_ExecuteProgram - should be unreachable");
951                 break;
952         default:
953                 Sys_Error("PR_ExecuteProgram - bad structtype");
954         }
955 }
956
957
958 void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum)
959 {
960         dfunction_t     *f;
961         int             i;
962         unsigned int initial_progs;
963         int             oldexitdepth;
964
965         int s;
966
967         int tempdepth;
968
969         unsigned int newprogs = (fnum & 0xff000000)>>24;
970
971         initial_progs = pr_typecurrent;
972         if (newprogs != initial_progs)
973         {
974                 if (newprogs >= maxprogs || !&pr_progstate[newprogs].globals)   //can happen with hexen2...
975                 {
976                         printf("PR_ExecuteProgram: tried branching into invalid progs\n");
977                         return;
978                 }
979                 PR_MoveParms(progfuncs, newprogs, pr_typecurrent);
980                 PR_SwitchProgs(progfuncs, newprogs);
981         }
982
983         if (!(fnum & ~0xff000000) || (signed)(fnum & ~0xff000000) >= pr_progs->numfunctions)
984         {
985 //              if (pr_global_struct->self)
986 //                      ED_Print (PROG_TO_EDICT(pr_global_struct->self));
987                 printf("PR_ExecuteProgram: NULL function from exe\n");
988 //              Host_Error ("PR_ExecuteProgram: NULL function from exe");
989
990 //              PR_MoveParms(0, pr_typecurrent);
991                 PR_SwitchProgs(progfuncs, initial_progs);
992                 return;
993         }
994
995         oldexitdepth = prinst->exitdepth;
996
997         f = &pr_functions[fnum & ~0xff000000];
998
999         if (f->first_statement < 0)
1000         {       // negative statements are built in functions
1001                 i = -f->first_statement;
1002
1003                 if (i < externs->numglobalbuiltins)
1004                         (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
1005                 else
1006                 {
1007                         i -= externs->numglobalbuiltins;
1008                         if (i > current_progstate->numbuiltins)
1009                         {
1010                                 printf ("Bad builtin call number %i (from exe)\n", -f->first_statement);
1011                         //      PR_MoveParms(p, pr_typecurrent);
1012                                 PR_SwitchProgs(progfuncs, initial_progs);
1013                                 return;
1014                         }
1015                         current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals);
1016                 }
1017                 PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
1018                 PR_SwitchProgs(progfuncs, initial_progs);
1019                 return;
1020         }
1021
1022         if (pr_trace)
1023                 pr_trace--;
1024
1025 // make a stack frame
1026         prinst->exitdepth = pr_depth;
1027
1028
1029         s = PR_EnterFunction (progfuncs, f, initial_progs);
1030
1031         tempdepth = prinst->numtempstringsstack;
1032         PR_ExecuteCode(progfuncs, s);
1033
1034
1035         PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
1036         PR_SwitchProgs(progfuncs, initial_progs);
1037
1038         PR_FreeTemps(progfuncs, tempdepth);
1039         prinst->numtempstringsstack = tempdepth;
1040
1041         prinst->exitdepth = oldexitdepth;
1042 }
1043
1044
1045
1046
1047
1048
1049 typedef struct {
1050         int fnum;
1051         int progsnum;
1052         int statement;
1053 } qcthreadstack_t;
1054 typedef struct qcthread_s {
1055         int fstackdepth;
1056         qcthreadstack_t fstack[MAX_STACK_DEPTH];
1057         int lstackused;
1058         int lstack[LOCALSTACK_SIZE];
1059         int xstatement;
1060         int xfunction;
1061         progsnum_t xprogs;
1062 } qcthread_t;
1063
1064 struct qcthread_s *PR_ForkStack(progfuncs_t *progfuncs)
1065 {       //QC code can call builtins that call qc code.
1066         //to get around the problems of restoring the builtins we simply don't save the thread over the builtin.
1067         int i, l;
1068         int ed = prinst->exitdepth;
1069         int localsoffset, baselocalsoffset;
1070         qcthread_t *thread = memalloc(sizeof(qcthread_t));
1071         dfunction_t *f;
1072
1073         //copy out the functions stack.
1074         for (i = 0,localsoffset=0; i < ed; i++)
1075         {
1076                 if (i+1 == pr_depth)
1077                         f = pr_xfunction;
1078                 else
1079                         f = pr_stack[i+1].f;
1080                 localsoffset += f->locals;      //this is where it crashes
1081         }
1082         baselocalsoffset = localsoffset;
1083         for (i = ed; i < pr_depth; i++)
1084         {
1085                 thread->fstack[i-ed].fnum = pr_stack[i].f - pr_progstate[pr_stack[i].progsnum].functions;
1086                 thread->fstack[i-ed].progsnum = pr_stack[i].progsnum;
1087                 thread->fstack[i-ed].statement = pr_stack[i].s;
1088
1089                 if (i+1 == pr_depth)
1090                         f = pr_xfunction;
1091                 else
1092                         f = pr_stack[i+1].f;
1093                 localsoffset += f->locals;
1094         }
1095         thread->fstackdepth = pr_depth - ed;
1096
1097         for (i = pr_depth - 1; i >= ed ; i--)
1098         {
1099                 if (i+1 == pr_depth)
1100                         f = pr_xfunction;
1101                 else
1102                         f = pr_stack[i+1].f;
1103                 localsoffset -= f->locals;
1104                 for (l = 0; l < f->locals; l++)
1105                 {
1106                         thread->lstack[localsoffset-baselocalsoffset + l ] = ((int *)pr_globals)[f->parm_start + l];
1107                         ((int *)pr_globals)[f->parm_start + l] = localstack[localsoffset+l];    //copy the old value into the globals (so the older functions have the correct locals.
1108                 }
1109         }
1110
1111         for (i = ed; i < pr_depth ; i++)        //we need to get the locals back to how they were.
1112         {
1113                 if (i+1 == pr_depth)
1114                         f = pr_xfunction;
1115                 else
1116                         f = pr_stack[i+1].f;
1117
1118                 for (l = 0; l < f->locals; l++)
1119                 {
1120                         ((int *)pr_globals)[f->parm_start + l] = thread->lstack[localsoffset-baselocalsoffset + l];
1121                 }
1122                 localsoffset += f->locals;
1123         }
1124         thread->lstackused = localsoffset - baselocalsoffset;
1125
1126         thread->xstatement = pr_xstatement;
1127         thread->xfunction = pr_xfunction - pr_progstate[pr_typecurrent].functions;
1128         thread->xprogs = pr_typecurrent;
1129
1130         return thread;
1131 }
1132
1133 void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread)
1134 {
1135         dfunction_t     *f, *oldf;
1136         int             i,l,ls;
1137         progsnum_t initial_progs;
1138         int             oldexitdepth;
1139
1140         int s;
1141         int tempdepth;
1142
1143         progsnum_t prnum = thread->xprogs;
1144         int fnum = thread->xfunction;
1145
1146         if (localstack_used + thread->lstackused > LOCALSTACK_SIZE)
1147                 PR_RunError(progfuncs, "Too many locals on resumtion of QC thread\n");
1148
1149         if (pr_depth + thread->fstackdepth > MAX_STACK_DEPTH)
1150                 PR_RunError(progfuncs, "Too large stack on resumtion of QC thread\n");
1151
1152
1153         //do progs switching stuff as appropriate. (fteqw only)
1154         initial_progs = pr_typecurrent;
1155         PR_MoveParms(progfuncs, prnum, pr_typecurrent);
1156         PR_SwitchProgs(progfuncs, prnum);
1157
1158
1159         oldexitdepth = prinst->exitdepth;
1160         prinst->exitdepth = pr_depth;
1161
1162         ls = 0;
1163         //add on the callstack.
1164         for (i = 0; i < thread->fstackdepth; i++)
1165         {
1166                 if (pr_depth == prinst->exitdepth)
1167                 {
1168                         pr_stack[pr_depth].f = pr_xfunction;
1169                         pr_stack[pr_depth].s = pr_xstatement;
1170                         pr_stack[pr_depth].progsnum = initial_progs;
1171                 }
1172                 else
1173                 {
1174                         pr_stack[pr_depth].progsnum = thread->fstack[i].progsnum;
1175                         pr_stack[pr_depth].f = pr_progstate[thread->fstack[i].progsnum].functions + thread->fstack[i].fnum;
1176                         pr_stack[pr_depth].s = thread->fstack[i].statement;
1177                 }
1178
1179                 if (i+1 == thread->fstackdepth)
1180                         f = &pr_functions[fnum];
1181                 else
1182                         f = pr_progstate[thread->fstack[i+1].progsnum].functions + thread->fstack[i+1].fnum;
1183                 for (l = 0; l < f->locals; l++)
1184                 {
1185                         localstack[localstack_used++] = ((int *)pr_globals)[f->parm_start + l];
1186                         ((int *)pr_globals)[f->parm_start + l] = thread->lstack[ls++];
1187                 }
1188
1189                 pr_depth++;
1190         }
1191
1192         if (ls != thread->lstackused)
1193                 PR_RunError(progfuncs, "Thread stores incorrect locals count\n");
1194
1195
1196         f = &pr_functions[fnum];
1197
1198 //      thread->lstackused -= f->locals;        //the current function is the odd one out.
1199
1200         //add on the locals stack
1201         memcpy(localstack+localstack_used, thread->lstack, sizeof(int)*thread->lstackused);
1202         localstack_used += thread->lstackused;
1203
1204         //bung the locals of the current function on the stack.
1205 //      for (i=0 ; i < f->locals ; i++)
1206 //              ((int *)pr_globals)[f->parm_start + i] = 0xff00ff00;//thread->lstack[thread->lstackused+i];
1207
1208
1209 //      PR_EnterFunction (progfuncs, f, initial_progs);
1210         oldf = pr_xfunction;
1211         pr_xfunction = f;
1212         s = thread->xstatement;
1213
1214         tempdepth = prinst->numtempstringsstack;
1215         PR_ExecuteCode(progfuncs, s);
1216
1217
1218         PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
1219         PR_SwitchProgs(progfuncs, initial_progs);
1220         PR_FreeTemps(progfuncs, tempdepth);
1221         prinst->numtempstringsstack = tempdepth;
1222
1223         prinst->exitdepth = oldexitdepth;
1224         pr_xfunction = oldf;
1225 }
1226
1227 void    PR_AbortStack                   (progfuncs_t *progfuncs)
1228 {
1229         while(pr_depth > prinst->exitdepth+1)
1230                 PR_LeaveFunction(progfuncs);
1231         prinst->continuestatement = 0;
1232 }
1233