home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / pr_exec.c < prev    next >
C/C++ Source or Header  |  1999-12-28  |  13KB  |  669 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20.  
  21. #include "quakedef.h"
  22.  
  23.  
  24. /*
  25.  
  26. */
  27.  
  28. typedef struct
  29. {
  30.   int       s;
  31.   dfunction_t   *f;
  32. } prstack_t;
  33.  
  34. #define MAX_STACK_DEPTH   32
  35. prstack_t pr_stack[MAX_STACK_DEPTH];
  36. int     pr_depth;
  37.  
  38. #define LOCALSTACK_SIZE   2048
  39. int     localstack[LOCALSTACK_SIZE];
  40. int     localstack_used;
  41.  
  42.  
  43. qboolean  pr_trace;
  44. dfunction_t *pr_xfunction;
  45. int     pr_xstatement;
  46.  
  47.  
  48. int   pr_argc;
  49.  
  50. char *pr_opnames[] =
  51. {
  52. "DONE",
  53.  
  54. "MUL_F",
  55. "MUL_V", 
  56. "MUL_FV",
  57. "MUL_VF",
  58.  
  59. "DIV",
  60.  
  61. "ADD_F",
  62. "ADD_V", 
  63.   
  64. "SUB_F",
  65. "SUB_V",
  66.  
  67. "EQ_F",
  68. "EQ_V",
  69. "EQ_S", 
  70. "EQ_E",
  71. "EQ_FNC",
  72.  
  73. "NE_F",
  74. "NE_V", 
  75. "NE_S",
  76. "NE_E", 
  77. "NE_FNC",
  78.  
  79. "LE",
  80. "GE",
  81. "LT",
  82. "GT", 
  83.  
  84. "INDIRECT",
  85. "INDIRECT",
  86. "INDIRECT", 
  87. "INDIRECT", 
  88. "INDIRECT",
  89. "INDIRECT", 
  90.  
  91. "ADDRESS", 
  92.  
  93. "STORE_F",
  94. "STORE_V",
  95. "STORE_S",
  96. "STORE_ENT",
  97. "STORE_FLD",
  98. "STORE_FNC",
  99.  
  100. "STOREP_F",
  101. "STOREP_V",
  102. "STOREP_S",
  103. "STOREP_ENT",
  104. "STOREP_FLD",
  105. "STOREP_FNC",
  106.  
  107. "RETURN",
  108.   
  109. "NOT_F",
  110. "NOT_V",
  111. "NOT_S", 
  112. "NOT_ENT", 
  113. "NOT_FNC", 
  114.   
  115. "IF",
  116. "IFNOT",
  117.   
  118. "CALL0",
  119. "CALL1",
  120. "CALL2",
  121. "CALL3",
  122. "CALL4",
  123. "CALL5",
  124. "CALL6",
  125. "CALL7",
  126. "CALL8",
  127.   
  128. "STATE",
  129.   
  130. "GOTO", 
  131.   
  132. "AND",
  133. "OR", 
  134.  
  135. "BITAND",
  136. "BITOR"
  137. };
  138.  
  139. char *PR_GlobalString (int ofs);
  140. char *PR_GlobalStringNoContents (int ofs);
  141.  
  142.  
  143. //=============================================================================
  144.  
  145. /*
  146. =================
  147. PR_PrintStatement
  148. =================
  149. */
  150. void PR_PrintStatement (dstatement_t *s)
  151. {
  152.   int   i;
  153.   
  154.   if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0]))
  155.   {
  156.     Con_Printf ("%s ",  pr_opnames[s->op]);
  157.     i = strlen(pr_opnames[s->op]);
  158.     for ( ; i<10 ; i++)
  159.       Con_Printf (" ");
  160.   }
  161.     
  162.   if (s->op == OP_IF || s->op == OP_IFNOT)
  163.     Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
  164.   else if (s->op == OP_GOTO)
  165.   {
  166.     Con_Printf ("branch %i",s->a);
  167.   }
  168.   else if ( (unsigned)(s->op - OP_STORE_F) < 6)
  169.   {
  170.     Con_Printf ("%s",PR_GlobalString(s->a));
  171.     Con_Printf ("%s", PR_GlobalStringNoContents(s->b));
  172.   }
  173.   else
  174.   {
  175.     if (s->a)
  176.       Con_Printf ("%s",PR_GlobalString(s->a));
  177.     if (s->b)
  178.       Con_Printf ("%s",PR_GlobalString(s->b));
  179.     if (s->c)
  180.       Con_Printf ("%s", PR_GlobalStringNoContents(s->c));
  181.   }
  182.   Con_Printf ("\n");
  183. }
  184.  
  185. /*
  186. ============
  187. PR_StackTrace
  188. ============
  189. */
  190. void PR_StackTrace (void)
  191. {
  192.   dfunction_t *f;
  193.   int     i;
  194.   
  195.   if (pr_depth == 0)
  196.   {
  197.     Con_Printf ("<NO STACK>\n");
  198.     return;
  199.   }
  200.   
  201.   pr_stack[pr_depth].f = pr_xfunction;
  202.   for (i=pr_depth ; i>=0 ; i--)
  203.   {
  204.     f = pr_stack[i].f;
  205.     
  206.     if (!f)
  207.     {
  208.       Con_Printf ("<NO FUNCTION>\n");
  209.     }
  210.     else
  211.       Con_Printf ("%12s : %s\n", pr_strings + f->s_file, pr_strings + f->s_name);   
  212.   }
  213. }
  214.  
  215.  
  216. /*
  217. ============
  218. PR_Profile_f
  219.  
  220. ============
  221. */
  222. void PR_Profile_f (void)
  223. {
  224.   dfunction_t *f, *best;
  225.   int     max;
  226.   int     num;
  227.   int     i;
  228.   
  229.   num = 0;  
  230.   do
  231.   {
  232.     max = 0;
  233.     best = NULL;
  234.     for (i=0 ; i<progs->numfunctions ; i++)
  235.     {
  236.       f = &pr_functions[i];
  237.       if (f->profile > max)
  238.       {
  239.         max = f->profile;
  240.         best = f;
  241.       }
  242.     }
  243.     if (best)
  244.     {
  245.       if (num < 10)
  246.         Con_Printf ("%7i %s\n", best->profile, pr_strings+best->s_name);
  247.       num++;
  248.       best->profile = 0;
  249.     }
  250.   } while (best);
  251. }
  252.  
  253.  
  254. /*
  255. ============
  256. PR_RunError
  257.  
  258. Aborts the currently executing function
  259. ============
  260. */
  261. void PR_RunError (char *error, ...)
  262. {
  263.   va_list   argptr;
  264.   char    string[1024];
  265.  
  266.   va_start (argptr,error);
  267.   vsprintf (string,error,argptr);
  268.   va_end (argptr);
  269.  
  270.   PR_PrintStatement (pr_statements + pr_xstatement);
  271.   PR_StackTrace ();
  272.   Con_Printf ("%s\n", string);
  273.   
  274.   pr_depth = 0;   // dump the stack so host_error can shutdown functions
  275.  
  276.   Host_Error ("Program error");
  277. }
  278.  
  279. /*
  280. ============================================================================
  281. PR_ExecuteProgram
  282.  
  283. The interpretation main loop
  284. ============================================================================
  285. */
  286.  
  287. /*
  288. ====================
  289. PR_EnterFunction
  290.  
  291. Returns the new program statement counter
  292. ====================
  293. */
  294. int PR_EnterFunction (dfunction_t *f)
  295. {
  296.   int   i, j, c, o;
  297.  
  298.   pr_stack[pr_depth].s = pr_xstatement;
  299.   pr_stack[pr_depth].f = pr_xfunction;  
  300.   pr_depth++;
  301.   if (pr_depth >= MAX_STACK_DEPTH)
  302.     PR_RunError ("stack overflow");
  303.  
  304. // save off any locals that the new function steps on
  305.   c = f->locals;
  306.   if (localstack_used + c > LOCALSTACK_SIZE)
  307.     PR_RunError ("PR_ExecuteProgram: locals stack overflow\n");
  308.  
  309.   for (i=0 ; i < c ; i++)
  310.     localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
  311.   localstack_used += c;
  312.  
  313. // copy parameters
  314.   o = f->parm_start;
  315.   for (i=0 ; i<f->numparms ; i++)
  316.   {
  317.     for (j=0 ; j<f->parm_size[i] ; j++)
  318.     {
  319.       ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];
  320.       o++;
  321.     }
  322.   }
  323.  
  324.   pr_xfunction = f;
  325.   return f->first_statement - 1;  // offset the s++
  326. }
  327.  
  328. /*
  329. ====================
  330. PR_LeaveFunction
  331. ====================
  332. */
  333. int PR_LeaveFunction (void)
  334. {
  335.   int   i, c;
  336.  
  337.   if (pr_depth <= 0)
  338.     Sys_Error ("prog stack underflow");
  339.  
  340. // restore locals from the stack
  341.   c = pr_xfunction->locals;
  342.   localstack_used -= c;
  343.   if (localstack_used < 0)
  344.     PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");
  345.  
  346.   for (i=0 ; i < c ; i++)
  347.     ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
  348.  
  349. // up stack
  350.   pr_depth--;
  351.   pr_xfunction = pr_stack[pr_depth].f;
  352.   return pr_stack[pr_depth].s;
  353. }
  354.  
  355.  
  356. /*
  357. ====================
  358. PR_ExecuteProgram
  359. ====================
  360. */
  361. void PR_ExecuteProgram (func_t fnum)
  362. {
  363.   eval_t  *a, *b, *c;
  364.   int     s;
  365.   dstatement_t  *st;
  366.   dfunction_t *f, *newf;
  367.   int   runaway;
  368.   int   i;
  369.   edict_t *ed;
  370.   int   exitdepth;
  371.   eval_t  *ptr;
  372.  
  373.   if (!fnum || fnum >= progs->numfunctions)
  374.   {
  375.     if (pr_global_struct->self)
  376.       ED_Print (PROG_TO_EDICT(pr_global_struct->self));
  377.     Host_Error ("PR_ExecuteProgram: NULL function");
  378.   }
  379.   
  380.   f = &pr_functions[fnum];
  381.  
  382.   runaway = 100000;
  383.   pr_trace = false;
  384.  
  385. // make a stack frame
  386.   exitdepth = pr_depth;
  387.  
  388.   s = PR_EnterFunction (f);
  389.   
  390. while (1)
  391. {
  392.   s++;  // next statement
  393.  
  394.   st = &pr_statements[s];
  395.   a = (eval_t *)&pr_globals[st->a];
  396.   b = (eval_t *)&pr_globals[st->b];
  397.   c = (eval_t *)&pr_globals[st->c];
  398.   
  399.   if (!--runaway)
  400.     PR_RunError ("runaway loop error");
  401.     
  402.   pr_xfunction->profile++;
  403.   pr_xstatement = s;
  404.   
  405.   if (pr_trace)
  406.     PR_PrintStatement (st);
  407.     
  408.   switch (st->op)
  409.   {
  410.   case OP_ADD_F:
  411.     c->_float = a->_float + b->_float;
  412.     break;
  413.   case OP_ADD_V:
  414.     c->vector[0] = a->vector[0] + b->vector[0];
  415.     c->vector[1] = a->vector[1] + b->vector[1];
  416.     c->vector[2] = a->vector[2] + b->vector[2];
  417.     break;
  418.     
  419.   case OP_SUB_F:
  420.     c->_float = a->_float - b->_float;
  421.     break;
  422.   case OP_SUB_V:
  423.     c->vector[0] = a->vector[0] - b->vector[0];
  424.     c->vector[1] = a->vector[1] - b->vector[1];
  425.     c->vector[2] = a->vector[2] - b->vector[2];
  426.     break;
  427.  
  428.   case OP_MUL_F:
  429.     c->_float = a->_float * b->_float;
  430.     break;
  431.   case OP_MUL_V:
  432.     c->_float = a->vector[0]*b->vector[0]
  433.         + a->vector[1]*b->vector[1]
  434.         + a->vector[2]*b->vector[2];
  435.     break;
  436.   case OP_MUL_FV:
  437.     c->vector[0] = a->_float * b->vector[0];
  438.     c->vector[1] = a->_float * b->vector[1];
  439.     c->vector[2] = a->_float * b->vector[2];
  440.     break;
  441.   case OP_MUL_VF:
  442.     c->vector[0] = b->_float * a->vector[0];
  443.     c->vector[1] = b->_float * a->vector[1];
  444.     c->vector[2] = b->_float * a->vector[2];
  445.     break;
  446.  
  447.   case OP_DIV_F:
  448.     c->_float = a->_float / b->_float;
  449.     break;
  450.   
  451.   case OP_BITAND:
  452.     c->_float = (int)a->_float & (int)b->_float;
  453.     break;
  454.   
  455.   case OP_BITOR:
  456.     c->_float = (int)a->_float | (int)b->_float;
  457.     break;
  458.   
  459.     
  460.   case OP_GE:
  461.     c->_float = a->_float >= b->_float;
  462.     break;
  463.   case OP_LE:
  464.     c->_float = a->_float <= b->_float;
  465.     break;
  466.   case OP_GT:
  467.     c->_float = a->_float > b->_float;
  468.     break;
  469.   case OP_LT:
  470.     c->_float = a->_float < b->_float;
  471.     break;
  472.   case OP_AND:
  473.     c->_float = a->_float && b->_float;
  474.     break;
  475.   case OP_OR:
  476.     c->_float = a->_float || b->_float;
  477.     break;
  478.     
  479.   case OP_NOT_F:
  480.     c->_float = !a->_float;
  481.     break;
  482.   case OP_NOT_V:
  483.     c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];
  484.     break;
  485.   case OP_NOT_S:
  486.     c->_float = !a->string || !pr_strings[a->string];
  487.     break;
  488.   case OP_NOT_FNC:
  489.     c->_float = !a->function;
  490.     break;
  491.   case OP_NOT_ENT:
  492.     c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts);
  493.     break;
  494.  
  495.   case OP_EQ_F:
  496.     c->_float = a->_float == b->_float;
  497.     break;
  498.   case OP_EQ_V:
  499.     c->_float = (a->vector[0] == b->vector[0]) &&
  500.           (a->vector[1] == b->vector[1]) &&
  501.           (a->vector[2] == b->vector[2]);
  502.     break;
  503.   case OP_EQ_S:
  504.     c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string);
  505.     break;
  506.   case OP_EQ_E:
  507.     c->_float = a->_int == b->_int;
  508.     break;
  509.   case OP_EQ_FNC:
  510.     c->_float = a->function == b->function;
  511.     break;
  512.  
  513.  
  514.   case OP_NE_F:
  515.     c->_float = a->_float != b->_float;
  516.     break;
  517.   case OP_NE_V:
  518.     c->_float = (a->vector[0] != b->vector[0]) ||
  519.           (a->vector[1] != b->vector[1]) ||
  520.           (a->vector[2] != b->vector[2]);
  521.     break;
  522.   case OP_NE_S:
  523.     c->_float = strcmp(pr_strings+a->string,pr_strings+b->string);
  524.     break;
  525.   case OP_NE_E:
  526.     c->_float = a->_int != b->_int;
  527.     break;
  528.   case OP_NE_FNC:
  529.     c->_float = a->function != b->function;
  530.     break;
  531.  
  532. //==================
  533.   case OP_STORE_F:
  534.   case OP_STORE_ENT:
  535.   case OP_STORE_FLD:    // integers
  536.   case OP_STORE_S:
  537.   case OP_STORE_FNC:    // pointers
  538.     b->_int = a->_int;
  539.     break;
  540.   case OP_STORE_V:
  541.     b->vector[0] = a->vector[0];
  542.     b->vector[1] = a->vector[1];
  543.     b->vector[2] = a->vector[2];
  544.     break;
  545.     
  546.   case OP_STOREP_F:
  547.   case OP_STOREP_ENT:
  548.   case OP_STOREP_FLD:   // integers
  549.   case OP_STOREP_S:
  550.   case OP_STOREP_FNC:   // pointers
  551.     ptr = (eval_t *)((byte *)sv.edicts + b->_int);
  552.     ptr->_int = a->_int;
  553.     break;
  554.   case OP_STOREP_V:
  555.     ptr = (eval_t *)((byte *)sv.edicts + b->_int);
  556.     ptr->vector[0] = a->vector[0];
  557.     ptr->vector[1] = a->vector[1];
  558.     ptr->vector[2] = a->vector[2];
  559.     break;
  560.     
  561.   case OP_ADDRESS:
  562.     ed = PROG_TO_EDICT(a->edict);
  563. #ifdef PARANOID
  564.     NUM_FOR_EDICT(ed);    // make sure it's in range
  565. #endif
  566.     if (ed == (edict_t *)sv.edicts && sv.state == ss_active)
  567.       PR_RunError ("assignment to world entity");
  568.     c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
  569.     break;
  570.     
  571.   case OP_LOAD_F:
  572.   case OP_LOAD_FLD:
  573.   case OP_LOAD_ENT:
  574.   case OP_LOAD_S:
  575.   case OP_LOAD_FNC:
  576.     ed = PROG_TO_EDICT(a->edict);
  577. #ifdef PARANOID
  578.     NUM_FOR_EDICT(ed);    // make sure it's in range
  579. #endif
  580.     a = (eval_t *)((int *)&ed->v + b->_int);
  581.     c->_int = a->_int;
  582.     break;
  583.  
  584.   case OP_LOAD_V:
  585.     ed = PROG_TO_EDICT(a->edict);
  586. #ifdef PARANOID
  587.     NUM_FOR_EDICT(ed);    // make sure it's in range
  588. #endif
  589.     a = (eval_t *)((int *)&ed->v + b->_int);
  590.     c->vector[0] = a->vector[0];
  591.     c->vector[1] = a->vector[1];
  592.     c->vector[2] = a->vector[2];
  593.     break;
  594.     
  595. //==================
  596.  
  597.   case OP_IFNOT:
  598.     if (!a->_int)
  599.       s += st->b - 1; // offset the s++
  600.     break;
  601.     
  602.   case OP_IF:
  603.     if (a->_int)
  604.       s += st->b - 1; // offset the s++
  605.     break;
  606.     
  607.   case OP_GOTO:
  608.     s += st->a - 1; // offset the s++
  609.     break;
  610.     
  611.   case OP_CALL0:
  612.   case OP_CALL1:
  613.   case OP_CALL2:
  614.   case OP_CALL3:
  615.   case OP_CALL4:
  616.   case OP_CALL5:
  617.   case OP_CALL6:
  618.   case OP_CALL7:
  619.   case OP_CALL8:
  620.     pr_argc = st->op - OP_CALL0;
  621.     if (!a->function)
  622.       PR_RunError ("NULL function");
  623.  
  624.     newf = &pr_functions[a->function];
  625.  
  626.     if (newf->first_statement < 0)
  627.     { // negative statements are built in functions
  628.       i = -newf->first_statement;
  629.       if (i >= pr_numbuiltins)
  630.         PR_RunError ("Bad builtin call number");
  631.       pr_builtins[i] ();
  632.       break;
  633.     }
  634.  
  635.     s = PR_EnterFunction (newf);
  636.     break;
  637.  
  638.   case OP_DONE:
  639.   case OP_RETURN:
  640.     pr_globals[OFS_RETURN] = pr_globals[st->a];
  641.     pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
  642.     pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
  643.   
  644.     s = PR_LeaveFunction ();
  645.     if (pr_depth == exitdepth)
  646.       return;   // all done
  647.     break;
  648.     
  649.   case OP_STATE:
  650.     ed = PROG_TO_EDICT(pr_global_struct->self);
  651. #ifdef FPS_20
  652.     ed->v.nextthink = pr_global_struct->time + 0.05;
  653. #else
  654.     ed->v.nextthink = pr_global_struct->time + 0.1;
  655. #endif
  656.     if (a->_float != ed->v.frame)
  657.     {
  658.       ed->v.frame = a->_float;
  659.     }
  660.     ed->v.think = b->function;
  661.     break;
  662.     
  663.   default:
  664.     PR_RunError ("Bad opcode %i", st->op);
  665.   }
  666. }
  667.  
  668. }
  669.