]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - pr_execprogram.h
forgot to remove #include "net_wipx.h"
[xonotic/darkplaces.git] / pr_execprogram.h
1
2 // This code isn't #ifdef/#define protectable, don't try.
3
4                 while (1)
5                 {
6                         st++;
7                         if (++profile > 1000000) // LordHavoc: increased runaway loop limit 10x
8                         {
9                                 pr_xstatement = st - pr_statements;
10                                 Host_Error ("runaway loop error");
11                         }
12
13 #if PRTRACE
14                         PR_PrintStatement (st);
15 #endif
16
17                         switch (st->op)
18                         {
19                         case OP_ADD_F:
20                                 OPC->_float = OPA->_float + OPB->_float;
21                                 break;
22                         case OP_ADD_V:
23                                 OPC->vector[0] = OPA->vector[0] + OPB->vector[0];
24                                 OPC->vector[1] = OPA->vector[1] + OPB->vector[1];
25                                 OPC->vector[2] = OPA->vector[2] + OPB->vector[2];
26                                 break;
27                         case OP_SUB_F:
28                                 OPC->_float = OPA->_float - OPB->_float;
29                                 break;
30                         case OP_SUB_V:
31                                 OPC->vector[0] = OPA->vector[0] - OPB->vector[0];
32                                 OPC->vector[1] = OPA->vector[1] - OPB->vector[1];
33                                 OPC->vector[2] = OPA->vector[2] - OPB->vector[2];
34                                 break;
35                         case OP_MUL_F:
36                                 OPC->_float = OPA->_float * OPB->_float;
37                                 break;
38                         case OP_MUL_V:
39                                 OPC->_float = OPA->vector[0]*OPB->vector[0] + OPA->vector[1]*OPB->vector[1] + OPA->vector[2]*OPB->vector[2];
40                                 break;
41                         case OP_MUL_FV:
42                                 OPC->vector[0] = OPA->_float * OPB->vector[0];
43                                 OPC->vector[1] = OPA->_float * OPB->vector[1];
44                                 OPC->vector[2] = OPA->_float * OPB->vector[2];
45                                 break;
46                         case OP_MUL_VF:
47                                 OPC->vector[0] = OPB->_float * OPA->vector[0];
48                                 OPC->vector[1] = OPB->_float * OPA->vector[1];
49                                 OPC->vector[2] = OPB->_float * OPA->vector[2];
50                                 break;
51                         case OP_DIV_F:
52                                 OPC->_float = OPA->_float / OPB->_float;
53                                 break;
54                         case OP_BITAND:
55                                 OPC->_float = (int)OPA->_float & (int)OPB->_float;
56                                 break;
57                         case OP_BITOR:
58                                 OPC->_float = (int)OPA->_float | (int)OPB->_float;
59                                 break;
60                         case OP_GE:
61                                 OPC->_float = OPA->_float >= OPB->_float;
62                                 break;
63                         case OP_LE:
64                                 OPC->_float = OPA->_float <= OPB->_float;
65                                 break;
66                         case OP_GT:
67                                 OPC->_float = OPA->_float > OPB->_float;
68                                 break;
69                         case OP_LT:
70                                 OPC->_float = OPA->_float < OPB->_float;
71                                 break;
72                         case OP_AND:
73                                 OPC->_float = OPA->_float && OPB->_float;
74                                 break;
75                         case OP_OR:
76                                 OPC->_float = OPA->_float || OPB->_float;
77                                 break;
78                         case OP_NOT_F:
79                                 OPC->_float = !OPA->_float;
80                                 break;
81                         case OP_NOT_V:
82                                 OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2];
83                                 break;
84                         case OP_NOT_S:
85                                 OPC->_float = !OPA->string || !*PR_GetString(OPA->string);
86                                 break;
87                         case OP_NOT_FNC:
88                                 OPC->_float = !OPA->function;
89                                 break;
90                         case OP_NOT_ENT:
91                                 OPC->_float = (OPA->edict == 0);
92                                 break;
93                         case OP_EQ_F:
94                                 OPC->_float = OPA->_float == OPB->_float;
95                                 break;
96                         case OP_EQ_V:
97                                 OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]);
98                                 break;
99                         case OP_EQ_S:
100                                 OPC->_float = !strcmp(PR_GetString(OPA->string),PR_GetString(OPB->string));
101                                 break;
102                         case OP_EQ_E:
103                                 OPC->_float = OPA->_int == OPB->_int;
104                                 break;
105                         case OP_EQ_FNC:
106                                 OPC->_float = OPA->function == OPB->function;
107                                 break;
108                         case OP_NE_F:
109                                 OPC->_float = OPA->_float != OPB->_float;
110                                 break;
111                         case OP_NE_V:
112                                 OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]);
113                                 break;
114                         case OP_NE_S:
115                                 OPC->_float = strcmp(PR_GetString(OPA->string),PR_GetString(OPB->string));
116                                 break;
117                         case OP_NE_E:
118                                 OPC->_float = OPA->_int != OPB->_int;
119                                 break;
120                         case OP_NE_FNC:
121                                 OPC->_float = OPA->function != OPB->function;
122                                 break;
123
124                 //==================
125                         case OP_STORE_F:
126                         case OP_STORE_ENT:
127                         case OP_STORE_FLD:              // integers
128                         case OP_STORE_S:
129                         case OP_STORE_FNC:              // pointers
130                                 OPB->_int = OPA->_int;
131                                 break;
132                         case OP_STORE_V:
133                                 OPB->ivector[0] = OPA->ivector[0];
134                                 OPB->ivector[1] = OPA->ivector[1];
135                                 OPB->ivector[2] = OPA->ivector[2];
136                                 break;
137
138                         case OP_STOREP_F:
139                         case OP_STOREP_ENT:
140                         case OP_STOREP_FLD:             // integers
141                         case OP_STOREP_S:
142                         case OP_STOREP_FNC:             // pointers
143 #if PRBOUNDSCHECK
144                                 if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
145                                 {
146                                         pr_xstatement = st - pr_statements;
147                                         Host_Error("Progs attempted to write to an out of bounds edict (%i)\n", OPB->_int);
148                                         return;
149                                 }
150 #endif
151                                 ptr = (eval_t *)((qbyte *)sv.edictsfields + OPB->_int);
152                                 ptr->_int = OPA->_int;
153                                 break;
154                         case OP_STOREP_V:
155 #if PRBOUNDSCHECK
156                                 if (OPB->_int < 0 || OPB->_int + 12 > pr_edictareasize)
157                                 {
158                                         pr_xstatement = st - pr_statements;
159                                         Host_Error("Progs attempted to write to an out of bounds edict (%i)\n", OPB->_int);
160                                         return;
161                                 }
162 #endif
163                                 ptr = (eval_t *)((qbyte *)sv.edictsfields + OPB->_int);
164                                 ptr->vector[0] = OPA->vector[0];
165                                 ptr->vector[1] = OPA->vector[1];
166                                 ptr->vector[2] = OPA->vector[2];
167                                 break;
168
169                         case OP_ADDRESS:
170                                 pr_xstatement = st - pr_statements;
171 #if PRBOUNDSCHECK
172                                 if ((unsigned int)(OPB->_int) >= (unsigned int)(progs->entityfields))
173                                 {
174                                         Host_Error("Progs attempted to address an invalid field (%i) in an edict\n", OPB->_int);
175                                         return;
176                                 }
177 #endif
178                                 if (OPA->edict == 0 && sv.state == ss_active)
179                                 {
180                                         Host_Error ("assignment to world entity");
181                                         return;
182                                 }
183                                 ed = PROG_TO_EDICT(OPA->edict);
184                                 OPC->_int = (qbyte *)((int *)ed->v + OPB->_int) - (qbyte *)sv.edictsfields;
185                                 break;
186
187                         case OP_LOAD_F:
188                         case OP_LOAD_FLD:
189                         case OP_LOAD_ENT:
190                         case OP_LOAD_S:
191                         case OP_LOAD_FNC:
192                                 pr_xstatement = st - pr_statements;
193 #if PRBOUNDSCHECK
194                                 if ((unsigned int)(OPB->_int) >= (unsigned int)(progs->entityfields))
195                                 {
196                                         Host_Error("Progs attempted to read an invalid field in an edict (%i)\n", OPB->_int);
197                                         return;
198                                 }
199 #endif
200                                 ed = PROG_TO_EDICT(OPA->edict);
201                                 OPC->_int = ((eval_t *)((int *)ed->v + OPB->_int))->_int;
202                                 break;
203
204                         case OP_LOAD_V:
205                                 pr_xstatement = st - pr_statements;
206 #if PRBOUNDSCHECK
207                                 if (OPB->_int < 0 || OPB->_int + 2 >= progs->entityfields)
208                                 {
209                                         Host_Error("Progs attempted to read an invalid field in an edict (%i)\n", OPB->_int);
210                                         return;
211                                 }
212 #endif
213                                 ed = PROG_TO_EDICT(OPA->edict);
214                                 OPC->vector[0] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[0];
215                                 OPC->vector[1] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[1];
216                                 OPC->vector[2] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[2];
217                                 break;
218
219                 //==================
220
221                         case OP_IFNOT:
222                                 if (!OPA->_int)
223                                         st += st->b - 1;        // offset the s++
224                                 break;
225
226                         case OP_IF:
227                                 if (OPA->_int)
228                                         st += st->b - 1;        // offset the s++
229                                 break;
230
231                         case OP_GOTO:
232                                 st += st->a - 1;        // offset the s++
233                                 break;
234
235                         case OP_CALL0:
236                         case OP_CALL1:
237                         case OP_CALL2:
238                         case OP_CALL3:
239                         case OP_CALL4:
240                         case OP_CALL5:
241                         case OP_CALL6:
242                         case OP_CALL7:
243                         case OP_CALL8:
244                                 pr_xfunction->profile += profile - startprofile;
245                                 startprofile = profile;
246                                 pr_xstatement = st - pr_statements;
247                                 pr_argc = st->op - OP_CALL0;
248                                 if (!OPA->function)
249                                         Host_Error ("NULL function");
250
251                                 newf = &pr_functions[OPA->function];
252
253                                 if (newf->first_statement < 0)
254                                 {
255                                         // negative statements are built in functions
256                                         if ((-newf->first_statement) >= pr_numbuiltins)
257                                                 Host_Error ("Bad builtin call number");
258                                         pr_xfunction->builtinsprofile++;
259                                         pr_builtins[-newf->first_statement] ();
260                                 }
261                                 else
262                                         st = pr_statements + PR_EnterFunction(newf);
263                                 break;
264
265                         case OP_DONE:
266                         case OP_RETURN:
267                                 pr_globals[OFS_RETURN] = pr_globals[(unsigned short) st->a];
268                                 pr_globals[OFS_RETURN+1] = pr_globals[(unsigned short) st->a+1];
269                                 pr_globals[OFS_RETURN+2] = pr_globals[(unsigned short) st->a+2];
270
271                                 st = pr_statements + PR_LeaveFunction();
272                                 if (pr_depth <= exitdepth)
273                                         return;         // all done
274                                 if (pr_trace != cachedpr_trace)
275                                         goto chooseexecprogram;
276                                 break;
277
278                         case OP_STATE:
279                                 ed = PROG_TO_EDICT(pr_global_struct->self);
280                                 ed->v->nextthink = pr_global_struct->time + 0.1;
281                                 ed->v->frame = OPA->_float;
282                                 ed->v->think = OPB->function;
283                                 break;
284
285 // LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
286 /*
287                         case OP_ADD_I:
288                                 OPC->_int = OPA->_int + OPB->_int;
289                                 break;
290                         case OP_ADD_IF:
291                                 OPC->_int = OPA->_int + (int) OPB->_float;
292                                 break;
293                         case OP_ADD_FI:
294                                 OPC->_float = OPA->_float + (float) OPB->_int;
295                                 break;
296                         case OP_SUB_I:
297                                 OPC->_int = OPA->_int - OPB->_int;
298                                 break;
299                         case OP_SUB_IF:
300                                 OPC->_int = OPA->_int - (int) OPB->_float;
301                                 break;
302                         case OP_SUB_FI:
303                                 OPC->_float = OPA->_float - (float) OPB->_int;
304                                 break;
305                         case OP_MUL_I:
306                                 OPC->_int = OPA->_int * OPB->_int;
307                                 break;
308                         case OP_MUL_IF:
309                                 OPC->_int = OPA->_int * (int) OPB->_float;
310                                 break;
311                         case OP_MUL_FI:
312                                 OPC->_float = OPA->_float * (float) OPB->_int;
313                                 break;
314                         case OP_MUL_VI:
315                                 OPC->vector[0] = (float) OPB->_int * OPA->vector[0];
316                                 OPC->vector[1] = (float) OPB->_int * OPA->vector[1];
317                                 OPC->vector[2] = (float) OPB->_int * OPA->vector[2];
318                                 break;
319                         case OP_DIV_VF:
320                                 {
321                                         float temp = 1.0f / OPB->_float;
322                                         OPC->vector[0] = temp * OPA->vector[0];
323                                         OPC->vector[1] = temp * OPA->vector[1];
324                                         OPC->vector[2] = temp * OPA->vector[2];
325                                 }
326                                 break;
327                         case OP_DIV_I:
328                                 OPC->_int = OPA->_int / OPB->_int;
329                                 break;
330                         case OP_DIV_IF:
331                                 OPC->_int = OPA->_int / (int) OPB->_float;
332                                 break;
333                         case OP_DIV_FI:
334                                 OPC->_float = OPA->_float / (float) OPB->_int;
335                                 break;
336                         case OP_CONV_IF:
337                                 OPC->_float = OPA->_int;
338                                 break;
339                         case OP_CONV_FI:
340                                 OPC->_int = OPA->_float;
341                                 break;
342                         case OP_BITAND_I:
343                                 OPC->_int = OPA->_int & OPB->_int;
344                                 break;
345                         case OP_BITOR_I:
346                                 OPC->_int = OPA->_int | OPB->_int;
347                                 break;
348                         case OP_BITAND_IF:
349                                 OPC->_int = OPA->_int & (int)OPB->_float;
350                                 break;
351                         case OP_BITOR_IF:
352                                 OPC->_int = OPA->_int | (int)OPB->_float;
353                                 break;
354                         case OP_BITAND_FI:
355                                 OPC->_float = (int)OPA->_float & OPB->_int;
356                                 break;
357                         case OP_BITOR_FI:
358                                 OPC->_float = (int)OPA->_float | OPB->_int;
359                                 break;
360                         case OP_GE_I:
361                                 OPC->_float = OPA->_int >= OPB->_int;
362                                 break;
363                         case OP_LE_I:
364                                 OPC->_float = OPA->_int <= OPB->_int;
365                                 break;
366                         case OP_GT_I:
367                                 OPC->_float = OPA->_int > OPB->_int;
368                                 break;
369                         case OP_LT_I:
370                                 OPC->_float = OPA->_int < OPB->_int;
371                                 break;
372                         case OP_AND_I:
373                                 OPC->_float = OPA->_int && OPB->_int;
374                                 break;
375                         case OP_OR_I:
376                                 OPC->_float = OPA->_int || OPB->_int;
377                                 break;
378                         case OP_GE_IF:
379                                 OPC->_float = (float)OPA->_int >= OPB->_float;
380                                 break;
381                         case OP_LE_IF:
382                                 OPC->_float = (float)OPA->_int <= OPB->_float;
383                                 break;
384                         case OP_GT_IF:
385                                 OPC->_float = (float)OPA->_int > OPB->_float;
386                                 break;
387                         case OP_LT_IF:
388                                 OPC->_float = (float)OPA->_int < OPB->_float;
389                                 break;
390                         case OP_AND_IF:
391                                 OPC->_float = (float)OPA->_int && OPB->_float;
392                                 break;
393                         case OP_OR_IF:
394                                 OPC->_float = (float)OPA->_int || OPB->_float;
395                                 break;
396                         case OP_GE_FI:
397                                 OPC->_float = OPA->_float >= (float)OPB->_int;
398                                 break;
399                         case OP_LE_FI:
400                                 OPC->_float = OPA->_float <= (float)OPB->_int;
401                                 break;
402                         case OP_GT_FI:
403                                 OPC->_float = OPA->_float > (float)OPB->_int;
404                                 break;
405                         case OP_LT_FI:
406                                 OPC->_float = OPA->_float < (float)OPB->_int;
407                                 break;
408                         case OP_AND_FI:
409                                 OPC->_float = OPA->_float && (float)OPB->_int;
410                                 break;
411                         case OP_OR_FI:
412                                 OPC->_float = OPA->_float || (float)OPB->_int;
413                                 break;
414                         case OP_NOT_I:
415                                 OPC->_float = !OPA->_int;
416                                 break;
417                         case OP_EQ_I:
418                                 OPC->_float = OPA->_int == OPB->_int;
419                                 break;
420                         case OP_EQ_IF:
421                                 OPC->_float = (float)OPA->_int == OPB->_float;
422                                 break;
423                         case OP_EQ_FI:
424                                 OPC->_float = OPA->_float == (float)OPB->_int;
425                                 break;
426                         case OP_NE_I:
427                                 OPC->_float = OPA->_int != OPB->_int;
428                                 break;
429                         case OP_NE_IF:
430                                 OPC->_float = (float)OPA->_int != OPB->_float;
431                                 break;
432                         case OP_NE_FI:
433                                 OPC->_float = OPA->_float != (float)OPB->_int;
434                                 break;
435                         case OP_STORE_I:
436                                 OPB->_int = OPA->_int;
437                                 break;
438                         case OP_STOREP_I:
439 #if PRBOUNDSCHECK
440                                 if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
441                                 {
442                                         pr_xstatement = st - pr_statements;
443                                         Host_Error("Progs attempted to write to an out of bounds edict\n");
444                                         return;
445                                 }
446 #endif
447                                 ptr = (eval_t *)((qbyte *)sv.edictsfields + OPB->_int);
448                                 ptr->_int = OPA->_int;
449                                 break;
450                         case OP_LOAD_I:
451 #if PRBOUNDSCHECK
452                                 if (OPA->edict < 0 || OPA->edict >= pr_edictareasize)
453                                 {
454                                         pr_xstatement = st - pr_statements;
455                                         Host_Error("Progs attempted to read an out of bounds edict number\n");
456                                         return;
457                                 }
458                                 if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
459                                 {
460                                         pr_xstatement = st - pr_statements;
461                                         Host_Error("Progs attempted to read an invalid field in an edict\n");
462                                         return;
463                                 }
464 #endif
465                                 ed = PROG_TO_EDICT(OPA->edict);
466                                 OPC->_int = ((eval_t *)((int *)ed->v + OPB->_int))->_int;
467                                 break;
468
469                         case OP_GSTOREP_I:
470                         case OP_GSTOREP_F:
471                         case OP_GSTOREP_ENT:
472                         case OP_GSTOREP_FLD:            // integers
473                         case OP_GSTOREP_S:
474                         case OP_GSTOREP_FNC:            // pointers
475 #if PRBOUNDSCHECK
476                                 if (OPB->_int < 0 || OPB->_int >= pr_globaldefs)
477                                 {
478                                         pr_xstatement = st - pr_statements;
479                                         Host_Error("Progs attempted to write to an invalid indexed global\n");
480                                         return;
481                                 }
482 #endif
483                                 pr_globals[OPB->_int] = OPA->_float;
484                                 break;
485                         case OP_GSTOREP_V:
486 #if PRBOUNDSCHECK
487                                 if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)
488                                 {
489                                         pr_xstatement = st - pr_statements;
490                                         Host_Error("Progs attempted to write to an invalid indexed global\n");
491                                         return;
492                                 }
493 #endif
494                                 pr_globals[OPB->_int  ] = OPA->vector[0];
495                                 pr_globals[OPB->_int+1] = OPA->vector[1];
496                                 pr_globals[OPB->_int+2] = OPA->vector[2];
497                                 break;
498
499                         case OP_GADDRESS:
500                                 i = OPA->_int + (int) OPB->_float;
501 #if PRBOUNDSCHECK
502                                 if (i < 0 || i >= pr_globaldefs)
503                                 {
504                                         pr_xstatement = st - pr_statements;
505                                         Host_Error("Progs attempted to address an out of bounds global\n");
506                                         return;
507                                 }
508 #endif
509                                 OPC->_float = pr_globals[i];
510                                 break;
511
512                         case OP_GLOAD_I:
513                         case OP_GLOAD_F:
514                         case OP_GLOAD_FLD:
515                         case OP_GLOAD_ENT:
516                         case OP_GLOAD_S:
517                         case OP_GLOAD_FNC:
518 #if PRBOUNDSCHECK
519                                 if (OPA->_int < 0 || OPA->_int >= pr_globaldefs)
520                                 {
521                                         pr_xstatement = st - pr_statements;
522                                         Host_Error("Progs attempted to read an invalid indexed global\n");
523                                         return;
524                                 }
525 #endif
526                                 OPC->_float = pr_globals[OPA->_int];
527                                 break;
528
529                         case OP_GLOAD_V:
530 #if PRBOUNDSCHECK
531                                 if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)
532                                 {
533                                         pr_xstatement = st - pr_statements;
534                                         Host_Error("Progs attempted to read an invalid indexed global\n");
535                                         return;
536                                 }
537 #endif
538                                 OPC->vector[0] = pr_globals[OPA->_int  ];
539                                 OPC->vector[1] = pr_globals[OPA->_int+1];
540                                 OPC->vector[2] = pr_globals[OPA->_int+2];
541                                 break;
542
543                         case OP_BOUNDCHECK:
544                                 if (OPA->_int < 0 || OPA->_int >= st->b)
545                                 {
546                                         pr_xstatement = st - pr_statements;
547                                         Host_Error("Progs boundcheck failed at line number %d, value is < 0 or >= %d\n", st->b, st->c);
548                                         return;
549                                 }
550                                 break;
551
552 */
553
554                         default:
555                                 pr_xstatement = st - pr_statements;
556                                 Host_Error ("Bad opcode %i", st->op);
557                         }
558                 }
559