home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Jeux / demos / crystalPPC.lha / script.cpp < prev    next >
C/C++ Source or Header  |  1998-02-05  |  11KB  |  488 lines

  1. #include <math.h>
  2. #include <time.h>
  3. #include "system.h"
  4.  
  5. #ifndef DEF_H
  6. #include "def.h"
  7. #endif
  8.  
  9. #ifndef SCRIPT_H
  10. #include "script.h"
  11. #endif
  12.  
  13. #ifndef THING_H
  14. #include "thing.h"
  15. #endif
  16.  
  17. #ifndef TOKEN_H
  18. #include "token.h"
  19. #endif
  20.  
  21. #ifndef WORLD_H
  22. #include "world.h"
  23. #endif
  24.  
  25. //---------------------------------------------------------------------------
  26.  
  27. CmdSequence::CmdSequence  ()
  28. {
  29.   cmds = NULL;
  30.   long_args = NULL;
  31.   mat_args = NULL;
  32.   vec_args = NULL;
  33.   seq_args = NULL;
  34. }
  35.  
  36. CmdSequence::~CmdSequence ()
  37. {
  38.   if (cmds) delete [] cmds;
  39.   if (long_args) delete [] long_args;
  40.   if (mat_args) delete [] mat_args;
  41.   if (vec_args) delete [] vec_args;
  42.   if (seq_args) delete [] seq_args;
  43. }
  44.  
  45. void CmdSequence::compile_pass1 (char** buf)
  46. {
  47.   char* t;
  48.  
  49.   num_cmds = 0;
  50.   num_long_args = 0;
  51.   num_mat_args = 0;
  52.   num_vec_args = 0;
  53.   num_seq_args = 0;
  54.   num_long_vars = 0;
  55.  
  56.   while (TRUE)
  57.   {
  58.     t = get_token (buf);
  59.     if (*t == ')' || *t == 0 || *t == '}') break;
  60.     if (!strcmp (t, "move"))
  61.     {
  62.       skip_token (buf, "(", "Expected '%s' instead of '%s' after 'move' cmd!\n");
  63.       get_token_float (buf);
  64.       skip_token (buf, ",", "Expected '%s' instead of '%s' in 'move' cmd!\n");
  65.       get_token_float (buf);
  66.       skip_token (buf, ",", "Expected '%s' instead of '%s' in 'move' cmd!\n");
  67.       get_token_float (buf);
  68.       skip_token (buf, ")", "Expected '%s' instead of '%s' to end 'move' cmd!\n");
  69.  
  70.       num_cmds++;
  71.       num_vec_args++;
  72.     }
  73.     else if (!strcmp (t, "transform"))
  74.     {
  75.       skip_token (buf, "(", "Expected '%s' instead of '%s' after 'transform' cmd!\n");
  76.       t = get_token (buf);
  77.       int bra = 1;
  78.       while (*t)
  79.       {
  80.         if (*t == ')')
  81.       if (bra <= 1) break;
  82.       else bra--;
  83.     if (*t == '(') bra++;
  84.         t = get_token (buf);
  85.       }
  86.       num_cmds++;
  87.       num_mat_args++;
  88.     }
  89.     else if (!strcmp (t, "forever"))
  90.     {
  91.       skip_token (buf, "{", "Expected '%s' instead of '%s' after 'forever' cmd!\n");
  92.       t = get_token (buf);
  93.       int bra = 1;
  94.       while (*t)
  95.       {
  96.         if (*t == '}')
  97.       if (bra <= 1) break;
  98.       else bra--;
  99.     if (*t == '{') bra++;
  100.         t = get_token (buf);
  101.       }
  102.       num_cmds++;
  103.       num_seq_args++;
  104.     }
  105.     else if (!strcmp (t, "loop"))
  106.     {
  107.       get_token_int (buf);
  108.       skip_token (buf, "{", "Expected '%s' instead of '%s' after 'loop' cmd!\n");
  109.       t = get_token (buf);
  110.       int bra = 1;
  111.       while (*t)
  112.       {
  113.         if (*t == '}' && bra <= 1) break;
  114.     if (*t == '{') bra++;
  115.         t = get_token (buf);
  116.       }
  117.       num_cmds++;        // INITLOOP command
  118.       num_long_args++;        // Number of times we should loop
  119.       num_long_args++;        // Index to variable where we keep our loop counter
  120.       num_cmds++;        // LOOP command
  121.       num_long_args++;        // Index to variable where we keep our loop counter
  122.       num_seq_args++;        // Sequence to loop
  123.       num_long_vars++;        // We need one extra loop counter
  124.     }
  125.     else if (!strcmp (t, "wait"))
  126.     {
  127.       num_cmds++;
  128.     }
  129.     else
  130.     {
  131.       printf ("What is '%s' doing in a SCRIPT?\n", t);
  132.       exit (0);
  133.     }
  134.   }
  135.  
  136.   num_cmds++; // Room for CMD_RETURN
  137.  
  138.   cmds = new ubyte [num_cmds];
  139.   if (num_long_args) long_args = new long [num_long_args];
  140.   if (num_mat_args) mat_args = new Matrix3 [num_mat_args];
  141.   if (num_vec_args) vec_args = new Vector3 [num_vec_args];
  142.   if (num_seq_args) seq_args = new CmdSequence [num_seq_args];
  143. }
  144.  
  145. void CmdSequence::compile_pass2 (char** buf)
  146. {
  147.   char* t;
  148.  
  149.   int idx_cmds = 0;
  150.   int idx_long_args = 0;
  151.   int idx_mat_args = 0;
  152.   int idx_vec_args = 0;
  153.   int idx_seq_args = 0;
  154.   int idx_long_vars = 0;
  155.  
  156.   while (TRUE)
  157.   {
  158.     t = get_token (buf);
  159.     if (*t == ')' || *t == 0 || *t == '}') break;
  160.     if (!strcmp (t, "move"))
  161.     {
  162.       cmds[idx_cmds++] = CMD_MOVE;
  163.       skip_token (buf, "(", "Expected '%s' instead of '%s' after 'move' cmd!\n");
  164.       vec_args[idx_vec_args].x = get_token_float (buf);
  165.       skip_token (buf, ",", "Expected '%s' instead of '%s' in 'move' cmd!\n");
  166.       vec_args[idx_vec_args].y = get_token_float (buf);
  167.       skip_token (buf, ",", "Expected '%s' instead of '%s' in 'move' cmd!\n");
  168.       vec_args[idx_vec_args].z = get_token_float (buf);
  169.       skip_token (buf, ")", "Expected '%s' instead of '%s' to end 'move' cmd!\n");
  170.       idx_vec_args++;
  171.     }
  172.     else if (!strcmp (t, "transform"))
  173.     {
  174.       cmds[idx_cmds++] = CMD_TRANSFORM;
  175.       skip_token (buf, "(", "Expected '%s' instead of '%s' after 'transform' cmd!\n");
  176.       Matrix3 r;
  177.       mat_args[idx_mat_args].identity ();
  178.       t = get_token (buf);
  179.       while (*t && *t != ')')
  180.       {
  181.     if (!strcmp (t, "rot_x"))
  182.     {
  183.       float a = get_token_float (buf);
  184.       a = a * 2*PI / 360.;
  185.       r.m11 = 1;       r.m12 = 0;       r.m13 = 0;
  186.       r.m21 = 0;       r.m22 = cos (a); r.m23 = -sin (a);
  187.       r.m31 = 0;       r.m32 = sin (a); r.m33 = cos (a);
  188.       r *= mat_args[idx_mat_args];
  189.       mat_args[idx_mat_args] = r;
  190.     }
  191.     else if (!strcmp (t, "rot_y"))
  192.     {
  193.       float a = get_token_float (buf);
  194.       a = a * 2*PI / 360.;
  195.       r.m11 = cos (a); r.m12 = 0;       r.m13 = -sin (a);
  196.       r.m21 = 0;       r.m22 = 1;       r.m23 = 0;
  197.       r.m31 = sin (a); r.m32 = 0;       r.m33 = cos (a);
  198.       r *= mat_args[idx_mat_args];
  199.       mat_args[idx_mat_args] = r;
  200.     }
  201.     else if (!strcmp (t, "rot_z"))
  202.     {
  203.       float a = get_token_float (buf);
  204.       a = a * 2*PI / 360.;
  205.       r.m11 = cos (a); r.m12 = -sin (a); r.m13 = 0;
  206.       r.m21 = sin (a); r.m22 = cos (a);  r.m23 = 0;
  207.       r.m31 = 0;       r.m32 = 0;        r.m33 = 1;
  208.       r *= mat_args[idx_mat_args];
  209.       mat_args[idx_mat_args] = r;
  210.     }
  211.     else
  212.     {
  213.       printf ("What is '%s' doing in a 'transform' cmd?\n", t);
  214.       exit (0);
  215.     }
  216.     t = get_token (buf);
  217.       }
  218.       idx_mat_args++;
  219.     }
  220.     else if (!strcmp (t, "forever"))
  221.     {
  222.       cmds[idx_cmds++] = CMD_FOREVER;
  223.       skip_token (buf, "{", "Expected '%s' instead of '%s' after 'forever' cmd!\n");
  224.       char* old_buf;
  225.       old_buf = *buf;
  226.       seq_args[idx_seq_args].compile_pass1 (buf);
  227.       *buf = old_buf;
  228.       seq_args[idx_seq_args].compile_pass2 (buf);
  229.       idx_seq_args++;
  230.     }
  231.     else if (!strcmp (t, "loop"))
  232.     {
  233.       cmds[idx_cmds++] = CMD_INITLOOP;
  234.       cmds[idx_cmds++] = CMD_LOOP;
  235.       long_args[idx_long_args++] = get_token_int (buf);
  236.       long_args[idx_long_args++] = idx_long_vars;
  237.       long_args[idx_long_args++] = idx_long_vars;
  238.       skip_token (buf, "{", "Expected '%s' instead of '%s' after 'loop' cmd!\n");
  239.       char* old_buf;
  240.       old_buf = *buf;
  241.       seq_args[idx_seq_args].compile_pass1 (buf);
  242.       *buf = old_buf;
  243.       seq_args[idx_seq_args].compile_pass2 (buf);
  244.       idx_seq_args++;
  245.       idx_long_vars++;
  246.     }
  247.     else if (!strcmp (t, "wait"))
  248.     {
  249.       cmds[idx_cmds++] = CMD_WAIT;
  250.     }
  251.     else
  252.     {
  253.       printf ("What is '%s' doing in a SCRIPT?\n", t);
  254.       exit (0);
  255.     }
  256.   }
  257.  
  258.   cmds[idx_cmds++] = CMD_RETURN;
  259. }
  260.  
  261. //---------------------------------------------------------------------------
  262.  
  263. Script::Script (char* name)
  264. {
  265.   strcpy (Script::name, name);
  266. }
  267.  
  268. Script::~Script ()
  269. {
  270. }
  271.  
  272. void Script::save (FILE* fp, int indent)
  273. {
  274. #if 0
  275. // @@@ NOT IMPLEMENTED YET
  276.   char sp[100]; strcpy (sp, spaces); sp[indent] = 0;
  277.   fprintf (fp, "%sSCRIPT '%s' (\n", sp, name);
  278.   fprintf (fp, "%s  TIMES=%d\n", sp, times);
  279.   fprintf (fp, "%s  DO (\n", sp);
  280.   m.save (fp, indent+4);
  281.   v.save (fp, indent+4);
  282.   fprintf (fp, "%s  )\n", sp);
  283.   fprintf (fp, "%s)\n", sp);
  284. #endif
  285. }
  286.  
  287. void Script::load (char** buf)
  288. {
  289.   char* t;
  290.   char* old_buf;
  291.  
  292.   skip_token (buf, "SCRIPT");
  293.   t = get_token (buf);
  294.   strcpy (name, t);
  295.   skip_token (buf, "(", "Expected '%s' instead of '%s' after the name of a SCRIPT!\n");
  296.  
  297.   old_buf = *buf;
  298.   main.compile_pass1 (buf);
  299.   *buf = old_buf;
  300.   main.compile_pass2 (buf);
  301. }
  302.  
  303. //---------------------------------------------------------------------------
  304.  
  305. CmdSequenceRun::CmdSequenceRun ()
  306. {
  307.   vars = NULL;
  308. }
  309.  
  310. CmdSequenceRun::~CmdSequenceRun ()
  311. {
  312.   if (vars) delete [] vars;
  313. }
  314.  
  315. void CmdSequenceRun::start (CmdSequence* seq)
  316. {
  317.   cur_cmd = 0;
  318.   cur_long_arg = 0;
  319.   cur_mat_arg = 0;
  320.   cur_vec_arg = 0;
  321.   cur_seq_arg = 0;
  322.   if (vars) { delete [] vars; vars = NULL; }
  323.   if (seq->num_long_vars)
  324.   {
  325.     vars = new long [seq->num_long_vars];
  326.   }
  327. }
  328.  
  329. //---------------------------------------------------------------------------
  330.  
  331. ScriptRun::ScriptRun (Script* script, CsObject* object)
  332. {
  333.   ScriptRun::script = script;
  334.   ScriptRun::object = object;
  335.   type = object->get_type ();
  336.   start ();
  337. }
  338.  
  339. ScriptRun::~ScriptRun ()
  340. {
  341. }
  342.  
  343. void ScriptRun::start ()
  344. {
  345.   stack_idx = 0;
  346.   seqr = &stackr[stack_idx];
  347.   seq = stack[stack_idx] = &script->main;
  348.   seqr->start (seq);
  349. }
  350.  
  351. int ScriptRun::step ()
  352. {
  353.   for (;;)
  354.   {
  355.     // printf ("[%d] Exec cmd [%d]: %d\n", stack_idx, seqr->cur_cmd, seq->cmds[seqr->cur_cmd]);
  356.  
  357.     switch (seq->cmds[seqr->cur_cmd])
  358.     {
  359.       case CMD_QUIT:
  360.     return TRUE;
  361.  
  362.       case CMD_RETURN:
  363.     if (stack_idx <= 0) return TRUE;
  364.     stack_idx--;
  365.     seqr = &stackr[stack_idx];
  366.     seq = stack[stack_idx];
  367.     break;
  368.  
  369.       case CMD_FOREVER:
  370.     {
  371.       CmdSequence* ns;
  372.       ns = &(seq->seq_args[seqr->cur_seq_arg]);
  373.       stack_idx++;
  374.       seqr = &stackr[stack_idx];
  375.       seq = stack[stack_idx] = ns;
  376.       seqr->start (seq);
  377.       break;
  378.     }
  379.  
  380.       case CMD_INITLOOP:
  381.     {
  382.       seqr->cur_cmd++;
  383.       seqr->vars[seq->long_args[seqr->cur_long_arg+1]] = seq->long_args[seqr->cur_long_arg];
  384.       seqr->cur_long_arg += 2;
  385.       break;
  386.     }
  387.  
  388.       case CMD_LOOP:
  389.     {
  390.       if (seqr->vars[seq->long_args[seqr->cur_long_arg]] > 0)
  391.       {
  392.         seqr->vars[seq->long_args[seqr->cur_long_arg]]--;
  393.  
  394.         CmdSequence* ns;
  395.         ns = &(seq->seq_args[seqr->cur_seq_arg]);
  396.         stack_idx++;
  397.         seqr = &stackr[stack_idx];
  398.         seq = stack[stack_idx] = ns;
  399.         seqr->start (seq);
  400.       }
  401.       else
  402.       {
  403.         seqr->cur_long_arg++;
  404.         seqr->cur_seq_arg++;
  405.         seqr->cur_cmd++;
  406.       }
  407.       break;
  408.     }
  409.  
  410.       case CMD_MOVE:
  411.     seqr->cur_cmd++;
  412.     if (type == CS_THING)
  413.     {
  414.       Thing* thing = (Thing*)object;
  415.       thing->move (seq->vec_args[seqr->cur_seq_arg++]);
  416.       thing->transform (); // @@@ This should be delayed until sure that the thing is really on screen.
  417.     }
  418.     else if (type == CS_COLLECTION)
  419.     {
  420.       Collection* col = (Collection*)object;
  421.       col->move (seq->vec_args[seqr->cur_seq_arg++]);
  422.       col->transform ();
  423.     }
  424.     break;
  425.  
  426.       case CMD_TRANSFORM:
  427.     seqr->cur_cmd++;
  428.     if (type == CS_THING)
  429.     {
  430.       Thing* thing = (Thing*)object;
  431.       thing->transform (seq->mat_args[seqr->cur_mat_arg++]);
  432.       thing->transform ();
  433.     }
  434.     else if (type == CS_COLLECTION)
  435.     {
  436.       Collection* col = (Collection*)object;
  437.       col->transform (seq->mat_args[seqr->cur_mat_arg++]);
  438.       col->transform ();
  439.     }
  440.     break;
  441.  
  442.       case CMD_WAIT:
  443.     seqr->cur_cmd++;
  444.     return FALSE;
  445.     }
  446.   }
  447.   return FALSE;
  448. }
  449.  
  450.  
  451. //---------------------------------------------------------------------------
  452.  
  453. TriggerList::TriggerList ()
  454. {
  455.   first_trigger = NULL;
  456. }
  457.  
  458. TriggerList::~TriggerList ()
  459. {
  460.   while (first_trigger)
  461.   {
  462.     Trigger* n = first_trigger->next;
  463.     delete first_trigger;
  464.     first_trigger = n;
  465.   }
  466. }
  467.  
  468. void TriggerList::add_trigger (Script* s, CsObject* object)
  469. {
  470.   Trigger* t = new Trigger ();
  471.   t->script = s;
  472.   t->next = first_trigger;
  473.   t->object = object;
  474.   first_trigger = t;
  475. }
  476.  
  477. void TriggerList::perform (World* w, CsObject* object)
  478. {
  479.   Trigger* t = first_trigger;
  480.   while (t)
  481.   {
  482.     w->run_script (t->script, t->object ? t->object : object);
  483.     t = t->next;
  484.   }
  485. }
  486.  
  487. //---------------------------------------------------------------------------
  488.