FTEQW
Documentation of the FTE engine source tree.
execloop.h
Go to the documentation of this file.
1//qc execution code.
2//we have two conditions.
3//one allows us to debug and trace through our code, the other doesn't.
4
5//hopefully, the compiler will do a great job at optimising this code for us, where required.
6//if it dosn't, then bum.
7
8//the general overhead should be reduced significantly, and I would be supprised if it did run slower.
9
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.
11
12//Appears to work fine.
13
14#if INTSIZE == 16
15#define reeval reeval16
16#define pr_statements pr_statements16
17#define fakeop fakeop16
18#define dstatement_t dstatement16_t
19#define sofs signed short
20#elif INTSIZE == 32
21#define reeval reeval32
22#define pr_statements pr_statements32
23#define fakeop fakeop32
24#define dstatement_t dstatement32_t
25#define sofs signed int
26#elif INTSIZE == 24
27#error INTSIZE should be set to 32.
28#else
29#error Bad cont size
30#endif
31
32#define ENGINEPOINTER(p) ((char*)(p) - progfuncs->funcs.stringtable)
33#define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->funcs.stringtable)
34#define QCPOINTERM(p) (eval_t *)((p)+progfuncs->funcs.stringtable)
35#define QCPOINTERWRITEFAIL(p,sz) ((unsigned int)(p)-1 >= prinst.addressableused-1-(sz)) //disallows null writes
36#define QCPOINTERREADFAIL(p,sz) ((unsigned int)(p) >= prinst.addressableused-(sz)) //permits null reads
37
38
39
40#define QCFAULT return (prinst.pr_xstatement=(st-pr_statements)-1),PR_HandleFault
41#define EVAL_FLOATISTRUE(ev) ((ev)->_int & 0x7fffffff) //mask away sign bit. This avoids using denormalized floats.
42
43#ifdef __GNUC__
44#define errorif(x) if(__builtin_expect(x,0))
45#else
46#define errorif(x) if(x)
47#endif
48
49//rely upon just st
50{
51#ifdef DEBUGABLE
52 s = st-pr_statements;
53 s+=1;
54
55 errorif (prinst.watch_ptr && prinst.watch_ptr->_int != prinst.watch_old._int)
56 {
57 //this will fire on the next instruction after the variable got changed.
58 prinst.pr_xstatement = s;
59 if (current_progstate->linenums)
60 externs->Printf("Watch point hit in %s:%u, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), current_progstate->linenums[s-1], prinst.watch_name);
61 else
62 externs->Printf("Watch point hit in %s, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), prinst.watch_name);
63 switch(prinst.watch_type)
64 {
65 case ev_float:
66 externs->Printf(" from %g to %g", prinst.watch_old._float, prinst.watch_ptr->_float);
67 break;
68 case ev_vector:
69 externs->Printf(" from '%g %g %g' to '%g %g %g'", prinst.watch_old._vector[0], prinst.watch_old._vector[1], prinst.watch_old._vector[2], prinst.watch_ptr->_vector[0], prinst.watch_ptr->_vector[1], prinst.watch_ptr->_vector[2]);
70 break;
71 default:
72 externs->Printf(" from %i to %i", prinst.watch_old._int, prinst.watch_ptr->_int);
73 break;
74 case ev_entity:
75 externs->Printf(" from %i(%s) to %i(%s)", prinst.watch_old._int, PR_GetEdictClassname(progfuncs, prinst.watch_old._int), prinst.watch_ptr->_int, PR_GetEdictClassname(progfuncs, prinst.watch_ptr->_int));
76 break;
77 case ev_function:
78 case ev_string:
79 externs->Printf(", now set to %s", PR_ValueString(progfuncs, prinst.watch_type, prinst.watch_ptr, false));
80 break;
81 }
82 externs->Printf(".\n");
83 prinst.watch_old = *prinst.watch_ptr;
84// prinst.watch_ptr = NULL;
85 progfuncs->funcs.debug_trace=DEBUG_TRACE_INTO; //this is what it's for
86
87 s=ShowStep(progfuncs, s, "Watchpoint hit", false);
88 }
89 else if (progfuncs->funcs.debug_trace)
90 s=ShowStep(progfuncs, s, NULL, false);
91 st = pr_statements + s;
92 prinst.pr_xfunction->profile+=1;
93
94 op = (progfuncs->funcs.debug_trace?(st->op & ~0x8000):st->op);
95reeval:
96#else
97 st++;
98 op = st->op;
99#endif
100
102 {
103 case OP_ADD_F:
104 OPC->_float = OPA->_float + OPB->_float;
105 break;
106 case OP_ADD_V:
107 OPC->_vector[0] = OPA->_vector[0] + OPB->_vector[0];
108 OPC->_vector[1] = OPA->_vector[1] + OPB->_vector[1];
109 OPC->_vector[2] = OPA->_vector[2] + OPB->_vector[2];
110 break;
111
112 case OP_SUB_F:
113 OPC->_float = OPA->_float - OPB->_float;
114 break;
115 case OP_SUB_V:
116 OPC->_vector[0] = OPA->_vector[0] - OPB->_vector[0];
117 OPC->_vector[1] = OPA->_vector[1] - OPB->_vector[1];
118 OPC->_vector[2] = OPA->_vector[2] - OPB->_vector[2];
119 break;
120
121 case OP_MUL_F:
122 OPC->_float = OPA->_float * OPB->_float;
123 break;
124 case OP_MUL_V:
125 OPC->_float = OPA->_vector[0]*OPB->_vector[0]
126 + OPA->_vector[1]*OPB->_vector[1]
127 + OPA->_vector[2]*OPB->_vector[2];
128 break;
129 case OP_MUL_FV:
130 tmpf = OPA->_float;
131 OPC->_vector[0] = tmpf * OPB->_vector[0];
132 OPC->_vector[1] = tmpf * OPB->_vector[1];
133 OPC->_vector[2] = tmpf * OPB->_vector[2];
134 break;
135 case OP_MUL_VF:
136 tmpf = OPB->_float;
137 OPC->_vector[0] = tmpf * OPA->_vector[0];
138 OPC->_vector[1] = tmpf * OPA->_vector[1];
139 OPC->_vector[2] = tmpf * OPA->_vector[2];
140 break;
141
142 case OP_DIV_F:
143/* errorif (OPB->_float == 0)
144 {
145 prinst.pr_xstatement = st-pr_statements;
146 externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
147 PR_StackTrace (&progfuncs->funcs, 1);
148 OPC->_float = 0.0;
149 }
150 else
151*/ OPC->_float = OPA->_float / OPB->_float;
152 break;
153 case OP_DIV_VF:
154 tmpf = OPB->_float;
155/* errorif (!tmpf)
156 {
157 prinst.pr_xstatement = st-pr_statements;
158 externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
159 PR_StackTrace (&progfuncs->funcs, 1);
160 }
161*/
162 OPC->_vector[0] = OPA->_vector[0] / tmpf;
163 OPC->_vector[1] = OPA->_vector[1] / tmpf;
164 OPC->_vector[2] = OPA->_vector[2] / tmpf;
165 break;
166
167 case OP_BITAND_F:
168 OPC->_float = (float)((int)OPA->_float & (int)OPB->_float);
169 break;
170
171 case OP_BITOR_F:
172 OPC->_float = (float)((int)OPA->_float | (int)OPB->_float);
173 break;
174
175
176 case OP_GE_F:
177 OPC->_float = (float)(OPA->_float >= OPB->_float);
178 break;
179 case OP_GE_I:
180 OPC->_int = (int)(OPA->_int >= OPB->_int);
181 break;
182 case OP_GE_IF:
183 OPC->_int = (int)(OPA->_int >= OPB->_float);
184 break;
185 case OP_GE_FI:
186 OPC->_int = (int)(OPA->_float >= OPB->_int);
187 break;
188
189 case OP_LE_F:
190 OPC->_float = (float)(OPA->_float <= OPB->_float);
191 break;
192 case OP_LE_I:
193 OPC->_int = (int)(OPA->_int <= OPB->_int);
194 break;
195 case OP_LE_IF:
196 OPC->_int = (int)(OPA->_int <= OPB->_float);
197 break;
198 case OP_LE_FI:
199 OPC->_int = (int)(OPA->_float <= OPB->_int);
200 break;
201 case OP_LE_U:
202 OPC->_int = (int)(OPA->_uint <= OPB->_uint);
203 break;
204
205 case OP_GT_F:
206 OPC->_float = (float)(OPA->_float > OPB->_float);
207 break;
208 case OP_GT_I:
209 OPC->_int = (int)(OPA->_int > OPB->_int);
210 break;
211 case OP_GT_IF:
212 OPC->_int = (int)(OPA->_int > OPB->_float);
213 break;
214 case OP_GT_FI:
215 OPC->_int = (int)(OPA->_float > OPB->_int);
216 break;
217
218 case OP_LT_F:
219 OPC->_float = (float)(OPA->_float < OPB->_float);
220 break;
221 case OP_LT_I:
222 OPC->_int = (int)(OPA->_int < OPB->_int);
223 break;
224 case OP_LT_IF:
225 OPC->_int = (int)(OPA->_int < OPB->_float);
226 break;
227 case OP_LT_FI:
228 OPC->_int = (int)(OPA->_float < OPB->_int);
229 break;
230 case OP_LT_U:
231 OPC->_int = (OPA->_uint < OPB->_uint);
232 break;
233
234 case OP_AND_F:
235 //original logic
236 //OPC->_float = (float)(OPA->_float && OPB->_float);
237 //deal with denormalized floats by ensuring that they're not 0 (ignoring sign bit).
238 //this avoids issues where the fpu treats denormalised floats as 0, or fpus that don't support denormals.
239 OPC->_float = (float)(EVAL_FLOATISTRUE(OPA) && EVAL_FLOATISTRUE(OPB));
240 break;
241 case OP_OR_F:
242 OPC->_float = (float)(EVAL_FLOATISTRUE(OPA) || EVAL_FLOATISTRUE(OPB));
243 break;
244
245 case OP_NOT_F:
246 OPC->_float = (float)(!EVAL_FLOATISTRUE(OPA));
247 break;
248 case OP_NOT_V:
249 OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]);
250 break;
251 case OP_NOT_S:
252 OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(&progfuncs->funcs, OPA->string));
253 break;
254 case OP_NOT_FNC:
255 OPC->_float = (float)(!(OPA->function & ~0xff000000));
256 break;
257 case OP_NOT_ENT:
258 OPC->_float = (float)(!(OPA->edict));//(PROG_TO_EDICT(progfuncs, OPA->edict) == (edictrun_t *)sv_edicts);
259 break;
260 case OP_NOT_I:
261 OPC->_int = !OPA->_int;
262 break;
263
264 case OP_EQ_F:
265 OPC->_float = (float)(OPA->_float == OPB->_float);
266 break;
267 case OP_EQ_IF:
268 OPC->_int = (float)(OPA->_int == OPB->_float);
269 break;
270 case OP_EQ_FI:
271 OPC->_int = (float)(OPA->_float == OPB->_int);
272 break;
273
274
275 case OP_EQ_V:
276 OPC->_float = (float)((OPA->_vector[0] == OPB->_vector[0]) &&
277 (OPA->_vector[1] == OPB->_vector[1]) &&
278 (OPA->_vector[2] == OPB->_vector[2]));
279 break;
280 case OP_EQ_S:
281 if (OPA->string==OPB->string)
282 OPC->_float = true;
283 else if (!OPA->string)
284 {
285 if (!OPB->string || !*PR_StringToNative(&progfuncs->funcs, OPB->string))
286 OPC->_float = true;
287 else
288 OPC->_float = false;
289 }
290 else if (!OPB->string)
291 {
292 if (!OPA->string || !*PR_StringToNative(&progfuncs->funcs, OPA->string))
293 OPC->_float = true;
294 else
295 OPC->_float = false;
296 }
297 else
298 OPC->_float = (float)(!strcmp(PR_StringToNative(&progfuncs->funcs, OPA->string),PR_StringToNative(&progfuncs->funcs, OPB->string)));
299 break;
300 case OP_EQ_E:
301 OPC->_float = (float)(OPA->_int == OPB->_int);
302 break;
303 case OP_EQ_FNC:
304 OPC->_float = (float)(OPA->function == OPB->function);
305 break;
306
307
308 case OP_NE_F:
309 OPC->_float = (float)(OPA->_float != OPB->_float);
310 break;
311 case OP_NE_V:
312 OPC->_float = (float)((OPA->_vector[0] != OPB->_vector[0]) ||
313 (OPA->_vector[1] != OPB->_vector[1]) ||
314 (OPA->_vector[2] != OPB->_vector[2]));
315 break;
316 case OP_NE_S:
317 if (OPA->string==OPB->string)
318 OPC->_float = false;
319 else if (!OPA->string)
320 {
321 if (!OPB->string || !*(PR_StringToNative(&progfuncs->funcs, OPB->string)))
322 OPC->_float = false;
323 else
324 OPC->_float = true;
325 }
326 else if (!OPB->string)
327 {
328 if (!OPA->string || !*PR_StringToNative(&progfuncs->funcs, OPA->string))
329 OPC->_float = false;
330 else
331 OPC->_float = true;
332 }
333 else
334 OPC->_float = (float)(strcmp(PR_StringToNative(&progfuncs->funcs, OPA->string),PR_StringToNative(&progfuncs->funcs, OPB->string)));
335 break;
336 case OP_NE_E:
337 OPC->_float = (float)(OPA->_int != OPB->_int);
338 break;
339 case OP_NE_FNC:
340 OPC->_float = (float)(OPA->function != OPB->function);
341 break;
342
343//==================
344 case OP_STORE_IF:
345 OPB->_float = (float)OPA->_int;
346 break;
347 case OP_STORE_FI:
348 OPB->_int = (int)OPA->_float;
349 break;
350
351 case OP_STORE_F:
352 case OP_STORE_ENT:
353 case OP_STORE_FLD: // integers
354 case OP_STORE_S:
355 case OP_STORE_I:
356 case OP_STORE_FNC: // pointers
357 case OP_STORE_P:
358 OPB->_int = OPA->_int;
359 break;
360 case OP_STORE_V:
361 OPB->_vector[0] = OPA->_vector[0];
362 OPB->_vector[1] = OPA->_vector[1];
363 OPB->_vector[2] = OPA->_vector[2];
364 break;
365
366 //store a value to a pointer
367 case OP_STOREP_IF:
368 i = OPB->_int + OPC->_int*sizeof(ptr->_float);
369 errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
370 {
371 if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(ptr->_float), sizeof(ptr->_float))))
372 {
373 if (i == -1)
374 break;
375 QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
376 }
377 }
378 else
379 ptr = QCPOINTERM(i);
380 ptr->_float = (float)OPA->_int;
381 break;
382 case OP_STOREP_FI:
383 i = OPB->_int + OPC->_int*sizeof(ptr->_int);
384 errorif (QCPOINTERWRITEFAIL(i, sizeof(int)))
385 {
386 if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(ptr->_int), sizeof(ptr->_int))))
387 {
388 if (i == -1)
389 break;
390 QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
391 }
392 }
393 else
394 ptr = QCPOINTERM(i);
395 ptr->_int = (int)OPA->_float;
396 break;
397 case OP_STOREP_I:
398 case OP_STOREP_F:
399 case OP_STOREP_ENT:
400 case OP_STOREP_FLD: // integers
401 case OP_STOREP_S:
402 case OP_STOREP_FNC: // pointers
403 i = OPB->_int + OPC->_int*sizeof(ptr->_int);
404 errorif (QCPOINTERWRITEFAIL(i, sizeof(ptr->_int)))
405 {
406 if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(ptr->_int), sizeof(ptr->_int))))
407 {
408 if (i == -1)
409 break;
410 if (i == 0)
411 QCFAULT(&progfuncs->funcs, "bad pointer write in %s (null pointer)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
412 else
413 QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused);
414 }
415 }
416 else
417 ptr = QCPOINTERM(i);
418 ptr->_int = OPA->_int;
419 break;
420 case OP_STOREP_I64: // 64bit
421 i = OPB->_int + OPC->_int*sizeof(ptr->_int);
422 errorif (QCPOINTERWRITEFAIL(i, sizeof(ptr->i64)))
423 {
424 if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(ptr->_int), sizeof(ptr->i64))))
425 {
426 if (i == -1)
427 break;
428 if (i == 0)
429 QCFAULT(&progfuncs->funcs, "bad pointer write in %s (null pointer)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
430 else
431 QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused);
432 }
433 }
434 else
435 ptr = QCPOINTERM(i);
436 ptr->i64 = OPA->i64;
437 break;
438 case OP_STOREP_V:
439 i = OPB->_int + (OPC->_int*sizeof(ptr->_int));
440 errorif (QCPOINTERWRITEFAIL(i, sizeof(pvec3_t)))
441 {
442 if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(ptr->_int), sizeof(pvec3_t))))
443 {
444 if (i == -1)
445 break;
446 QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused);
447 }
448 }
449 else
450 ptr = QCPOINTERM(i);
451 ptr->_vector[0] = OPA->_vector[0];
452 ptr->_vector[1] = OPA->_vector[1];
453 ptr->_vector[2] = OPA->_vector[2];
454 break;
455
456 case OP_STOREP_C: //store (float) character in a string
457 i = OPB->_int + (OPC->_int)*sizeof(char);
458 errorif (QCPOINTERWRITEFAIL(i, sizeof(char)))
459 {
460 if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(char), sizeof(char))))
461 {
462 if (i == -1)
463 break;
464 QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused);
465 }
466 }
467 else
468 ptr = QCPOINTERM(i);
469 *(unsigned char *)ptr = (char)OPA->_float;
470 break;
471 case OP_STOREP_B: //store (byte) character in a string
472 i = OPB->_int + (OPC->_int)*sizeof(pbyte);
473 errorif (QCPOINTERWRITEFAIL(i, sizeof(pbyte)))
474 {
475 if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(pbyte), sizeof(pbyte))))
476 {
477 if (i == -1)
478 break;
479 QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused);
480 }
481 }
482 else
483 ptr = QCPOINTERM(i);
484 *(pbyte *)ptr = (pbyte)OPA->_int;
485 break;
486
487 case OP_STOREF_F:
488 case OP_STOREF_I:
489 case OP_STOREF_S:
490 errorif ((unsigned)OPA->edict >= (unsigned)num_edicts)
491 {
492 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_STOREF_? references invalid entity in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
493 return prinst.pr_xstatement;
494 break;
495 }
496 ed = PROG_TO_EDICT_PB(progfuncs, OPA->edict);
497 errorif (!ed || ed->readonly)
498 { //boot it over to the debugger
499#if INTSIZE == 16
501#else
503#endif
504 fdef_t *f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->funcs.fieldadjust);
505 if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):"??", f?f->name:"??"))
506 return prinst.pr_xstatement;
507 break;
508 }
509
510//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
511#ifdef NOLEGACY
512 errorif (ed->ereftype == ER_FREE)
513 {
514 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "assignment to free entity in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
515 return prinst.pr_xstatement;
516 break;
517 }
518#endif
519
520 i = OPB->_int + progfuncs->funcs.fieldadjust;
521 errorif ((unsigned int)i*4 >= ed->fieldsize) //FIXME:lazy size check
522 {
523 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_STOREF_? references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
524 return prinst.pr_xstatement;
525 break;
526 }
527
528 ptr = (eval_t *)(((int *)edvars(ed)) + i);
529 ptr->_int = OPC->_int;
530 break;
531 case OP_STOREF_I64:
532 errorif ((unsigned)OPA->edict >= (unsigned)num_edicts)
533 {
534 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_STOREF_? references invalid entity in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
535 return prinst.pr_xstatement;
536 break;
537 }
538 ed = PROG_TO_EDICT_PB(progfuncs, OPA->edict);
539 errorif (!ed || ed->readonly)
540 { //boot it over to the debugger
541#if INTSIZE == 16
543#else
545#endif
546 fdef_t *f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->funcs.fieldadjust);
547 if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):"??", f?f->name:"??"))
548 return prinst.pr_xstatement;
549 break;
550 }
551
552//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
553#ifdef NOLEGACY
554 errorif (ed->ereftype == ER_FREE)
555 {
556 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "assignment to free entity in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
557 return prinst.pr_xstatement;
558 break;
559 }
560#endif
561
562 i = OPB->_int + progfuncs->funcs.fieldadjust;
563 errorif ((unsigned int)i*4 >= ed->fieldsize) //FIXME:lazy size check
564 {
565 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_STOREF_? references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
566 return prinst.pr_xstatement;
567 break;
568 }
569
570 ptr = (eval_t *)(((int *)edvars(ed)) + i);
571 ptr->i64 = OPC->i64;
572 break;
573 case OP_STOREF_V:
574 errorif ((unsigned)OPA->edict >= (unsigned)num_edicts)
575 {
576 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_STOREF_? references invalid entity in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
577 return prinst.pr_xstatement;
578 break;
579 }
580 ed = PROG_TO_EDICT_PB(progfuncs, OPA->edict);
581 errorif (!ed || ed->readonly)
582 { //boot it over to the debugger
583#if INTSIZE == 16
585#else
587#endif
588 fdef_t *f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->funcs.fieldadjust);
589 if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):"??", f?f->name:"??"))
590 return prinst.pr_xstatement;
591 break;
592 }
593
594//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
595#ifdef NOLEGACY
596 errorif (ed->ereftype == ER_FREE)
597 {
598 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "assignment to free entity in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
599 return prinst.pr_xstatement;
600 break;
601 }
602#endif
603
604 i = OPB->_int + progfuncs->funcs.fieldadjust;
605 errorif ((unsigned int)i*4 >= ed->fieldsize) //FIXME:lazy size check
606 {
607 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_STOREF_? references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
608 return prinst.pr_xstatement;
609 break;
610 }
611
612 ptr = (eval_t *)(((int *)edvars(ed)) + i);
613 ptr->_vector[0] = OPC->_vector[0];
614 ptr->_vector[1] = OPC->_vector[1];
615 ptr->_vector[2] = OPC->_vector[2];
616 break;
617
618
619 //get a pointer to a field var
620 case OP_ADDRESS:
621 errorif ((unsigned)OPA->edict >= (unsigned)num_edicts)
622 {
623 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_ADDRESS references invalid entity in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
624 return prinst.pr_xstatement;
625 break;
626 }
627 ed = PROG_TO_EDICT_PB(progfuncs, OPA->edict);
628#ifdef PARANOID
629 NUM_FOR_EDICT(ed); // make sure it's in range
630#endif
631 errorif (!ed || ed->readonly)
632 {
633
634 //boot it over to the debugger
635 {
636#if INTSIZE == 16
638#else
640#endif
641 fdef_t *f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->funcs.fieldadjust);
642 if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):"??", f?f->name:"??"))
643 return prinst.pr_xstatement;
644 OPC->_int = ~0;
645 break;
646 }
647 }
648
649//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
650#ifdef NOLEGACY
651 errorif (ed->ereftype == ER_FREE)
652 {
653 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "assignment to free entity in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
654 return prinst.pr_xstatement;
655 break;
656 }
657#endif
658
659 i = OPB->_int + progfuncs->funcs.fieldadjust;
660#ifdef PARANOID
661 errorif ((unsigned int)i*4 >= ed->fieldsize) //FIXME:lazy size check
662 {
663 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_ADDRESS references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
664 return prinst.pr_xstatement;
665 OPC->_int = 0;
666 break;
667 }
668#endif
669
670 OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + i));
671 break;
672
673 //load a field to a value
674 case OP_LOAD_P:
675 case OP_LOAD_I:
676 case OP_LOAD_F:
677 case OP_LOAD_FLD:
678 case OP_LOAD_ENT:
679 case OP_LOAD_S:
680 case OP_LOAD_FNC:
681 errorif ((unsigned)OPA->edict >= (unsigned)num_edicts)
682 {
683 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
684 return prinst.pr_xstatement;
685 OPC->_int = 0;
686 break;
687 }
688 ed = PROG_TO_EDICT_PB(progfuncs, OPA->edict);
689#ifdef PARANOID
690 NUM_FOR_EDICT(ed); // make sure it's in range
691#endif
692#ifdef NOLEGACY
693 if (ed->ereftype == ER_FREE)
694 {
695 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references free entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
696 return prinst.pr_xstatement;
697 OPC->_int = 0;
698 }
699 else
700#endif
701 {
702 i = OPB->_int + progfuncs->funcs.fieldadjust;
703 errorif ((unsigned int)(i+1)*4 > ed->fieldsize) //FIXME:lazy size check
704 {
705 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
706 return prinst.pr_xstatement;
707 OPC->_int = 0;
708 break;
709 }
710 ptr = (eval_t *)(((int *)edvars(ed)) + i);
711 OPC->_int = ptr->_int;
712 }
713 break;
714 case OP_LOAD_I64:
715 errorif ((unsigned)OPA->edict >= (unsigned)num_edicts)
716 {
717 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD_V references invalid entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
718 return prinst.pr_xstatement;
719 OPC->_vector[0] = 0;
720 OPC->_vector[1] = 0;
721 OPC->_vector[2] = 0;
722 break;
723 }
724 ed = PROG_TO_EDICT_PB(progfuncs, OPA->edict);
725#ifdef PARANOID
726 NUM_FOR_EDICT(ed); // make sure it's in range
727#endif
728#ifdef NOLEGACY
729 if (ed->ereftype == ER_FREE)
730 {
731 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references free entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
732 return prinst.pr_xstatement;
733 OPC->_vector[0] = 0;
734 OPC->_vector[1] = 0;
735 OPC->_vector[2] = 0;
736 }
737 else
738#endif
739 {
740 i = OPB->_int + progfuncs->funcs.fieldadjust;
741 errorif ((unsigned int)(i+2)*4 > ed->fieldsize) //FIXME:lazy size check
742 {
743 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
744 return prinst.pr_xstatement;
745 OPC->_int = 0;
746 break;
747 }
748 ptr = (eval_t *)(((int *)edvars(ed)) + i);
749 OPC->i64 = ptr->i64;
750 }
751 break;
752 case OP_LOAD_V:
753 errorif ((unsigned)OPA->edict >= (unsigned)num_edicts)
754 {
755 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD_V references invalid entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
756 return prinst.pr_xstatement;
757 OPC->_vector[0] = 0;
758 OPC->_vector[1] = 0;
759 OPC->_vector[2] = 0;
760 break;
761 }
762 ed = PROG_TO_EDICT_PB(progfuncs, OPA->edict);
763#ifdef PARANOID
764 NUM_FOR_EDICT(ed); // make sure it's in range
765#endif
766#ifdef NOLEGACY
767 if (ed->ereftype == ER_FREE)
768 {
769 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references free entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
770 return prinst.pr_xstatement;
771 OPC->_vector[0] = 0;
772 OPC->_vector[1] = 0;
773 OPC->_vector[2] = 0;
774 }
775 else
776#endif
777 {
778 i = OPB->_int + progfuncs->funcs.fieldadjust;
779 errorif ((unsigned int)(i+3)*4 > ed->fieldsize) //FIXME:lazy size check
780 {
781 if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)))
782 return prinst.pr_xstatement;
783 OPC->_int = 0;
784 break;
785 }
786 ptr = (eval_t *)(((int *)edvars(ed)) + i);
787 OPC->_vector[0] = ptr->_vector[0];
788 OPC->_vector[1] = ptr->_vector[1];
789 OPC->_vector[2] = ptr->_vector[2];
790 }
791 break;
792
793//==================
794
795 case OP_IFNOT_S:
796 RUNAWAYCHECK();
797 if (!OPA->string || !PR_StringToNative(&progfuncs->funcs, OPA->string))
798 st += (sofs)st->b - 1; // offset the s++
799 break;
800
801 case OP_IFNOT_F:
802 RUNAWAYCHECK();
803 if (!EVAL_FLOATISTRUE(OPA))
804 st += (sofs)st->b - 1; // offset the s++
805 break;
806
807 //WARNING: vanilla uses this for floats too, which results in a discrepancy with -0
808 case OP_IFNOT_I:
809 RUNAWAYCHECK();
810 if (!OPA->_int)
811 st += (sofs)st->b - 1; // offset the s++
812 break;
813
814 case OP_IF_S:
815 RUNAWAYCHECK();
816 if (OPA->string && PR_StringToNative(&progfuncs->funcs, OPA->string))
817 st += (sofs)st->b - 1; // offset the s++
818 break;
819
820 case OP_IF_F:
821 RUNAWAYCHECK();
822 if (EVAL_FLOATISTRUE(OPA))
823 st += (sofs)st->b - 1; // offset the s++
824 break;
825
826 //WARNING: vanilla uses this for floats too, which results in a discrepancy with -0
827 case OP_IF_I:
828 RUNAWAYCHECK();
829 if (OPA->_int)
830 st += (sofs)st->b - 1; // offset the s++
831 break;
832
833 case OP_GOTO:
834 RUNAWAYCHECK();
835 st += (sofs)st->a - 1; // offset the s++
836 break;
837
838 case OP_CALL8H:
839 case OP_CALL7H:
840 case OP_CALL6H:
841 case OP_CALL5H:
842 case OP_CALL4H:
843 case OP_CALL3H:
844 case OP_CALL2H:
845 G_VECTOR(OFS_PARM1)[0] = OPC->_vector[0];
846 G_VECTOR(OFS_PARM1)[1] = OPC->_vector[1];
847 G_VECTOR(OFS_PARM1)[2] = OPC->_vector[2];
848 case OP_CALL1H:
849 G_VECTOR(OFS_PARM0)[0] = OPB->_vector[0];
850 G_VECTOR(OFS_PARM0)[1] = OPB->_vector[1];
851 G_VECTOR(OFS_PARM0)[2] = OPB->_vector[2];
852
853 case OP_CALL8:
854 case OP_CALL7:
855 case OP_CALL6:
856 case OP_CALL5:
857 case OP_CALL4:
858 case OP_CALL3:
859 case OP_CALL2:
860 case OP_CALL1:
861 case OP_CALL0:
862 {
863 int callerprogs;
864 int newpr;
865 unsigned int fnum;
866 RUNAWAYCHECK();
867 prinst.pr_xstatement = st-pr_statements;
868
869 if (op > OP_CALL8)
870 progfuncs->funcs.callargc = op - (OP_CALL1H-1);
871 else
872 progfuncs->funcs.callargc = op - OP_CALL0;
873 fnum = OPA->function;
874
875 glob = NULL; //try to derestrict it.
876
877 callerprogs=prinst.pr_typecurrent; //so we can revert to the right caller.
878 newpr = (fnum & 0xff000000)>>24; //this is the progs index of the callee
879 fnum &= ~0xff000000; //the callee's function index.
880
881 //if it's an external call, switch now (before any function pointers are used)
882 errorif (!PR_SwitchProgsParms(progfuncs, newpr) || !fnum || fnum > pr_progs->numfunctions)
883 {
884 char *msg = fnum?"OP_CALL references invalid function in %s\n":"NULL function from qc (inside %s).\n";
885 PR_SwitchProgsParms(progfuncs, callerprogs);
886
887 glob = pr_globals;
888 if (!progfuncs->funcs.debug_trace)
889 QCFAULT(&progfuncs->funcs, msg, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
890
891 //skip the instruction if they just try stepping over it anyway.
892 PR_StackTrace(&progfuncs->funcs, 0);
893 externs->Printf(msg, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
894
895 pr_globals[OFS_RETURN] = 0;
896 pr_globals[OFS_RETURN+1] = 0;
897 pr_globals[OFS_RETURN+2] = 0;
898 break;
899 }
900
901 newf = &pr_cp_functions[fnum & ~0xff000000];
902
903 if (newf->first_statement <= 0)
904 { // negative statements are built in functions
905 /*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*/
906 if (prinst.pr_typecurrent != 0)
907 {
908 //builtins quite hackily refer to only a single global.
909 //for builtins to affect the globals of other progs, we need to first switch to the progs that it will affect, so they'll be correct when we switch back
911 }
912 i = -newf->first_statement;
913 if (i < externs->numglobalbuiltins)
914 {
915#ifndef QCGC
916 prinst.numtempstringsstack = prinst.numtempstrings;
917#endif
918 (*externs->globalbuiltins[i]) (&progfuncs->funcs, (struct globalvars_s *)current_progstate->globals);
919
920 //in case ed_alloc was called
921 num_edicts = sv_num_edicts;
922 }
923 else
924 PR_RunError (&progfuncs->funcs, "Bad builtin call number - %i", -newf->first_statement);
926
927 //decide weather non debugger wants to start debugging.
928 return prinst.pr_xstatement;
929 }
930 s = PR_EnterFunction (progfuncs, newf, callerprogs);
931 st = &pr_statements[s];
932 }
933
934 //resume at the new statement, which might be in a different progs
935 return s;
936
937 case OP_DONE:
938 case OP_RETURN:
939
940 RUNAWAYCHECK();
941
942 glob[OFS_RETURN] = glob[st->a];
943 glob[OFS_RETURN+1] = glob[st->a+1];
944 glob[OFS_RETURN+2] = glob[st->a+2];
945
946 s = PR_LeaveFunction (progfuncs);
947 st = &pr_statements[s];
948 if (prinst.pr_depth == prinst.exitdepth)
949 {
950 prinst.pr_xstatement = s;
951 return -1; // all done
952 }
953 return s;
954// break;
955
956 case OP_STATE:
957 externs->stateop(&progfuncs->funcs, OPA->_float, OPB->function);
958 break;
959
960 case OP_ADD_I:
961 OPC->_int = OPA->_int + OPB->_int;
962 break;
963 case OP_ADD_FI:
964 OPC->_float = OPA->_float + (float)OPB->_int;
965 break;
966 case OP_ADD_IF:
967 OPC->_float = (float)OPA->_int + OPB->_float;
968 break;
969
970 case OP_SUB_I:
971 OPC->_int = OPA->_int - OPB->_int;
972 break;
973 case OP_SUB_FI:
974 OPC->_float = OPA->_float - (float)OPB->_int;
975 break;
976 case OP_SUB_IF:
977 OPC->_float = (float)OPA->_int - OPB->_float;
978 break;
979
980 case OP_CONV_ITOF:
981 OPC->_float = (float)OPA->_int;
982 break;
983 case OP_CONV_FTOI:
984 OPC->_int = (int)OPA->_float;
985 break;
986
987 case OP_LOADP_ITOF:
988 i = OPA->_int;
989 errorif (QCPOINTERREADFAIL(i, sizeof(char)))
990 {
991 QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int);
992 }
993 ptr = QCPOINTERM(i);
994 OPC->_float = (float)ptr->_int;
995 break;
996
997 case OP_LOADP_FTOI:
998 i = OPA->_int;
999 errorif (QCPOINTERREADFAIL(i, sizeof(char)))
1000 {
1001 QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int);
1002 }
1003 ptr = QCPOINTERM(i);
1004 OPC->_int = (int)ptr->_float;
1005 break;
1006
1007 case OP_BITAND_I:
1008 OPC->_int = (OPA->_int & OPB->_int);
1009 break;
1010
1011 case OP_BITOR_I:
1012 OPC->_int = (OPA->_int | OPB->_int);
1013 break;
1014
1015 case OP_MUL_I:
1016 OPC->_int = OPA->_int * OPB->_int;
1017 break;
1018 case OP_DIV_I:
1019 if (OPB->_int == 0) //no division by zero allowed...
1020 OPC->_int = 0;
1021 else
1022 OPC->_int = OPA->_int / OPB->_int;
1023 break;
1024 case OP_DIV_U:
1025 if (OPB->_uint == 0) //no division by zero allowed...
1026 OPC->_uint = 0;
1027 else
1028 OPC->_uint = OPA->_uint / OPB->_uint;
1029 break;
1030 case OP_EQ_I:
1031 OPC->_int = (OPA->_int == OPB->_int);
1032 break;
1033 case OP_NE_I:
1034 OPC->_int = (OPA->_int != OPB->_int);
1035 break;
1036
1037
1038 //array/structure reading/writing.
1039 case OP_GLOBALADDRESS:
1040 OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int); /*pointer arithmatic*/
1041 break;
1042 case OP_ADD_PIW: //pointer to 32 bit (remember to *3 for vectors)
1043 OPC->_int = OPA->_int + OPB->_int*sizeof(float);
1044 break;
1045
1046 case OP_LOADA_I:
1047 case OP_LOADA_F:
1048 case OP_LOADA_FLD:
1049 case OP_LOADA_ENT:
1050 case OP_LOADA_S:
1051 case OP_LOADA_FNC:
1052 i = st->a + OPB->_int;
1053 if ((size_t)i >= (size_t)(current_progstate->globals_bytes>>2))
1054 {
1055 QCFAULT(&progfuncs->funcs, "bad array read in %s (index %i)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int);
1056 }
1057 else
1058 OPC->_int = ((eval_t *)&glob[i])->_int;
1059 break;
1060 case OP_LOADA_I64:
1061 i = st->a + OPB->_int;
1062 if ((size_t)i >= (size_t)(current_progstate->globals_bytes>>2)-1u)
1063 {
1064 QCFAULT(&progfuncs->funcs, "bad array read in %s (index %i)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int);
1065 }
1066 else
1067 OPC->i64 = ((eval_t *)&glob[i])->i64;
1068 break;
1069 case OP_LOADA_V:
1070 i = st->a + OPB->_int;
1071 if ((size_t)(i) >= (size_t)(current_progstate->globals_bytes>>2)-2u)
1072 {
1073 QCFAULT(&progfuncs->funcs, "bad array read in %s (index %i)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int);
1074 }
1075 else
1076 {
1077 OPC->_vector[0] = ((eval_t *)&glob[i])->_vector[0];
1078 OPC->_vector[1] = ((eval_t *)&glob[i])->_vector[1];
1079 OPC->_vector[2] = ((eval_t *)&glob[i])->_vector[2];
1080 }
1081 break;
1082
1083
1084
1085 case OP_ADD_SF: //(char*)c = (char*)a + (float)b
1086 OPC->_int = OPA->_int + (int)OPB->_float;
1087 break;
1088 case OP_SUB_S: //(float)c = (char*)a - (char*)b
1089 OPC->_int = OPA->_int - OPB->_int;
1090 break;
1091 case OP_LOADP_C: //load character from a string/pointer
1092 i = (unsigned int)OPA->_int + (int)OPB->_float;
1093 errorif (QCPOINTERREADFAIL(i, sizeof(char)))
1094 {
1095 if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_float, sizeof(char))))
1096 {
1097 if (i == -1)
1098 {
1099 OPC->_float = 0;
1100 break;
1101 }
1102 QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr);
1103 }
1104 }
1105 else
1106 ptr = QCPOINTERM(i);
1107 OPC->_float = *(unsigned char *)ptr;
1108 break;
1109 case OP_LOADP_B: //load character from a string/pointer
1110 i = (unsigned int)OPA->_int + (int)OPB->_int;
1111 errorif (QCPOINTERREADFAIL(i, sizeof(pbyte)))
1112 {
1113 if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int, sizeof(pbyte))))
1114 {
1115 if (i == -1)
1116 {
1117 OPC->_int = 0;
1118 break;
1119 }
1120 QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr);
1121 }
1122 }
1123 else
1124 ptr = QCPOINTERM(i);
1125 OPC->_int = *(pbyte *)ptr;
1126 break;
1127 case OP_LOADP_I:
1128 case OP_LOADP_F:
1129 case OP_LOADP_FLD:
1130 case OP_LOADP_ENT:
1131 case OP_LOADP_S:
1132 case OP_LOADP_FNC:
1133 i = OPA->_int + OPB->_int*4;
1134 errorif (QCPOINTERREADFAIL(i, sizeof(int)))
1135 {
1136 if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int*4, sizeof(int))))
1137 {
1138 if (i == -1)
1139 {
1140 OPC->_int = 0;
1141 break;
1142 }
1143 QCFAULT(&progfuncs->funcs, "bad pointer read in %s (from %#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i);
1144 }
1145 }
1146 else
1147 ptr = QCPOINTERM(i);
1148 OPC->_int = ptr->_int;
1149 break;
1150
1151 case OP_LOADP_I64:
1152 i = OPA->_int + OPB->_int*4;
1153 errorif (QCPOINTERREADFAIL(i, sizeof(pint64_t)))
1154 {
1155 if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int*4, sizeof(pint64_t))))
1156 {
1157 if (i == -1)
1158 {
1159 OPC->i64 = 0;
1160 break;
1161 }
1162 QCFAULT(&progfuncs->funcs, "bad pointer read in %s (from %#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i);
1163 }
1164 }
1165 else
1166 ptr = QCPOINTERM(i);
1167 OPC->i64 = ptr->i64;
1168 break;
1169
1170 case OP_LOADP_V:
1171 i = OPA->_int + OPB->_int*4; //NOTE: inconsistant, but a bit more practical for the qcc when structs etc are involved
1172 errorif (QCPOINTERREADFAIL(i, sizeof(pvec3_t)))
1173 {
1174 if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int*4, sizeof(pvec3_t))))
1175 {
1176 if (i == -1)
1177 {
1178 OPC->_vector[0] = 0;
1179 OPC->_vector[1] = 0;
1180 OPC->_vector[2] = 0;
1181 break;
1182 }
1183 QCFAULT(&progfuncs->funcs, "bad pointer read in %s (from %#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i);
1184 }
1185 }
1186 else
1187 ptr = QCPOINTERM(i);
1188 OPC->_vector[0] = ptr->_vector[0];
1189 OPC->_vector[1] = ptr->_vector[1];
1190 OPC->_vector[2] = ptr->_vector[2];
1191 break;
1192
1193 case OP_BITXOR_I:
1194 OPC->_int = OPA->_int ^ OPB->_int;
1195 break;
1196 case OP_RSHIFT_I:
1197 OPC->_int = OPA->_int >> OPB->_int;
1198 break;
1199 case OP_RSHIFT_U:
1200 OPC->_uint = OPA->_uint >> OPB->_uint;
1201 break;
1202 case OP_LSHIFT_I:
1203 OPC->_int = OPA->_int << OPB->_int;
1204 break;
1205
1206 //hexen2 arrays contain a prefix global set to (arraysize-1) inserted before the actual array data
1207 //for vectors, this prefix is the number of vectors rather than the number of globals. this can cause issues with using OP_FETCH_GBL_V within structs.
1208 case OP_FETCH_GBL_F:
1209 case OP_FETCH_GBL_S:
1210 case OP_FETCH_GBL_E:
1211 case OP_FETCH_GBL_FNC:
1212 i = OPB->_float;
1213 errorif((unsigned)i > (unsigned)((eval_t *)&glob[st->a-1])->_int)
1214 {
1215 prinst.pr_xstatement = st-pr_statements;
1216 PR_RunError(&progfuncs->funcs, "array index out of bounds: %s[%d] (max %d)", PR_GlobalStringNoContents(progfuncs, st->a), i, ((eval_t *)&glob[st->a-1])->_int);
1217 }
1218 OPC->_int = ((eval_t *)&glob[st->a + i])->_int;
1219 break;
1220 case OP_FETCH_GBL_V:
1221 i = OPB->_float;
1222 errorif((unsigned)i > (unsigned)((eval_t *)&glob[st->a-1])->_int)
1223 {
1224 prinst.pr_xstatement = st-pr_statements;
1225 PR_RunError(&progfuncs->funcs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
1226 }
1227 ptr = (eval_t *)&glob[st->a + i*3];
1228 OPC->_vector[0] = ptr->_vector[0];
1229 OPC->_vector[1] = ptr->_vector[1];
1230 OPC->_vector[2] = ptr->_vector[2];
1231 break;
1232
1233 case OP_CSTATE:
1234 externs->cstateop(&progfuncs->funcs, OPA->_float, OPB->_float, prinst.pr_xfunction - pr_cp_functions);
1235 break;
1236
1237 case OP_CWSTATE:
1238 externs->cwstateop(&progfuncs->funcs, OPA->_float, OPB->_float, prinst.pr_xfunction - pr_cp_functions);
1239 break;
1240
1241 case OP_THINKTIME:
1242 externs->thinktimeop(&progfuncs->funcs, (struct edict_s *)PROG_TO_EDICT_UB(progfuncs, OPA->edict), OPB->_float);
1243 break;
1244
1245 case OP_MULSTORE_F:
1246 /*OPC->_float = */OPB->_float *= OPA->_float;
1247 break;
1248 case OP_MULSTORE_VF:
1249 tmpf = OPA->_float; //don't break on vec*=vec_x;
1250 /*OPC->_vector[0] = */OPB->_vector[0] *= tmpf;
1251 /*OPC->_vector[1] = */OPB->_vector[1] *= tmpf;
1252 /*OPC->_vector[2] = */OPB->_vector[2] *= tmpf;
1253 break;
1254 case OP_MULSTOREP_F:
1255 i = OPB->_int;
1256 errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
1257 {
1258 prinst.pr_xstatement = st-pr_statements;
1259 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1260 }
1261 ptr = QCPOINTERM(i);
1262 OPC->_float = ptr->_float *= OPA->_float;
1263 break;
1264 case OP_MULSTOREP_VF:
1265 i = OPB->_int;
1266 errorif (QCPOINTERWRITEFAIL(i, sizeof(pvec3_t)))
1267 {
1268 prinst.pr_xstatement = st-pr_statements;
1269 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1270 }
1271 ptr = QCPOINTERM(i);
1272 tmpf = OPA->_float; //don't break on vec*=vec_x;
1273 OPC->_vector[0] = ptr->_vector[0] *= tmpf;
1274 OPC->_vector[1] = ptr->_vector[1] *= tmpf;
1275 OPC->_vector[2] = ptr->_vector[2] *= tmpf;
1276 break;
1277 case OP_DIVSTORE_F:
1278 /*OPC->_float = */OPB->_float /= OPA->_float;
1279 break;
1280 case OP_DIVSTOREP_F:
1281 i = OPB->_int;
1282 errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
1283 {
1284 prinst.pr_xstatement = st-pr_statements;
1285 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1286 }
1287 ptr = QCPOINTERM(i);
1288 OPC->_float = ptr->_float /= OPA->_float;
1289 break;
1290 case OP_ADDSTORE_F:
1291 /*OPC->_float = */OPB->_float += OPA->_float;
1292 break;
1293 case OP_ADDSTORE_V:
1294 /*OPC->_vector[0] =*/ OPB->_vector[0] += OPA->_vector[0];
1295 /*OPC->_vector[1] =*/ OPB->_vector[1] += OPA->_vector[1];
1296 /*OPC->_vector[2] =*/ OPB->_vector[2] += OPA->_vector[2];
1297 break;
1298 case OP_ADDSTOREP_F:
1299 i = OPB->_int;
1300 errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
1301 {
1302 prinst.pr_xstatement = st-pr_statements;
1303 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1304 }
1305 ptr = QCPOINTERM(i);
1306 OPC->_float = ptr->_float += OPA->_float;
1307 break;
1308 case OP_ADDSTOREP_V:
1309 i = OPB->_int;
1310 errorif (QCPOINTERWRITEFAIL(i, sizeof(pvec3_t)))
1311 {
1312 prinst.pr_xstatement = st-pr_statements;
1313 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1314 }
1315 ptr = QCPOINTERM(i);
1316 OPC->_vector[0] = ptr->_vector[0] += OPA->_vector[0];
1317 OPC->_vector[1] = ptr->_vector[1] += OPA->_vector[1];
1318 OPC->_vector[2] = ptr->_vector[2] += OPA->_vector[2];
1319 break;
1320 case OP_SUBSTORE_F:
1321 /*OPC->_float = */OPB->_float -= OPA->_float;
1322 break;
1323 case OP_SUBSTORE_V:
1324 /*OPC->_vector[0] = */OPB->_vector[0] -= OPA->_vector[0];
1325 /*OPC->_vector[1] = */OPB->_vector[1] -= OPA->_vector[1];
1326 /*OPC->_vector[2] = */OPB->_vector[2] -= OPA->_vector[2];
1327 break;
1328 case OP_SUBSTOREP_F:
1329 i = OPB->_int;
1330 errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
1331 {
1332 prinst.pr_xstatement = st-pr_statements;
1333 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1334 }
1335 ptr = QCPOINTERM(i);
1336 OPC->_float = ptr->_float -= OPA->_float;
1337 break;
1338 case OP_SUBSTOREP_V:
1339 i = OPB->_int;
1340 errorif (QCPOINTERWRITEFAIL(i, sizeof(pvec3_t)))
1341 {
1342 prinst.pr_xstatement = st-pr_statements;
1343 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1344 }
1345 ptr = QCPOINTERM(i);
1346 OPC->_vector[0] = ptr->_vector[0] -= OPA->_vector[0];
1347 OPC->_vector[1] = ptr->_vector[1] -= OPA->_vector[1];
1348 OPC->_vector[2] = ptr->_vector[2] -= OPA->_vector[2];
1349 break;
1350 case OP_BITSETSTORE_F:
1351 OPB->_float = (int)OPB->_float | (int)OPA->_float;
1352 break;
1353 case OP_BITSETSTOREP_F:
1354 i = OPB->_int;
1355 errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
1356 {
1357 prinst.pr_xstatement = st-pr_statements;
1358 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1359 }
1360 ptr = QCPOINTERM(i);
1361 ptr->_float = (int)ptr->_float | (int)OPA->_float;
1362 break;
1363 case OP_BITCLRSTORE_F:
1364 OPB->_float = (int)OPB->_float & ~(int)OPA->_float;
1365 break;
1366 case OP_BITCLRSTOREP_F:
1367 i = OPB->_int;
1368 errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
1369 {
1370 prinst.pr_xstatement = st-pr_statements;
1371 PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
1372 }
1373 ptr = QCPOINTERM(i);
1374 ptr->_float = (int)ptr->_float & ~(int)OPA->_float;
1375 break;
1376
1377 //for scaler randoms, prevent the random value from ever reaching 1
1378 //this avoids issues when array[random()*array.length]
1379 case OP_RAND0:
1380 OPC->_float = (rand ()&0x7fff) / ((float)0x8000);
1381 break;
1382 case OP_RAND1:
1383 OPC->_float = (rand ()&0x7fff) / ((float)0x8000)*OPA->_float;
1384 break;
1385 case OP_RAND2: //backwards range shouldn't matter (except that it is b that is never reached, rather than the higher of the two)
1386 OPC->_float = OPA->_float + (rand ()&0x7fff) / ((float)0x8000)*(OPB->_float-OPA->_float);
1387 break;
1388 //random vectors DO result in 0 to 1 inclusive, to try to ensure a more balanced range
1389 case OP_RANDV0:
1390 OPC->_vector[0] = (rand ()&0x7fff) / ((float)0x7fff);
1391 OPC->_vector[1] = (rand ()&0x7fff) / ((float)0x7fff);
1392 OPC->_vector[2] = (rand ()&0x7fff) / ((float)0x7fff);
1393 break;
1394 case OP_RANDV1:
1395 OPC->_vector[0] = (rand ()&0x7fff) / ((float)0x7fff)*OPA->_vector[0];
1396 OPC->_vector[1] = (rand ()&0x7fff) / ((float)0x7fff)*OPA->_vector[1];
1397 OPC->_vector[2] = (rand ()&0x7fff) / ((float)0x7fff)*OPA->_vector[2];
1398 break;
1399 case OP_RANDV2: //backwards range shouldn't matter
1400 OPC->_vector[0] = OPA->_vector[0] + (rand ()&0x7fff) / ((float)0x7fff)*(OPB->_vector[0]-OPA->_vector[0]);
1401 OPC->_vector[1] = OPA->_vector[1] + (rand ()&0x7fff) / ((float)0x7fff)*(OPB->_vector[1]-OPA->_vector[1]);
1402 OPC->_vector[2] = OPA->_vector[2] + (rand ()&0x7fff) / ((float)0x7fff)*(OPB->_vector[2]-OPA->_vector[2]);
1403 break;
1404
1405 case OP_SWITCH_F:
1406 case OP_SWITCH_V:
1407 case OP_SWITCH_S:
1408 case OP_SWITCH_E:
1409 case OP_SWITCH_FNC:
1410 //the case opcodes depend upon the preceding switch.
1411 //otherwise the switch itself is much like a goto
1412 //don't embed the case/caserange checks directly into the switch so that custom caseranges can be potentially be implemented with hybrid emulation.
1413 switchcomparison = op - OP_SWITCH_F;
1414 switchref = OPA;
1415 RUNAWAYCHECK();
1416 st += (sofs)st->b - 1; // offset the s++
1417 break;
1418 case OP_SWITCH_I:
1419 //the case opcodes depend upon the preceding switch.
1420 //otherwise the switch itself is much like a goto
1421 //don't embed the case/caserange checks directly into the switch so that custom caseranges can be potentially be implemented with hybrid emulation.
1422 switchcomparison = OP_SWITCH_E - OP_SWITCH_F;
1423 switchref = OPA;
1424 RUNAWAYCHECK();
1425 st += (sofs)st->b - 1; // offset the s++
1426 break;
1427 case OP_CASE:
1428 //if the comparison is true, jump (back up) to the relevent code block
1429 if (casecmp[switchcomparison](progfuncs, switchref, OPA))
1430 {
1431 RUNAWAYCHECK();
1432 st += (sofs)st->b-1; // -1 to offset the s++
1433 }
1434 break;
1435 case OP_CASERANGE:
1436 //if the comparison is true, jump (back up) to the relevent code block
1437 if (casecmprange[switchcomparison](progfuncs, switchref, OPA, OPB))
1438 {
1439 RUNAWAYCHECK();
1440 st += (sofs)st->c-1; // -1 to offset the s++
1441 }
1442 break;
1443
1444
1445
1446
1447
1448
1449
1450
1451 case OP_BITAND_IF:
1452 OPC->_int = (OPA->_int & (int)OPB->_float);
1453 break;
1454 case OP_BITOR_IF:
1455 OPC->_int = (OPA->_int | (int)OPB->_float);
1456 break;
1457 case OP_BITAND_FI:
1458 OPC->_int = ((int)OPA->_float & OPB->_int);
1459 break;
1460 case OP_BITOR_FI:
1461 OPC->_int = ((int)OPA->_float | OPB->_int);
1462 break;
1463
1464 case OP_MUL_IF:
1465 OPC->_float = (OPA->_int * OPB->_float);
1466 break;
1467 case OP_MUL_FI:
1468 OPC->_float = (OPA->_float * OPB->_int);
1469 break;
1470
1471 case OP_MUL_VI:
1472 tmpi = OPB->_int;
1473 OPC->_vector[0] = OPA->_vector[0] * tmpi;
1474 OPC->_vector[1] = OPA->_vector[1] * tmpi;
1475 OPC->_vector[2] = OPA->_vector[2] * tmpi;
1476 break;
1477 case OP_MUL_IV:
1478 tmpi = OPA->_int;
1479 OPC->_vector[0] = tmpi * OPB->_vector[0];
1480 OPC->_vector[1] = tmpi * OPB->_vector[1];
1481 OPC->_vector[2] = tmpi * OPB->_vector[2];
1482 break;
1483
1484 case OP_DIV_IF:
1485 OPC->_float = (OPA->_int / OPB->_float);
1486 break;
1487 case OP_DIV_FI:
1488 OPC->_float = (OPA->_float / OPB->_int);
1489 break;
1490
1491 /*case OP_MOD_I:
1492 OPC->_int = (OPA->_int % OPB->_int);
1493 break;
1494 case OP_MOD_U:
1495 OPC->_uint = (OPA->_uint % OPB->_uint);
1496 break;
1497 case OP_MOD_F:
1498 OPC->_float = OPA->_float - OPB->_float*(int)(OPA->_float/OPB->_float);
1499 break;
1500 case OP_MOD_V:
1501 OPC->_vector[0] = OPA->_vector[0] - OPB->_vector[0]*(int)(OPA->_vector[0]/OPB->_vector[0]);
1502 OPC->_vector[1] = OPA->_vector[1] - OPB->_vector[1]*(int)(OPA->_vector[1]/OPB->_vector[1]);
1503 OPC->_vector[2] = OPA->_vector[2] - OPB->_vector[2]*(int)(OPA->_vector[2]/OPB->_vector[2]);
1504 break;*/
1505
1506
1507 case OP_AND_I:
1508 OPC->_int = (OPA->_int && OPB->_int);
1509 break;
1510 case OP_OR_I:
1511 OPC->_int = (OPA->_int || OPB->_int);
1512 break;
1513
1514 case OP_AND_IF:
1515 OPC->_int = (OPA->_int && OPB->_float);
1516 break;
1517 case OP_OR_IF:
1518 OPC->_int = (OPA->_int || OPB->_float);
1519 break;
1520
1521 case OP_AND_FI:
1522 OPC->_int = (OPA->_float && OPB->_int);
1523 break;
1524 case OP_OR_FI:
1525 OPC->_int = (OPA->_float || OPB->_int);
1526 break;
1527
1528 case OP_NE_IF:
1529 OPC->_int = (OPA->_int != OPB->_float);
1530 break;
1531 case OP_NE_FI:
1532 OPC->_int = (OPA->_float != OPB->_int);
1533 break;
1534
1535 case OP_GADDRESS: //return glob[aint+bfloat]
1536 //this instruction is not implemented due to the weirdness of it.
1537 //its theoretically a more powerful load... but untyped?
1538 //or is it meant to be an LEA instruction (that could simply be switched with OP_GLOAD_I)
1539 prinst.pr_xstatement = st-pr_statements;
1540 PR_RunError (&progfuncs->funcs, "OP_GADDRESS not implemented (found in %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
1541 break;
1542 case OP_GLOAD_I:
1543 case OP_GLOAD_F:
1544 case OP_GLOAD_FLD:
1545 case OP_GLOAD_ENT:
1546 case OP_GLOAD_S:
1547 case OP_GLOAD_FNC:
1548 errorif (OPA->_int < 0 || OPA->_int >= (current_progstate->globals_bytes>>2))
1549 {
1550 prinst.pr_xstatement = st-pr_statements;
1551 PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int, current_progstate->globals_bytes>>2);
1552 }
1553 ptr = ((eval_t *)&glob[OPA->_int]);
1554 OPC->_int = ptr->_int;
1555 break;
1556 case OP_GLOAD_V:
1557 errorif (OPA->_int < 0 || OPA->_int >= (current_progstate->globals_bytes>>2)-2u)
1558 {
1559 prinst.pr_xstatement = st-pr_statements;
1560 PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int, current_progstate->globals_bytes>>2);
1561 }
1562 ptr = ((eval_t *)&glob[OPA->_int]);
1563 OPC->_vector[0] = ptr->_vector[0];
1564 OPC->_vector[1] = ptr->_vector[1];
1565 OPC->_vector[2] = ptr->_vector[2];
1566 break;
1567 case OP_GSTOREP_I:
1568 case OP_GSTOREP_F:
1569 case OP_GSTOREP_ENT:
1570 case OP_GSTOREP_FLD:
1571 case OP_GSTOREP_S:
1572 case OP_GSTOREP_FNC:
1573 errorif (OPB->_int < 0 || OPB->_int >= (current_progstate->globals_bytes>>2))
1574 {
1575 prinst.pr_xstatement = st-pr_statements;
1576 PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int, current_progstate->globals_bytes>>2);
1577 }
1578 ptr = ((eval_t *)&glob[OPB->_int]);
1579 ptr->_int = OPA->_int;
1580 break;
1581 case OP_GSTOREP_V:
1582 errorif (OPB->_int < 0 || OPB->_int >= (current_progstate->globals_bytes>>2)-2u)
1583 {
1584 prinst.pr_xstatement = st-pr_statements;
1585 PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int, current_progstate->globals_bytes>>2);
1586 }
1587 ptr = ((eval_t *)&glob[OPB->_int]);
1588 ptr->_vector[0] = OPA->_vector[0];
1589 ptr->_vector[1] = OPA->_vector[1];
1590 ptr->_vector[2] = OPA->_vector[2];
1591 break;
1592
1593 case OP_BOUNDCHECK:
1594 errorif ((unsigned int)OPA->_int < (unsigned int)st->c || (unsigned int)OPA->_int >= (unsigned int)st->b)
1595 {
1596 externs->Printf("Progs boundcheck failed. Value is %i. Must be %u<=value<%u\n", OPA->_int, st->c, st->b);
1597 QCFAULT(&progfuncs->funcs, "Progs boundcheck failed. Value is %i. Must be %u<=value<%u\n", OPA->_int, st->c, st->b);
1598/* s=ShowStepf(progfuncs, st - pr_statements, "Progs boundcheck failed. Value is %i. Must be between %u and %u\n", OPA->_int, st->c, st->b);
1599 if (st == pr_statements + s)
1600 PR_RunError(&progfuncs->funcs, "unable to resume boundcheck");
1601 st = pr_statements + s;
1602 return s;
1603*/ }
1604 break;
1605 case OP_PUSH:
1606 OPC->_int = ENGINEPOINTER(&prinst.localstack[prinst.localstack_used+prinst.spushed]);
1607 prinst.spushed += OPA->_int;
1608 if (prinst.spushed + prinst.localstack_used >= LOCALSTACK_SIZE)
1609 {
1610 prinst.spushed = 0;
1611 prinst.pr_xstatement = st-pr_statements;
1612 PR_RunError(&progfuncs->funcs, "Progs pushed too much");
1613 }
1614 break;
1615/* case OP_POP:
1616 pr_spushed -= OPA->_int;
1617 if (pr_spushed < 0)
1618 {
1619 pr_spushed = 0;
1620 prinst.pr_xstatement = st-pr_statements;
1621 PR_RunError(progfuncs, "Progs poped more than it pushed");
1622 }
1623 break;
1624*/
1625
1626
1627 //[u]int64+double opcodes
1628 case OP_ADD_I64: OPC->i64 = OPA->i64 + OPB->i64; break;
1629 case OP_SUB_I64: OPC->i64 = OPA->i64 - OPB->i64; break;
1630 case OP_MUL_I64: OPC->i64 = OPA->i64 * OPB->i64; break;
1631 case OP_DIV_I64: OPC->i64 = OPA->i64 / OPB->i64; break;
1632 case OP_BITAND_I64: OPC->i64 = OPA->i64 & OPB->i64; break;
1633 case OP_BITOR_I64: OPC->i64 = OPA->i64 | OPB->i64; break;
1634 case OP_BITXOR_I64: OPC->i64 = OPA->i64 ^ OPB->i64; break;
1635 case OP_LSHIFT_I64I: OPC->i64 = OPA->i64 << OPB->_int; break;
1636 case OP_RSHIFT_I64I: OPC->i64 = OPA->i64 >> OPB->_int; break;
1637 case OP_LT_I64: OPC->_int = OPA->i64 < OPB->i64; break;
1638 case OP_LE_I64: OPC->_int = OPA->i64 <= OPB->i64; break;
1639 case OP_EQ_I64: OPC->_int = OPA->i64 == OPB->i64; break;
1640 case OP_NE_I64: OPC->_int = OPA->i64 != OPB->i64; break;
1641 case OP_LT_U64: OPC->_int = OPA->u64 < OPB->u64; break;
1642 case OP_LE_U64: OPC->_int = OPA->u64 <= OPB->u64; break;
1643 case OP_DIV_U64: OPC->u64 = OPA->u64 / OPB->u64; break;
1644 case OP_RSHIFT_U64I: OPC->u64 = OPA->u64 >> OPB->_int; break;
1645 case OP_STORE_I64: OPB->i64 = OPA->i64; break;
1646 case OP_CONV_UI64: OPC->i64 = OPA->_uint; break;
1647 case OP_CONV_II64: OPC->i64 = OPA->_int; break;
1648 case OP_CONV_I64I: OPC->_int = OPA->i64; break;
1649 case OP_CONV_FD: OPC->_double = OPA->_float; break;
1650 case OP_CONV_DF: OPC->_float = OPA->_double; break;
1651 case OP_CONV_I64F: OPC->_float = OPA->i64; break;
1652 case OP_CONV_FI64: OPC->i64 = OPA->_float; break;
1653 case OP_CONV_I64D: OPC->_double = OPA->i64; break;
1654 case OP_CONV_DI64: OPC->i64 = OPA->_double; break;
1655 case OP_ADD_D: OPC->_double = OPA->_double + OPB->_double; break;
1656 case OP_SUB_D: OPC->_double = OPA->_double - OPB->_double; break;
1657 case OP_MUL_D: OPC->_double = OPA->_double * OPB->_double; break;
1658 case OP_DIV_D: OPC->_double = OPA->_double / OPB->_double; break;
1659 case OP_LT_D: OPC->_int = OPA->_double < OPB->_double; break;
1660 case OP_LE_D: OPC->_int = OPA->_double <= OPB->_double; break;
1661 case OP_EQ_D: OPC->_int = OPA->_double == OPB->_double; break;
1662 case OP_NE_D: OPC->_int = OPA->_double != OPB->_double; break;
1663
1664
1665
1666
1667 case OP_UNUSED:
1668 case OP_POP:
1669
1670#ifdef __GNUC__
1671 case OP_NUMREALOPS ... OP_NUMOPS:
1672#endif
1673
1674 safedefault:
1675 if (op & OP_BIT_BREAKPOINT) //break point!
1676 {
1677 op &= ~OP_BIT_BREAKPOINT;
1678 s = st-pr_statements;
1679 if (prinst.pr_xstatement != s)
1680 {
1681 prinst.pr_xstatement = s;
1682 externs->Printf("Break point hit in %s.\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name));
1683 s = ShowStep(progfuncs, s, NULL, false);
1684 st = &pr_statements[s]; //let the user move execution
1685 prinst.pr_xstatement = s = st-pr_statements;
1686 op = st->op & ~OP_BIT_BREAKPOINT;
1687 }
1688 goto reeval; //reexecute
1689 }
1690 prinst.pr_xstatement = st-pr_statements;
1691 PR_RunError (&progfuncs->funcs, "Bad opcode %i", st->op);
1692 }
1693}
1694
1695
1696#undef reeval
1697#undef st
1698#undef pr_statements
1699#undef fakeop
1700#undef dstatement_t
1701#undef sofs
1702#undef OPCODE
1703
1704#undef ENGINEPOINTER
1705#undef QCPOINTER
1706#undef QCPOINTERM
1707
cvar_t msg
Definition: cl_main.c:159
s
Definition: execloop.h:53
errorif(prinst.watch_ptr &&prinst.watch_ptr->_int !=prinst.watch_old._int)
Definition: execloop.h:55
safeswitch((enum qcop_e) op)
Definition: execloop.h:101
op
Definition: execloop.h:94
st
Definition: execloop.h:91
else if(progfuncs->funcs.debug_trace) s
static CONST PIXELFORMATDESCRIPTOR *static int
Definition: gl_vidnt.c:222
eval_t * PR_GetWriteTempStringPtr(progfuncs_t *progfuncs, string_t str, size_t offset, size_t datasize)
Definition: initlib.c:1081
const char *ASMCALL PR_StringToNative(pubprogfuncs_t *ppf, string_t str)
Definition: initlib.c:1020
eval_t * PR_GetReadTempStringPtr(progfuncs_t *progfuncs, string_t str, size_t offset, size_t datasize)
Definition: initlib.c:1064
qcop_e
Definition: pr_comp.h:51
@ OP_SUB_FI
Definition: pr_comp.h:208
@ OP_STOREP_S
Definition: pr_comp.h:98
@ OP_IF_I
Definition: pr_comp.h:109
@ OP_NE_E
Definition: pr_comp.h:72
@ OP_LT_D
Definition: pr_comp.h:396
@ OP_LOADA_ENT
Definition: pr_comp.h:245
@ OP_AND_I
Definition: pr_comp.h:298
@ OP_LOADA_I64
Definition: pr_comp.h:377
@ OP_LE_FI
Definition: pr_comp.h:271
@ OP_CONV_DF
Definition: pr_comp.h:384
@ OP_CALL7H
Definition: pr_comp.h:195
@ OP_SUBSTORE_V
Definition: pr_comp.h:145
@ OP_BITSETSTOREP_F
Definition: pr_comp.h:161
@ OP_ADD_I
Definition: pr_comp.h:203
@ OP_FETCH_GBL_F
Definition: pr_comp.h:149
@ OP_GSTOREP_FLD
Definition: pr_comp.h:311
@ OP_STORE_V
Definition: pr_comp.h:90
@ OP_GSTOREP_FNC
Definition: pr_comp.h:313
@ OP_ADDSTORE_F
Definition: pr_comp.h:139
@ OP_RANDV2
Definition: pr_comp.h:170
@ OP_LOADP_B
Definition: pr_comp.h:343
@ OP_RSHIFT_U
Definition: pr_comp.h:350
@ OP_SUB_F
Definition: pr_comp.h:60
@ OP_MUL_I64
Definition: pr_comp.h:355
@ OP_LOAD_ENT
Definition: pr_comp.h:83
@ OP_LOAD_F
Definition: pr_comp.h:80
@ OP_IFNOT_F
Definition: pr_comp.h:333
@ OP_LT_FI
Definition: pr_comp.h:273
@ OP_GE_I
Definition: pr_comp.h:262
@ OP_DIV_I
Definition: pr_comp.h:224
@ OP_LT_I
Definition: pr_comp.h:263
@ OP_LOAD_FLD
Definition: pr_comp.h:84
@ OP_ADD_SF
Definition: pr_comp.h:281
@ OP_MUL_VI
Definition: pr_comp.h:290
@ OP_BITOR_F
Definition: pr_comp.h:126
@ OP_STOREP_V
Definition: pr_comp.h:97
@ OP_GLOAD_ENT
Definition: pr_comp.h:319
@ OP_GLOAD_F
Definition: pr_comp.h:317
@ OP_BITXOR_I
Definition: pr_comp.h:235
@ OP_LOADP_C
Definition: pr_comp.h:284
@ OP_EQ_FI
Definition: pr_comp.h:277
@ OP_CONV_FD
Definition: pr_comp.h:383
@ OP_GSTOREP_I
Definition: pr_comp.h:308
@ OP_FETCH_GBL_E
Definition: pr_comp.h:152
@ OP_MUL_VF
Definition: pr_comp.h:56
@ OP_ADD_IF
Definition: pr_comp.h:205
@ OP_GLOAD_FLD
Definition: pr_comp.h:318
@ OP_NOT_I
Definition: pr_comp.h:231
@ OP_LOADA_I
Definition: pr_comp.h:248
@ OP_GSTOREP_F
Definition: pr_comp.h:309
@ OP_CALL8
Definition: pr_comp.h:119
@ OP_CONV_ITOF
Definition: pr_comp.h:211
@ OP_SUB_I64
Definition: pr_comp.h:354
@ OP_CALL1H
Definition: pr_comp.h:189
@ OP_CWSTATE
Definition: pr_comp.h:156
@ OP_DIV_F
Definition: pr_comp.h:57
@ OP_GT_F
Definition: pr_comp.h:78
@ OP_STOREP_IF
Definition: pr_comp.h:217
@ OP_DIV_IF
Definition: pr_comp.h:292
@ OP_MUL_I
Definition: pr_comp.h:223
@ OP_OR_FI
Definition: pr_comp.h:303
@ OP_CALL6
Definition: pr_comp.h:117
@ OP_RAND0
Definition: pr_comp.h:165
@ OP_SUB_S
Definition: pr_comp.h:282
@ OP_ADD_V
Definition: pr_comp.h:59
@ OP_STOREF_V
Definition: pr_comp.h:336
@ OP_LSHIFT_I64I
Definition: pr_comp.h:360
@ OP_STOREP_ENT
Definition: pr_comp.h:99
@ OP_RSHIFT_I64I
Definition: pr_comp.h:361
@ OP_ADDSTORE_V
Definition: pr_comp.h:140
@ OP_STOREP_FNC
Definition: pr_comp.h:101
@ OP_AND_IF
Definition: pr_comp.h:300
@ OP_CALL5H
Definition: pr_comp.h:193
@ OP_CALL5
Definition: pr_comp.h:116
@ OP_LOADP_V
Definition: pr_comp.h:254
@ OP_NE_FNC
Definition: pr_comp.h:73
@ OP_NUMREALOPS
Definition: pr_comp.h:401
@ OP_RANDV0
Definition: pr_comp.h:168
@ OP_CALL6H
Definition: pr_comp.h:194
@ OP_NE_S
Definition: pr_comp.h:71
@ OP_BITOR_FI
Definition: pr_comp.h:297
@ OP_LT_IF
Definition: pr_comp.h:268
@ OP_STORE_P
Definition: pr_comp.h:250
@ OP_CONV_FTOI
Definition: pr_comp.h:212
@ OP_LOADA_FNC
Definition: pr_comp.h:247
@ OP_LOADP_ENT
Definition: pr_comp.h:256
@ OP_STORE_I
Definition: pr_comp.h:199
@ OP_SUB_V
Definition: pr_comp.h:61
@ OP_BITAND_FI
Definition: pr_comp.h:296
@ OP_SWITCH_V
Definition: pr_comp.h:173
@ OP_MUL_IV
Definition: pr_comp.h:291
@ OP_MULSTORE_F
Definition: pr_comp.h:131
@ OP_NOT_ENT
Definition: pr_comp.h:107
@ OP_CONV_I64F
Definition: pr_comp.h:385
@ OP_GSTOREP_S
Definition: pr_comp.h:312
@ OP_STOREP_I64
Definition: pr_comp.h:374
@ OP_STORE_IF
Definition: pr_comp.h:200
@ OP_RSHIFT_U64I
Definition: pr_comp.h:370
@ OP_GLOAD_I
Definition: pr_comp.h:316
@ OP_OR_IF
Definition: pr_comp.h:301
@ OP_STOREF_I64
Definition: pr_comp.h:375
@ OP_STOREP_FI
Definition: pr_comp.h:218
@ OP_FETCH_GBL_V
Definition: pr_comp.h:150
@ OP_LOADP_I64
Definition: pr_comp.h:378
@ OP_SUBSTORE_F
Definition: pr_comp.h:144
@ OP_STOREP_I
Definition: pr_comp.h:216
@ OP_CALL3H
Definition: pr_comp.h:191
@ OP_SWITCH_I
Definition: pr_comp.h:329
@ OP_DIV_FI
Definition: pr_comp.h:293
@ OP_EQ_FNC
Definition: pr_comp.h:67
@ OP_DIV_D
Definition: pr_comp.h:394
@ OP_STOREP_B
Definition: pr_comp.h:342
@ OP_LE_U
Definition: pr_comp.h:347
@ OP_STOREP_FLD
Definition: pr_comp.h:100
@ OP_SUBSTOREP_V
Definition: pr_comp.h:147
@ OP_BITOR_I64
Definition: pr_comp.h:358
@ OP_MUL_FV
Definition: pr_comp.h:55
@ OP_LOAD_P
Definition: pr_comp.h:251
@ OP_STOREF_F
Definition: pr_comp.h:337
@ OP_ADD_D
Definition: pr_comp.h:391
@ OP_NE_V
Definition: pr_comp.h:70
@ OP_STORE_FLD
Definition: pr_comp.h:93
@ OP_GLOBALADDRESS
Definition: pr_comp.h:239
@ OP_ADD_PIW
Definition: pr_comp.h:240
@ OP_CALL1
Definition: pr_comp.h:112
@ OP_EQ_I
Definition: pr_comp.h:225
@ OP_EQ_V
Definition: pr_comp.h:64
@ OP_THINKTIME
Definition: pr_comp.h:158
@ OP_STORE_ENT
Definition: pr_comp.h:92
@ OP_BITCLRSTORE_F
Definition: pr_comp.h:162
@ OP_MUL_IF
Definition: pr_comp.h:288
@ OP_LE_D
Definition: pr_comp.h:395
@ OP_MUL_D
Definition: pr_comp.h:393
@ OP_LOADP_FTOI
Definition: pr_comp.h:214
@ OP_LE_U64
Definition: pr_comp.h:367
@ OP_GSTOREP_ENT
Definition: pr_comp.h:310
@ OP_GT_IF
Definition: pr_comp.h:269
@ OP_NE_IF
Definition: pr_comp.h:304
@ OP_IF_F
Definition: pr_comp.h:332
@ OP_ADD_F
Definition: pr_comp.h:58
@ OP_CONV_I64D
Definition: pr_comp.h:387
@ OP_NUMOPS
Definition: pr_comp.h:567
@ OP_UNUSED
Definition: pr_comp.h:325
@ OP_LT_F
Definition: pr_comp.h:77
@ OP_FETCH_GBL_S
Definition: pr_comp.h:151
@ OP_RSHIFT_I
Definition: pr_comp.h:236
@ OP_LOADP_S
Definition: pr_comp.h:255
@ OP_MUL_FI
Definition: pr_comp.h:289
@ OP_LOADA_F
Definition: pr_comp.h:242
@ OP_GE_F
Definition: pr_comp.h:76
@ OP_GE_IF
Definition: pr_comp.h:267
@ OP_MULSTOREP_VF
Definition: pr_comp.h:134
@ OP_DIV_U
Definition: pr_comp.h:349
@ OP_CONV_UI64
Definition: pr_comp.h:380
@ OP_LE_I
Definition: pr_comp.h:261
@ OP_LE_F
Definition: pr_comp.h:75
@ OP_LOADP_I
Definition: pr_comp.h:259
@ OP_STOREP_C
Definition: pr_comp.h:283
@ OP_DIVSTORE_F
Definition: pr_comp.h:136
@ OP_BITAND_F
Definition: pr_comp.h:125
@ OP_LE_IF
Definition: pr_comp.h:266
@ OP_STOREF_I
Definition: pr_comp.h:339
@ OP_CALL8H
Definition: pr_comp.h:196
@ OP_ADD_FI
Definition: pr_comp.h:204
@ OP_NE_D
Definition: pr_comp.h:398
@ OP_GE_FI
Definition: pr_comp.h:272
@ OP_IFNOT_S
Definition: pr_comp.h:228
@ OP_AND_F
Definition: pr_comp.h:122
@ OP_CALL0
Definition: pr_comp.h:111
@ OP_LOADP_FLD
Definition: pr_comp.h:257
@ OP_NE_F
Definition: pr_comp.h:69
@ OP_NOT_F
Definition: pr_comp.h:104
@ OP_STORE_S
Definition: pr_comp.h:91
@ OP_LOAD_S
Definition: pr_comp.h:82
@ OP_OR_I
Definition: pr_comp.h:299
@ OP_LT_I64
Definition: pr_comp.h:363
@ OP_CALL4
Definition: pr_comp.h:115
@ OP_ADDSTOREP_V
Definition: pr_comp.h:142
@ OP_EQ_E
Definition: pr_comp.h:66
@ OP_DIV_VF
Definition: pr_comp.h:233
@ OP_FETCH_GBL_FNC
Definition: pr_comp.h:153
@ OP_STOREP_F
Definition: pr_comp.h:96
@ OP_DIV_I64
Definition: pr_comp.h:356
@ OP_RANDV1
Definition: pr_comp.h:169
@ OP_STORE_I64
Definition: pr_comp.h:373
@ OP_ADD_I64
Definition: pr_comp.h:353
@ OP_SUB_D
Definition: pr_comp.h:392
@ OP_SUB_IF
Definition: pr_comp.h:209
@ OP_RAND2
Definition: pr_comp.h:167
@ OP_CSTATE
Definition: pr_comp.h:155
@ OP_BITXOR_I64
Definition: pr_comp.h:359
@ OP_LSHIFT_I
Definition: pr_comp.h:237
@ OP_CONV_FI64
Definition: pr_comp.h:386
@ OP_LOAD_I64
Definition: pr_comp.h:376
@ OP_CALL2H
Definition: pr_comp.h:190
@ OP_CALL2
Definition: pr_comp.h:113
@ OP_GLOAD_V
Definition: pr_comp.h:330
@ OP_EQ_D
Definition: pr_comp.h:397
@ OP_LE_I64
Definition: pr_comp.h:362
@ OP_STORE_FI
Definition: pr_comp.h:201
@ OP_MUL_V
Definition: pr_comp.h:54
@ OP_CONV_I64I
Definition: pr_comp.h:382
@ OP_EQ_I64
Definition: pr_comp.h:364
@ OP_GLOAD_S
Definition: pr_comp.h:320
@ OP_NE_I64
Definition: pr_comp.h:365
@ OP_LOADA_FLD
Definition: pr_comp.h:246
@ OP_LT_U64
Definition: pr_comp.h:368
@ OP_SUB_I
Definition: pr_comp.h:207
@ OP_SWITCH_E
Definition: pr_comp.h:175
@ OP_CONV_DI64
Definition: pr_comp.h:388
@ OP_ADDSTOREP_F
Definition: pr_comp.h:141
@ OP_NE_FI
Definition: pr_comp.h:305
@ OP_LOADP_F
Definition: pr_comp.h:253
@ OP_STATE
Definition: pr_comp.h:120
@ OP_GT_I
Definition: pr_comp.h:264
@ OP_LOAD_I
Definition: pr_comp.h:215
@ OP_SWITCH_FNC
Definition: pr_comp.h:176
@ OP_LOADA_V
Definition: pr_comp.h:243
@ OP_LOADA_S
Definition: pr_comp.h:244
@ OP_CALL3
Definition: pr_comp.h:114
@ OP_BITCLRSTOREP_F
Definition: pr_comp.h:163
@ OP_LOADP_ITOF
Definition: pr_comp.h:213
@ OP_RETURN
Definition: pr_comp.h:103
@ OP_BITAND_I64
Definition: pr_comp.h:357
@ OP_OR_F
Definition: pr_comp.h:123
@ OP_IF_S
Definition: pr_comp.h:229
@ OP_ADDRESS
Definition: pr_comp.h:87
@ OP_IFNOT_I
Definition: pr_comp.h:110
@ OP_SUBSTOREP_F
Definition: pr_comp.h:146
@ OP_EQ_IF
Definition: pr_comp.h:276
@ OP_BITAND_I
Definition: pr_comp.h:220
@ OP_EQ_F
Definition: pr_comp.h:63
@ OP_SWITCH_S
Definition: pr_comp.h:174
@ OP_DONE
Definition: pr_comp.h:52
@ OP_NOT_V
Definition: pr_comp.h:105
@ OP_DIV_U64
Definition: pr_comp.h:369
@ OP_BOUNDCHECK
Definition: pr_comp.h:324
@ OP_CONV_II64
Definition: pr_comp.h:381
@ OP_AND_FI
Definition: pr_comp.h:302
@ OP_GSTOREP_V
Definition: pr_comp.h:314
@ OP_EQ_S
Definition: pr_comp.h:65
@ OP_BITOR_IF
Definition: pr_comp.h:295
@ OP_MULSTOREP_F
Definition: pr_comp.h:133
@ OP_STOREF_S
Definition: pr_comp.h:338
@ OP_LOAD_FNC
Definition: pr_comp.h:85
@ OP_NE_I
Definition: pr_comp.h:226
@ OP_GT_FI
Definition: pr_comp.h:274
@ OP_NOT_FNC
Definition: pr_comp.h:108
@ OP_RAND1
Definition: pr_comp.h:166
@ OP_DIVSTOREP_F
Definition: pr_comp.h:137
@ OP_LOAD_V
Definition: pr_comp.h:81
@ OP_GOTO
Definition: pr_comp.h:121
@ OP_GLOAD_FNC
Definition: pr_comp.h:321
@ OP_BITAND_IF
Definition: pr_comp.h:294
@ OP_CALL7
Definition: pr_comp.h:118
@ OP_GADDRESS
Definition: pr_comp.h:315
@ OP_STORE_FNC
Definition: pr_comp.h:94
@ OP_MULSTORE_VF
Definition: pr_comp.h:132
@ OP_CASE
Definition: pr_comp.h:178
@ OP_SWITCH_F
Definition: pr_comp.h:172
@ OP_BITSETSTORE_F
Definition: pr_comp.h:160
@ OP_LT_U
Definition: pr_comp.h:348
@ OP_BITOR_I
Definition: pr_comp.h:221
@ OP_MUL_F
Definition: pr_comp.h:53
@ OP_LOADP_FNC
Definition: pr_comp.h:258
@ OP_NOT_S
Definition: pr_comp.h:106
@ OP_CALL4H
Definition: pr_comp.h:192
@ OP_CASERANGE
Definition: pr_comp.h:179
@ OP_STORE_F
Definition: pr_comp.h:89
char * PR_ValueString(progfuncs_t *progfuncs, etype_t type, eval_t *val, pbool verbose)
Definition: pr_edict.c:519
char * PR_GlobalStringNoContents(progfuncs_t *progfuncs, int ofs)
Definition: pr_edict.c:992
ddef16_t * ED_GlobalAtOfs16(progfuncs_t *progfuncs, int ofs)
Definition: pr_edict.c:219
fdef_t * ED_FieldAtOfs(progfuncs_t *progfuncs, unsigned int ofs)
Definition: pr_edict.c:251
ddef32_t * ED_GlobalAtOfs32(progfuncs_t *progfuncs, unsigned int ofs)
Definition: pr_edict.c:232
int ShowStep(progfuncs_t *progfuncs, int statement, char *fault, pbool fatal)
Definition: pr_exec.c:1336
void PDECL PR_StackTrace(pubprogfuncs_t *ppf, int showlocals)
Definition: pr_exec.c:371
void VARGS PR_RunError(pubprogfuncs_t *progfuncs, const char *error,...)
Definition: pr_exec.c:1491
const char * PR_GetEdictClassname(progfuncs_t *progfuncs, unsigned int edict)
Definition: pr_exec.c:1556
pubprogfuncs_t progfuncs
Definition: pr_lua.c:198
pbool PR_SwitchProgsParms(progfuncs_t *progfuncs, progsnum_t newpr)
Definition: pr_multi.c:45
unsigned char pbyte
Definition: progsint.h:39
@ ER_FREE
Definition: progslib.h:62
@ ev_function
Definition: progslib.h:83
@ ev_vector
Definition: progslib.h:80
@ ev_entity
Definition: progslib.h:81
@ ev_string
Definition: progslib.h:78
@ ev_float
Definition: progslib.h:79
@ DEBUG_TRACE_INTO
Definition: progslib.h:102
pint_t progsnum_t
Definition: progtype.h:64
pvec_t pvec3_t[3]
Definition: progtype.h:63
@ OP_PUSH
Definition: qvm.c:300
@ OP_POP
Definition: qvm.c:301
static int void * ptr
Definition: snd_dma.c:483
int i
Definition: snd_ov.c:50
Definition: pr_comp.h:633
string_t s_name
Definition: pr_comp.h:637
Definition: pr_comp.h:641
Definition: progs.h:65
Definition: progslib.h:111
const char * name
Definition: progslib.h:115
Definition: progdefs.h:24
int char * function
Definition: progslib.h:195
int debug_trace
Definition: progslib.h:174
int callargc
Definition: progslib.h:182
int fieldadjust
Definition: progslib.h:187
struct globalvars_s *PDECL * globals(pubprogfuncs_t *prinst, progsnum_t num)
Definition: progslib.h:295