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.
38 #define ENGINEPOINTER(p) ((char*)(p) - progfuncs->stringtable)
39 #define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->stringtable)
40 #define QCPOINTERM(p) (eval_t *)((p)+progfuncs->stringtable)
45 cont: //last statement may have been a breakpoint
48 s=ShowStep(progfuncs, s);
49 st = pr_statements + s;
59 OPC->_float = OPA->_float + OPB->_float;
62 OPC->_vector[0] = OPA->_vector[0] + OPB->_vector[0];
63 OPC->_vector[1] = OPA->_vector[1] + OPB->_vector[1];
64 OPC->_vector[2] = OPA->_vector[2] + OPB->_vector[2];
68 OPC->_float = OPA->_float - OPB->_float;
71 OPC->_vector[0] = OPA->_vector[0] - OPB->_vector[0];
72 OPC->_vector[1] = OPA->_vector[1] - OPB->_vector[1];
73 OPC->_vector[2] = OPA->_vector[2] - OPB->_vector[2];
77 OPC->_float = OPA->_float * OPB->_float;
80 OPC->_float = OPA->_vector[0]*OPB->_vector[0]
81 + OPA->_vector[1]*OPB->_vector[1]
82 + OPA->_vector[2]*OPB->_vector[2];
85 OPC->_vector[0] = OPA->_float * OPB->_vector[0];
86 OPC->_vector[1] = OPA->_float * OPB->_vector[1];
87 OPC->_vector[2] = OPA->_float * OPB->_vector[2];
90 OPC->_vector[0] = OPB->_float * OPA->_vector[0];
91 OPC->_vector[1] = OPB->_float * OPA->_vector[1];
92 OPC->_vector[2] = OPB->_float * OPA->_vector[2];
96 OPC->_float = OPA->_float / OPB->_float;
99 OPC->_vector[0] = OPB->_float / OPA->_vector[0];
100 OPC->_vector[1] = OPB->_float / OPA->_vector[1];
101 OPC->_vector[2] = OPB->_float / OPA->_vector[2];
105 OPC->_float = (float)((int)OPA->_float & (int)OPB->_float);
109 OPC->_float = (float)((int)OPA->_float | (int)OPB->_float);
114 OPC->_float = (float)(OPA->_float >= OPB->_float);
117 OPC->_int = (int)(OPA->_int >= OPB->_int);
120 OPC->_float = (float)(OPA->_int >= OPB->_float);
123 OPC->_float = (float)(OPA->_float >= OPB->_int);
127 OPC->_float = (float)(OPA->_float <= OPB->_float);
130 OPC->_int = (int)(OPA->_int <= OPB->_int);
133 OPC->_float = (float)(OPA->_int <= OPB->_float);
136 OPC->_float = (float)(OPA->_float <= OPB->_int);
140 OPC->_float = (float)(OPA->_float > OPB->_float);
143 OPC->_int = (int)(OPA->_int > OPB->_int);
146 OPC->_float = (float)(OPA->_int > OPB->_float);
149 OPC->_float = (float)(OPA->_float > OPB->_int);
153 OPC->_float = (float)(OPA->_float < OPB->_float);
156 OPC->_int = (int)(OPA->_int < OPB->_int);
159 OPC->_float = (float)(OPA->_int < OPB->_float);
162 OPC->_float = (float)(OPA->_float < OPB->_int);
166 OPC->_float = (float)(OPA->_float && OPB->_float);
169 OPC->_float = (float)(OPA->_float || OPB->_float);
173 OPC->_float = (float)(!OPA->_float);
176 OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
179 OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string));
182 OPC->_float = (float)(!(OPA->function & ~0xff000000));
185 OPC->_float = (float)(PROG_TO_EDICT(progfuncs, OPA->edict) == (edictrun_t *)sv_edicts);
189 OPC->_float = (float)(OPA->_float == OPB->_float);
192 OPC->_float = (float)(OPA->_int == OPB->_float);
195 OPC->_float = (float)(OPA->_float == OPB->_int);
200 OPC->_float = (float)((OPA->_vector[0] == OPB->_vector[0]) &&
201 (OPA->_vector[1] == OPB->_vector[1]) &&
202 (OPA->_vector[2] == OPB->_vector[2]));
205 if (OPA->string==OPB->string)
207 else if (!OPA->string)
209 if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string))
214 else if (!OPB->string)
216 if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
222 OPC->_float = (float)(!strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
225 OPC->_float = (float)(OPA->_int == OPB->_int);
228 OPC->_float = (float)(OPA->function == OPB->function);
233 OPC->_float = (float)(OPA->_float != OPB->_float);
236 OPC->_float = (float)((OPA->_vector[0] != OPB->_vector[0]) ||
237 (OPA->_vector[1] != OPB->_vector[1]) ||
238 (OPA->_vector[2] != OPB->_vector[2]));
241 if (OPA->string==OPB->string)
243 else if (!OPA->string)
245 if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string)))
250 else if (!OPB->string)
252 if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string))
258 OPC->_float = (float)(strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string)));
261 OPC->_float = (float)(OPA->_int != OPB->_int);
264 OPC->_float = (float)(OPA->function != OPB->function);
269 OPB->_float = (float)OPA->_int;
272 OPB->_int = (int)OPA->_float;
277 case OP_STORE_FLD: // integers
280 case OP_STORE_FNC: // pointers
282 OPB->_int = OPA->_int;
285 OPB->_vector[0] = OPA->_vector[0];
286 OPB->_vector[1] = OPA->_vector[1];
287 OPB->_vector[2] = OPA->_vector[2];
290 //store a value to a pointer
292 if ((unsigned int)OPB->_int >= addressableused)
294 pr_xstatement = st-pr_statements;
295 PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
297 ptr = QCPOINTER(OPB);
298 ptr->_float = (float)OPA->_int;
301 if ((unsigned int)OPB->_int >= addressableused)
303 pr_xstatement = st-pr_statements;
304 PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
306 ptr = QCPOINTER(OPB);
307 ptr->_int = (int)OPA->_float;
310 if ((unsigned int)OPB->_int >= addressableused)
312 pr_xstatement = st-pr_statements;
313 PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
315 ptr = QCPOINTER(OPB);
316 ptr->_int = OPA->_int;
320 case OP_STOREP_FLD: // integers
322 case OP_STOREP_FNC: // pointers
323 if ((unsigned int)OPB->_int >= addressableused)
325 pr_xstatement = st-pr_statements;
326 PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
328 ptr = QCPOINTER(OPB);
329 ptr->_int = OPA->_int;
332 if ((unsigned int)OPB->_int >= addressableused)
334 pr_xstatement = st-pr_statements;
335 PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
337 ptr = QCPOINTER(OPB);
338 ptr->_vector[0] = OPA->_vector[0];
339 ptr->_vector[1] = OPA->_vector[1];
340 ptr->_vector[2] = OPA->_vector[2];
343 case OP_STOREP_C: //store character in a string
344 if ((unsigned int)OPB->_int >= addressableused)
346 pr_xstatement = st-pr_statements;
347 PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
349 ptr = QCPOINTER(OPB);
350 *(unsigned char *)ptr = (char)OPA->_float;
353 case OP_MULSTORE_F: // f *= f
354 OPB->_float *= OPA->_float;
356 case OP_MULSTORE_V: // v *= f
357 OPB->_vector[0] *= OPA->_float;
358 OPB->_vector[1] *= OPA->_float;
359 OPB->_vector[2] *= OPA->_float;
361 case OP_MULSTOREP_F: // e.f *= f
362 if ((unsigned int)OPB->_int >= addressableused)
364 pr_xstatement = st-pr_statements;
365 PR_RunError (progfuncs, "bad pointer write in %s", progfuncs->stringtable + pr_xfunction->s_name);
367 ptr = QCPOINTER(OPB);
368 OPC->_float = (ptr->_float *= OPA->_float);
370 case OP_MULSTOREP_V: // e.v *= f
371 ptr = QCPOINTER(OPB);
372 OPC->_vector[0] = (ptr->_vector[0] *= OPA->_float);
373 OPC->_vector[0] = (ptr->_vector[1] *= OPA->_float);
374 OPC->_vector[0] = (ptr->_vector[2] *= OPA->_float);
377 case OP_DIVSTORE_F: // f /= f
378 OPB->_float /= OPA->_float;
380 case OP_DIVSTOREP_F: // e.f /= f
381 ptr = QCPOINTER(OPB);
382 OPC->_float = (ptr->_float /= OPA->_float);
385 case OP_ADDSTORE_F: // f += f
386 OPB->_float += OPA->_float;
388 case OP_ADDSTORE_V: // v += v
389 OPB->_vector[0] += OPA->_vector[0];
390 OPB->_vector[1] += OPA->_vector[1];
391 OPB->_vector[2] += OPA->_vector[2];
393 case OP_ADDSTOREP_F: // e.f += f
394 ptr = QCPOINTER(OPB);
395 OPC->_float = (ptr->_float += OPA->_float);
397 case OP_ADDSTOREP_V: // e.v += v
398 ptr = QCPOINTER(OPB);
399 OPC->_vector[0] = (ptr->_vector[0] += OPA->_vector[0]);
400 OPC->_vector[1] = (ptr->_vector[1] += OPA->_vector[1]);
401 OPC->_vector[2] = (ptr->_vector[2] += OPA->_vector[2]);
404 case OP_SUBSTORE_F: // f -= f
405 OPB->_float -= OPA->_float;
407 case OP_SUBSTORE_V: // v -= v
408 OPB->_vector[0] -= OPA->_vector[0];
409 OPB->_vector[1] -= OPA->_vector[1];
410 OPB->_vector[2] -= OPA->_vector[2];
412 case OP_SUBSTOREP_F: // e.f -= f
413 ptr = QCPOINTER(OPB);
414 OPC->_float = (ptr->_float -= OPA->_float);
416 case OP_SUBSTOREP_V: // e.v -= v
417 ptr = QCPOINTER(OPB);
418 OPC->_vector[0] = (ptr->_vector[0] -= OPA->_vector[0]);
419 OPC->_vector[1] = (ptr->_vector[1] -= OPA->_vector[1]);
420 OPC->_vector[2] = (ptr->_vector[2] -= OPA->_vector[2]);
424 //get a pointer to a field var
426 if ((unsigned)OPA->edict >= (unsigned)maxedicts)
430 printf("OP_ADDRESS references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
434 PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
437 ed = PROG_TO_EDICT(progfuncs, OPA->edict);
439 NUM_FOR_EDICT(ed); // make sure it's in range
441 if (!ed || ed->readonly)
443 pr_xstatement = st-pr_statements;
445 //boot it over to the debugger
447 printf("assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
454 d16 = ED_GlobalAtOfs16(progfuncs, st->a);
455 f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->fieldadjust);
456 PR_RunError (progfuncs, "assignment to read-only entity in %s (%s.%s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), PR_StringToNative(progfuncs, d16->s_name), f?f->name:NULL);
461 //Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
464 // pr_xstatement = st-pr_statements;
465 // PR_RunError (progfuncs, "assignment to free entitiy in %s", progfuncs->stringtable + pr_xfunction->s_name);
467 OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
470 //load a field to a value
477 if ((unsigned)OPA->edict >= (unsigned)maxedicts)
478 PR_RunError (progfuncs, "OP_LOAD references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
479 ed = PROG_TO_EDICT(progfuncs, OPA->edict);
481 NUM_FOR_EDICT(ed); // make sure it's in range
483 ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust);
484 OPC->_int = ptr->_int;
488 if ((unsigned)OPA->edict >= (unsigned)maxedicts)
489 PR_RunError (progfuncs, "OP_LOAD_V references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
490 ed = PROG_TO_EDICT(progfuncs, OPA->edict);
492 NUM_FOR_EDICT(ed); // make sure it's in range
494 ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust);
495 OPC->_vector[0] = ptr->_vector[0];
496 OPC->_vector[1] = ptr->_vector[1];
497 OPC->_vector[2] = ptr->_vector[2];
504 if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string))
505 st += (sofs)st->b - 1; // offset the s++
511 st += (sofs)st->b - 1; // offset the s++
517 st += (sofs)st->b - 1; // offset the s++
522 if (OPA->string && PR_StringToNative(progfuncs, OPA->string))
523 st += (sofs)st->b - 1; // offset the s++
529 st += (sofs)st->b - 1; // offset the s++
535 st += (sofs)st->b - 1; // offset the s++
540 st += (sofs)st->a - 1; // offset the s++
550 G_VECTOR(OFS_PARM1)[0] = OPC->_vector[0];
551 G_VECTOR(OFS_PARM1)[1] = OPC->_vector[1];
552 G_VECTOR(OFS_PARM1)[2] = OPC->_vector[2];
554 G_VECTOR(OFS_PARM0)[0] = OPB->_vector[0];
555 G_VECTOR(OFS_PARM0)[1] = OPB->_vector[1];
556 G_VECTOR(OFS_PARM0)[2] = OPB->_vector[2];
568 pr_xstatement = st-pr_statements;
571 if (st->op > OP_CALL8)
572 pr_argc = st->op - (OP_CALL1H-1);
574 pr_argc = st->op - OP_CALL0;
575 fnum = OPA->function;
576 if ((fnum & ~0xff000000)==0)
579 printf("NULL function from qc (%s).\n", progfuncs->stringtable + pr_xfunction->s_name);
587 static char buffer[1024*1024*8];
588 int size = sizeof buffer;
589 progfuncs->save_ents(progfuncs, buffer, &size, 0);
594 //about to switch. needs caching.
596 //if it's an external call, switch now (before any function pointers are used)
597 PR_MoveParms(progfuncs, (fnum & 0xff000000)>>24, p);
598 PR_SwitchProgs(progfuncs, (fnum & 0xff000000)>>24);
600 newf = &pr_functions[fnum & ~0xff000000];
602 if (newf->first_statement < 0)
603 { // negative statements are built in functions
605 if (pr_typecurrent != 0)
607 PR_MoveParms(progfuncs, 0, pr_typecurrent);
608 PR_SwitchProgs(progfuncs, 0);
610 i = -newf->first_statement;
611 // p = pr_typecurrent;
612 progfuncs->lastcalledbuiltinnumber = i;
613 if (i < externs->numglobalbuiltins)
615 prinst->numtempstringsstack = prinst->numtempstrings;
616 (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
617 if (prinst->continuestatement!=-1)
619 st=&pr_statements[prinst->continuestatement];
620 prinst->continuestatement=-1;
626 i -= externs->numglobalbuiltins;
627 if (i >= current_progstate->numbuiltins)
629 // if (newf->first_statement == -0x7fffffff)
630 // ((builtin_t)newf->profile) (progfuncs, (struct globalvars_s *)current_progstate->globals);
632 PR_RunError (progfuncs, "Bad builtin call number - %i", -newf->first_statement);
635 current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals);
637 PR_MoveParms(progfuncs, p, pr_typecurrent);
638 // memcpy(&pr_progstate[p].globals[OFS_RETURN], ¤t_progstate->globals[OFS_RETURN], sizeof(vec3_t));
639 PR_SwitchProgs(progfuncs, (progsnum_t)p);
641 //#ifndef DEBUGABLE //decide weather non debugger wants to start debugging.
642 s = st-pr_statements;
647 // PR_MoveParms((OPA->function & 0xff000000)>>24, pr_typecurrent);
648 // PR_SwitchProgs((OPA->function & 0xff000000)>>24);
649 s = PR_EnterFunction (progfuncs, newf, p);
650 st = &pr_statements[s];
660 pr_globals[OFS_RETURN] = pr_globals[st->a];
661 pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
662 pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
665 static char buffer[1024*1024*8];
666 int size = sizeof buffer;
667 progfuncs->save_ents(progfuncs, buffer, &size, 0);
670 s = PR_LeaveFunction (progfuncs);
671 st = &pr_statements[s];
672 if (pr_depth == prinst->exitdepth)
680 externs->stateop(progfuncs, OPA->_float, OPB->function);
684 OPC->_int = OPA->_int + OPB->_int;
687 OPC->_float = OPA->_float + (float)OPB->_int;
690 OPC->_float = (float)OPA->_int + OPB->_float;
694 OPC->_int = OPA->_int - OPB->_int;
697 OPC->_float = OPA->_float - (float)OPB->_int;
700 OPC->_float = (float)OPA->_int - OPB->_float;
704 OPC->_float = (float)OPA->_int;
707 OPC->_int = (int)OPA->_float;
711 ptr = (eval_t *)(((qbyte *)sv_edicts) + OPA->_int);
712 OPC->_float = (float)ptr->_int;
716 ptr = (eval_t *)(((qbyte *)sv_edicts) + OPA->_int);
717 OPC->_int = (int)ptr->_float;
721 OPC->_int = (OPA->_int & OPB->_int);
725 OPC->_int = (OPA->_int | OPB->_int);
729 OPC->_int = OPA->_int * OPB->_int;
732 if (OPB->_int == 0) //no division by zero allowed...
735 OPC->_int = OPA->_int / OPB->_int;
738 OPC->_int = (OPA->_int == OPB->_int);
741 OPC->_int = (OPA->_int != OPB->_int);
745 //array/structure reading/riting.
746 case OP_GLOBALADDRESS:
747 OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int);
749 case OP_POINTER_ADD: //pointer to 32 bit (remember to *3 for vectors)
750 OPC->_int = OPA->_int + OPB->_int*4;
759 ptr = (eval_t *)(&OPA->_int + OPB->_int);
760 OPC->_int = ptr->_int;
764 ptr = (eval_t *)(&OPA->_int + OPB->_int);
765 OPC->_vector[0] = ptr->_vector[0];
766 OPC->_vector[1] = ptr->_vector[1];
767 OPC->_vector[2] = ptr->_vector[2];
772 case OP_ADD_SF: //(char*)c = (char*)a + (float)b
773 OPC->_int = OPA->_int + (int)OPB->_float;
775 case OP_SUB_S: //(float)c = (char*)a - (char*)b
776 OPC->_int = OPA->_int - OPB->_int;
778 case OP_LOADP_C: //load character from a string
779 ptr = QCPOINTERM(OPA->_int + (int)OPB->_float);
780 OPC->_float = *(unsigned char *)ptr;
788 ptr = QCPOINTERM(OPA->_int + OPB->_int);
789 OPC->_int = ptr->_int;
793 ptr = QCPOINTERM(OPA->_int + OPB->_int);
794 OPC->_vector[0] = ptr->_vector[0];
795 OPC->_vector[1] = ptr->_vector[1];
796 OPC->_vector[2] = ptr->_vector[2];
800 OPC->_int = OPA->_int ^ OPB->_int;
803 OPC->_int = OPA->_int >> OPB->_int;
806 OPC->_int = OPA->_int << OPB->_int;
813 case OP_FETCH_GBL_FNC:
814 i = (int)OPB->_float;
815 if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
817 PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
819 t = (eval_t *)&pr_globals[(uofs)st->a + i];
823 i = (int)OPB->_float;
824 if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
826 PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
828 t = (eval_t *)&pr_globals[(uofs)st->a
829 +((int)OPB->_float)*3];
830 OPC->_vector[0] = t->_vector[0];
831 OPC->_vector[1] = t->_vector[1];
832 OPC->_vector[2] = t->_vector[2];
836 externs->cstateop(progfuncs, OPA->_float, OPB->_float, fnum);
840 externs->cwstateop(progfuncs, OPA->_float, OPB->_float, fnum);
844 externs->thinktimeop(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, OPA->edict), OPB->_float);
848 case OP_BITSET: // b (+) a
849 OPB->_float = (float)((int)OPB->_float | (int)OPA->_float);
851 case OP_BITSETP: // .b (+) a
852 ptr = QCPOINTER(OPB);
853 ptr->_float = (float)((int)ptr->_float | (int)OPA->_float);
855 case OP_BITCLR: // b (-) a
856 OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float));
858 case OP_BITCLRP: // .b (-) a
859 ptr = QCPOINTER(OPB);
860 ptr->_float = (float)((int)ptr->_float & ~((int)OPA->_float));
864 G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff);
867 G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
870 if(OPA->_float < OPB->_float)
872 G_FLOAT(OFS_RETURN) = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
873 *(OPB->_float-OPA->_float));
877 G_FLOAT(OFS_RETURN) = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
878 *(OPA->_float-OPB->_float));
882 G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff);
883 G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff);
884 G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff);
887 G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[0];
888 G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[1];
889 G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[2];
892 for(i = 0; i < 3; i++)
894 if(OPA->_vector[i] < OPB->_vector[i])
896 G_FLOAT(OFS_RETURN+i) = OPA->_vector[i]+((rand()&0x7fff)/((float)0x7fff)
897 *(OPB->_vector[i]-OPA->_vector[i]));
901 G_FLOAT(OFS_RETURN+i) = OPB->_vector[i]+(rand()*(1.0f/RAND_MAX)
902 *(OPA->_vector[i]-OPB->_vector[i]));
916 st += (sofs)st->b - 1; // offset the st++
922 if (swtch->_float == OPA->_float)
925 st += (sofs)st->b-1; // -1 to offset the s++
930 if (swtch->_int == OPA->_int)
933 st += (sofs)st->b-1; // -1 to offset the s++
937 if (swtch->_int == OPA->_int)
940 st += (sofs)st->b-1; // -1 to offset the s++
942 if ((!swtch->_int && PR_StringToNative(progfuncs, OPA->string)) || (!OPA->_int && PR_StringToNative(progfuncs, swtch->string))) //one is null (cannot be not both).
944 if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string)))
947 st += (sofs)st->b-1; // -1 to offset the s++
951 if (swtch->_vector[0] == OPA->_vector[0] && swtch->_vector[1] == OPA->_vector[1] && swtch->_vector[2] == OPA->_vector[2])
954 st += (sofs)st->b-1; // -1 to offset the s++
958 PR_RunError (progfuncs, "OP_CASE with bad/missing OP_SWITCH %i", swtchtype);
966 if (swtch->_float >= OPA->_float && swtch->_float <= OPB->_float)
969 st += (sofs)st->c-1; // -1 to offset the s++
973 PR_RunError (progfuncs, "OP_CASERANGE with bad/missing OP_SWITCH %i", swtchtype);
986 OPC->_int = (OPA->_int & (int)OPB->_float);
989 OPC->_int = (OPA->_int | (int)OPB->_float);
992 OPC->_int = ((int)OPA->_float & OPB->_int);
995 OPC->_int = ((int)OPA->_float | OPB->_int);
999 OPC->_float = (OPA->_int * OPB->_float);
1002 OPC->_float = (OPA->_float * OPB->_int);
1006 OPC->_vector[0] = OPA->_vector[0] * OPB->_int;
1007 OPC->_vector[1] = OPA->_vector[0] * OPB->_int;
1008 OPC->_vector[2] = OPA->_vector[0] * OPB->_int;
1011 OPC->_vector[0] = OPB->_int * OPA->_vector[0];
1012 OPC->_vector[1] = OPB->_int * OPA->_vector[1];
1013 OPC->_vector[2] = OPB->_int * OPA->_vector[2];
1017 OPC->_float = (OPA->_int / OPB->_float);
1020 OPC->_float = (OPA->_float / OPB->_int);
1024 OPC->_int = (OPA->_int && OPB->_int);
1027 OPC->_int = (OPA->_int || OPB->_int);
1031 OPC->_int = (OPA->_int && OPB->_float);
1034 OPC->_int = (OPA->_int || OPB->_float);
1038 OPC->_int = (OPA->_float && OPB->_int);
1041 OPC->_int = (OPA->_float || OPB->_int);
1045 OPC->_int = !OPA->_int;
1049 OPC->_int = (OPA->_int != OPB->_float);
1052 OPC->_int = (OPA->_float != OPB->_int);
1057 case OP_GSTOREP_ENT:
1058 case OP_GSTOREP_FLD: // integers
1060 case OP_GSTOREP_FNC: // pointers
1069 pr_xstatement = st-pr_statements;
1070 PR_RunError(progfuncs, "Extra opcode not implemented\n");
1074 if ((unsigned int)OPA->_int < (unsigned int)st->c || (unsigned int)OPA->_int >= (unsigned int)st->b)
1076 pr_xstatement = st-pr_statements;
1077 PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i.", OPA->_int);
1081 OPC->_int = ENGINEPOINTER(&localstack[localstack_used+pr_spushed]);
1082 pr_spushed += OPA->_int;
1083 if (pr_spushed + localstack_used >= LOCALSTACK_SIZE)
1086 pr_xstatement = st-pr_statements;
1087 PR_RunError(progfuncs, "Progs pushed too much");
1091 pr_spushed -= OPA->_int;
1095 pr_xstatement = st-pr_statements;
1096 PR_RunError(progfuncs, "Progs poped more than it pushed");
1101 if (st->op & 0x8000) //break point!
1103 pr_xstatement = s = st-pr_statements;
1105 printf("Break point hit in %s.\n", pr_xfunction->s_name+progfuncs->stringtable);
1107 pr_trace=1; //this is what it's for
1109 s = ShowStep(progfuncs, s);
1110 st = &pr_statements[s]; //let the user move execution
1111 pr_xstatement = s = st-pr_statements;
1113 #if 0 //fakeop stuff - not practical, the rest of the code is more optimised, st needs to point at the correct statement
1114 memcpy(&fakeop, st, sizeof(dstatement_t)); //don't hit the new statement as a break point, cos it's probably the same one.
1115 fakeop.op &= ~0x8000;
1116 st = &fakeop; //a little remapping...
1118 st->op &= ~0x8000; //just remove the breakpoint and go around again, but this time in the debugger.
1121 goto reeval; //reexecute
1123 pr_xstatement = st-pr_statements;
1124 PR_RunError (progfuncs, "Bad opcode %i", st->op);
1132 #undef pr_statements
1138 #undef ENGINEPOINTER