home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.70.zip / src / gtable.c < prev    next >
C/C++ Source or Header  |  2008-04-01  |  23KB  |  1,060 lines

  1. //
  2. // GOATTRACKER v2 table editor
  3. //
  4.  
  5. #define GTABLE_C
  6.  
  7. #include "goattrk2.h"
  8.  
  9. unsigned char ltablecopybuffer[MAX_TABLELEN];
  10. unsigned char rtablecopybuffer[MAX_TABLELEN];
  11. int tablecopyrows = 0;
  12.  
  13. int etview[MAX_TABLES];
  14. int etnum;
  15. int etpos;
  16. int etcolumn;
  17. int etlock = 1;
  18. int etmarknum = -1;
  19. int etmarkstart;
  20. int etmarkend;
  21.  
  22. void tablecommands(void)
  23. {
  24.   int c;
  25.  
  26.   switch(rawkey)
  27.   {
  28.       case KEY_Q:
  29.       if ((shiftpressed) && (etnum == STBL))
  30.       {
  31.           int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
  32.           speed *= 34716;
  33.           speed /= 32768;
  34.           if (speed > 65535) speed = 65535;
  35.  
  36.           ltable[etnum][etpos] = speed >> 8;
  37.           rtable[etnum][etpos] = speed & 0xff;
  38.       }
  39.     break;
  40.  
  41.       case KEY_A:
  42.       if ((shiftpressed) && (etnum == STBL))
  43.       {
  44.           int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
  45.           speed *= 30929;
  46.           speed /= 32768;
  47.  
  48.           ltable[etnum][etpos] = speed >> 8;
  49.           rtable[etnum][etpos] = speed & 0xff;
  50.       }
  51.     break;
  52.     
  53.       case KEY_W:
  54.       if ((shiftpressed) && (etnum == STBL))
  55.       {
  56.           int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
  57.           speed *= 2;
  58.           if (speed > 65535) speed = 65535;
  59.  
  60.           ltable[etnum][etpos] = speed >> 8;
  61.           rtable[etnum][etpos] = speed & 0xff;
  62.       }
  63.       if ((shiftpressed) && ((etnum == PTBL) || (etnum == FTBL)) && (ltable[etnum][etpos] < 0x80))
  64.       {
  65.           int speed = (signed char)(rtable[etnum][etpos]);
  66.           speed *= 2;
  67.  
  68.       if (speed > 127) speed = 127;
  69.       if (speed < -128) speed = -128;
  70.           rtable[etnum][etpos] = speed;
  71.       }
  72.     break;
  73.     
  74.       case KEY_S:
  75.       if ((shiftpressed) && (etnum == STBL))
  76.       {
  77.           int speed = (ltable[etnum][etpos] << 8) | rtable[etnum][etpos];
  78.           speed /= 2;
  79.  
  80.           ltable[etnum][etpos] = speed >> 8;
  81.           rtable[etnum][etpos] = speed & 0xff;
  82.       }
  83.       if ((shiftpressed) && ((etnum == PTBL) || (etnum == FTBL)) && (ltable[etnum][etpos] < 0x80))
  84.       {
  85.           int speed = (signed char)(rtable[etnum][etpos]);
  86.           speed /= 2;
  87.  
  88.           rtable[etnum][etpos] = speed;
  89.       }
  90.     break;
  91.  
  92.     case KEY_SPACE:
  93.     if (!shiftpressed)
  94.       playtestnote(FIRSTNOTE + epoctave * 12, einum, epchn);
  95.     else
  96.       releasenote(epchn);
  97.     break;
  98.  
  99.     case KEY_RIGHT:
  100.     etcolumn++;
  101.     if (etcolumn > 3)
  102.     {
  103.       etpos -= etview[etnum];
  104.       etcolumn = 0;
  105.       etnum++;
  106.       if (etnum >= MAX_TABLES) etnum = 0;
  107.       etpos += etview[etnum];
  108.     }
  109.     if (shiftpressed) etmarknum = -1;
  110.     break;
  111.  
  112.     case KEY_LEFT:
  113.     etcolumn--;
  114.     if (etcolumn < 0)
  115.     {
  116.       etpos -= etview[etnum];
  117.       etcolumn = 3;
  118.       etnum--;
  119.       if (etnum < 0) etnum = MAX_TABLES - 1;
  120.       etpos += etview[etnum];
  121.     }
  122.     if (shiftpressed) etmarknum = -1;
  123.     break;
  124.  
  125.     case KEY_HOME:
  126.     while (etpos != 0) tableup();
  127.     break;
  128.     
  129.     case KEY_END:
  130.     while (etpos != MAX_TABLELEN-1) tabledown();
  131.     break;
  132.  
  133.     case KEY_PGUP:
  134.     for (c = 0; c < PGUPDNREPEAT; c++) tableup();
  135.     break;
  136.  
  137.     case KEY_PGDN:
  138.     for (c = 0; c < PGUPDNREPEAT; c++) tabledown();
  139.     break;
  140.  
  141.     case KEY_UP:
  142.     tableup();
  143.     break;
  144.  
  145.     case KEY_DOWN:
  146.     tabledown();
  147.     break;
  148.  
  149.     case KEY_X:
  150.     case KEY_C:
  151.     if (shiftpressed)
  152.     {
  153.       if (etmarknum != -1)
  154.       {
  155.         int d = 0;
  156.         if (etmarkstart <= etmarkend)
  157.         {
  158.           for (c = etmarkstart; c <= etmarkend; c++)
  159.           {
  160.             ltablecopybuffer[d] = ltable[etmarknum][c];
  161.             rtablecopybuffer[d] = rtable[etmarknum][c];
  162.             if (rawkey == KEY_X)
  163.             {
  164.               ltable[etmarknum][c] = 0;
  165.               rtable[etmarknum][c] = 0;
  166.             }
  167.             d++;
  168.           }
  169.         }
  170.         else
  171.         {
  172.           for (c = etmarkend; c <= etmarkstart; c++)
  173.           {
  174.             ltablecopybuffer[d] = ltable[etmarknum][c];
  175.             rtablecopybuffer[d] = rtable[etmarknum][c];
  176.             if (rawkey == KEY_X)
  177.             {
  178.               ltable[etmarknum][c] = 0;
  179.               rtable[etmarknum][c] = 0;
  180.             }
  181.             d++;
  182.           }
  183.         }
  184.         tablecopyrows = d;
  185.       }
  186.       etmarknum = -1;
  187.     }
  188.     break;
  189.  
  190.     case KEY_V:
  191.     if (shiftpressed)
  192.     {
  193.       if (tablecopyrows)
  194.       {
  195.         for (c = 0; c < tablecopyrows; c++)
  196.         {
  197.           ltable[etnum][etpos] = ltablecopybuffer[c];
  198.           rtable[etnum][etpos] = rtablecopybuffer[c];
  199.           etpos++;
  200.           if (etpos >= MAX_TABLELEN) etpos = MAX_TABLELEN-1;
  201.         }
  202.       }
  203.     }
  204.     break;
  205.  
  206.     case KEY_O:
  207.     if (shiftpressed) optimizetable(etnum);
  208.     break;
  209.  
  210.     case KEY_U:
  211.     if (shiftpressed)
  212.     {
  213.       etlock ^= 1;
  214.       validatetableview();
  215.     }
  216.     break;
  217.  
  218.     case KEY_R:
  219.     if (etnum == WTBL)
  220.     {
  221.       if (ltable[etnum][etpos] != 0xff)
  222.       {
  223.         // Convert absolute pitch to relative pitch or vice versa
  224.         int basenote = epoctave * 12;
  225.         int note = rtable[etnum][etpos];
  226.  
  227.         if (note >= 0x80)
  228.         {
  229.           note -= basenote;
  230.           note &= 0x7f;
  231.         }
  232.         else
  233.         {
  234.           note += basenote;
  235.           note |= 0x80;
  236.         }
  237.  
  238.         rtable[etnum][etpos] = note;
  239.       }
  240.     }
  241.  
  242.     case KEY_L:
  243.     if (etnum == PTBL)
  244.     {
  245.       int c;
  246.       int currentpulse = -1;
  247.       int targetpulse = ltable[etnum][etpos] << 4;
  248.       int speed = rtable[etnum][etpos];
  249.       int time;
  250.       int steps;
  251.  
  252.       if (!speed) break;
  253.  
  254.       // Follow the chain of pulse commands backwards to the nearest set command so we know what current pulse is
  255.       for (c = etpos-1; c >= 0; c--)
  256.       {
  257.         if (ltable[etnum][c] == 0xff) break;
  258.         if (ltable[etnum][c] >= 0x80)
  259.         {
  260.           currentpulse = (ltable[etnum][c] << 8) | rtable[etnum][c];
  261.           currentpulse &= 0xfff;
  262.           break;
  263.         }
  264.       }
  265.       if (currentpulse == -1) break;
  266.  
  267.       // Then follow the chain of modulation steps
  268.       for (; c < etpos; c++)
  269.       {
  270.         if (ltable[etnum][c] < 0x80)
  271.         {
  272.           currentpulse += ltable[etnum][c] * (rtable[etnum][c] & 0xff);
  273.           if (rtable[etnum][c] >= 0x80) currentpulse -= 256 * ltable[etnum][c];
  274.           currentpulse &= 0xfff;
  275.         }
  276.       }
  277.  
  278.       time = abs(targetpulse - currentpulse) / speed;
  279.       if (speed < 128)
  280.         steps = (time + 126) / 127;
  281.       else
  282.         steps = time;
  283.  
  284.       if (!steps) break;
  285.       if (etpos + steps > MAX_TABLELEN) break;
  286.       if (targetpulse < currentpulse) speed = -speed;
  287.  
  288.       // Make room in the table
  289.       for (c = steps; c > 1; c--) inserttable(etnum, etpos, 1);
  290.  
  291.       while (time)
  292.       {
  293.           if (abs(speed) < 128)
  294.           {
  295.           if (time < 127) ltable[etnum][etpos] = time;
  296.             else ltable[etnum][etpos] = 127;
  297.           rtable[etnum][etpos] = speed;
  298.           time -= ltable[etnum][etpos];
  299.           etpos++;
  300.         }
  301.         else
  302.         {
  303.           currentpulse += speed;
  304.             ltable[etnum][etpos] = 0x80 | ((currentpulse >> 8) & 0xf);
  305.           rtable[etnum][etpos] = currentpulse & 0xff;
  306.           time--;
  307.           etpos++;
  308.         }
  309.       }
  310.     }
  311.     if (etnum == FTBL)
  312.     {
  313.       int c;
  314.       int currentfilter = -1;
  315.       int targetfilter = ltable[etnum][etpos];
  316.       int speed = rtable[etnum][etpos] & 0x7f;
  317.       int time;
  318.       int steps;
  319.  
  320.       if (!speed) break;
  321.  
  322.       // Follow the chain of filter commands backwards to the nearest set command so we know what current pulse is
  323.       for (c = etpos-1; c >= 0; c--)
  324.       {
  325.         if (ltable[etnum][c] == 0xff) break;
  326.         if (ltable[etnum][c] == 0x00)
  327.         {
  328.           currentfilter = rtable[etnum][c];
  329.           break;
  330.         }
  331.       }
  332.       if (currentfilter == -1) break;
  333.  
  334.       // Then follow the chain of modulation steps
  335.       for (; c < etpos; c++)
  336.       {
  337.         if (ltable[etnum][c] < 0x80)
  338.         {
  339.           currentfilter += ltable[etnum][c] * rtable[etnum][c];
  340.           currentfilter &= 0xff;
  341.         }
  342.       }
  343.  
  344.       time = abs(targetfilter - currentfilter) / speed;
  345.       steps = (time + 126) / 127;
  346.       if (!steps) break;
  347.       if (etpos + steps > MAX_TABLELEN) break;
  348.       if (targetfilter < currentfilter) speed = -speed;
  349.  
  350.       // Make room in the table
  351.       for (c = steps; c > 1; c--) inserttable(etnum, etpos, 1);
  352.  
  353.       while (time)
  354.       {
  355.         if (time < 127) ltable[etnum][etpos] = time;
  356.           else ltable[etnum][etpos] = 127;
  357.         rtable[etnum][etpos] = speed;
  358.         time -= ltable[etnum][etpos];
  359.         etpos++;
  360.       }
  361.     }
  362.     break;
  363.  
  364.     case KEY_N:
  365.     if (shiftpressed)
  366.     {
  367.       switch (etnum)
  368.       {
  369.         // Negate pulse or filter speed
  370.         case FTBL:
  371.         if (!ltable[etnum][etpos]) break;
  372.         case PTBL:
  373.         if (ltable[etnum][etpos] < 0x80)
  374.           rtable[etnum][etpos] = (rtable[etnum][etpos] ^ 0xff) + 1;
  375.         break;
  376.  
  377.         // Negate relative note
  378.         case WTBL:
  379.         if ((ltable[etnum][etpos] != 0xff) && (rtable[etnum][etpos] < 0x80))
  380.           rtable[etnum][etpos] = (0x80 - rtable[etnum][etpos]) & 0x7f;
  381.         break;
  382.       }
  383.     }
  384.     break;
  385.  
  386.     case KEY_DEL:
  387.     deletetable(etnum, etpos);
  388.     break;
  389.  
  390.     case KEY_INS:
  391.     inserttable(etnum, etpos, shiftpressed);
  392.     break;
  393.  
  394.     case KEY_ENTER:
  395.     if (etnum == WTBL)
  396.     {
  397.         int table = -1;
  398.         int mstmode = MST_PORTAMENTO;
  399.  
  400.         switch (ltable[etnum][etpos])
  401.         {
  402.             case WAVECMD + CMD_PORTAUP:
  403.             case WAVECMD + CMD_PORTADOWN:
  404.             case WAVECMD + CMD_TONEPORTA:
  405.             table = STBL;
  406.             break;
  407.  
  408.             case WAVECMD + CMD_VIBRATO:
  409.             table = STBL;
  410.             mstmode = finevibrato;
  411.             break;
  412.  
  413.             case WAVECMD + CMD_FUNKTEMPO:
  414.         table = STBL;
  415.         mstmode = MST_FUNKTEMPO;
  416.             break;
  417.  
  418.             case WAVECMD + CMD_SETPULSEPTR:
  419.             table = PTBL;
  420.             break;
  421.  
  422.             case WAVECMD + CMD_SETFILTERPTR:
  423.             table = FTBL;
  424.             break;
  425.         }
  426.       switch (table)
  427.       {
  428.           default:
  429.         editmode = EDIT_INSTRUMENT;
  430.         eipos = etnum + 2;
  431.         return;
  432.  
  433.         case STBL:
  434.         if (rtable[etnum][etpos])
  435.         {
  436.           if (!shiftpressed)
  437.             {
  438.             gototable(STBL, rtable[etnum][etpos] - 1);
  439.             return;
  440.           }
  441.           else
  442.           {
  443.             int oldeditpos = etpos;
  444.             int oldeditcolumn = etcolumn;
  445.             int pos = makespeedtable(rtable[etnum][etpos], mstmode, 1);
  446.             gototable(WTBL, oldeditpos);
  447.             etcolumn = oldeditcolumn;
  448.  
  449.             rtable[etnum][etpos] = pos + 1;
  450.             return;
  451.           }
  452.         }
  453.         else
  454.         {
  455.           int pos = findfreespeedtable();
  456.           if (pos >= 0)
  457.           {
  458.             rtable[etnum][etpos] = pos + 1;
  459.             gototable(STBL, pos);
  460.             return;
  461.           }
  462.         }
  463.         break;
  464.  
  465.         case PTBL:
  466.         case FTBL:
  467.         if (rtable[etnum][etpos])
  468.         {
  469.           gototable(table, rtable[etnum][etpos] - 1);
  470.           return;
  471.         }
  472.         else
  473.         {
  474.             if (shiftpressed)
  475.             {
  476.             int pos = gettablelen(table);
  477.             if (pos >= MAX_TABLELEN-1) pos = MAX_TABLELEN - 1;
  478.             rtable[etnum][etpos] = pos + 1;
  479.             gototable(table, pos);
  480.             return;
  481.           }
  482.         }
  483.       }
  484.     }
  485.     else
  486.     {
  487.       editmode = EDIT_INSTRUMENT;
  488.       eipos = etnum + 2;
  489.       return;
  490.     }
  491.     break;
  492.     
  493.     case KEY_APOST2:
  494.     if (shiftpressed)
  495.     {
  496.       etpos -= etview[etnum];
  497.       etnum--;
  498.       if (etnum < 0) etnum = MAX_TABLES-1;
  499.       etpos += etview[etnum];
  500.     }
  501.     else
  502.     {
  503.       etpos -= etview[etnum];
  504.       etnum++;
  505.       if (etnum >= MAX_TABLES) etnum = 0;
  506.       etpos += etview[etnum];
  507.     }
  508.   }
  509.  
  510.   if (hexnybble >= 0)
  511.   {
  512.     switch(etcolumn)
  513.     {
  514.       case 0:
  515.       ltable[etnum][etpos] &= 0x0f;
  516.       ltable[etnum][etpos] |= hexnybble << 4;
  517.       break;
  518.       case 1:
  519.       ltable[etnum][etpos] &= 0xf0;
  520.       ltable[etnum][etpos] |= hexnybble;
  521.       break;
  522.       case 2:
  523.       rtable[etnum][etpos] &= 0x0f;
  524.       rtable[etnum][etpos] |= hexnybble << 4;
  525.       break;
  526.       case 3:
  527.       rtable[etnum][etpos] &= 0xf0;
  528.       rtable[etnum][etpos] |= hexnybble;
  529.       break;
  530.     }
  531.     etcolumn++;
  532.     if (etcolumn > 3)
  533.     {
  534.       etcolumn = 0;
  535.       etpos++;
  536.       if (etpos >= MAX_TABLELEN) etpos = MAX_TABLELEN-1;
  537.     }
  538.   }
  539.  
  540.   validatetableview();
  541. }
  542.  
  543. void deletetable(int num, int pos)
  544. {
  545.   int c, d;
  546.  
  547.   // Shift tablepointers in instruments
  548.   for (c = 1; c < MAX_INSTR; c++)
  549.   {
  550.     if ((instr[c].ptr[num]-1) > pos) instr[c].ptr[num]--;
  551.   }
  552.  
  553.   // Shift tablepointers in wavetable commands
  554.   for (c = 0; c < MAX_TABLELEN; c++)
  555.   {
  556.       if ((ltable[WTBL][c] >= WAVECMD) && (ltable[WTBL][c] <= WAVELASTCMD))
  557.     {
  558.       int cmd = ltable[WTBL][c] & 0xf;
  559.  
  560.       if (num < STBL)
  561.       {
  562.           if (cmd == CMD_SETWAVEPTR+num)
  563.           {
  564.           if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]--;
  565.         }
  566.       }
  567.       else
  568.       {
  569.         if ((cmd == CMD_FUNKTEMPO) || ((cmd >= CMD_PORTAUP) && (cmd <= CMD_VIBRATO)))
  570.         {
  571.           if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]--;
  572.         }
  573.       }
  574.     }
  575.   }
  576.  
  577.   // Shift tablepointers in patterns
  578.   for (c = 0; c < MAX_PATT; c++)
  579.   {
  580.     for (d = 0; d <= MAX_PATTROWS; d++)
  581.     {
  582.       if (num < STBL)
  583.       {
  584.         if (pattern[c][d*4+2] == CMD_SETWAVEPTR+num)
  585.         {
  586.           if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]--;
  587.         }
  588.       }
  589.       else
  590.       {
  591.         if ((pattern[c][d*4+2] == CMD_FUNKTEMPO) ||
  592.            ((pattern[c][d*4+2] >= CMD_PORTAUP) && (pattern[c][d*4+2] <= CMD_VIBRATO)))
  593.         {
  594.           if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]--;
  595.         }
  596.       }
  597.     }
  598.   }
  599.  
  600.   // Shift jumppointers in the table itself
  601.   for (c = 0; c < MAX_TABLELEN; c++)
  602.   {
  603.     if (num != STBL)
  604.     {
  605.       if (ltable[num][c] == 0xff)
  606.         if ((rtable[num][c]-1) > pos) rtable[num][c]--;
  607.     }
  608.   }
  609.  
  610.   for (c = pos; c < MAX_TABLELEN; c++)
  611.   {
  612.     if (c+1 < MAX_TABLELEN)
  613.     {
  614.       ltable[num][c] = ltable[num][c+1];
  615.       rtable[num][c] = rtable[num][c+1];
  616.     }
  617.     else
  618.     {
  619.       ltable[num][c] = 0;
  620.       rtable[num][c] = 0;
  621.     }
  622.   }
  623. }
  624.  
  625. void inserttable(int num, int pos, int mode)
  626. {
  627.   int c, d;
  628.  
  629.   // Shift tablepointers in instruments
  630.   for (c = 1; c < MAX_INSTR; c++)
  631.   {
  632.     if (!mode)
  633.     {
  634.       if ((instr[c].ptr[num]-1) >= pos) instr[c].ptr[num]++;
  635.     }
  636.     else
  637.     {
  638.       if ((instr[c].ptr[num]-1) > pos) instr[c].ptr[num]++;
  639.     }
  640.   }
  641.  
  642.   // Shift tablepointers in wavetable commands
  643.   for (c = 0; c < MAX_TABLELEN; c++)
  644.   {
  645.       if ((ltable[WTBL][c] >= WAVECMD) && (ltable[WTBL][c] <= WAVELASTCMD))
  646.     {
  647.       int cmd = ltable[WTBL][c] & 0xf;
  648.  
  649.       if (num < STBL)
  650.       {
  651.           if (cmd == CMD_SETWAVEPTR+num)
  652.           {
  653.           if (!mode)
  654.           {
  655.               if ((rtable[WTBL][c]-1) >= pos) rtable[WTBL][c]++;
  656.           }
  657.           else
  658.           {
  659.               if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]++;
  660.           }
  661.         }
  662.       }
  663.       else
  664.       {
  665.         if ((cmd == CMD_FUNKTEMPO) || ((cmd >= CMD_PORTAUP) && (cmd <= CMD_VIBRATO)))
  666.         {
  667.           if (!mode)
  668.           {
  669.             if ((rtable[WTBL][c]-1) >= pos) rtable[WTBL][c]++;
  670.           }
  671.           else
  672.           {
  673.             if ((rtable[WTBL][c]-1) > pos) rtable[WTBL][c]++;
  674.           }
  675.         }
  676.       }
  677.     }
  678.   }
  679.  
  680.  
  681.   // Shift tablepointers in patterns
  682.   for (c = 0; c < MAX_PATT; c++)
  683.   {
  684.     for (d = 0; d <= MAX_PATTROWS; d++)
  685.     {
  686.       if (num < STBL)
  687.       {
  688.         if (pattern[c][d*4+2] == CMD_SETWAVEPTR+num)
  689.         {
  690.           if (!mode)
  691.           {
  692.             if ((pattern[c][d*4+3]-1) >= pos) pattern[c][d*4+3]++;
  693.           }
  694.           else
  695.           {
  696.             if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]++;
  697.           }
  698.         }
  699.       }
  700.       else
  701.       {
  702.         if ((pattern[c][d*4+2] == CMD_FUNKTEMPO) ||
  703.            ((pattern[c][d*4+2] >= CMD_PORTAUP) && (pattern[c][d*4+2] <= CMD_VIBRATO)))
  704.         {
  705.           if (!mode)
  706.           {
  707.             if ((pattern[c][d*4+3]-1) >= pos) pattern[c][d*4+3]++;
  708.           }
  709.           else
  710.           {
  711.             if ((pattern[c][d*4+3]-1) > pos) pattern[c][d*4+3]++;
  712.           }
  713.         }
  714.       }
  715.     }
  716.   }
  717.  
  718.   // Shift jumppointers in the table itself
  719.   if (num != STBL)
  720.   {
  721.     for (c = 0; c < MAX_TABLELEN; c++)
  722.     {
  723.       if (ltable[num][c] == 0xff)
  724.       {
  725.         if (!mode)
  726.         {
  727.           if ((rtable[num][c]-1) >= pos) rtable[num][c]++;
  728.         }
  729.         else
  730.         {
  731.           if ((rtable[num][c]-1) > pos) rtable[num][c]++;
  732.         }
  733.       }
  734.     }
  735.   }
  736.  
  737.   for (c = MAX_TABLELEN-1; c >= pos; c--)
  738.   {
  739.     if (c > pos)
  740.     {
  741.       ltable[num][c] = ltable[num][c-1];
  742.       rtable[num][c] = rtable[num][c-1];
  743.     }
  744.     else
  745.     {
  746.       if ((num == WTBL) && (mode == 1))
  747.       {
  748.         ltable[num][c] = 0xe9;
  749.         rtable[num][c] = 0;
  750.       }
  751.       else
  752.       {
  753.         ltable[num][c] = 0;
  754.         rtable[num][c] = 0;
  755.       }
  756.     }
  757.   }
  758. }
  759.  
  760. int gettablelen(int num)
  761. {
  762.   int c;
  763.  
  764.   for (c = MAX_TABLELEN-1; c >= 0; c--)
  765.   {
  766.     if (ltable[num][c] | rtable[num][c]) break;
  767.   }
  768.   return c+1;
  769. }
  770.  
  771. int gettablepartlen(int num, int pos)
  772. {
  773.   int c;
  774.  
  775.   if (pos < 0) return 0;
  776.   if (num == STBL) return 1;
  777.  
  778.   for (c = pos; c < MAX_TABLELEN; c++)
  779.   {
  780.     if (ltable[num][c] == 0xff)
  781.     {
  782.       c++;
  783.       break;
  784.     }
  785.   }
  786.   return c-pos;
  787. }
  788.  
  789. void optimizetable(int num)
  790. {
  791.   int c,d;
  792.  
  793.   memset(tableused, 0, sizeof tableused);
  794.  
  795.   for (c = 0; c < MAX_PATT; c++)
  796.   {
  797.     for (d = 0; d < pattlen[c]; d++)
  798.     {
  799.       if ((pattern[c][d*4+2] >= CMD_SETWAVEPTR) && (pattern[c][d*4+2] <= CMD_SETFILTERPTR))
  800.         exectable(pattern[c][d*4+2] - CMD_SETWAVEPTR, pattern[c][d*4+3]);
  801.       if ((pattern[c][d*4+2] >= CMD_PORTAUP) && (pattern[c][d*4+2] <= CMD_VIBRATO))
  802.         exectable(STBL, pattern[c][d*4+3]);
  803.       if (pattern[c][d*4+2] == CMD_FUNKTEMPO)
  804.         exectable(STBL, pattern[c][d*4+3]);
  805.     }
  806.   }
  807.  
  808.   for (c = 0; c < MAX_INSTR; c++)
  809.   {
  810.     for (d = 0; d < MAX_TABLES; d++)
  811.     {
  812.       exectable(d, instr[c].ptr[d]);
  813.     }
  814.   }
  815.  
  816.   for (c = 0; c < MAX_TABLELEN; c++)
  817.   {
  818.       if (tableused[WTBL][c+1])
  819.       {
  820.       if ((ltable[WTBL][c] >= WAVECMD) && (ltable[WTBL][c] <= WAVELASTCMD))
  821.       {
  822.             d = -1;
  823.  
  824.         switch(ltable[WTBL][c] - WAVECMD)
  825.         {
  826.             case CMD_PORTAUP:
  827.             case CMD_PORTADOWN:
  828.           case CMD_TONEPORTA:
  829.           case CMD_VIBRATO:
  830.           d = STBL;
  831.           break;
  832.  
  833.               case CMD_SETPULSEPTR:
  834.               d = PTBL;
  835.                  break;
  836.  
  837.                  case CMD_SETFILTERPTR:
  838.                  d = FTBL;
  839.           break;
  840.         }
  841.  
  842.         if (d != -1) exectable(d, rtable[WTBL][c]);
  843.       }
  844.     }
  845.   }
  846.  
  847.   for (c = MAX_TABLELEN-1; c >= 0; c--)
  848.   {
  849.     if ((ltable[num][c]) || (rtable[num][c])) break;
  850.   }
  851.   for (; c >= 0; c--)
  852.   {
  853.     if (!tableused[num][c+1]) deletetable(num, c);
  854.   }
  855. }
  856.  
  857. int makespeedtable(unsigned data, int mode, int makenew)
  858. {
  859.   int c;
  860.   unsigned char l = 0, r = 0;
  861.  
  862.   if (!data) return -1;
  863.  
  864.   switch (mode)
  865.   {
  866.     case MST_NOFINEVIB:
  867.     l = (data & 0xf0) >> 4;
  868.     r = (data & 0x0f) << 4;
  869.     break;
  870.  
  871.     case MST_FINEVIB:
  872.     l = (data & 0x70) >> 4;
  873.     r = ((data & 0x0f) << 4) | ((data & 0x80) >> 4);
  874.     break;
  875.  
  876.     case MST_FUNKTEMPO:
  877.     l = (data & 0xf0) >> 4;
  878.     r = data & 0x0f;
  879.     break;
  880.  
  881.     case MST_PORTAMENTO:
  882.     l = (data << 2) >> 8;
  883.     r = (data << 2) & 0xff;
  884.     break;
  885.     
  886.     case MST_RAW:
  887.     r = data & 0xff;
  888.     l = data >> 8;
  889.     break;
  890.   }
  891.  
  892.   if (makenew == 0)
  893.   {
  894.     for (c = 0; c < MAX_TABLELEN; c++)
  895.     {
  896.       if ((ltable[STBL][c] == l) && (rtable[STBL][c] == r))
  897.         return c;
  898.     }
  899.   }
  900.  
  901.   for (c = 0; c < MAX_TABLELEN; c++)
  902.   {
  903.     if ((!ltable[STBL][c]) && (!rtable[STBL][c]))
  904.     {
  905.       ltable[STBL][c] = l;
  906.       rtable[STBL][c] = r;
  907.  
  908.       settableview(STBL, c);
  909.       return c;
  910.     }
  911.   }
  912.   return -1;
  913. }
  914.  
  915. void deleteinstrtable(int i)
  916. {
  917.   int c,d;
  918.   int eraseok = 1;
  919.  
  920.   for (c = 0; c < MAX_TABLES; c++)
  921.   {
  922.     if (instr[i].ptr[c])
  923.     {
  924.       int pos = instr[i].ptr[c]-1;
  925.       int len = gettablepartlen(c, pos);
  926.  
  927.       // Check that this table area isn't used by another instrument
  928.       for (d = 1; d < MAX_INSTR; d++)
  929.       {
  930.         if ((d != i) && (instr[d].ptr[c]))
  931.         {
  932.           int cmppos = instr[d].ptr[c]-1;
  933.           if ((cmppos >= pos) && (cmppos < pos+len)) eraseok = 0;
  934.         }
  935.       }
  936.       if (eraseok)
  937.         while (len--) deletetable(c, pos);
  938.     }
  939.   }
  940. }
  941.  
  942. void gototable(int num, int pos)
  943. {
  944.   editmode = EDIT_TABLES;
  945.   settableview(num, pos);
  946. }
  947.  
  948. void settableview(int num, int pos)
  949. {
  950.   etnum = num;
  951.   etcolumn = 0;
  952.   etpos = pos;
  953.  
  954.   validatetableview();
  955. }
  956.  
  957. void settableviewfirst(int num, int pos)
  958. {
  959.   etview[num] = pos;
  960.   settableview(num, pos);
  961. }
  962. void validatetableview(void)
  963. {
  964.   if (etpos - etview[etnum] < 0)
  965.     etview[etnum] = etpos;
  966.   if (etpos - etview[etnum] >= VISIBLETABLEROWS)
  967.     etview[etnum] = etpos - VISIBLETABLEROWS + 1;
  968.  
  969.   // Table view lock?
  970.   if (etlock)
  971.   {
  972.     int c;
  973.  
  974.     for (c = 0; c < MAX_TABLES; c++) etview[c] = etview[etnum];
  975.   }
  976. }
  977.  
  978. void tableup(void)
  979. {
  980.   if (shiftpressed)
  981.   {
  982.     if ((etmarknum != etnum) || (etpos != etmarkend))
  983.     {
  984.       etmarknum = etnum;
  985.       etmarkstart = etmarkend = etpos;
  986.     }
  987.   }
  988.   etpos--;
  989.   if (etpos < 0) etpos = 0;
  990.   if (shiftpressed) etmarkend = etpos;
  991. }
  992.  
  993. void tabledown(void)
  994. {
  995.   if (shiftpressed)
  996.   {
  997.     if ((etmarknum != etnum) || (etpos != etmarkend))
  998.     {
  999.       etmarknum = etnum;
  1000.       etmarkstart = etmarkend = etpos;
  1001.     }
  1002.   }
  1003.   etpos++;
  1004.   if (etpos >= MAX_TABLELEN) etpos = MAX_TABLELEN-1;
  1005.   if (shiftpressed) etmarkend = etpos;
  1006. }
  1007.  
  1008. void exectable(int num, int ptr)
  1009. {
  1010.   // Jump error check
  1011.   if ((num != STBL) && (ptr) && (ptr <= MAX_TABLELEN))
  1012.   {
  1013.     if (ltable[num][ptr-1] == 0xff)
  1014.     {
  1015.       tableerror = TYPE_JUMP;
  1016.       return;
  1017.     }
  1018.   }
  1019.  
  1020.   for (;;)
  1021.   {
  1022.     // Exit when table stopped
  1023.     if (!ptr) break;
  1024.     // Overflow check
  1025.     if ((num != STBL) && (ptr > MAX_TABLELEN))
  1026.     {
  1027.       tableerror = TYPE_OVERFLOW;
  1028.       break;
  1029.     }
  1030.     // If were already here, exit
  1031.     if (tableused[num][ptr]) break;
  1032.     // Mark current position used
  1033.     tableused[num][ptr] = 1;
  1034.     // Go to next ptr.
  1035.     if (num != STBL)
  1036.     {
  1037.       if (ltable[num][ptr-1] == 0xff)
  1038.       {
  1039.         ptr = rtable[num][ptr-1];
  1040.       }
  1041.       else ptr++;
  1042.     }
  1043.     else break;
  1044.   }
  1045. }
  1046.  
  1047. int findfreespeedtable(void)
  1048. {
  1049.   int c;
  1050.   for (c = 0; c < MAX_TABLELEN; c++)
  1051.   {
  1052.     if ((!ltable[STBL][c]) && (!rtable[STBL][c]))
  1053.     {
  1054.       return c;
  1055.     }
  1056.   }
  1057.   return -1;
  1058. }
  1059.  
  1060.