Advertisement
ZoriaRPG

Debug Cheat Shell (v1.14.4)

Nov 3rd, 2018
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 53.59 KB | None | 0 0
  1. /////////////////////////////////
  2. /// Debug Shell for ZC Quests ///
  3. /// Alpha Version 1.14.4      ///
  4. /// 3rd November, 2018        ///
  5. /// By: ZoriaRPG              ///
  6. /// Requires: ZC Necromancer  ///
  7. /////////////////////////////////
  8. //
  9. // v1.2   : Finished working code. now it all functions as I intend.
  10. // v1.2.1 : Added a code comment block with examples on how to add more instructions to match_instruction().
  11. // v1.2.1 : Added a sanity check to setting Link->Item[]. It now only works on inventory items.
  12. // v1.3.0 : Added the SAVE instruction.
  13. // v1.4.0 : Added CREATEITEM ( cri,id,x,y )
  14. // v1.4.0 : Added CREATENPC ( crn,id,x,y )
  15. // v1.4.0 : Fixed bug where buffer persists through saves.
  16. // v1.5.0 : Added LX and LY as literal args for Link's X and Y positions.
  17. // v1.6.0 : Added LX and LY tracing.
  18. // v1.6.0 : Added PALETTE as pal,n1,n2 -- POS now requires more than 'p' -- to change DMap Palette. -1 for current DMap.
  19. // v1.6.0 :       This sets Game->DmapPalette[n1] = n2
  20. // v1.6.0 : Added MONOCHROME as mon,n to set Graphics->Monochrome(n1)
  21. // v1.6.1 : Added break instructiosn to fix invalid rval and other invalid returns in switch statements.
  22. // v1.6.2 : Added clear instructions to case for NONE in switch(instr).
  23. // v1.7.0 : Added LTRIFORCE to set if Link has the triforce for a given level as 'lt,id,true|false'
  24. // v1.7.0 : Added LCOMPASS to set if Link has the compass for a given level as 'lc,id,true|false'
  25. // v1.7.0 : Added LMAP to set if Link has the map for a given level as 'lm,id,true|false'
  26. // v1.7.0 : Added LBOSSKEY to set if Link has the boss key for a given level as 'lb,id,true|false'
  27. // v1.7.0 : Added LKEYS to set the current number of LEVEL KEYS for a given level ID as 'lk,levelid,number'
  28. // v1.7.0 : Added BOMBS to set the current number of bombs as 'b,number'
  29. // v1.7.0 : Added MBOMBS to set the current number of max bombs as 'b,number'
  30. // v1.7.0 : Added ARROWS to set the current number of arrows as 'a,number'
  31. // v1.7.0 : Added MARROWS to set the current number of max arrows as 'a,number'
  32. // v1.7.0 : Added RUPEES to set the current number of rupees as 'r,number'
  33. // v1.7.0 : Added MRUPEES to set the current number of max rupees as 'r,number'
  34. // v1.7.0 : Added KEYS to set the current number of keys as 'k,number'
  35. // v1.7.0 : Added BIGHITBOX to set the if Link's hitbox is large (full tile collision), or small, as 'h,t|f'
  36. // v1.7.0 : Added LINKDIAGONAL to set the if Link may move diagonally, as 'd,t|f'
  37. // v1.7.1 : orrected a bug where RUPEES was using Game->Counter[RUPEES} insead of CR_RUPEES.
  38. // v1.7.1 : Added a NULL case for token[1] of command 'r', so that 'r' without any other legal char as the next token is RUPEES.
  39. // v1.8.0 : Added SETFFSCRIPT as 'fs,ffc_id,script_id'
  40. // v1.8.0 : Added SETFFCDATA as 'fs,ffc_id,combo_id'
  41. // v1.8.0 : Added RUNFFCSCRIPTID as 'run,script_id'
  42. // v1.8.0 : Fixed missing break statements in execute(stack) switch(instr).
  43. // v1.9.0 : Added HUE as 'hu,r,g,b,t|f'
  44. // v1.9.0 : Added TINT as 't,r,g,b'
  45. // v1.9.0 : Added CLEARTINT as 'cl'
  46. /* v1.10.0 :
  47.     Added all FFC vars:
  48.     fc FCSET; fx FX; fy FY; fvx FVX; fvy FVY; fax FAX ; fay FAY; ffl FFLAGS; fth FTHEIGHT; ftw FTWIDTH ; feh FEHEIGHT ; few FEWIDTH
  49.     fl FLINK; fm FMISC
  50.     Added PLAYSOUND as 'pls,sound_id'
  51.     Added PLAYMIDI as 'plm,midi_id'
  52.     Added DMAPMIDI as 'dmm,dmap_id,midi_id'
  53. */
  54. // v1.10.1 : Added KEY_STOP (period) to the list of legal keys, to permit floating point values.
  55. // v1.10.1 : Fixed a bug where instructions missing params would not abort, and clear Start presses on abort().
  56. /* v1.11.0 :
  57.     The key used to open the shell is now a config option, with a base setting of F7.
  58.     Added an instruction QUEUE. You can now store up to 20 instructions.
  59.     Press the DOWN ARROW KEY to store an instruction.
  60.     Press the ENTER key on an empty line to process all stored instructions.
  61. */
  62. /* v1.11.1 :
  63.     Fixed some issues with the number of ENQUEUED instructions being offset based on whether the user tried
  64.     to press the ENTER key on an empty line, or on a line with an instruction.
  65. */
  66. /* v1.11.2 : Further patches to enqueued counts and behaviour.
  67.     Both of these now work properly, without any error codes.
  68.     I converted 'bool type()' into 'int type()' and now I return three possible conditions:
  69.         NONE: The user escaped out of the shell, or there were no instructions to process on pressing ENTER.
  70.         ENQUEUE: There are instructions in the queue.
  71.         RAW : This is when there is only one instruction, and no prior instructions entered,
  72.             and the user presses ENTER.
  73. */
  74.  
  75. // v1.12.0 : Added 'h,value' for SETLIFE.
  76. // v1.12.0 : Added 'm,value' for SETMAGIC.
  77. // v1.12.0 : Added 'co,counter_id,value' for SETCOUNTER.
  78. // v1.12.0 : Changed BIGHITBOX from 'h,t|f' to 'hb,t|f'.
  79.  
  80. // v1.13.0 : Begin adding SEQUENCES to save a sequence of instructions. Added ten sequence slots.
  81. // v1.13.0 : To save a sequence, hold CONTROL and press a main row number from 1 through 0.
  82. // v1.13.0 : That number will be the SEQUENCE SLOT that you are using. Sequences can be saved!
  83. // v1.13.0 : To run a sequence, open the shell and type RunSequence,id : This command is CaSe-SeNsItIvE!
  84. // v1.13.1 : WTF? I found a parser bug. Scan the file for 'parser' to read more.
  85. // v1.13.2 : Created a temporary work-around for the parser bug and fixed the save/read SEQUENCE functions.
  86. // v1.13.2 : Sequences now seem to work.
  87. // v1.14.0 : Added TRACE as an instruction to print to log. This uses the format of:
  88. // v1.14.0 : %s:string -- traces 'string' to the log.
  89. // v1.14.0 : %d:value -- traces value to the log.
  90. // v1.14.1 : Patched error in the offset of TRACE copying into temp buffers.
  91. // v1.14.1 : Increased size of MAX_TOKEN_LENGTH from 16 to 100, to allow for strings.
  92. // v1.14.1 : Fixed call to atof() in TRACE for token %d
  93. // v1.14.1 : Removed extraneous spaces and colons in strings inside calls to TrqaceError*()
  94. // v1.14.2 : TRACE now eats all leading spaces and colons, instead of using a hardcoded offset.
  95. // v1.14.3 : Moved a number of traces into 'if ( log_actions ) ' statements, and disabled others.
  96. // v1.14.4 : Fixed a bug where holding down a shift key would only modify the very next character.
  97.  
  98.  
  99.  
  100.  
  101. import "std.zh"
  102.  
  103. /*
  104. DEFINED INSTRUCTION VALUES
  105.     w WARP: return 2;   //dmap,screen
  106.     p POS: return 2;        //x,y
  107.     mx MOVEX: return 1;     //pixels (+/-)
  108.     my MOVEY: return 1;     //pixels (+/-)
  109.     rh REFILLHP: return 0;  //aNONE
  110.     rm REFILLMP: return 0;  //NONE
  111.     rc REFILLCTR: return 1; //counter
  112.     mh MAXHP: return 1; //amount
  113.     mm MAXMP: return 1; //amount
  114.     mc MAXCTR: return 2;    //counter, amount
  115.     save SAVE: return 0;   
  116.     cri CREATEITEM: return 3;   //id, x, y
  117.     crn CREATENPC: return 3;    //id, x, y
  118.    
  119.     inv INVINCIBLE: return 1;   //(BOOL) on / off
  120.     itm LINKITEM: return 2; //item, (BOOL), on / off
  121.     pal PALETTE return 2
  122.     mon MONOCHROME return 1
  123.    
  124.     h BIGHITBOX
  125.     d LINKDIAGONAL
  126.    
  127.     a ARROWS
  128.     b BOMBS
  129.     r RUPEES
  130.     mb MAXBOMBS
  131.     ma MAXARROWS
  132.     mr MAXRUPEES
  133.     k KEYS
  134.     lk LKEYS
  135.     lm LMAP
  136.     lc LCOMPASS
  137.     lt LTRIFORCE
  138.    
  139.     hu HUE
  140.     t TINT
  141.     cl CLEARTINT
  142.    
  143.     fc FCSET
  144.     fx FX
  145.     fy FY
  146.     fvx FVX
  147.     fvy FVY
  148.     fax FAX
  149.     fay FAY
  150.     ffl FFLAGS
  151.     fth FTHEIGHT
  152.     ftw FTWIDTH
  153.     feh FEHEIGHT
  154.     few FEWIDTH
  155.     fl FLINK
  156.     fm FMISC
  157.    
  158.     pls PLAYSOUND
  159.     plm PLAYMIDI
  160.     dmm DMAPMIDI
  161.  
  162. //COMMAND LIST
  163.     w: Warp Link to a specific dmap and screen
  164.     p: Reposition Link on the screen.
  165.     mx: Move link by +/-n pixels on the X axis.
  166.     my: Move link by +/-n pixels on the Y axis.
  167.     rh: Refill Link's HP to Max.
  168.     rm: Refill Link's HP to Max.
  169.     rc: Refill a specific counter to Max.
  170.     mh: Set Link's Max HP.
  171.     mm: Set Link's Max MP
  172.     mc: Set the maximum value of a specific counter.
  173.     inv: Set Link's Invisible state.
  174.     itm: Set the state of a specific item in Link's inventory.
  175.     save: Save the game.
  176.     cri: Create an item.
  177.     crn: Create an npc.
  178.     pal: Change a DMap palette; -1 for current dmap.
  179.     mono: Set monochrome effect.
  180.    
  181.     h: Set if Link uses a full tile hitbox. (hitbox)
  182.     d: Set if Link can move diagonally.
  183.    
  184.     a: Set the current number of Arrows
  185.     b: Set the current number of Bombs
  186.     r: Set the current number of Rupees
  187.     mb: Set the current number of Max Bombs
  188.     ma: Set the current number of Max Arrows
  189.     mr: Set the current number of Max Rupees
  190.     k: Set the current number of Keys
  191.     lk: Set the current number of Level Keys for a specific level ID.
  192.     lm: Set if the MAP item for a specific Level is in inventory.
  193.     lc: Set if the COMPASS item for a specific Level is in inventory.
  194.     lt: Set if the TRIFORCE item for a specific Level is in inventory.
  195.     lb: Set if the BOSS KEy item for a specific Level is in inventory.
  196.    
  197.     fd: Set the Data value of one ffc.
  198.     fs: Set the Script value of one ffc.
  199.     run: Attempt to run an ffc script.
  200.    
  201.     hu: Set a specific hue effect.
  202.     t: Set a specific tint effect.
  203.     cl: Clear hue/tint.
  204.    
  205.     fc: Set the CSet of an ffc.
  206.     fx: Set the X component of an ffc.
  207.     fy: Set the Y component of an ffc.
  208.     fvx: Set the X Velocity Component of an ffc.
  209.     fvy: Set the Y Velocity Component of an ffc.
  210.     fax: Set the X Accel. Component of an ffc.
  211.     fay: Set the XYAccel. Component of an ffc.
  212.    
  213.     ffl: Set an ffc flag state true or false.
  214.     fth: Set the TileHeight of an ffc.
  215.     ftw: Set the TileWidth of an ffc.
  216.     feh: Set the EffectHeight of an ffc.
  217.     few: Set the EffectWidth of an ffc.
  218.     fl: Link an ffc to another, or clear a link.
  219.     fm: Write to the Misc[] values of an ffc.
  220.    
  221.     pls: Play a sound effect.
  222.     plm: Play a MIDI.
  223.     dmm: Set the MIDI for a specific DMap to a desired ID.
  224.    
  225. //SYNTAX
  226. //command,args
  227.     w,1,2
  228.     p,1,2
  229.     mx,1
  230.     mx,-1
  231.     my,1
  232.     my,-1
  233.     rh
  234.     rm
  235.     rc,1
  236.     mh,1
  237.     mm,1
  238.     mc,1,2
  239.     inv,true
  240.     inv,false
  241.     itm,1,true
  242.     itm,1,false
  243.     save
  244.     cri,1,2,3 //id,x,y
  245.     crn,1,2,3 //id,x,y
  246.     pal,1,2 //dmap (-1 for current), palette
  247.     mono,1 : mono,type
  248.     h,true|false
  249.     d,true|false
  250.    
  251.     a,1
  252.     b,1
  253.     r,1
  254.     mb,1
  255.     ma,1
  256.     mr,1
  257.     k,1
  258.     lk,1,2 (level id, number)
  259.     lm,1,t|f (level id, true|false)
  260.     lc,1,t|f (level id, true|false)
  261.     lt,1,t|f (level id, true|false)
  262.     lb,1,t|f (level id, true|false)
  263.    
  264.     fd,1,2 (fs,ffc_id,combo_id)
  265.     fs,1,2 (fs,ffc_id,script_id)
  266.     run,1 (run,ffc_script_id)
  267.    
  268.     hu,1,2,3,t|f (hu,red,green,blue,true|false)
  269.     t,1,2,3 (t,red,green,blue)
  270.     cl
  271.    
  272.     fc,1,2 (fs,ffc_id,cset)
  273.     fx,1,2 (fs,ffc_id,x)
  274.     fy,1,2 (fs,ffc_id,y)
  275.     fvx,1,2 (fs,ffc_id,vx)
  276.     fvy,1,2 (fs,ffc_id,vy)
  277.     fax,1,2 (fs,ffc_id,ax)
  278.     fay,1,2 (fs,ffc_id,ay)
  279.    
  280.     ffl,1,2,t|f  (fs,ffc_id,flag,true|false)
  281.     fth,1,2 (fs,ffc_id,tileheight)
  282.     ftw,1,2 (fs,ffc_id,tilewidth)
  283.     feh,1,2 (fs,ffc_id,effectheight)
  284.     few,1,2 (fs,ffc_id,effectwidth)
  285.     fl,1,2 (fs,ffc_id,link_id)
  286.     fm,1,2,3 (fs,ffc_id,index,value)
  287.    
  288.     pls,1 (pls,sound_id)
  289.     plm,1 (pls,midi_id)
  290.     dmm,1,2 (dmm,dmap_id,midi_id)
  291.    
  292.        
  293.  
  294. */
  295.  
  296. script typedef ffc namespace;
  297. typedef const int define;
  298. typedef const int CFG;
  299.  
  300.  
  301.  
  302. namespace script debugshell
  303. {
  304.     CFG INVISIBLE_COMBO = 1;
  305.    
  306.     define INSTRUCTION_SIZE = 1; //The number of stack registers that any given *instruction* requires.
  307.     define MAX_INSTR_QUEUE = 20; //The number of instructions that can be enqueued.
  308.     define MAX_ARGS     = 4; //The maximum number of args that any instruction can use/require.
  309.     define STACK_SIZE   = 2 + ((INSTRUCTION_SIZE+MAX_ARGS)*MAX_INSTR_QUEUE);  //+2 now includes TOP
  310.     define MAX_TOKEN_LENGTH = 100;
  311.     define BUFFER_LENGTH    = 42;
  312.     int stack[STACK_SIZE];
  313.     int SP;
  314.     int ENQUEUED;
  315.     define TOP = ((INSTRUCTION_SIZE+MAX_ARGS)*MAX_INSTR_QUEUE)+1;
  316.     int debug_buffer[BUFFER_LENGTH];
  317.     define rERROR = 0;
  318.     define rRAW = 1;
  319.     define rENQUEUED = 2;
  320.     define SEQUENCES = 10;
  321.     int sequences[(STACK_SIZE+1)*SEQUENCES];
  322.    
  323.    
  324.     void runsequence(int id)
  325.     {
  326.         int seq[STACK_SIZE+1];
  327.         ENQUEUED = sequences[(id*STACK_SIZE)+STACK_SIZE]-1; //the last value is the number of instructions that were enqueued.
  328.         if ( log_actions ) TraceError("Sequence ENQUEUED is: ",ENQUEUED);
  329.         //int seq_max = (id*STACK_SIZE)+STACK_SIZE;
  330.         for ( int q = 0; q < STACK_SIZE; ++q ) seq[q] = sequences[id*(STACK_SIZE+1)+q]; //copy the sequence set to the temp stack.
  331.         if ( log_actions ) TraceErrorS("Tracing sequence stack.", " ");
  332.         if ( log_actions ) TraceStack(seq);
  333.         execute(seq); //run the temp stack.
  334.     }
  335.     int savesequence(int id)
  336.     {
  337.         if ( log_actions ) TraceError("Saving sequence, ID: ",id);
  338.         //int seq_max = (id*STACK_SIZE)+STACK_SIZE;
  339.         for ( int q = 0; q < STACK_SIZE; ++q )
  340.         {
  341.             sequences[(id*(STACK_SIZE+1))+q] = stack[q];
  342.         }
  343.         sequences[(id*STACK_SIZE)+STACK_SIZE] = ENQUEUED;
  344.         ENQUEUED = 0;
  345.         clearstack();
  346.         abort();
  347.         return id;
  348.     }
  349.     int sizeof(int p) { return SizeOfArray(p); }
  350.    
  351.     define YES = 1;
  352.     define NO = 0;
  353.    
  354.     CFG log_actions = NO;
  355.     CFG WINDOW_F_KEY = 53; //We use F7 to open the debug window.
  356.    
  357.    
  358.     define FONT = FONT_APPLE2; //Apple II
  359.     define F_COLOUR = 0x01; //font colour, white
  360.     define F_BCOLOUR = -1; //font background colour, translucent
  361.     define W_COLOUR = 0x03; //window colour (background), black
  362.     define W_S_COLOUR = 0xC5; //window colour (background), black
  363.     define CHAR_WIDTH = 6; //5 + one space
  364.     define CHAR_HEIGHT = 9; //8 + one space
  365.     define WINDOW_X = 15; //window indent over screen
  366.     define WINDOW_Y = 19; //window indent over screen
  367.     define WINDOW_H = 50;//CHAR_WIDTH * BUFFER_LENGTH;
  368.     define WINDOW_W = 180; //CHAR_HEIGHT * 3;
  369.     define WINDOW_S_X = 12; //window indent over screen
  370.     define WINDOW_S_Y = 16; //window indent over screen
  371.     define WINDOW_S_H = 50; //CHAR_WIDTH * BUFFER_LENGTH;
  372.     define WINDOW_S_W = 180; //CHAR_HEIGHT * 3;
  373.     define CHAR_X = 2; //Initial x indent
  374.     define CHAR_Y = 2; //Initial y indent
  375.     define W_OPACITY = OP_OPAQUE; //Window translucency.
  376.     define F_OPACITY = OP_OPAQUE; //Font translucency.
  377.     define W_LAYER = 6; //window draw layer
  378.     define F_LAYER = 6; //font draw layer
  379.    
  380.     CFG KEY_DELAY = 6; //frames between keystrokes
  381.    
  382.     define TYPESFX = 63;
  383.    
  384.     void process()
  385.     {
  386.         if ( Input->ReadKey[WINDOW_F_KEY] ) //46+WINDOW_F_KEY] )
  387.         {
  388.             if ( log_actions ) TraceS("Enabled Debug Shell");
  389.             int typeval = type();
  390.             if ( typeval == rRAW ) //maybe type should be int with 0 being no return, 1 being enqueued, and 2 being raw?
  391.             {
  392.                 if ( log_actions ) TraceS("process() evaluated type() true");
  393.                 if ( !ENQUEUED )
  394.                 {
  395.                     int r = read(debug_buffer,false);
  396.                     if ( r ) execute(stack);
  397.                 }
  398.                 else execute(stack);
  399.             }
  400.             else if ( typeval == rENQUEUED ) //maybe type should be int with 0 being no return, 1 being enqueued, and 2 being raw?
  401.             {
  402.                 if ( log_actions ) TraceS("process() evaluated type() true");
  403.                 --ENQUEUED;
  404.                 execute(stack);
  405.             }
  406.             else
  407.             {
  408.                 if ( log_actions ) TraceErrorS("type() returned: ", "false");
  409.                 Link->PressStart = false;
  410.                 Link->InputStart = false;
  411.             }
  412.         }
  413.     }
  414.    
  415.     //if ( type() execute(stack) )
  416.     //returns true if the user presses enter
  417.     int type()
  418.     {
  419.         int frame = 0;
  420.         if ( !frame && log_actions ) TraceS("Starting type()");
  421.         ++frame;
  422.         Game->TypingMode = true;
  423.         int key_timer; int buffer_pos = 0;
  424.         bool typing = true; int e;
  425.         //while(!Input->ReadKey[KEY_ENTER] || Input->ReadKey[KEY_ENTER_PAD])
  426.         while(typing)
  427.         {
  428.             //if ( key_timer <= 0 )
  429.             //{
  430.                 if ( Input->ReadKey[KEY_BACKSPACE] ) //backspace
  431.                 {
  432.                    
  433.                     if ( buffer_pos > 0 )
  434.                     {
  435.                         debug_buffer[buffer_pos] = 0;
  436.                         --buffer_pos;
  437.                         debug_buffer[buffer_pos] = 0;
  438.                     }
  439.                     key_timer = KEY_DELAY;
  440.                     continue;
  441.                 }
  442.                 else if ( Input->ReadKey[KEY_DOWN] )
  443.                 {
  444.                     e = enqueue();
  445.                     if ( log_actions ) TraceError("type() enqueued an instruction, queue ID: ", e);
  446.                    
  447.                 }
  448.                 else if ( Input->ReadKey[KEY_ENTER] || Input->ReadKey[KEY_ENTER_PAD] )
  449.                 {
  450.                     Game->TypingMode = false;
  451.                     //TraceNL(); TraceS("Read enter key, and buffer position is: "); Trace(buffer_pos); TraceNL();
  452.                     if ( !buffer_pos )
  453.                     {
  454.                         if ( !ENQUEUED ) return 0; //do not execute if there are no commands
  455.                         else return rENQUEUED;
  456.                     }
  457.                     else //we've typed something
  458.                     {
  459.                         if ( ENQUEUED )
  460.                         {
  461.                             e = enqueue(); return rENQUEUED; //also enqueue this line
  462.                         }
  463.                         else return rRAW;
  464.                     }
  465.                 }
  466.                 else if ( Input->Key[KEY_LCONTROL] || Input->Key[KEY_RCONTROL] )
  467.                 {
  468.                     if ( Input->ReadKey[KEY_0] ) { savesequence(0); return 0; }
  469.                     else if ( Input->ReadKey[KEY_1] ) { savesequence(1); return 0; }
  470.                     else if ( Input->ReadKey[KEY_2] ) { savesequence(2); return 0; }
  471.                     else if ( Input->ReadKey[KEY_3] ) { savesequence(3); return 0; }
  472.                     else if ( Input->ReadKey[KEY_4] ) { savesequence(4); return 0; }
  473.                     else if ( Input->ReadKey[KEY_5] ) { savesequence(5); return 0; }
  474.                     else if ( Input->ReadKey[KEY_6] ) { savesequence(6); return 0; }
  475.                     else if ( Input->ReadKey[KEY_7] ) { savesequence(7); return 0; }
  476.                     else if ( Input->ReadKey[KEY_8] ) { savesequence(8); return 0; }
  477.                     else if ( Input->ReadKey[KEY_9] ) { savesequence(9); return 0; }
  478.                 }
  479.                 else if ( EscKey() )
  480.                 {
  481.                     for ( int q = 0; q < BUFFER_LENGTH; ++q ) debug_buffer[q] = 0;
  482.                     clearstack();
  483.                    
  484.                     Game->TypingMode = false;
  485.                     return 0; //exit and do not process.
  486.                 }
  487.                
  488.                 else
  489.                 {
  490.                     //else normal key
  491.                     int k;
  492.                     int LegalKeys[]=
  493.                     {
  494.                         KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H,
  495.                         KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P,
  496.                         KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X,
  497.                         KEY_Y, KEY_Z, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
  498.                         KEY_6, KEY_7, KEY_8, KEY_9, KEY_0_PAD, KEY_1_PAD, KEY_2_PAD,
  499.                         KEY_3_PAD, KEY_4_PAD, KEY_5_PAD,
  500.                         KEY_6_PAD, KEY_7_PAD, KEY_8_PAD, KEY_9_PAD, KEY_STOP, //period
  501.                         KEY_TILDE,
  502.                         KEY_MINUS,
  503.                         KEY_EQUALS, KEY_OPENBRACE, KEY_CLOSEBRACE,
  504.                         KEY_COLON, KEY_QUOTE, KEY_BACKSLASH, KEY_BACKSLASH2,
  505.                         KEY_COMMA,
  506.                         KEY_SEMICOLON, KEY_SLASH, KEY_SPACE, KEY_SLASH_PAD,
  507.                         KEY_ASTERISK,
  508.                         KEY_MINUS_PAD,
  509.                         KEY_PLUS_PAD, KEY_CIRCUMFLEX, KEY_COLON2, KEY_EQUALS_PAD, KEY_STOP
  510.                     };
  511.  
  512.                    
  513.                     for ( int kk = SizeOfArray(LegalKeys)-1; kk >= 0; --kk )
  514.                     {
  515.                         k = LegalKeys[kk];
  516.                         if ( Input->ReadKey[k] )
  517.                         {
  518.                             //TraceS("Read a key: "); Trace(k); TraceNL();
  519.                             debug_buffer[buffer_pos] = KeyToChar(k,(Input->Key[KEY_LSHIFT])||(Input->Key[KEY_RSHIFT])); //Warning!: Some masking may occur. :P
  520.                             //TraceNL(); TraceS(debug_buffer); TraceNL();
  521.                             ++buffer_pos;
  522.                             key_timer = KEY_DELAY;
  523.                             break;
  524.                         }
  525.                     }
  526.                    
  527.                     //continue;
  528.                 }
  529.             //}
  530.             //else { --key_timer; }
  531.             if ( e )
  532.             {
  533.                 clearbuffer();
  534.                 buffer_pos = 0;
  535.                 e = 0;
  536.             }
  537.             draw();
  538.             Waitframe();
  539.         }
  540.        
  541.     }
  542.    
  543.     void draw()
  544.     {
  545.         Screen->Rectangle(W_LAYER, WINDOW_S_X, WINDOW_S_Y, WINDOW_S_X+WINDOW_W, WINDOW_S_Y+WINDOW_H, W_S_COLOUR, 1, 0,0,0,true,W_OPACITY);
  546.         Screen->Rectangle(W_LAYER, WINDOW_X, WINDOW_Y, WINDOW_X+WINDOW_W, WINDOW_Y+WINDOW_H, W_COLOUR, 1, 0,0,0,true,W_OPACITY);
  547.         Screen->DrawString(F_LAYER,WINDOW_X+CHAR_X,WINDOW_Y+CHAR_Y,FONT,F_COLOUR,F_BCOLOUR,0,debug_buffer,F_OPACITY);
  548.     }
  549.    
  550.     void TraceErrorS(int s, int s2)
  551.     {
  552.         TraceS(s); TraceS(": "); TraceS(s2); TraceNL();
  553.     }
  554.    
  555.     void TraceError(int s, float v, float v2)
  556.     {
  557.         int buf[12]; int buf2[12];
  558.         ftoa(buf,v);
  559.         ftoa(buf2,v2);
  560.         TraceS(s); TraceS(": "); TraceS(buf); TraceS(", "); TraceS(buf2); TraceNL();
  561.     }
  562.    
  563.     void TraceErrorVS(int s, float v, int s2)
  564.     {
  565.         int buf[12];
  566.         ftoa(buf,v);
  567.         TraceS(s); TraceS(": "); TraceS(buf); TraceS(", "); TraceS(s2); TraceNL();
  568.     }
  569.    
  570.     //instruction       //variables
  571.     define NONE =   0;  //NONE
  572.     define WARP     =   1;  //dmap,screen
  573.     define POS  =   2;  //x,y
  574.     define MOVEX    =   3;  //pixels (+/-)
  575.     define MOVEY    =   4;  //pixels (+/-)
  576.     define REFILLHP =   5;  //aNONE
  577.     define REFILLMP =   6;  //NONE
  578.     define REFILLCTR =  7;  //counter
  579.     define MAXHP    =   8;  //amount
  580.     define MAXMP    =   9;  //amount
  581.     define MAXCTR   =   10; //counter, amount
  582.    
  583.     define INVINCIBLE =     11; //(BOOL) on / off
  584.     define LINKITEM =   12; //item, (BOOL), on / off
  585.     define SAVE =       13; //item, (BOOL), on / off
  586.     define CREATEITEM =     14; //item, (BOOL), on / off
  587.     define CREATENPC =  15; //item, (BOOL), on / off
  588.     define PALETTE =    16; //item, (BOOL), on / off
  589.     define MONOCHROME =     17; //item, (BOOL), on / off
  590.     define BOMBS =      18; //item, (BOOL), on / off
  591.     define MBOMBS =     19; //item, (BOOL), on / off
  592.     define ARROWS =     20; //item, (BOOL), on / off
  593.     define MARROWS =    21; //item, (BOOL), on / off
  594.     define KEYS =       22; //item, (BOOL), on / off
  595.     define LKEYS =      23; //item, (BOOL), on / off
  596.     define RUPEES =     24; //item, (BOOL), on / off
  597.     define MRUPEES =    25; //item, (BOOL), on / off
  598.     define LMAP =       26; //level map, level id, true|false
  599.     define LBOSSKEY =   27; //level map, level id, true|false
  600.     define BIGHITBOX =  28; //level map, level id, true|false
  601.     define LINKDIAGONAL =   29; //level map, level id, true|false
  602.     define LTRIFORCE =  30; //level map, level id, true|false
  603.     define LCOMPASS =   31; //level map, level id, true|false
  604.     define RUNFFCSCRIPTID = 32;
  605.     define SETFFSCRIPT =    33;
  606.     define SETFFDATA =  34;
  607.    
  608.     define TINT =       35;
  609.     define HUE =        36;
  610.     define CLEARTINT =  37;
  611.    
  612.     define FCSET =      38;
  613.     define FX =     39;
  614.     define FY =     40;
  615.     define FVX =        41;
  616.     define FVY =        42;
  617.     define FAX =        43;
  618.     define FAY =        44;
  619.     define FFLAGS =     45; //ffc flags
  620.     define FTHEIGHT =   46;
  621.     define FTWIDTH =    47;
  622.     define FEHEIGHT =   48;
  623.     define FEWIDTH =    49;
  624.     define FLINK =      50;
  625.     define FMISC =      51;
  626.    
  627.     define PLAYSOUND =  52;
  628.     define PLAYMIDI =   53;
  629.     define DMAPMIDI =   54;
  630.    
  631.     define SETLIFE =    55;
  632.     define SETMAGIC =   56;
  633.     define SETCOUNTER = 57;
  634.    
  635.     define SAVESEQUENCE =   58;
  636.     define RUNSEQUENCE =    59;
  637.    
  638.     define TRACE =      60;
  639.    
  640.    
  641.    
  642.    
  643.    
  644.     int num_instruction_params(int instr)
  645.     {
  646.         switch(instr)
  647.         {
  648.             //instruction       //variables
  649.             case NONE: return 0;
  650.             case WARP: return 2;    //dmap,screen
  651.             case POS: return 2;     //x,y
  652.             case MOVEX: return 1;   //pixels (+/-)
  653.             case MOVEY: return 1;   //pixels (+/-)
  654.             case REFILLHP: return 0;    //aNONE
  655.             case REFILLMP: return 0;    //NONE
  656.             case REFILLCTR: return 1;   //counter
  657.             case MAXHP: return 1;   //amount
  658.             case MAXMP: return 1;   //amount
  659.             case MAXCTR: return 2;  //counter, amount
  660.            
  661.             case INVINCIBLE: return 1;  //(BOOL) on / off
  662.             case LINKITEM: return 2;    //item, (BOOL), on / off
  663.             case SAVE: return 0;    //item, (BOOL), on / off
  664.             case CREATEITEM: return 3;  //item, (BOOL), on / off
  665.             case CREATENPC: return 3;   //item, (BOOL), on / off
  666.             case PALETTE: return 2; //item, (BOOL), on / off
  667.             case MONOCHROME: return 1;  //item, (BOOL), on / off
  668.            
  669.             case BOMBS: return 1;
  670.             case MBOMBS: return 1;
  671.             case ARROWS: return 1;
  672.             case MARROWS: return 1;
  673.             case KEYS: return 1;
  674.             case LKEYS: return 2; //level, number
  675.             case RUPEES: return 1;
  676.             case MRUPEES: return 1;
  677.             case LMAP: return 2;    //level map, level id, true|false
  678.             case LBOSSKEY: return 2;    //level bosskey, level id, true|false
  679.             case LTRIFORCE: return 2;   //level bosskey, level id, true|false
  680.             case LCOMPASS: return 2;    //level bosskey, level id, true|false
  681.             case BIGHITBOX: return 1;   //true|false
  682.             case LINKDIAGONAL: return 1;    //true|false
  683.             case RUNFFCSCRIPTID: return 1;
  684.             case SETFFSCRIPT: return 2;
  685.             case SETFFDATA: return 2;
  686.            
  687.             case TINT: return 3;
  688.             case HUE: return 4;
  689.             case CLEARTINT: return 0;
  690.            
  691.             case FCSET: return 2;
  692.             case FX: return 2;
  693.             case FCSET: return 2;
  694.             case FX: return 2;
  695.             case FY: return 2;
  696.             case FVX: return 2;
  697.             case FVY: return 2;
  698.             case FAX: return 2;
  699.             case FAY: return 2;
  700.             case FFLAGS: return 3;
  701.             case FTHEIGHT: return 2;
  702.             case FTWIDTH: return 2;
  703.             case FEHEIGHT: return 2;
  704.             case FEWIDTH: return 2;
  705.             case FLINK: return 2;
  706.             case FMISC: return 3;
  707.            
  708.             case PLAYSOUND: return 1;
  709.             case PLAYMIDI: return 1;
  710.             case DMAPMIDI: return 3;
  711.            
  712.             case SETLIFE: return 1;
  713.             case SETMAGIC: return 1;
  714.             case SETCOUNTER: return 2;
  715.            
  716.             case SAVESEQUENCE: return 1;
  717.             case RUNSEQUENCE: return 1;
  718.             case TRACE: return 0;
  719.    
  720.             default:
  721.             {
  722.                
  723.                 TraceError("Invalid instruction passed to stack",instr);
  724.                 clearbuffer();
  725.                 return 0;
  726.             }
  727.         }
  728.     }
  729.    
  730.    
  731.    
  732.     int match_instruction(int token)
  733.     {
  734.         if ( log_actions )  {TraceNL(); TraceS("Input token into match_instruction is: "); TraceS(token); TraceNL();}
  735.        
  736.         if ( log_actions ) {TraceNL(); TraceErrorS("match_instruction() token is: ",token); TraceNL();}
  737.         if ( log_actions ) {TraceNL(); TraceError("Matching string with strcmp to 'w': ", strcmp(token,"w")); TraceNL();}
  738.        
  739.         /* ONE WAY TO DO THIS. I did this with individual characters, and switches, to minimise the checks down
  740.         to the absolute minimum. -Z
  741.        
  742.         You could add specific instructions this way, if you wish.
  743.        
  744.         if ( !(strcmp(token,"w") ) ) TraceErrorS("Token in match_instruction() matched to WARP. Token: ", token);
  745.         if ( !(strcmp(token,"W") ) ) TraceErrorS("Token in match_instruction() matched to WARP. Token: ", token);
  746.         if ( !(strcmp(token,"p") ) ) TraceErrorS("Token in match_instruction() matched to POS. Token: ", token);
  747.         if ( !(strcmp(token,"P") ) ) TraceErrorS("Token in match_instruction() matched to POS. Token: ", token);
  748.         if ( !(strcmp(token,"rh") ) ) TraceErrorS("Token in match_instruction() matched to REFILLHP. Token: ", token);
  749.         if ( !(strcmp(token,"RH") ) ) TraceErrorS("Token in match_instruction() matched to REFILLHP. Token: ", token);
  750.         if ( !(strcmp(token,"Rh") ) ) TraceErrorS("Token in match_instruction() matched to REFILLHP. Token: ", token);
  751.         if ( !(strcmp(token,"rH") ) ) TraceErrorS("Token in match_instruction() matched to REFILLHP. Token: ", token);
  752.         if ( !(strcmp(token,"rH") ) ) TraceErrorS("Token in match_instruction() matched to REFILLHP. Token: ", token);
  753.         */
  754.        
  755.         /* Putting BRACES here causes Invalid pointer errors?! PARSER BUG!!
  756.         it works just find without the braces!!
  757.         if ( !(strcmp(token,"RunSequence") ) )
  758.         {
  759.             TraceErrorS("Found token RunSequence", token); // return RUNSEQUENCE; }//TraceErrorS("Token in match_instruction() matched to POS. Token: ", token);
  760.         }
  761.         */
  762.             //if ( !(strcmp(token,"RunSequence") ) ) { TraceError("Found token RunSequence", " "); return RUNSEQUENCE; }
  763.         //if ( !(strcmp(token,"SaveSequence") ) ) return SAVESEQUENCE;
  764.        
  765.         int sc;
  766.         if ( !(strcmp(token,"RunSequence") ) ) sc = RUNSEQUENCE;
  767.         if ( sc == RUNSEQUENCE ) { TraceError("Found token RunSequence", " "); return RUNSEQUENCE;}
  768.        
  769.         switch(token[0])
  770.         {
  771.             case '%':
  772.             {
  773.                 switch(token[1])
  774.                 {
  775.                     case 's':
  776.                     case 'S':
  777.                     {
  778.                         //TraceS(token);
  779.                         int buf[MAX_TOKEN_LENGTH];
  780.                         //Trace(buf);
  781.                         int offset = 2;
  782.                         for ( ; (token[offset] == ' ' || token[offset] == ':'); ++offset ) continue; //destroy leading spaces
  783.                        
  784.                         for ( int qq = offset; qq < MAX_TOKEN_LENGTH; ++qq )
  785.                         {
  786.                             buf[qq-offset] = token[qq];
  787.                         }
  788.                         TraceErrorS("Log",buf);
  789.                         //TraceS(buf);
  790.                         return TRACE;
  791.                     }
  792.                     case 'd':
  793.                     case 'D':
  794.                     {
  795.                         int buf[MAX_TOKEN_LENGTH];
  796.                         int offset = 2;
  797.                         for ( ; (token[offset] == ' ' || token[offset] == ':'); ++offset ) continue; //destroy leading spaces
  798.                        
  799.                         for ( int q = offset; q < MAX_TOKEN_LENGTH; ++q )
  800.                         {
  801.                             buf[q-offset] = token[q];
  802.                         }
  803.                         int tmp = atof(buf);
  804.                        
  805.                         TraceError("Log",tmp);
  806.                        
  807.                         return TRACE;
  808.                     }
  809.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  810.                 }
  811.                 break;
  812.             }
  813.             //A
  814.             case 'a':
  815.             case 'A':
  816.                 return ARROWS;
  817.             //B
  818.             case 'b':
  819.             case 'B':
  820.             {
  821.                 return BOMBS;
  822.                 /*
  823.                 switch(token[1])
  824.                 {
  825.                     case 'i':
  826.                     case 'I':
  827.                         return BIGHITBOX;
  828.                     case 'o':
  829.                     case 'O':
  830.                         return BOMBS;
  831.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  832.                 }
  833.                 */
  834.             }
  835.             case 'c':
  836.             case 'C':
  837.             {
  838.                 switch(token[1])
  839.                 {
  840.                     case NULL:
  841.                     case 'o':
  842.                     case 'O':
  843.                         return SETCOUNTER;
  844.                     case 'l':
  845.                     case 'L':
  846.                         return CLEARTINT;
  847.                     case 'r':
  848.                     case 'R':
  849.                     {
  850.                         switch(token[2])
  851.                         {
  852.                             case 'i':
  853.                             case 'I':
  854.                             {
  855.                                 //TraceNL(); TraceS("instr() found token 'cri'"); TraceNL();
  856.                                 return CREATEITEM;
  857.                             }
  858.                            
  859.                             case 'n':
  860.                             case 'N':
  861.                             {
  862.                                 //TraceNL(); TraceS("instr() found token 'cri'"); TraceNL();
  863.                                 return CREATENPC;
  864.                             }
  865.                
  866.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  867.                         }
  868.                     }
  869.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  870.                 }
  871.                 break;
  872.             }
  873.             //D
  874.             case 'd':
  875.             case 'D':
  876.             {
  877.                 switch(token[1])
  878.                 {
  879.                     case NULL:
  880.                     case 'i':
  881.                     case 'I':
  882.                         return LINKDIAGONAL;
  883.                     case 'm':
  884.                     case 'M': //dmap stuff
  885.                     {
  886.                         switch(token[2])
  887.                         {
  888.                            
  889.                             case NULL:
  890.                             case 'm':
  891.                             case 'M':
  892.                                 return DMAPMIDI;
  893.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  894.                
  895.                         }
  896.                     }  
  897.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  898.                
  899.                 }
  900.                 break;
  901.             }
  902.             //E
  903.             //F
  904.             case 'f':
  905.             case 'F':
  906.             {
  907.                 switch(token[1])
  908.                 {
  909.                     case 'a':
  910.                     case 'A':
  911.                     {
  912.                         switch(token[2])
  913.                         {
  914.                             case 'x':
  915.                             case 'X':
  916.                                 return FAX;
  917.                             case 'Y':
  918.                             case 'y':
  919.                                 return FAY;
  920.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  921.                
  922.                         }
  923.                         break;
  924.                        
  925.                     }
  926.                     case 'c':
  927.                     case 'C':
  928.                         return FCSET;
  929.                     case 'd':
  930.                     case 'D':
  931.                         return SETFFDATA;
  932.                     case 'e':
  933.                     case 'E':
  934.                     {
  935.                         switch(token[2])
  936.                         {
  937.                             case 'h':
  938.                             case 'H':
  939.                                 return FEHEIGHT;
  940.                             case 'w':
  941.                             case 'W':
  942.                                 return FEWIDTH;
  943.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  944.                         }
  945.                         break;
  946.                     }
  947.                     case 'f':
  948.                     case 'F':
  949.                     {
  950.                         switch(token[2])
  951.                         {
  952.                             case NULL:
  953.                             case 'l':
  954.                             case 'L':
  955.                                 return FFLAGS;
  956.                            
  957.                                
  958.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  959.                         }
  960.                         break;
  961.                        
  962.                     }
  963.                     case 'l':
  964.                     case 'L':
  965.                         return FLINK;
  966.                     case 'M':
  967.                     case 'm':
  968.                         return FMISC;
  969.                     case 'S':
  970.                     case 's':
  971.                         return SETFFSCRIPT;
  972.                     case 't':
  973.                     case 'T':
  974.                     {
  975.                         switch(token[2])
  976.                         {
  977.                             case 'H':
  978.                             case 'h':
  979.                                 return FTHEIGHT;
  980.                             case 'w':
  981.                             case 'W':
  982.                                 return FTWIDTH;
  983.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  984.                         }
  985.                         break;
  986.                        
  987.                     }
  988.                     case 'v':
  989.                     case 'V':
  990.                     {
  991.                         switch(token[2])
  992.                         {
  993.                             case 'x':
  994.                             case 'X':
  995.                                 return FVX;
  996.                             case 'y':
  997.                             case 'Y':
  998.                                 return FVY;
  999.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1000.                         }
  1001.                         break;
  1002.                        
  1003.                     }
  1004.                     case 'x':
  1005.                     case 'X':
  1006.                         return FX;
  1007.                     case 'y':
  1008.                     case 'Y':
  1009.                         return FY;
  1010.                    
  1011.                    
  1012.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1013.                 }
  1014.                 break;
  1015.             }
  1016.             //G
  1017.             //H
  1018.             case 'h':
  1019.             case 'H':
  1020.             {
  1021.                 switch(token[1])
  1022.                 {
  1023.                     case NULL:
  1024.                         return SETLIFE;
  1025.                     case 'b':
  1026.                     case 'B':
  1027.                         return BIGHITBOX;
  1028.                     case 'u':
  1029.                     case 'U':
  1030.                         return HUE;
  1031.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1032.                 }
  1033.             }
  1034.             //I
  1035.             case 'i':
  1036.             case 'I':
  1037.             {
  1038.                 switch(token[1])
  1039.                 {
  1040.                     case 'n':
  1041.                     case 'N':
  1042.                         return INVINCIBLE;
  1043.                     case 't':
  1044.                     case 'T':
  1045.                         return LINKITEM;
  1046.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1047.                 }
  1048.                 break;
  1049.             }
  1050.             //J
  1051.             //K
  1052.             case 'k':
  1053.             case 'K':
  1054.                 return KEYS;
  1055.             //L
  1056.             case 'l':
  1057.             case 'L':
  1058.             {
  1059.                 switch(token[1])
  1060.                 {
  1061.                     case 'b':
  1062.                     case 'B':
  1063.                         return LBOSSKEY;
  1064.                     case 'c':
  1065.                     case 'C':
  1066.                         return LCOMPASS;
  1067.                     case 'K':
  1068.                     case 'k':
  1069.                         return LKEYS;
  1070.                     case 'M':
  1071.                     case 'm':
  1072.                         return LMAP;
  1073.                     case 't':
  1074.                     case 'T':
  1075.                         return LTRIFORCE;
  1076.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1077.                 }
  1078.                
  1079.             }
  1080.             //M
  1081.             case 'm':
  1082.             case 'M':
  1083.             {
  1084.                 switch(token[1])
  1085.                 {
  1086.                     case NULL:
  1087.                         return SETMAGIC;
  1088.                     case 'x':
  1089.                     case 'X':
  1090.                         //TraceNL(); TraceS("instr() found token 'mx'");
  1091.                         return MOVEX;
  1092.                     case 'y':
  1093.                     case 'Y':
  1094.                         //TraceNL(); TraceS("instr() found token 'my'");
  1095.                         return MOVEY;
  1096.                     case 'h':
  1097.                     case 'H':
  1098.                         return MAXHP;
  1099.                     case 'm':
  1100.                     case 'M':
  1101.                         return MAXMP;
  1102.                     case 'c':
  1103.                     case 'C':
  1104.                         return MAXCTR;
  1105.                     case 'o':
  1106.                     case 'O':
  1107.                         return MONOCHROME;
  1108.                     case 'b':
  1109.                     case 'B':
  1110.                         return MBOMBS;
  1111.                    
  1112.                     case 'a':
  1113.                     case 'A':
  1114.                         return MARROWS;
  1115.                     case 'R':
  1116.                     case 'r':
  1117.                         return MRUPEES;
  1118.                    
  1119.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1120.                 }
  1121.                 break;
  1122.             }
  1123.            
  1124.             //P
  1125.             case 'p':
  1126.             case 'P':
  1127.             {
  1128.                 switch(token[1])
  1129.                 {
  1130.                    
  1131.                     case 'a':
  1132.                     case 'A':
  1133.                         //TraceNL(); TraceS("instr() found token 'p'"); TraceNL();
  1134.                         return PALETTE;
  1135.                    
  1136.                     case 'l':
  1137.                     case 'L':
  1138.                     {
  1139.                         switch(token[2])
  1140.                         {
  1141.                             case 'm':
  1142.                             case 'M':
  1143.                                 return PLAYMIDI;
  1144.                             case 's':
  1145.                             case 'S':
  1146.                                 return PLAYSOUND;
  1147.                            
  1148.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1149.                         }
  1150.                     }
  1151.                     case 'o':
  1152.                     case 'O':
  1153.                         //TraceNL(); TraceS("instr() found token 'pos'"); TraceNL();
  1154.                         return POS;
  1155.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1156.                 }
  1157.                 break;
  1158.             }
  1159.             //Q
  1160.             //R
  1161.             case 'r':
  1162.             case 'R':
  1163.             {
  1164.                 switch(token[1])
  1165.                 {
  1166.                     case NULL:
  1167.                         return RUPEES;
  1168.                     case 'h':
  1169.                     case 'H':
  1170.                         return REFILLHP;
  1171.                     case 'm':
  1172.                     case 'M':
  1173.                         return REFILLMP;
  1174.                     case 'c':
  1175.                     case 'C':
  1176.                         return REFILLCTR;
  1177.                     case 'U':
  1178.                     case 'u':
  1179.                     {
  1180.                         switch(token[2])
  1181.                         {
  1182.                             case NULL:
  1183.                                 return RUPEES;
  1184.                             case 'n':
  1185.                             case 'N':
  1186.                                 return RUNFFCSCRIPTID;
  1187.                             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1188.                         }
  1189.                     }
  1190.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1191.                 }
  1192.                 break;
  1193.             }
  1194.             //S
  1195.             case 's':
  1196.             case 'S':
  1197.             {
  1198.                 switch(token[1])
  1199.                 {
  1200.                     case 'a':
  1201.                     case 'A':
  1202.                     case 'V':
  1203.                     case 'v':
  1204.                     {
  1205.                         //TraceNL(); TraceS("instr() found token 'save'");
  1206.                         return SAVE;
  1207.                     }
  1208.                     default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1209.                 }
  1210.                 break;
  1211.             }
  1212.             //T
  1213.             case 't':
  1214.             case 'T':
  1215.                 return TINT;
  1216.             //U
  1217.             //V
  1218.             //W
  1219.             case 'w':
  1220.             case 'W':
  1221.                 //TraceNL(); TraceS("instr() found token 'w'"); TraceNL();
  1222.                 return WARP;
  1223.            
  1224.             default: TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token); abort(); return 0;
  1225.         }
  1226.        
  1227.         //if ( strcmp(token,"w") == 0) { TraceNL(); TraceS("instr() found token 'w'"); return WARP; }
  1228.         //else if ( strcmp(token,"p") == 0) { TraceNL(); TraceS("instr() found token 'p'"); return POS; }
  1229.         //else if ( strcmp(token,"mx") == 0) { TraceNL(); TraceS("instr() found token 'mx'"); return MOVEX; }
  1230.         //else if ( strcmp(token,"my") == 0) return MOVEY;
  1231.         //else if ( strcmp(token,"rh") == 0) return REFILLHP;
  1232.         //else if ( strcmp(token,"rm") == 0) return REFILLMP;
  1233.         //else if ( strcmp(token,"rc") == 0) return REFILLCTR;
  1234.         //else if ( strcmp(token,"mh") == 0) return MAXHP;
  1235.         //else if ( strcmp(token,"mm") == 0) return MAXMP;
  1236.         //else if ( strcmp(token,"mc") == 0) return MAXCTR;
  1237.         //else if ( strcmp(token,"inv") == 0) return INVINCIBLE;
  1238.         //else// if ( strcmp(token,"itm") == 0) return LINKITEM;
  1239.         //else
  1240.         //{
  1241.         //  TraceErrorS("match_instruction(TOKEN) could not evaluate the instruction",token);
  1242.         //  return 0;
  1243.         //}
  1244.     }
  1245.     void clearstack()
  1246.     {
  1247.         for ( int q = 0; q <= stack[TOP]; ++q ) stack[q] = 0;
  1248.         SP = 0;
  1249.         stack[TOP] = 0;
  1250.     }
  1251.     int enqueue()
  1252.     {
  1253.         if ( log_actions ) TraceErrorS("enqueue() is pushing a string.", " ");
  1254.         int r = read(debug_buffer,true);
  1255.         //clearbuffer();
  1256.         ++ENQUEUED;
  1257.         if ( log_actions ) TraceError("Enqueued is: ", ENQUEUED);
  1258.         if ( log_actions ) TraceStack();
  1259.         if ( log_actions ) TraceError("SP is now: ",SP);
  1260.         return ENQUEUED;
  1261.     }
  1262.     void TraceStack()
  1263.     {
  1264.         for ( int q = stack[TOP]; q >= 0; --q )
  1265.         TraceError("Stack register and value: ", q, stack[q]);
  1266.     }
  1267.     void TraceStack(int s)
  1268.     {
  1269.         for ( int q = s[TOP]; q >= 0; --q )
  1270.         TraceError("Stack register and value: ", q, s[q]);
  1271.     }
  1272.     void abort()
  1273.     {
  1274.         clearbuffer();
  1275.         Game->TypingMode = false;
  1276.         Link->PressStart = false;
  1277.         Link->InputStart = false;
  1278.     }
  1279.     void clearbuffer()
  1280.     {
  1281.         for ( int q = 0; q < BUFFER_LENGTH; ++q ) debug_buffer[q] = 0;
  1282.     }
  1283.     int read(int str, bool enqueued)
  1284.     {
  1285.         //debug
  1286.         //if ( !enqueued ) {TraceNL(); TraceS("Starting read() with an initial buffer of: "); TraceS(str); TraceNL();}
  1287.         //else {TraceNL(); TraceS("read() is running from enqueue() with an initial buffer of: "); TraceS(str); TraceNL();}
  1288.         int token[MAX_TOKEN_LENGTH]; int input_string_pos;
  1289.         int e; int token_pos = 0; int current_param;
  1290.         for ( input_string_pos = 0; input_string_pos < MAX_TOKEN_LENGTH; ++input_string_pos )
  1291.         {
  1292.             if (str[input_string_pos] == ',' ) { ++input_string_pos; break; }
  1293.             if (str[input_string_pos] == NULL ) break;
  1294.            
  1295.             token[token_pos] = str[input_string_pos];
  1296.             ++token_pos;
  1297.            
  1298.            
  1299.             //debug
  1300.            
  1301.             //++input_string_pos; //skip the comma now. If there are no params, we'll be on NULL.
  1302.         }
  1303.         //debug
  1304.         TraceNL(); TraceS("read() token: "); TraceS(token); TraceNL();
  1305.        
  1306.         //put the instruction onto the stack.
  1307.         //Right now, we are only allowing one instruction at a time.
  1308.         //This allows for future expansion.
  1309.         stack[SP] = match_instruction(token);
  1310.         //TraceNL(); TraceS("SP is: "); Trace(stack[SP]); TraceNL();
  1311.         int num_params = num_instruction_params(stack[SP]);
  1312.         //TraceNL(); TraceS("Number of expected params "); Trace(num_params); TraceNL();
  1313.        
  1314.         if ( num_params )
  1315.         {
  1316.             if ( str[input_string_pos] == NULL )
  1317.             {
  1318.                 //no params.
  1319.                 TraceErrorS("Input string is missing params. Token was", token);
  1320.                 return 0;
  1321.             }
  1322.         }
  1323.        
  1324.         ++SP; //get the stack ready for the next instruction.
  1325.         stack[TOP] = SP+1;
  1326.         //push the variables onto the stack.
  1327.         while ( current_param < num_params )  //repeat this until we are out of params
  1328.             //NOT a Do loop, because some instructions have no params!
  1329.         {
  1330.             for ( token_pos = MAX_TOKEN_LENGTH-1; token_pos >= 0; --token_pos ) token[token_pos] = 0; //clear the token
  1331.            
  1332.             //copy over new token
  1333.             token_pos = 0;
  1334.             //TraceNL(); TraceS("read() is seeking for params."); TraceNL();
  1335.             int temp_max = input_string_pos+MAX_TOKEN_LENGTH;
  1336.             for ( ; input_string_pos < temp_max; ++input_string_pos )
  1337.             {
  1338.                 if (str[input_string_pos] == ',' ) { ++input_string_pos; break; }
  1339.                 if (str[input_string_pos] == NULL ) break;
  1340.                
  1341.                 token[token_pos] = str[input_string_pos];
  1342.                 ++token_pos;
  1343.                
  1344.                
  1345.                 //debug
  1346.                
  1347.                 //++input_string_pos; //skip the comma now. If there are no params, we'll be on NULL.
  1348.             }
  1349.             /*
  1350.             while( str[input_string_pos] != ',' || str[input_string_pos] != NULL ) //|| current_param >= num_params ) //token terminates on a comma, or the end of the string
  1351.             {
  1352.                 token[token_pos] = str[input_string_pos]; //store the variable into a new token
  1353.                 ++token_pos;
  1354.             }
  1355.             */
  1356.             //TraceNL(); TraceS("read() is getting tval"); TraceNL();
  1357.             int tval; //value of the param
  1358.             //first check the boolean types:
  1359.             //TraceNL(); TraceS("The arg token is: "); TraceS(token); TraceNL();
  1360.             if ( !isNumber(token[0]) )
  1361.             {
  1362.                 switch(token[0])
  1363.                 {
  1364.                    
  1365.                     case '-': tval = atof(token); break;
  1366.                     case '.': tval = atof(token); break;
  1367.                    
  1368.                     case 't':
  1369.                     case 'T':
  1370.                         tval = 1; break;
  1371.                     case 'f':
  1372.                     case 'F':
  1373.                         tval = 0; break;
  1374.                    
  1375.                     case 'l':
  1376.                     case 'L':
  1377.                     {
  1378.                         switch(token[1])
  1379.                         {
  1380.                             case 'x':
  1381.                             case 'X':
  1382.                             {
  1383.                                 if ( log_actions ) TraceError("tval set to Link->X: ", Link->X);
  1384.                                 tval = Link->X; break;
  1385.                             }
  1386.                             case 'y':
  1387.                             case 'Y':
  1388.                             {
  1389.                                 if ( log_actions ) TraceError("tval set to Link->Y: ", Link->Y);
  1390.                                 tval = Link->Y; break;
  1391.                             }
  1392.                             default: TraceErrorS("Invalid token passed as an argument for instruction: ", token); tval = 0; break;
  1393.                         }
  1394.                         break;
  1395.                     }
  1396.                    
  1397.                     default: TraceErrorS("Invalid token passed as an argument for instruction: ", token); tval = 0; break;
  1398.                 }
  1399.                 //if ( strcmp(token,"true") ) tval = 1;
  1400.                 //else if ( strcmp(token,"T") ) tval = 1;
  1401.                 //else if ( strcmp(token,"false") ) tval = 0;
  1402.                 //else if ( strcmp(token,"F") ) tval = 0;
  1403.                
  1404.             }
  1405.             else //literals
  1406.             {
  1407.                
  1408.                 tval = atof(token);
  1409.                 //TraceNL(); TraceS("found a literal var of: "); Trace(tval); TraceNL();
  1410.                
  1411.             }
  1412.             //push the token value onto the stack
  1413.             stack[SP] = tval;
  1414.        
  1415.             //now out stack looks like:
  1416.            
  1417.             //: PARAMn where n is the loop iteration
  1418.             //: PARAMn where n is the loop iteration
  1419.             //: PARAMn where n is the loop iteration
  1420.             //: INSTRUCTION
  1421.            
  1422.             ++SP; //this is why the stack size must be +1 larger than the3 total number of instructions and
  1423.             //params that it can hold.
  1424.             ++current_param;
  1425.            
  1426.         } //repeat this until we are out of params
  1427.         return 1;
  1428.        
  1429.     }
  1430.    
  1431.     //void getVarValue(int str)
  1432.     //{
  1433.     //  variables[VP] = atof(str);
  1434.     //  ++VP;
  1435.     //}
  1436.    
  1437.     void execute(int s)
  1438.     {
  1439.         if ( log_actions )
  1440.         {
  1441.             TraceNL(); TraceS("Stack Trace");
  1442.             for ( int q = stack[TOP]; q >= 0; --q )
  1443.             {
  1444.                 TraceNL(); Trace(stack[q]);
  1445.             }
  1446.         }
  1447.        
  1448.        
  1449.         //TraceNL(); TraceS("Running execute(stack)"); TraceNL();
  1450.         int reg_ptr = 0; //read the stack starting here, until we reach TOP.
  1451.         int args[MAX_ARGS];
  1452.         //evaluate the instruction:
  1453.         int instr;
  1454.         int current_arg = 0;
  1455.         int num_of_params = 0;
  1456.         for ( ; ENQUEUED >= 0; --ENQUEUED )
  1457.         {
  1458.             current_arg = 0; //we clear this for each enqueued instruction, so that we properly place args
  1459.                     //into their positions. Otherwise, we'd be trying to store args[5] instead of [2]!
  1460.             instr = s[reg_ptr];
  1461.             ++reg_ptr;
  1462.             num_of_params = num_instruction_params(instr);
  1463.             //TraceNL(); TraceS("execute(stack) expects number of args to be: "); Trace(num_of_params); TraceNL();
  1464.             for ( ; num_of_params > 0; --num_of_params )
  1465.             {
  1466.                 args[current_arg] = s[reg_ptr];
  1467.                 //TraceNL(); TraceS("Putting an arg on the heap. Arg value: "); Trace(args[current_arg]); TraceNL();
  1468.                 ++current_arg;
  1469.                 ++reg_ptr;
  1470.                
  1471.             }
  1472.            
  1473.             if ( log_actions )
  1474.             {
  1475.                 TraceNL(); TraceS("execute believes that the present instruction is: "); Trace(instr); TraceNL();
  1476.                 TraceNL(); TraceS("args[0] is: "); Trace(args[0]); TraceNL();
  1477.                 TraceNL(); TraceS("args[1] is: "); Trace(args[1]); TraceNL();
  1478.             }
  1479.             switch(instr)
  1480.             {
  1481.                 case NONE:
  1482.                 TraceError("STACK INSTRUCTION IS INVALID: ", instr);
  1483.                 Game->TypingMode = false;
  1484.                 clearbuffer();
  1485.                 break;
  1486.                 case WARP:
  1487.                 {
  1488.                     Link->Warp(args[0],args[1]);
  1489.                     if ( log_actions ) TraceError("Cheat System Warped Link to dmap,screen",args[0],args[1]);
  1490.                     break;
  1491.                 }
  1492.                 case POS:
  1493.                 {
  1494.                     Link->X = args[0];
  1495.                     Link->Y = args[1];
  1496.                     if ( log_actions ) TraceError("Cheat System repositioned Link to X,Y",args[0],args[1]);
  1497.                     break;
  1498.                 }
  1499.                
  1500.                 case MOVEX:
  1501.                 {
  1502.                     Link->X += args[0];
  1503.                     if ( log_actions ) TraceError("Cheat system moved Link on his X axis by", args[0]);
  1504.                     break;
  1505.                 }
  1506.                 case MOVEY:
  1507.                 {
  1508.                     Link->Y += args[0];
  1509.                     if ( log_actions ) TraceError("Cheat system moved Link on his Y axis by", args[0]);
  1510.                     break;
  1511.                 }
  1512.                 case REFILLHP:
  1513.                 {
  1514.                     Link->HP =  Link->MaxHP;
  1515.                     if ( log_actions ) TraceError("Cheat system refilled Link's HP to", Link->MaxHP);
  1516.                     break;
  1517.                 }
  1518.                 case REFILLMP:
  1519.                 {
  1520.                     Link->MP =  Link->MaxMP;
  1521.                     if ( log_actions ) TraceError("Cheat system refilled Link's MP to", Link->MaxHP);
  1522.                     break;
  1523.                 }
  1524.                 case REFILLCTR:
  1525.                 {
  1526.                     Game->Counter[args[0]] =  Game->MCounter[args[0]];
  1527.                     if ( log_actions ) TraceError("Cheat system refilled Counter", args[0]);
  1528.                     break;
  1529.                 }
  1530.                 case MAXHP:
  1531.                 {
  1532.                     Game->MCounter[CR_LIFE] = args[0];
  1533.                     if ( log_actions ) TraceError("Cheat system set Link's Max HP to",args[0]);
  1534.                     break;
  1535.                 }
  1536.                 case MAXMP:
  1537.                 {
  1538.                     Game->MCounter[CR_MAGIC] = args[0];
  1539.                     if ( log_actions ) TraceError("Cheat system set Link's Max MP to",args[0]);
  1540.                     break;
  1541.                 }
  1542.                 case MAXCTR:
  1543.                 {
  1544.                     Game->Counter[args[0]] = args[1];
  1545.                     if ( log_actions ) TraceError("Cheat system refilled Counter (id, amount)",args[0],args[1]);
  1546.                     break;
  1547.                 }
  1548.                
  1549.                 case INVINCIBLE:
  1550.                 {
  1551.                     if ( args[0] )
  1552.                     {
  1553.                         Link->Invisible = true;
  1554.                         if ( log_actions ) TraceErrorS("Cheat system set Link's Invisibility state to ","true");
  1555.                         break;
  1556.                     }
  1557.                     else
  1558.                     {
  1559.                         Link->Invisible = false;
  1560.                         if ( log_actions ) TraceErrorS("Cheat system set Link's Invisibility state to ","false");
  1561.                         break;
  1562.                        
  1563.                     }
  1564.                    
  1565.                 }
  1566.                 case LINKITEM:
  1567.                 {
  1568.                     itemdata id = Game->LoadItemData(args[0]);
  1569.                     if ( id->Keep )
  1570.                     {
  1571.                         if ( args[1] )
  1572.                         {
  1573.                            
  1574.                             Link->Item[args[0]] = true;
  1575.                             if ( log_actions ) TraceErrorS("Cheat system set Link's Inventory Item to (item, state)","true");
  1576.                             break;
  1577.                         }
  1578.                         else
  1579.                         {
  1580.                             Link->Item[args[0]] = false;
  1581.                             if ( log_actions ) TraceErrorS("Cheat system set Link's Inventory Item to (item, state)","false");
  1582.                             break;
  1583.                            
  1584.                         }
  1585.                     }
  1586.                     else break;
  1587.                 }
  1588.                 case SAVE:
  1589.                 {
  1590.                     TraceNL(); TraceS("Cheat system is saving the game.");
  1591.                     clearbuffer();
  1592.                     Game->Save();
  1593.                     break;
  1594.                 }
  1595.                 case CREATEITEM:
  1596.                 {
  1597.                     if ( log_actions ) TraceError("Cheat system is creating item ID: ", args[0]);
  1598.                     if ( log_actions ) TraceError("Cheat system is creating item at X Position: ", args[1]);
  1599.                     if ( log_actions ) TraceError("Cheat system is creating item at Y Position: ", args[2]);
  1600.                     item cci = Screen->CreateItem(args[0]);
  1601.                     cci->X = args[1];
  1602.                     cci->Y = args[2];
  1603.                     break;
  1604.                 }
  1605.                 case CREATENPC:
  1606.                 {
  1607.                     if ( log_actions ) TraceError("Cheat system is creating npc ID: ", args[0]);
  1608.                     if ( log_actions ) TraceError("Cheat system is creating npc at X Position: ", args[1]);
  1609.                     if ( log_actions ) TraceError("Cheat system is creating npc at Y Position: ", args[2]);
  1610.                     npc ccn = Screen->CreateNPC(args[0]);
  1611.                     ccn->X = args[1];
  1612.                     ccn->Y = args[2];
  1613.                     break;
  1614.                 }
  1615.                 case PALETTE:
  1616.                 {
  1617.                     if ( args[0] < 0 )
  1618.                     {
  1619.                         Game->DMapPalette[Game->GetCurDMap()] = args[1];
  1620.                     }
  1621.                     else Game->DMapPalette[args[0]] = args[1];
  1622.                     break;
  1623.                 }
  1624.                 case MONOCHROME:
  1625.                 {
  1626.                     Graphics->Monochrome(args[0]); break;
  1627.                 }
  1628.                 case MBOMBS: Game->MCounter[CR_BOMBS] = args[0]; break;
  1629.                 case BOMBS: Game->Counter[CR_BOMBS] = args[0]; break;
  1630.                 case MARROWS: Game->MCounter[CR_ARROWS] = args[0]; break;
  1631.                 case ARROWS: Game->Counter[CR_ARROWS] = args[0]; break;
  1632.                 case KEYS: Game->Counter[CR_KEYS] = args[0]; break;
  1633.                 case RUPEES: Game->Counter[CR_RUPEES] = args[0]; break;
  1634.                 case MRUPEES: Game->MCounter[CR_RUPEES] = args[0]; break;
  1635.                
  1636.                 case LKEYS: Game->LKeys[args[0]] = args[1]; break;
  1637.                 case LINKDIAGONAL: Link->Diagonal = Cond(args[0],true,false); break;
  1638.                 case BIGHITBOX: Link->BigHitbox = Cond(args[0],true,false); break;
  1639.                
  1640.                 case LMAP:
  1641.                 {
  1642.                     if ( args[1] ) //true
  1643.                     {  
  1644.                         Game->LItems[args[0]] |= LI_MAP;
  1645.                     }
  1646.                     else Game->LItems[args[0]] &= ~LI_MAP;
  1647.                     break;
  1648.                 }
  1649.                 case LBOSSKEY:
  1650.                 {
  1651.                     if ( args[1] ) //true
  1652.                     {  
  1653.                         Game->LItems[args[0]] |= LI_BOSSKEY;
  1654.                     }
  1655.                     else Game->LItems[args[0]] &= ~LI_BOSSKEY;
  1656.                     break;
  1657.                 }
  1658.                 case LCOMPASS:
  1659.                 {
  1660.                     if ( args[1] ) //true
  1661.                     {  
  1662.                         Game->LItems[args[0]] |= LI_COMPASS;
  1663.                     }
  1664.                     else Game->LItems[args[0]] &= ~LI_COMPASS;
  1665.                     break;
  1666.                 }
  1667.                 case LTRIFORCE:
  1668.                 {
  1669.                     if ( args[1] ) //true
  1670.                     {  
  1671.                         Game->LItems[args[0]] |= LI_TRIFORCE;
  1672.                     }
  1673.                     else Game->LItems[args[0]] &= ~LI_TRIFORCE;
  1674.                     break;
  1675.                 }
  1676.                 case SETFFDATA:
  1677.                 {
  1678.                     ffc f = Screen->LoadFFC(args[0]);
  1679.                     f->Data = args[1];
  1680.                     break;
  1681.                 }
  1682.                 case SETFFSCRIPT:
  1683.                 {
  1684.                     ffc f = Screen->LoadFFC(args[0]);
  1685.                     f->Script = args[1];
  1686.                     break;
  1687.                 }
  1688.                 case RUNFFCSCRIPTID:
  1689.                 {
  1690.                     ffc f; bool running;
  1691.                     for ( int q = 1; q < 33; ++q )
  1692.                     {  
  1693.                         f = Screen->LoadFFC(args[0]);
  1694.                         if ( !f->Script )
  1695.                         {
  1696.                             if ( !f->Data ) f->Data = INVISIBLE_COMBO;
  1697.                             f->Script = args[1];
  1698.                             running = true;
  1699.                             break;
  1700.                         }
  1701.                     }
  1702.                     if ( !running ) TraceError("Cheat system could not find a free ffc for command RUN. Try FS,id,scriptid instead.",NULL);
  1703.                     break;
  1704.                 }
  1705.                 case CLEARTINT:
  1706.                 {
  1707.                     if ( log_actions ) TraceError("Cheat shell is clearing all Tint().",NULL);
  1708.                     Graphics->ClearTint();
  1709.                     break;
  1710.                 }
  1711.                 case TINT:
  1712.                 {
  1713.                     if ( log_actions )
  1714.                     {
  1715.                         TraceError("Cheat shell is setting Tint().",NULL);
  1716.                         TraceError("Tint(red) is: ",args[0]);
  1717.                         TraceError("Tint(green) is: ",args[1]);
  1718.                         TraceError("Tint(blue) is: ",args[2]);
  1719.                     }
  1720.                    
  1721.                     Graphics->Tint(args[0],args[1],args[2]);
  1722.                     break;
  1723.                 }
  1724.                 case HUE:
  1725.                 {
  1726.                     if ( log_actions )
  1727.                     {
  1728.                         TraceError("Cheat shell is setting Hue().",NULL);
  1729.                         TraceError("Hue(red) is: ",args[0]);
  1730.                         TraceError("Hue(green) is: ",args[1]);
  1731.                         TraceError("Hue(blue) is: ",args[2]);
  1732.                         if ( args[3] ) TraceErrorS("Hue(distribution) is: ","true");
  1733.                         else TraceErrorS("Hue(distribution) is: ","false");
  1734.                     }
  1735.                    
  1736.                     Graphics->MonochromeHue(args[0],args[1],args[2],Cond(args[3],true,false));
  1737.                     break;
  1738.                 }
  1739.                 case FCSET:
  1740.                 {
  1741.                     ffc f = Screen->LoadFFC(args[0]);
  1742.                     f->CSet = args[1];
  1743.                     break;
  1744.                 }
  1745.                 case FX:
  1746.                 {
  1747.                     ffc f = Screen->LoadFFC(args[0]);
  1748.                     f->X = args[1];
  1749.                     break;
  1750.                 }  
  1751.                 case FY:
  1752.                 {
  1753.                     ffc f = Screen->LoadFFC(args[0]);
  1754.                     f->Y = args[1];
  1755.                     break;
  1756.                 }
  1757.                 case FVX:
  1758.                 {
  1759.                     ffc f = Screen->LoadFFC(args[0]);
  1760.                     f->Vx = args[1];
  1761.                     break;
  1762.                 }  
  1763.                 case FVY:
  1764.                 {
  1765.                     ffc f = Screen->LoadFFC(args[0]);
  1766.                     f->Vy = args[1];
  1767.                     break;
  1768.                 }  
  1769.                 case FAX:
  1770.                 {
  1771.                     ffc f = Screen->LoadFFC(args[0]);
  1772.                     f->Ax = args[1];
  1773.                     break;
  1774.                 }  
  1775.                 case FAY:
  1776.                 {
  1777.                     ffc f = Screen->LoadFFC(args[0]);
  1778.                     f->Ay = args[1];
  1779.                     break;
  1780.                 }  
  1781.                 case FFLAGS:
  1782.                 {
  1783.                     ffc f = Screen->LoadFFC(args[0]);
  1784.                     f->Flags[args[1]] = (args[2]);
  1785.                     break;
  1786.                 }  
  1787.                 case FTHEIGHT:
  1788.                 {
  1789.                     ffc f = Screen->LoadFFC(args[0]);
  1790.                     f->TileHeight = args[1];
  1791.                     break;
  1792.                 }  
  1793.                 case FTWIDTH:
  1794.                 {
  1795.                     ffc f = Screen->LoadFFC(args[0]);
  1796.                     f->TileWidth = args[1];
  1797.                     break;
  1798.                 }  
  1799.                 case FEHEIGHT:
  1800.                 {
  1801.                     ffc f = Screen->LoadFFC(args[0]);
  1802.                     f->EffectHeight = args[1];
  1803.                     break;
  1804.                 }  
  1805.                 case FEWIDTH:
  1806.                 {
  1807.                     ffc f = Screen->LoadFFC(args[0]);
  1808.                     f->EffectWidth = args[1];
  1809.                     break;
  1810.                 }  
  1811.                 case FLINK:
  1812.                 {
  1813.                     ffc f = Screen->LoadFFC(args[0]);
  1814.                     f->Link = args[1];
  1815.                     break;
  1816.                 }  
  1817.                 case FMISC:
  1818.                 {
  1819.                     ffc f = Screen->LoadFFC(args[0]);
  1820.                     f->Misc[args[1]] = args[2];
  1821.                     break;
  1822.                 }  
  1823.                
  1824.                 case PLAYSOUND: Game->PlaySound(args[0]); break;
  1825.                 case PLAYMIDI: Game->PlayMIDI(args[0]); break;
  1826.                 case DMAPMIDI:
  1827.                 {
  1828.                     if ( args[0] < 0 )
  1829.                     {
  1830.                         if ( log_actions ) TraceError("Cheat system is setting the DMap MIDI for the current DMap to: ",args[1]);
  1831.                         Game->DMapMIDI[Game->GetCurDMap()] = args[1];
  1832.                     }
  1833.                    
  1834.                     else
  1835.                     {
  1836.                         if ( log_actions ) TraceError("Cheat system is setting the DMap MIDI for the DMap: ",args[0]);
  1837.                         if ( log_actions ) TraceError("...to MIDI ID: ",args[1]);
  1838.                         Game->DMapMIDI[args[0]] = args[1];
  1839.                     }
  1840.                     break;
  1841.                 }
  1842.                
  1843.                 case SETLIFE: Game->Counter[CR_LIFE] = args[0]; break;
  1844.                 case SETMAGIC: Game->Counter[CR_MAGIC] = args[0]; break;
  1845.                 case SETCOUNTER: Game->Counter[args[0]] = args[1]; break;
  1846.                    
  1847.                
  1848.                 case RUNSEQUENCE: { TraceError("Running Saved Sequence", args[0]); runsequence(args[0]); break; }
  1849.                 case SAVESEQUENCE: TraceError("Saving Sequence", savesequence(args[0])); break;
  1850.                
  1851.                 case TRACE: break; //It's handled in match_instruction()
  1852.                
  1853.                 default:
  1854.                 {
  1855.                    
  1856.                     TraceError("Invalid instruction passed to stack",instr);
  1857.                     break;
  1858.                 }
  1859.                
  1860.             }
  1861.         }
  1862.         ///-----later, we'll add this: //pop everything off of the stack
  1863.         //just wipe the stack for now, as we only support one command at this time
  1864.         for ( int q = 0; q <= s[TOP]; ++q ) s[q] = 0;
  1865.         SP = 0;
  1866.        
  1867.         //clear the main buffer, too!
  1868.         for ( int cl = 0; cl < BUFFER_LENGTH; ++cl ) debug_buffer[cl] = 0;
  1869.         Game->TypingMode = false; //insurance clear
  1870.         Link->PressStart = false;
  1871.         Link->InputStart = false;
  1872.         ENQUEUED = 0;
  1873.        
  1874.        
  1875.     }
  1876.        
  1877.     void run()
  1878.     {
  1879.    
  1880.        
  1881.        
  1882.     }
  1883. }
  1884.  
  1885. global script test
  1886. {
  1887.     void run()
  1888.     {
  1889.         debugshell.SP = 0;
  1890.         debugshell.clearbuffer();
  1891.         while(1)
  1892.         {
  1893.             debugshell.process();
  1894.             Waitdraw();
  1895.             Waitframe();
  1896.         }
  1897.        
  1898.     }
  1899. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement