2 //we have two conditions.
3 //one allows us to debug and trace through our code, the other doesn't.
5 //hopefully, the compiler will do a great job at optimising this code for us, where required.
6 //if it dosn't, then bum.
8 //the general overhead should be reduced significantly, and I would be supprised if it did run slower.
10 //run away loops are checked for ONLY on gotos and function calls. This might give a poorer check, but it will run faster overall.
12 //Appears to work fine.
16 #define reeval reeval16
18 #define pr_statements pr_statements16
19 #define fakeop fakeop16
20 #define dstatement_t dstatement16_t
21 #define sofs signed short
22 #define uofs unsigned short
25 #define reeval reeval32
27 #define pr_statements pr_statements32
28 #define fakeop fakeop32
29 #define dstatement_t dstatement32_t
30 #define sofs signed int
31 #define uofs unsigned int
33 #error INTSIZE should be set to 32.
39 #define OPCODE (st->op & ~0x8000)
41 #define OPCODE (st->op)
44 #define ENGINEPOINTER(p) ((char*)(p) - progfuncs->stringtable)
45 #define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->stringtable)
46 #define QCPOINTERM(p) (eval_t *)((p)+progfuncs->stringtable)
51 cont: //last statement may have been a breakpoint
54 s=ShowStep(progfuncs, s);
55 st = pr_statements + s;
64 OPC->_float = OPA->_float + OPB->_float;
67 OPC->_vector[0] = OPA->_vector[0] + OPB->_vector[0];
68 OPC->_vector[1] = OPA->_vector[1] + OPB->_vector[1];
69 OPC->_vector[2] = OPA->_vector[2] + OPB->_vector[2];
73 OPC->_float = OPA->_float - OPB->_float;
76 OPC->_vector[0] = OPA->_vector[0] - OPB->_vector[0];
77 OPC->_vector[1] = OPA->_vector[1] - OPB->_vector[1];
78 OPC->_vector[2] = OPA->_vector[2] - OPB->_vector[2];
82 OPC->_float = OPA->_float * OPB->_float;
85 OPC->_float = OPA->_vector[0]*OPB->_vector[0]
86 + OPA->_vector[1]*OPB->_vector[1]
87 + OPA->_vector[2]*OPB->_vector[2];
90 OPC->_vector[0] = OPA->_float * OPB->_vector[0];
91 OPC->_vector[1] = OPA->_float * OPB->_vector[1];
92 OPC->_vector[2] = OPA->_float * OPB->_vector[2];
95 OPC->_vector[0] = OPB->_float * OPA->_vector[0];
96 OPC->_vector[1] = OPB->_float * OPA->_vector[1];
97 OPC->_vector[2] = OPB->_float * OPA->_vector[2];
101 OPC->_float = OPA->_float / OPB->_float;
104 OPC->_vector[0] = OPB->_float / OPA->_vector[0];
105 OPC->_vector[1] = OPB->_float / OPA->_vector[1];
106 OPC->_vector[2] = OPB->_float / OPA->_vector[2];
110 OPC->_float = (float)((int)OPA->_float & (int)OPB->_float);
114 OPC->_float = (float)((int)OPA->_float | (int)OPB->_float);
119 OPC->_float = (float)(OPA->_float >= OPB->_float);
122 OPC->_int = (int)(OPA->_int >= OPB->_int);
125 OPC->_float = (float)(OPA->_int >= OPB->_float);
128 OPC->_float = (float)(OPA->_float >= OPB->_int);
132 OPC->_float = (float)(OPA->_float <= OPB->_float);
135 OPC->_int = (int)(OPA->_int <= OPB->_int);
138 OPC->_float = (float)(OPA->_int <= OPB->_float);
141 OPC->_float = (float)(OPA->_float <= OPB->_int);
145 OPC->_float = (float)(OPA->_float > OPB->_float);
148 OPC->_int = (int)(OPA->_int > OPB->_int);
151 OPC->_float = (float)(OPA->_int > OPB->_float);
154 OPC->_float = (float)(OPA->_float > OPB->_int);
158 OPC->_float = (float)(OPA->_float < OPB->_float);
161 OPC->_int = (int)(OPA->_int < OPB->_int);
164 OPC->_float = (float)(OPA->_int < OPB->_float);
167 OPC->_float = (float)(OPA->_float < OPB->_int);
171 OPC->_float = (float)(OPA->_float && OPB->_float);
174 OPC->_float = (float)(OPA->_float || OPB->_float);
178 OPC->_float = (float)(!OPA->_float);
181 OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
184 OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
187 OPC->_float = (float)(!(OPA->function & ~0xff000000));
190 OPC->_float = (float)(PROG_TO_EDICT(progfuncs, OPA->edict) == (edictrun_t *)sv_edicts);
194 OPC->_float = (float)(OPA->_float == OPB->_float);
197 OPC->_float = (float)(OPA->_int == OPB->_float);
200 OPC->_float = (float)(OPA->_float == OPB->_int);
205 OPC->_float = (float)((OPA->_vector[0] == OPB->_vector[0]) &&
206 (OPA->_vector[1] == OPB->_vector[1]) &&
207 (OPA->_vector[2] == OPB->_vector[2]));
210 if (OPA->string==OPB->string)
212 else if (!OPA->string)
214 if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
219 else if (!OPB->string)
221 if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
227 OPC->_float = (float)(!strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
230 OPC->_float = (float)(OPA->_int == OPB->_int);
233 OPC->_float = (float)(OPA->function == OPB->function);
238 OPC->_float = (float)(OPA->_float != OPB->_float);
241 OPC->_float = (float)((OPA->_vector[0] != OPB->_vector[0]) ||
242 (OPA->_vector[1] != OPB->_vector[1]) ||
243 (OPA->_vector[2] != OPB->_vector[2]));
246 if (OPA->string==OPB->string)
248 else if (!OPA->string)
250 if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
255 else if (!OPB->string)
257 if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
263 OPC->_float = (float)(strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
266 OPC->_float = (float)(OPA->_int != OPB->_int);
269 OPC->_float = (float)(OPA->function != OPB->function);
274 OPB->_float = (float)OPA->_int;
277 OPB->_int = (int)OPA->_float;
282 case OP_STORE_FLD: // integers
285 case OP_STORE_FNC: // pointers
287 OPB->_int = OPA->_int;
290 OPB->_vector[0] = OPA->_vector[0];
291 OPB->_vector[1] = OPA->_vector[1];
292 OPB->_vector[2] = OPA->_vector[2];
295 //store a value to a pointer
297 if ((unsigned int)OPB->_int >= prinst->addressableused)
299 pr_xstatement = st-pr_statements;
300 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
302 ptr = QCPOINTER(OPB);
303 ptr->_float = (float)OPA->_int;
306 if ((unsigned int)OPB->_int >= prinst->addressableused)
308 pr_xstatement = st-pr_statements;
309 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
311 ptr = QCPOINTER(OPB);
312 ptr->_int = (int)OPA->_float;
316 if ((unsigned int)OPB->_int >= prinst->addressableused)
318 pr_xstatement = st-pr_statements;
319 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
321 ptr = QCPOINTER(OPB);
322 ptr->_int = OPA->_int;
328 case OP_STOREP_FLD: // integers
332 case OP_STOREP_FNC: // pointers
334 if ((unsigned int)OPB->_int >= prinst->addressableused)
336 pr_xstatement = st-pr_statements;
337 PR_RunError (progfuncs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(progfuncs, pr_xfunction->s_name), OPB->_int, prinst->addressableused);
339 ptr = QCPOINTER(OPB);
340 ptr->_int = OPA->_int;
344 if ((unsigned int)OPB->_int >= prinst->addressableused)
346 pr_xstatement = st-pr_statements;
347 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
349 ptr = QCPOINTER(OPB);
350 ptr->_vector[0] = OPA->_vector[0];
351 ptr->_vector[1] = OPA->_vector[1];
352 ptr->_vector[2] = OPA->_vector[2];
355 case OP_STOREP_C: //store character in a string
356 if ((unsigned int)OPB->_int >= prinst->addressableused)
358 pr_xstatement = st-pr_statements;
359 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
361 ptr = QCPOINTER(OPB);
362 *(unsigned char *)ptr = (char)OPA->_float;
365 case OP_MULSTORE_F: // f *= f
366 OPB->_float *= OPA->_float;
368 case OP_MULSTORE_VF: // v *= f
369 OPB->_vector[0] *= OPA->_float;
370 OPB->_vector[1] *= OPA->_float;
371 OPB->_vector[2] *= OPA->_float;
373 case OP_MULSTOREP_F: // e.f *= f
374 if ((unsigned int)OPB->_int >= prinst->addressableused)
376 pr_xstatement = st-pr_statements;
377 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
379 ptr = QCPOINTER(OPB);
380 OPC->_float = (ptr->_float *= OPA->_float);
382 case OP_MULSTOREP_VF: // e.v *= f
383 if ((unsigned int)OPB->_int >= prinst->addressableused)
385 pr_xstatement = st-pr_statements;
386 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
388 ptr = QCPOINTER(OPB);
389 OPC->_vector[0] = (ptr->_vector[0] *= OPA->_float);
390 OPC->_vector[0] = (ptr->_vector[1] *= OPA->_float);
391 OPC->_vector[0] = (ptr->_vector[2] *= OPA->_float);
394 case OP_DIVSTORE_F: // f /= f
395 OPB->_float /= OPA->_float;
397 case OP_DIVSTOREP_F: // e.f /= f
398 if ((unsigned int)OPB->_int >= prinst->addressableused)
400 pr_xstatement = st-pr_statements;
401 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
403 ptr = QCPOINTER(OPB);
404 OPC->_float = (ptr->_float /= OPA->_float);
407 case OP_ADDSTORE_F: // f += f
408 OPB->_float += OPA->_float;
410 case OP_ADDSTORE_V: // v += v
411 OPB->_vector[0] += OPA->_vector[0];
412 OPB->_vector[1] += OPA->_vector[1];
413 OPB->_vector[2] += OPA->_vector[2];
415 case OP_ADDSTOREP_F: // e.f += f
416 if ((unsigned int)OPB->_int >= prinst->addressableused)
418 pr_xstatement = st-pr_statements;
419 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
421 ptr = QCPOINTER(OPB);
422 OPC->_float = (ptr->_float += OPA->_float);
424 case OP_ADDSTOREP_V: // e.v += v
425 if ((unsigned int)OPB->_int >= prinst->addressableused)
427 pr_xstatement = st-pr_statements;
428 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
430 ptr = QCPOINTER(OPB);
431 OPC->_vector[0] = (ptr->_vector[0] += OPA->_vector[0]);
432 OPC->_vector[1] = (ptr->_vector[1] += OPA->_vector[1]);
433 OPC->_vector[2] = (ptr->_vector[2] += OPA->_vector[2]);
436 case OP_SUBSTORE_F: // f -= f
437 OPB->_float -= OPA->_float;
439 case OP_SUBSTORE_V: // v -= v
440 OPB->_vector[0] -= OPA->_vector[0];
441 OPB->_vector[1] -= OPA->_vector[1];
442 OPB->_vector[2] -= OPA->_vector[2];
444 case OP_SUBSTOREP_F: // e.f -= f
445 if ((unsigned int)OPB->_int >= prinst->addressableused)
447 pr_xstatement = st-pr_statements;
448 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
450 ptr = QCPOINTER(OPB);
451 OPC->_float = (ptr->_float -= OPA->_float);
453 case OP_SUBSTOREP_V: // e.v -= v
454 if ((unsigned int)OPB->_int >= prinst->addressableused)
456 pr_xstatement = st-pr_statements;
457 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
459 ptr = QCPOINTER(OPB);
460 OPC->_vector[0] = (ptr->_vector[0] -= OPA->_vector[0]);
461 OPC->_vector[1] = (ptr->_vector[1] -= OPA->_vector[1]);
462 OPC->_vector[2] = (ptr->_vector[2] -= OPA->_vector[2]);
466 //get a pointer to a field var
468 if ((unsigned)OPA->edict >= (unsigned)maxedicts)
472 printf("OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
476 PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
479 ed = PROG_TO_EDICT(progfuncs, OPA->edict);
481 NUM_FOR_EDICT(ed); // make sure it's in range
483 if (!ed || ed->readonly)
485 pr_xstatement = st-pr_statements;
487 //boot it over to the debugger
489 printf("assignment to read-only entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
496 d16 = ED_GlobalAtOfs16(progfuncs, st->a);
497 f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->fieldadjust);
498 printf ("assignment to read-only entity in %s (%s.%s)\n", PR_StringToNative(progfuncs, pr_xfunction->s_name), d16?PR_StringToNative(progfuncs, d16->s_name):NULL, f?f->name:NULL);
503 //Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
506 // pr_xstatement = st-pr_statements;
507 // PR_RunError (progfuncs, "assignment to free entitiy in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
509 OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
512 //load a field to a value
519 if ((unsigned)OPA->edict >= (unsigned)maxedicts)
520 PR_RunError (progfuncs, "OP_LOAD references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
521 ed = PROG_TO_EDICT(progfuncs, OPA->edict);
523 NUM_FOR_EDICT(ed); // make sure it's in range
525 ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust);
526 OPC->_int = ptr->_int;
530 if ((unsigned)OPA->edict >= (unsigned)maxedicts)
531 PR_RunError (progfuncs, "OP_LOAD_V references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
532 ed = PROG_TO_EDICT(progfuncs, OPA->edict);
534 NUM_FOR_EDICT(ed); // make sure it's in range
536 ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust);
537 OPC->_vector[0] = ptr->_vector[0];
538 OPC->_vector[1] = ptr->_vector[1];
539 OPC->_vector[2] = ptr->_vector[2];
546 if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
547 st += (sofs)st->b - 1; // offset the s++
553 st += (sofs)st->b - 1; // offset the s++
559 st += (sofs)st->b - 1; // offset the s++
564 if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
565 st += (sofs)st->b - 1; // offset the s++
571 st += (sofs)st->b - 1; // offset the s++
577 st += (sofs)st->b - 1; // offset the s++
582 st += (sofs)st->a - 1; // offset the s++
592 G_VECTOR(OFS_PARM1)[0] = OPC->_vector[0];
593 G_VECTOR(OFS_PARM1)[1] = OPC->_vector[1];
594 G_VECTOR(OFS_PARM1)[2] = OPC->_vector[2];
596 G_VECTOR(OFS_PARM0)[0] = OPB->_vector[0];
597 G_VECTOR(OFS_PARM0)[1] = OPB->_vector[1];
598 G_VECTOR(OFS_PARM0)[2] = OPB->_vector[2];
610 pr_xstatement = st-pr_statements;
612 if (OPCODE > OP_CALL8)
613 pr_argc = OPCODE - (OP_CALL1H-1);
615 pr_argc = OPCODE - OP_CALL0;
616 fnum = OPA->function;
617 if ((fnum & ~0xff000000)==0)
619 PR_RunError(progfuncs, "NULL function from qc (%s).\n", PR_StringToNative(progfuncs, pr_xfunction->s_name));
627 static char buffer[1024*1024*8];
628 int size = sizeof buffer;
629 progfuncs->save_ents(progfuncs, buffer, &size, 0);
633 int callerprogs=pr_typecurrent;
634 //about to switch. needs caching.
636 //if it's an external call, switch now (before any function pointers are used)
637 PR_MoveParms(progfuncs, (fnum & 0xff000000)>>24, callerprogs);
638 PR_SwitchProgs(progfuncs, (fnum & 0xff000000)>>24);
640 newf = &pr_functions[fnum & ~0xff000000];
642 if (newf->first_statement < 0)
643 { // negative statements are built in functions
644 /*calling a builtin in another progs may affect that other progs' globals instead, is the theory anyway, so args and stuff need to move over*/
645 if (pr_typecurrent != 0)
647 PR_MoveParms(progfuncs, 0, pr_typecurrent);
648 PR_SwitchProgs(progfuncs, 0);
650 i = -newf->first_statement;
651 // p = pr_typecurrent;
652 progfuncs->lastcalledbuiltinnumber = i;
653 if (i < externs->numglobalbuiltins)
655 prinst->numtempstringsstack = prinst->numtempstrings;
656 (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
657 if (prinst->continuestatement!=-1)
659 st=&pr_statements[prinst->continuestatement];
660 prinst->continuestatement=-1;
666 i -= externs->numglobalbuiltins;
667 if (i >= current_progstate->numbuiltins)
669 // if (newf->first_statement == -0x7fffffff)
670 // ((builtin_t)newf->profile) (progfuncs, (struct globalvars_s *)current_progstate->globals);
672 PR_RunError (progfuncs, "Bad builtin call number - %i", -newf->first_statement);
675 current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals);
677 PR_MoveParms(progfuncs, callerprogs, pr_typecurrent);
678 // memcpy(&pr_progstate[p].globals[OFS_RETURN], ¤t_progstate->globals[OFS_RETURN], sizeof(vec3_t));
679 PR_SwitchProgs(progfuncs, (progsnum_t)callerprogs);
681 //#ifndef DEBUGABLE //decide weather non debugger wants to start debugging.
682 s = st-pr_statements;
687 // PR_MoveParms((OPA->function & 0xff000000)>>24, pr_typecurrent);
688 // PR_SwitchProgs((OPA->function & 0xff000000)>>24);
689 s = PR_EnterFunction (progfuncs, newf, callerprogs);
690 st = &pr_statements[s];
701 pr_globals[OFS_RETURN] = pr_globals[st->a];
702 pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
703 pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
706 static char buffer[1024*1024*8];
707 int size = sizeof buffer;
708 progfuncs->save_ents(progfuncs, buffer, &size, 0);
711 s = PR_LeaveFunction (progfuncs);
712 st = &pr_statements[s];
713 if (pr_depth == prinst->exitdepth)
721 externs->stateop(progfuncs, OPA->_float, OPB->function);
725 OPC->_int = OPA->_int + OPB->_int;
728 OPC->_float = OPA->_float + (float)OPB->_int;
731 OPC->_float = (float)OPA->_int + OPB->_float;
735 OPC->_int = OPA->_int - OPB->_int;
738 OPC->_float = OPA->_float - (float)OPB->_int;
741 OPC->_float = (float)OPA->_int - OPB->_float;
745 OPC->_float = (float)OPA->_int;
748 OPC->_int = (int)OPA->_float;
752 ptr = (eval_t *)(((qbyte *)sv_edicts) + OPA->_int);
753 OPC->_float = (float)ptr->_int;
757 ptr = (eval_t *)(((qbyte *)sv_edicts) + OPA->_int);
758 OPC->_int = (int)ptr->_float;
762 OPC->_int = (OPA->_int & OPB->_int);
766 OPC->_int = (OPA->_int | OPB->_int);
770 OPC->_int = OPA->_int * OPB->_int;
773 if (OPB->_int == 0) //no division by zero allowed...
776 OPC->_int = OPA->_int / OPB->_int;
779 OPC->_int = (OPA->_int == OPB->_int);
782 OPC->_int = (OPA->_int != OPB->_int);
786 //array/structure reading/writing.
787 case OP_GLOBALADDRESS:
788 OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int); /*pointer arithmatic*/
790 case OP_POINTER_ADD: //pointer to 32 bit (remember to *3 for vectors)
791 OPC->_int = OPA->_int + OPB->_int*4;
800 ptr = (eval_t *)(&OPA->_int + OPB->_int); /*pointer arithmatic*/
801 OPC->_int = ptr->_int;
805 ptr = (eval_t *)(&OPA->_int + OPB->_int);
806 OPC->_vector[0] = ptr->_vector[0];
807 OPC->_vector[1] = ptr->_vector[1];
808 OPC->_vector[2] = ptr->_vector[2];
813 case OP_ADD_SF: //(char*)c = (char*)a + (float)b
814 OPC->_int = OPA->_int + (int)OPB->_float;
816 case OP_SUB_S: //(float)c = (char*)a - (char*)b
817 OPC->_int = OPA->_int - OPB->_int;
819 case OP_LOADP_C: //load character from a string
820 i = (unsigned int)OPA->_int + (unsigned int)OPB->_float;
821 if ((unsigned int)i >= prinst->addressableused)
823 i = (unsigned int)OPB->_float;
824 ptr = (eval_t*)PR_StringToNative(progfuncs, OPA->_int);
825 if ((size_t)i > strlen((char*)ptr))
827 pr_xstatement = st-pr_statements;
828 PR_RunError (progfuncs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), i, ptr);
830 ptr = (eval_t*)((char*)ptr + i);
834 OPC->_float = *(unsigned char *)ptr;
842 i = OPA->_int + OPB->_int*4;
843 if ((unsigned int)i >= prinst->addressableused)
845 pr_xstatement = st-pr_statements;
846 PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
848 ptr = QCPOINTERM(OPA->_int + OPB->_int*4);
849 OPC->_int = ptr->_int;
853 i = OPA->_int + OPB->_int*4;
854 if ((unsigned int)i >= prinst->addressableused)
856 pr_xstatement = st-pr_statements;
857 PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
860 OPC->_vector[0] = ptr->_vector[0];
861 OPC->_vector[1] = ptr->_vector[1];
862 OPC->_vector[2] = ptr->_vector[2];
866 OPC->_int = OPA->_int ^ OPB->_int;
869 OPC->_int = OPA->_int >> OPB->_int;
872 OPC->_int = OPA->_int << OPB->_int;
879 case OP_FETCH_GBL_FNC:
880 i = (int)OPB->_float;
881 if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
883 PR_RunError(progfuncs, "array index out of bounds: %s[%d] (max %d)", PR_GlobalStringNoContents(progfuncs, st->a), i, ((eval_t *)&glob[st->a-1])->_int);
885 t = (eval_t *)&pr_globals[(uofs)st->a + i];
889 i = (int)OPB->_float;
890 if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
892 PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
894 t = (eval_t *)&pr_globals[(uofs)st->a + i*3];
895 OPC->_vector[0] = t->_vector[0];
896 OPC->_vector[1] = t->_vector[1];
897 OPC->_vector[2] = t->_vector[2];
901 externs->cstateop(progfuncs, OPA->_float, OPB->_float, fnum);
905 externs->cwstateop(progfuncs, OPA->_float, OPB->_float, fnum);
909 externs->thinktimeop(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, OPA->edict), OPB->_float);
913 case OP_BITSET: // b (+) a
914 OPB->_float = (float)((int)OPB->_float | (int)OPA->_float);
916 case OP_BITSETP: // .b (+) a
917 if ((unsigned int)OPB->_int >= prinst->addressableused)
919 pr_xstatement = st-pr_statements;
920 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
922 ptr = QCPOINTER(OPB);
923 ptr->_float = (float)((int)ptr->_float | (int)OPA->_float);
925 case OP_BITCLR: // b (-) a
926 OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float));
928 case OP_BITCLRP: // .b (-) a
929 if ((unsigned int)OPB->_int >= prinst->addressableused)
931 pr_xstatement = st-pr_statements;
932 PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
934 ptr = QCPOINTER(OPB);
935 ptr->_float = (float)((int)ptr->_float & ~((int)OPA->_float));
939 OPC->_float = (rand()&0x7fff)/((float)0x7fff);
942 OPC->_float = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
945 if(OPA->_float < OPB->_float)
947 OPC->_float = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
948 *(OPB->_float-OPA->_float));
952 OPC->_float = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
953 *(OPA->_float-OPB->_float));
957 OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff);
958 OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff);
959 OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff);
962 OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[0];
963 OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[1];
964 OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[2];
967 for(i = 0; i < 3; i++)
969 if(OPA->_vector[i] < OPB->_vector[i])
971 OPC->_vector[i] = OPA->_vector[i]+((rand()&0x7fff)/((float)0x7fff)
972 *(OPB->_vector[i]-OPA->_vector[i]));
976 OPC->_vector[i] = OPB->_vector[i]+(rand()*(1.0f/RAND_MAX)
977 *(OPA->_vector[i]-OPB->_vector[i]));
991 st += (sofs)st->b - 1; // offset the st++
997 if (swtch->_float == OPA->_float)
1000 st += (sofs)st->b-1; // -1 to offset the s++
1005 if (swtch->_int == OPA->_int)
1008 st += (sofs)st->b-1; // -1 to offset the s++
1012 if (swtch->_int == OPA->_int)
1015 st += (sofs)st->b-1; // -1 to offset the s++
1017 if ((!swtch->_int && PR_StringToNative(progfuncs, OPA->string)) || (!OPA->_int && PR_StringToNative(progfuncs, swtch->string))) //one is null (cannot be not both).
1019 if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
1022 st += (sofs)st->b-1; // -1 to offset the s++
1026 if (swtch->_vector[0] == OPA->_vector[0] && swtch->_vector[1] == OPA->_vector[1] && swtch->_vector[2] == OPA->_vector[2])
1029 st += (sofs)st->b-1; // -1 to offset the s++
1033 PR_RunError (progfuncs, "OP_CASE with bad/missing OP_SWITCH %i", swtchtype);
1041 if (swtch->_float >= OPA->_float && swtch->_float <= OPB->_float)
1044 st += (sofs)st->c-1; // -1 to offset the s++
1048 PR_RunError (progfuncs, "OP_CASERANGE with bad/missing OP_SWITCH %i", swtchtype);
1061 OPC->_int = (OPA->_int & (int)OPB->_float);
1064 OPC->_int = (OPA->_int | (int)OPB->_float);
1067 OPC->_int = ((int)OPA->_float & OPB->_int);
1070 OPC->_int = ((int)OPA->_float | OPB->_int);
1074 OPC->_float = (OPA->_int * OPB->_float);
1077 OPC->_float = (OPA->_float * OPB->_int);
1081 OPC->_vector[0] = OPA->_vector[0] * OPB->_int;
1082 OPC->_vector[1] = OPA->_vector[0] * OPB->_int;
1083 OPC->_vector[2] = OPA->_vector[0] * OPB->_int;
1086 OPC->_vector[0] = OPB->_int * OPA->_vector[0];
1087 OPC->_vector[1] = OPB->_int * OPA->_vector[1];
1088 OPC->_vector[2] = OPB->_int * OPA->_vector[2];
1092 OPC->_float = (OPA->_int / OPB->_float);
1095 OPC->_float = (OPA->_float / OPB->_int);
1099 OPC->_int = (OPA->_int && OPB->_int);
1102 OPC->_int = (OPA->_int || OPB->_int);
1106 OPC->_int = (OPA->_int && OPB->_float);
1109 OPC->_int = (OPA->_int || OPB->_float);
1113 OPC->_int = (OPA->_float && OPB->_int);
1116 OPC->_int = (OPA->_float || OPB->_int);
1120 OPC->_int = !OPA->_int;
1124 OPC->_int = (OPA->_int != OPB->_float);
1127 OPC->_int = (OPA->_float != OPB->_int);
1137 pr_xstatement = st-pr_statements;
1138 PR_RunError(progfuncs, "Extra opcode not implemented\n");
1142 if ((unsigned int)OPA->_int < (unsigned int)st->c || (unsigned int)OPA->_int >= (unsigned int)st->b)
1144 pr_xstatement = st-pr_statements;
1145 PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i. Must be between %u and %u", OPA->_int, st->c, st->b);
1149 OPC->_int = ENGINEPOINTER(&localstack[localstack_used+pr_spushed]);
1150 pr_spushed += OPA->_int;
1151 if (pr_spushed + localstack_used >= LOCALSTACK_SIZE)
1154 pr_xstatement = st-pr_statements;
1155 PR_RunError(progfuncs, "Progs pushed too much");
1159 pr_spushed -= OPA->_int;
1163 pr_xstatement = st-pr_statements;
1164 PR_RunError(progfuncs, "Progs poped more than it pushed");
1169 if (st->op & 0x8000) //break point!
1171 pr_xstatement = s = st-pr_statements;
1173 printf("Break point hit in %s.\n", PR_StringToNative(progfuncs, pr_xfunction->s_name));
1175 pr_trace=1; //this is what it's for
1177 s = ShowStep(progfuncs, s);
1178 st = &pr_statements[s]; //let the user move execution
1179 pr_xstatement = s = st-pr_statements;
1181 goto reeval; //reexecute
1183 pr_xstatement = st-pr_statements;
1184 PR_RunError (progfuncs, "Bad opcode %i", st->op);
1192 #undef pr_statements
1199 #undef ENGINEPOINTER