home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.65.zip / src / gsong.c < prev    next >
C/C++ Source or Header  |  2007-04-14  |  45KB  |  1,578 lines

  1. //
  2. // GOATTRACKER v2 song data model, loading/saving/conversion
  3. //
  4.  
  5. #define GSONG_C
  6.  
  7. #include "goattrk2.h"
  8.  
  9. INSTR instr[MAX_INSTR];
  10. unsigned char ltable[MAX_TABLES][MAX_TABLELEN];
  11. unsigned char rtable[MAX_TABLES][MAX_TABLELEN];
  12. unsigned char songorder[MAX_SONGS][MAX_CHN][MAX_SONGLEN+2];
  13. unsigned char pattern[MAX_PATT][MAX_PATTROWS*4+4];
  14. unsigned char songname[MAX_STR];
  15. unsigned char authorname[MAX_STR];
  16. unsigned char copyrightname[MAX_STR];
  17. int pattlen[MAX_PATT];
  18. int songlen[MAX_SONGS][MAX_CHN];
  19. int highestusedpattern;
  20. int highestusedinstr;
  21.  
  22. int savesong(void)
  23. {
  24.   int c;
  25.   char ident[] = {'G', 'T', 'S', '5'};
  26.   FILE *handle;
  27.  
  28.   if (strlen(songfilename) < MAX_FILENAME-4)
  29.   {
  30.     int extfound = 0;
  31.     for (c = strlen(songfilename)-1; c >= 0; c--)
  32.     {
  33.       if (songfilename[c] == '.') extfound = 1;
  34.     }
  35.     if (!extfound) strcat(songfilename, ".sng");
  36.   }
  37.   handle = fopen(songfilename, "wb");
  38.   if (handle)
  39.   {
  40.     int d;
  41.     int length;
  42.     int amount;
  43.     int writebytes;
  44.     fwrite(ident, 4, 1, handle);
  45.  
  46.     // Determine amount of patterns & instruments
  47.     countpatternlengths();
  48.     for (c = 1; c < MAX_INSTR; c++)
  49.     {
  50.       if ((instr[c].ad) || (instr[c].sr) || (instr[c].ptr[0]) || (instr[c].ptr[1]) ||
  51.           (instr[c].ptr[2]) || (instr[c].vibdelay) || (instr[c].ptr[3]))
  52.       {
  53.         if (c > highestusedinstr) highestusedinstr = c;
  54.       }
  55.     }
  56.  
  57.     // Write infotexts
  58.     fwrite(songname, sizeof songname, 1, handle);
  59.     fwrite(authorname, sizeof authorname, 1, handle);
  60.     fwrite(copyrightname, sizeof copyrightname, 1, handle);
  61.  
  62.     // Determine amount of songs to be saved
  63.     c = MAX_SONGS - 1;
  64.     for (;;)
  65.     {
  66.       if ((songlen[c][0])&&
  67.          (songlen[c][1])&&
  68.          (songlen[c][2])) break;
  69.       if (c == 0) break;
  70.       c--;
  71.     }
  72.     amount = c + 1;
  73.  
  74.     fwrite8(handle, amount);
  75.     // Write songorderlists
  76.     for (d = 0; d < amount; d++)
  77.     {
  78.       for (c = 0; c < MAX_CHN; c++)
  79.       {
  80.         length = songlen[d][c]+1;
  81.         fwrite8(handle, length);
  82.         writebytes = length;
  83.         writebytes++;
  84.         fwrite(songorder[d][c], writebytes, 1, handle);
  85.       }
  86.     }
  87.     // Write amount of instruments
  88.     fwrite8(handle, highestusedinstr);
  89.     // Write instruments
  90.     for (c = 1; c <= highestusedinstr; c++)
  91.     {
  92.       fwrite8(handle, instr[c].ad);
  93.       fwrite8(handle, instr[c].sr);
  94.       fwrite8(handle, instr[c].ptr[WTBL]);
  95.       fwrite8(handle, instr[c].ptr[PTBL]);
  96.       fwrite8(handle, instr[c].ptr[FTBL]);
  97.       fwrite8(handle, instr[c].ptr[STBL]);
  98.       fwrite8(handle, instr[c].vibdelay);
  99.       fwrite8(handle, instr[c].gatetimer);
  100.       fwrite8(handle, instr[c].firstwave);
  101.       fwrite(&instr[c].name, MAX_INSTRNAMELEN, 1, handle);
  102.     }
  103.     // Write tables
  104.     for (c = 0; c < MAX_TABLES; c++)
  105.     {
  106.       writebytes = gettablelen(c);
  107.       fwrite8(handle, writebytes);
  108.       fwrite(ltable[c], writebytes, 1, handle);
  109.       fwrite(rtable[c], writebytes, 1, handle);
  110.     }
  111.     // Write patterns
  112.     amount = highestusedpattern + 1;
  113.     fwrite8(handle, amount);
  114.     for (c = 0; c < amount; c++)
  115.     {
  116.       length = pattlen[c]+1;
  117.       fwrite8(handle, length);
  118.       fwrite(pattern[c], length * 4, 1, handle);
  119.     }
  120.     fclose(handle);
  121.     strcpy(loadedsongfilename, songfilename);
  122.     return 1;
  123.   }
  124.   return 0;
  125. }
  126.  
  127. int saveinstrument(void)
  128. {
  129.   int c;
  130.   char ident[] = {'G', 'T', 'I', '5'};
  131.   FILE *handle;
  132.  
  133.   if (strlen(instrfilename) < MAX_FILENAME-4)
  134.   {
  135.     int extfound = 0;
  136.     for (c = strlen(instrfilename)-1; c >= 0; c--)
  137.     {
  138.       if (instrfilename[c] == '.') extfound = 1;
  139.     }
  140.     if (!extfound) strcat(instrfilename, ".ins");
  141.   }
  142.  
  143.   handle = fopen(instrfilename, "wb");
  144.   if (handle)
  145.   {
  146.     fwrite(ident, 4, 1, handle);
  147.  
  148.     // Write instrument
  149.     fwrite8(handle, instr[einum].ad);
  150.     fwrite8(handle, instr[einum].sr);
  151.     fwrite8(handle, instr[einum].ptr[WTBL]);
  152.     fwrite8(handle, instr[einum].ptr[PTBL]);
  153.     fwrite8(handle, instr[einum].ptr[FTBL]);
  154.     fwrite8(handle, instr[einum].ptr[STBL]);
  155.     fwrite8(handle, instr[einum].vibdelay);
  156.     fwrite8(handle, instr[einum].gatetimer);
  157.     fwrite8(handle, instr[einum].firstwave);
  158.     fwrite(&instr[einum].name, MAX_INSTRNAMELEN, 1, handle);
  159.     for (c = 0; c < MAX_TABLES; c++)
  160.     {
  161.       if (instr[einum].ptr[c])
  162.       {
  163.         int pos = instr[einum].ptr[c] - 1;
  164.         int len = gettablepartlen(c, pos);
  165.         fwrite8(handle, len);
  166.         fwrite(<able[c][pos], len, 1, handle);
  167.         fwrite(&rtable[c][pos], len, 1, handle);
  168.       }
  169.       else fwrite8(handle, 0);
  170.     }
  171.     fclose(handle);
  172.     return 1;
  173.   }
  174.   return 0;
  175. }
  176.  
  177. void loadsong(void)
  178. {
  179.   int c;
  180.   int ok = 0;
  181.   char ident[4];
  182.   FILE *handle;
  183.  
  184.   handle = fopen(songfilename, "rb");
  185.  
  186.   if (handle)
  187.   {
  188.     fread(ident, 4, 1, handle);
  189.     if ((!memcmp(ident, "GTS3", 4)) || (!memcmp(ident, "GTS4", 4)) || (!memcmp(ident, "GTS5", 4)))
  190.     {
  191.       int d;
  192.       int length;
  193.       int amount;
  194.       int loadsize;
  195.       clearsong(1,1,1,1,1);
  196.       ok = 1;
  197.  
  198.       // Read infotexts
  199.       fread(songname, sizeof songname, 1, handle);
  200.       fread(authorname, sizeof authorname, 1, handle);
  201.       fread(copyrightname, sizeof copyrightname, 1, handle);
  202.  
  203.       // Read songorderlists
  204.       amount = fread8(handle);
  205.       for (d = 0; d < amount; d++)
  206.       {
  207.         for (c = 0; c < MAX_CHN; c++)
  208.         {
  209.           length = fread8(handle);
  210.           loadsize = length;
  211.           loadsize++;
  212.           fread(songorder[d][c], loadsize, 1, handle);
  213.         }
  214.       }
  215.       // Read instruments
  216.       amount = fread8(handle);
  217.       for (c = 1; c <= amount; c++)
  218.       {
  219.         instr[c].ad = fread8(handle);
  220.         instr[c].sr = fread8(handle);
  221.         instr[c].ptr[WTBL] = fread8(handle);
  222.         instr[c].ptr[PTBL] = fread8(handle);
  223.         instr[c].ptr[FTBL] = fread8(handle);
  224.         instr[c].ptr[STBL] = fread8(handle);
  225.         instr[c].vibdelay = fread8(handle);
  226.         instr[c].gatetimer = fread8(handle);
  227.         instr[c].firstwave = fread8(handle);
  228.         fread(&instr[c].name, MAX_INSTRNAMELEN, 1, handle);
  229.       }
  230.       // Read tables
  231.       for (c = 0; c < MAX_TABLES; c++)
  232.       {
  233.         loadsize = fread8(handle);
  234.         fread(ltable[c], loadsize, 1, handle);
  235.         fread(rtable[c], loadsize, 1, handle);
  236.       }
  237.       // Read patterns
  238.       amount = fread8(handle);
  239.       for (c = 0; c < amount; c++)
  240.       {
  241.         length = fread8(handle) * 4;
  242.         fread(pattern[c], length, 1, handle);
  243.       }
  244.       countpatternlengths();
  245.       songchange();
  246.     }
  247.  
  248.     // Goattracker v2.xx (3-table) import
  249.     if (!memcmp(ident, "GTS2", 4))
  250.     {
  251.       int d;
  252.       int length;
  253.       int amount;
  254.       int loadsize;
  255.       clearsong(1,1,1,1,1);
  256.       ok = 1;
  257.  
  258.       // Read infotexts
  259.       fread(songname, sizeof songname, 1, handle);
  260.       fread(authorname, sizeof authorname, 1, handle);
  261.       fread(copyrightname, sizeof copyrightname, 1, handle);
  262.  
  263.       // Read songorderlists
  264.       amount = fread8(handle);
  265.       for (d = 0; d < amount; d++)
  266.       {
  267.         for (c = 0; c < MAX_CHN; c++)
  268.         {
  269.           length = fread8(handle);
  270.           loadsize = length;
  271.           loadsize++;
  272.           fread(songorder[d][c], loadsize, 1, handle);
  273.         }
  274.       }
  275.       // Read instruments
  276.       amount = fread8(handle);
  277.       for (c = 1; c <= amount; c++)
  278.       {
  279.         instr[c].ad = fread8(handle);
  280.         instr[c].sr = fread8(handle);
  281.         instr[c].ptr[WTBL] = fread8(handle);
  282.         instr[c].ptr[PTBL] = fread8(handle);
  283.         instr[c].ptr[FTBL] = fread8(handle);
  284.         instr[c].vibdelay = fread8(handle);
  285.         instr[c].ptr[STBL] = makespeedtable(fread8(handle), finevibrato, 0) + 1;
  286.         instr[c].gatetimer = fread8(handle);
  287.         instr[c].firstwave = fread8(handle);
  288.         fread(&instr[c].name, MAX_INSTRNAMELEN, 1, handle);
  289.       }
  290.       // Read tables
  291.       for (c = 0; c < MAX_TABLES-1; c++)
  292.       {
  293.         loadsize = fread8(handle);
  294.         fread(ltable[c], loadsize, 1, handle);
  295.         fread(rtable[c], loadsize, 1, handle);
  296.       }
  297.       // Read patterns
  298.       amount = fread8(handle);
  299.       for (c = 0; c < amount; c++)
  300.       {
  301.         int d;
  302.         length = fread8(handle) * 4;
  303.         fread(pattern[c], length, 1, handle);
  304.  
  305.         // Convert speedtable-requiring commands
  306.         for (d = 0; d < length; d++)
  307.         {
  308.           switch (pattern[c][d*4+2])
  309.           {
  310.             case CMD_FUNKTEMPO:
  311.             pattern[c][d*4+3] = makespeedtable(pattern[c][d*4+3], MST_FUNKTEMPO, 0) + 1;
  312.             break;
  313.  
  314.             case CMD_PORTAUP:
  315.             case CMD_PORTADOWN:
  316.             case CMD_TONEPORTA:
  317.             pattern[c][d*4+3] = makespeedtable(pattern[c][d*4+3], MST_PORTAMENTO, 0) + 1;
  318.             break;
  319.  
  320.             case CMD_VIBRATO:
  321.             pattern[c][d*4+3] = makespeedtable(pattern[c][d*4+3], finevibrato, 0) + 1;
  322.             break;
  323.           }
  324.         }
  325.       }
  326.       countpatternlengths();
  327.       songchange();
  328.     }
  329.     // Goattracker 1.xx import
  330.     if (!memcmp(ident, "GTS!", 4))
  331.     {
  332.       int d;
  333.       int length;
  334.       int amount;
  335.       int loadsize;
  336.       int fw = 0;
  337.       int fp = 0;
  338.       int ff = 0;
  339.       int fi = 0;
  340.       int numfilter = 0;
  341.       unsigned char filtertable[256];
  342.       unsigned char filtermap[64];
  343.       int arpmap[32][256];
  344.       unsigned char pulse[32], pulseadd[32], pulselimitlow[32], pulselimithigh[32];
  345.       int filterjumppos[64];
  346.  
  347.       clearsong(1,1,1,1,1);
  348.       ok = 1;
  349.  
  350.       // Read infotexts
  351.       fread(songname, sizeof songname, 1, handle);
  352.       fread(authorname, sizeof authorname, 1, handle);
  353.       fread(copyrightname, sizeof copyrightname, 1, handle);
  354.  
  355.       // Read songorderlists
  356.       amount = fread8(handle);
  357.       for (d = 0; d < amount; d++)
  358.       {
  359.         for (c = 0; c < MAX_CHN; c++)
  360.         {
  361.           length = fread8(handle);
  362.           loadsize = length;
  363.           loadsize++;
  364.           fread(songorder[d][c], loadsize, 1, handle);
  365.         }
  366.       }
  367.  
  368.       // Convert instruments
  369.       for (c = 1; c < 32; c++)
  370.       {
  371.         unsigned char wavelen;
  372.  
  373.         instr[c].ad = fread8(handle);
  374.         instr[c].sr = fread8(handle);
  375.         pulse[c] = fread8(handle);
  376.         pulseadd[c] = fread8(handle);
  377.         pulselimitlow[c] = fread8(handle);
  378.         pulselimithigh[c] = fread8(handle);
  379.         instr[c].ptr[FTBL] = fread8(handle); // Will be converted later
  380.         if (instr[c].ptr[FTBL] > numfilter) numfilter = instr[c].ptr[FTBL];
  381.         if (pulse[c] & 1) instr[c].gatetimer |= 0x80; // "No hardrestart" flag
  382.         pulse[c] &= 0xfe;
  383.         wavelen = fread8(handle)/2;
  384.         fread(&instr[c].name, MAX_INSTRNAMELEN, 1, handle);
  385.         instr[c].ptr[WTBL] = fw+1;
  386.  
  387.         // Convert wavetable
  388.         for (d = 0; d < wavelen; d++)
  389.         {
  390.           if (fw < MAX_TABLELEN)
  391.           {
  392.             ltable[WTBL][fw] = fread8(handle);
  393.             rtable[WTBL][fw] = fread8(handle);
  394.             if (ltable[WTBL][fw] == 0xff)
  395.               if (rtable[WTBL][fw]) rtable[WTBL][fw] += instr[c].ptr[WTBL]-1;
  396.             if ((ltable[WTBL][fw] >= 0x8) && (ltable[WTBL][fw] <= 0xf))
  397.               ltable[WTBL][fw] |= 0xe0;
  398.             fw++;
  399.           }
  400.           else
  401.           {
  402.             fread8(handle);
  403.             fread8(handle);
  404.           }
  405.         }
  406.  
  407.         // Remove empty wavetable afterwards
  408.         if ((wavelen == 2) && (!ltable[WTBL][fw-2]) && (!rtable[WTBL][fw-2]))
  409.         {
  410.           instr[c].ptr[WTBL] = 0;
  411.           fw -= 2;
  412.           ltable[WTBL][fw] = 0;
  413.           rtable[WTBL][fw] = 0;
  414.           ltable[WTBL][fw+1] = 0;
  415.           rtable[WTBL][fw+1] = 0;
  416.         }
  417.  
  418.         // Convert pulsetable
  419.         if (pulse[c])
  420.         {
  421.           int pulsetime, pulsedist, hlpos;
  422.  
  423.           // Check for duplicate pulse settings
  424.           for (d = 1; d < c; d++)
  425.           {
  426.             if ((pulse[d] == pulse[c]) && (pulseadd[d] == pulseadd[c]) && (pulselimitlow[d] == pulselimitlow[c]) &&
  427.                 (pulselimithigh[d] == pulselimithigh[c]))
  428.             {
  429.               instr[c].ptr[PTBL] = instr[d].ptr[PTBL];
  430.               goto PULSEDONE;
  431.             }
  432.           }
  433.  
  434.           // Initial pulse setting
  435.           if (fp >= MAX_TABLELEN) goto PULSEDONE;
  436.           instr[c].ptr[PTBL] = fp+1;
  437.           ltable[PTBL][fp] = 0x80 | (pulse[c] >> 4);
  438.           rtable[PTBL][fp] = pulse[c] << 4;
  439.           fp++;
  440.  
  441.           // Pulse modulation
  442.           if (pulseadd[c])
  443.           {
  444.             int startpulse = pulse[c]*16;
  445.             int currentpulse = pulse[c]*16;
  446.             // Phase 1: From startpos to high limit
  447.             pulsedist = pulselimithigh[c]*16 - currentpulse;
  448.             if (pulsedist > 0)
  449.             {
  450.               pulsetime = pulsedist/pulseadd[c];
  451.               currentpulse += pulsetime*pulseadd[c];
  452.               while (pulsetime)
  453.               {
  454.                 int acttime = pulsetime;
  455.                 if (acttime > 127) acttime = 127;
  456.                 if (fp >= MAX_TABLELEN) goto PULSEDONE;
  457.                 ltable[PTBL][fp] = acttime;
  458.                 rtable[PTBL][fp] = pulseadd[c] / 2;
  459.                 fp++;
  460.                 pulsetime -= acttime;
  461.               }
  462.             }
  463.  
  464.             hlpos = fp;
  465.             // Phase 2: from high limit to low limit
  466.             pulsedist = currentpulse - pulselimitlow[c]*16;
  467.             if (pulsedist > 0)
  468.             {
  469.               pulsetime = pulsedist/pulseadd[c];
  470.               currentpulse -= pulsetime*pulseadd[c];
  471.               while (pulsetime)
  472.               {
  473.                 int acttime = pulsetime;
  474.                 if (acttime > 127) acttime = 127;
  475.                 if (fp >= MAX_TABLELEN) goto PULSEDONE;
  476.                 ltable[PTBL][fp] = acttime;
  477.                 rtable[PTBL][fp] = -(pulseadd[c] / 2);
  478.                 fp++;
  479.                 pulsetime -= acttime;
  480.               }
  481.             }
  482.  
  483.             // Phase 3: from low limit back to startpos/high limit
  484.             if ((startpulse < pulselimithigh[c]*16) && (startpulse > currentpulse))
  485.             {
  486.               pulsedist = startpulse - currentpulse;
  487.               if (pulsedist > 0)
  488.               {
  489.                 pulsetime = pulsedist/pulseadd[c];
  490.                 while (pulsetime)
  491.                 {
  492.                   int acttime = pulsetime;
  493.                   if (acttime > 127) acttime = 127;
  494.                   if (fp >= MAX_TABLELEN) goto PULSEDONE;
  495.                   ltable[PTBL][fp] = acttime;
  496.                   rtable[PTBL][fp] = pulseadd[c] / 2;
  497.                   fp++;
  498.                   pulsetime -= acttime;
  499.                 }
  500.               }
  501.               // Pulse jump back to beginning
  502.               if (fp >= MAX_TABLELEN) goto PULSEDONE;
  503.               ltable[PTBL][fp] = 0xff;
  504.               rtable[PTBL][fp] = instr[c].ptr[PTBL] + 1;
  505.               fp++;
  506.             }
  507.             else
  508.             {
  509.               pulsedist = pulselimithigh[c]*16 - currentpulse;
  510.               if (pulsedist > 0)
  511.               {
  512.                 pulsetime = pulsedist/pulseadd[c];
  513.                 while (pulsetime)
  514.                 {
  515.                   int acttime = pulsetime;
  516.                   if (acttime > 127) acttime = 127;
  517.                   if (fp >= MAX_TABLELEN) goto PULSEDONE;
  518.                   ltable[PTBL][fp] = acttime;
  519.                   rtable[PTBL][fp] = pulseadd[c] / 2;
  520.                   fp++;
  521.                   pulsetime -= acttime;
  522.                 }
  523.               }
  524.               // Pulse jump back to beginning
  525.               if (fp >= MAX_TABLELEN) goto PULSEDONE;
  526.               ltable[PTBL][fp] = 0xff;
  527.               rtable[PTBL][fp] = hlpos + 1;
  528.               fp++;
  529.             }
  530.           }
  531.           else
  532.           {
  533.             // Pulse stopped
  534.             if (fp >= MAX_TABLELEN) goto PULSEDONE;
  535.             ltable[PTBL][fp] = 0xff;
  536.             rtable[PTBL][fp] = 0;
  537.             fp++;
  538.           }
  539.           PULSEDONE: {}
  540.         }
  541.       }
  542.       // Convert patterns
  543.       amount = fread8(handle);
  544.       for (c = 0; c < amount; c++)
  545.       {
  546.         length = fread8(handle);
  547.         for (d = 0; d < length/3; d++)
  548.         {
  549.           unsigned char note, cmd, data, instr;
  550.           note = fread8(handle);
  551.           cmd = fread8(handle);
  552.           data = fread8(handle);
  553.           instr = cmd >> 3;
  554.           cmd &= 7;
  555.  
  556.           switch(note)
  557.           {
  558.             default:
  559.             note += FIRSTNOTE;
  560.             if (note > LASTNOTE) note = REST;
  561.             break;
  562.  
  563.             case OLDKEYOFF:
  564.             note = KEYOFF;
  565.             break;
  566.  
  567.             case OLDREST:
  568.             note = REST;
  569.             break;
  570.  
  571.             case ENDPATT:
  572.             break;
  573.           }
  574.           switch(cmd)
  575.           {
  576.             case 5:
  577.             cmd = CMD_SETFILTERPTR;
  578.             if (data > numfilter) numfilter = data;
  579.             break;
  580.  
  581.             case 7:
  582.             if (data < 0xf0)
  583.               cmd = CMD_SETTEMPO;
  584.             else
  585.             {
  586.               cmd = CMD_SETMASTERVOL;
  587.               data &= 0x0f;
  588.             }
  589.             break;
  590.           }
  591.           pattern[c][d*4] = note;
  592.           pattern[c][d*4+1] = instr;
  593.           pattern[c][d*4+2] = cmd;
  594.           pattern[c][d*4+3] = data;
  595.         }
  596.       }
  597.       countpatternlengths();
  598.       fi = highestusedinstr + 1;
  599.       songchange();
  600.  
  601.       // Read filtertable
  602.       fread(filtertable, 256, 1, handle);
  603.  
  604.       // Convert filtertable
  605.       for (c = 0; c < 64; c++)
  606.       {
  607.         filterjumppos[c] = -1;
  608.         filtermap[c] = 0;
  609.         if (filtertable[c*4+3] > numfilter) numfilter = filtertable[c*4+3];
  610.       }
  611.  
  612.       if (numfilter > 63) numfilter = 63;
  613.  
  614.       for (c = 1; c <= numfilter; c++)
  615.       {
  616.         filtermap[c] = ff+1;
  617.  
  618.         if (filtertable[c*4]|filtertable[c*4+1]|filtertable[c*4+2]|filtertable[c*4+3])
  619.         {
  620.           // Filter set
  621.           if (filtertable[c*4])
  622.           {
  623.             ltable[FTBL][ff] = 0x80 + (filtertable[c*4+1] & 0x70);
  624.             rtable[FTBL][ff] = filtertable[c*4];
  625.             ff++;
  626.             if (filtertable[c*4+2])
  627.             {
  628.               ltable[FTBL][ff] = 0x00;
  629.               rtable[FTBL][ff] = filtertable[c*4+2];
  630.               ff++;
  631.             }
  632.           }
  633.           else
  634.           {
  635.             // Filter modulation
  636.             int time = filtertable[c*4+1];
  637.  
  638.             while (time)
  639.             {
  640.               int acttime = time;
  641.               if (acttime > 127) acttime = 127;
  642.               ltable[FTBL][ff] = acttime;
  643.               rtable[FTBL][ff] = filtertable[c*4+2];
  644.               ff++;
  645.               time -= acttime;
  646.             }
  647.           }
  648.  
  649.           // Jump to next step: unnecessary if follows directly
  650.           if (filtertable[c*4+3] != c+1)
  651.           {
  652.             filterjumppos[c] = ff;
  653.             ltable[FTBL][ff] = 0xff;
  654.             rtable[FTBL][ff] = filtertable[c*4+3]; // Fix the jump later
  655.             ff++;
  656.           }
  657.         }
  658.       }
  659.  
  660.       // Now fix jumps as the filterstep mapping is known
  661.       for (c = 1; c <= numfilter; c++)
  662.       {
  663.         if (filterjumppos[c] != -1)
  664.           rtable[FTBL][filterjumppos[c]] = filtermap[rtable[FTBL][filterjumppos[c]]];
  665.       }
  666.  
  667.       // Fix filterpointers in instruments
  668.       for (c = 1; c < 32; c++)
  669.         instr[c].ptr[FTBL] = filtermap[instr[c].ptr[FTBL]];
  670.  
  671.       // Now fix pattern commands
  672.       memset(arpmap, 0, sizeof arpmap);
  673.       for (c = 0; c < MAX_PATT; c++)
  674.       {
  675.         unsigned char i = 0;
  676.         for (d = 0; d <= MAX_PATTROWS; d++)
  677.         {
  678.           if (pattern[c][d*4+1]) i = pattern[c][d*4+1];
  679.  
  680.           // Convert portamento & vibrato
  681.           if (pattern[c][d*4+2] == CMD_PORTAUP)
  682.             pattern[c][d*4+3] = makespeedtable(pattern[c][d*4+3], MST_PORTAMENTO, 0) + 1;
  683.           if (pattern[c][d*4+2] == CMD_PORTADOWN)
  684.             pattern[c][d*4+3] = makespeedtable(pattern[c][d*4+3], MST_PORTAMENTO, 0) + 1;
  685.           if (pattern[c][d*4+2] == CMD_TONEPORTA)
  686.             pattern[c][d*4+3] = makespeedtable(pattern[c][d*4+3], MST_PORTAMENTO, 0) + 1;
  687.           if (pattern[c][d*4+2] == CMD_VIBRATO)
  688.             pattern[c][d*4+3] = makespeedtable(pattern[c][d*4+3], MST_NOFINEVIB, 0) + 1;
  689.  
  690.           // Convert filterjump
  691.           if (pattern[c][d*4+2] == CMD_SETFILTERPTR)
  692.             pattern[c][d*4+3] = filtermap[pattern[c][d*4+3]];
  693.  
  694.           // Convert funktempo
  695.           if ((pattern[c][d*4+2] == CMD_SETTEMPO) && (!pattern[c][d*4+3]))
  696.           {
  697.             pattern[c][d*4+2] = CMD_FUNKTEMPO;
  698.             pattern[c][d*4+3] = makespeedtable((filtertable[2] << 4) | (filtertable[3] & 0x0f), MST_FUNKTEMPO, 0) + 1;
  699.           }
  700.           // Convert arpeggio
  701.           if ((pattern[c][d*4+2] == CMD_DONOTHING) && (pattern[c][d*4+3]))
  702.           {
  703.             // Must be in conjunction with a note
  704.             if ((pattern[c][d*4] >= FIRSTNOTE) && (pattern[c][d*4] <= LASTNOTE))
  705.             {
  706.               unsigned char param = pattern[c][d*4+3];
  707.               if (i)
  708.               {
  709.                 // Old arpeggio
  710.                 if (arpmap[i][param])
  711.                 {
  712.                   // As command, or as instrument?
  713.                   if (arpmap[i][param] < 256)
  714.                   {
  715.                     pattern[c][d*4+2] = CMD_SETWAVEPTR;
  716.                     pattern[c][d*4+3] = arpmap[i][param];
  717.                   }
  718.                   else
  719.                   {
  720.                     pattern[c][d*4+1] = arpmap[i][param] - 256;
  721.                     pattern[c][d*4+3] = 0;
  722.                   }
  723.                 }
  724.                 else
  725.                 {
  726.                   int e;
  727.                   unsigned char arpstart;
  728.                   unsigned char arploop;
  729.  
  730.                   // New arpeggio
  731.                   // Copy first the instrument's wavetable up to loop/end point
  732.                   arpstart = fw + 1;
  733.                   if (instr[i].ptr[WTBL])
  734.                   {
  735.                     for (e = instr[i].ptr[WTBL]-1;; e++)
  736.                     {
  737.                       if (ltable[WTBL][e] == 0xff) break;
  738.                       if (fw < MAX_TABLELEN)
  739.                       {
  740.                         ltable[WTBL][fw] = ltable[WTBL][e];
  741.                         fw++;
  742.                       }
  743.                     }
  744.                   }
  745.                   // Then make the arpeggio
  746.                   arploop = fw + 1;
  747.                   if (fw < MAX_TABLELEN-3)
  748.                   {
  749.                     ltable[WTBL][fw] = (param & 0x80) >> 7;
  750.                     rtable[WTBL][fw] = (param  & 0x70) >> 4;
  751.                     fw++;
  752.                     ltable[WTBL][fw] = (param & 0x80) >> 7;
  753.                     rtable[WTBL][fw] = (param & 0xf);
  754.                     fw++;
  755.                     ltable[WTBL][fw] = (param & 0x80) >> 7;
  756.                     rtable[WTBL][fw] = 0;
  757.                     fw++;
  758.                     ltable[WTBL][fw] = 0xff;
  759.                     rtable[WTBL][fw] = arploop;
  760.                     fw++;
  761.  
  762.                     // Create new instrument if possible
  763.                     if (fi < MAX_INSTR)
  764.                     {
  765.                       arpmap[i][param] = fi + 256;
  766.                       instr[fi] = instr[i];
  767.                       instr[fi].ptr[WTBL] = arpstart;
  768.                       // Add arpeggio parameter to new instrument name
  769.                       if (strlen(instr[fi].name) < MAX_INSTRNAMELEN-3)
  770.                       {
  771.                         char arpname[8];
  772.                         sprintf(arpname, "0%02X", param&0x7f);
  773.                         strcat(instr[fi].name, arpname);
  774.                       }
  775.                       fi++;
  776.                     }
  777.                     else
  778.                     {
  779.                       arpmap[i][param] = arpstart;
  780.                     }
  781.                   }
  782.  
  783.                   if (arpmap[i][param])
  784.                   {
  785.                     // As command, or as instrument?
  786.                     if (arpmap[i][param] < 256)
  787.                     {
  788.                       pattern[c][d*4+2] = CMD_SETWAVEPTR;
  789.                       pattern[c][d*4+3] = arpmap[i][param];
  790.                     }
  791.                     else
  792.                     {
  793.                       pattern[c][d*4+1] = arpmap[i][param] - 256;
  794.                       pattern[c][d*4+3] = 0;
  795.                     }
  796.                   }
  797.                 }
  798.               }
  799.             }
  800.             // If arpeggio could not be converted, databyte zero
  801.             if (!pattern[c][d*4+2])
  802.               pattern[c][d*4+3] = 0;
  803.           }
  804.         }
  805.       }
  806.     }
  807.     fclose(handle);
  808.   }
  809.   if (ok)
  810.   {
  811.     strcpy(loadedsongfilename, songfilename);
  812.  
  813.     // Reset table views
  814.     for (c = 0; c < MAX_TABLES; c++) settableview(c, 0);
  815.  
  816.     // Convert pulsemodulation speed of < v2.4 songs
  817.     if (ident[3] < '4')
  818.     {
  819.         for (c = 0; c < MAX_TABLELEN; c++)
  820.         {
  821.             if ((ltable[PTBL][c] < 0x80) && (rtable[PTBL][c]))
  822.             {
  823.                 int speed = ((signed char)rtable[PTBL][c]);
  824.                 speed <<= 1;
  825.                 if (speed > 127) speed = 127;
  826.                 if (speed < -128) speed = -128;
  827.                 rtable[PTBL][c] = speed;
  828.             }
  829.         }
  830.     }
  831.  
  832.     // Convert old legato/nohr parameters
  833.     if (ident[3] < '5')
  834.     {
  835.         for (c = 1; c < MAX_INSTR; c++)
  836.         {
  837.             if (instr[c].firstwave >= 0x80)
  838.             {
  839.                 instr[c].gatetimer |= 0x80;
  840.                 instr[c].firstwave &= 0x7f;
  841.             }
  842.             if (!instr[c].firstwave) instr[c].gatetimer |= 0x40;
  843.         }
  844.     }
  845.   }
  846. }
  847.  
  848. void loadinstrument(void)
  849. {
  850.   char ident[4];
  851.   FILE *handle;
  852.   int c,d;
  853.   int pulsestart = -1;
  854.   int pulseend = -1;
  855.  
  856.   handle = fopen(instrfilename, "rb");
  857.   if (handle)
  858.   {
  859.     stopsong();
  860.     fread(ident, 4, 1, handle);
  861.  
  862.     if ((!memcmp(ident, "GTI3", 4)) || (!memcmp(ident, "GTI4", 4)) || (!memcmp(ident, "GTI5", 4)))
  863.     {
  864.       unsigned char optr[4];
  865.  
  866.       instr[einum].ad = fread8(handle);
  867.       instr[einum].sr = fread8(handle);
  868.       optr[0] = fread8(handle);
  869.       optr[1] = fread8(handle);
  870.       optr[2] = fread8(handle);
  871.       optr[3] = fread8(handle);
  872.       instr[einum].vibdelay = fread8(handle);
  873.       instr[einum].gatetimer = fread8(handle);
  874.       instr[einum].firstwave = fread8(handle);
  875.       fread(&instr[einum].name, MAX_INSTRNAMELEN, 1, handle);
  876.  
  877.       // Erase old tabledata
  878.       deleteinstrtable(einum);
  879.  
  880.       // Load new tabledata
  881.       for (c = 0; c < MAX_TABLES; c++)
  882.       {
  883.         int start = gettablelen(c);
  884.         int len = fread8(handle);
  885.  
  886.         if (len)
  887.         {
  888.           for (d = start; (d < start+len) && (d < MAX_TABLELEN); d++)
  889.             ltable[c][d] = fread8(handle);
  890.           while (d < start+len)
  891.           {
  892.             fread8(handle);
  893.             d++;
  894.           }
  895.           for (d = start; (d < start+len) && (d < MAX_TABLELEN); d++)
  896.             rtable[c][d] = fread8(handle);
  897.           while (d < start+len)
  898.           {
  899.             fread8(handle);
  900.             d++;
  901.           }
  902.           if (c != STBL)
  903.           {
  904.             for (d = start; (d < start+len) && (d < MAX_TABLELEN); d++)
  905.             {
  906.               if (ltable[c][d] == 0xff)
  907.               {
  908.                 if (rtable[c][d])
  909.                   rtable[c][d] = rtable[c][d] - optr[c] + start + 1;
  910.               }
  911.             }
  912.           }
  913.           if (c == PTBL)
  914.           {
  915.               pulsestart = start;
  916.               pulseend = start + len;
  917.           }
  918.           instr[einum].ptr[c] = start + 1;
  919.         }
  920.         else instr[einum].ptr[c] = 0;
  921.       }
  922.     }
  923.  
  924.     // Goattracker v2.xx (3-table) import
  925.     if (!memcmp(ident, "GTI2", 4))
  926.     {
  927.       unsigned char optr[3];
  928.  
  929.       instr[einum].ad = fread8(handle);
  930.       instr[einum].sr = fread8(handle);
  931.       optr[0] = fread8(handle);
  932.       optr[1] = fread8(handle);
  933.       optr[2] = fread8(handle);
  934.       instr[einum].vibdelay = fread8(handle);
  935.       instr[einum].ptr[STBL] = makespeedtable(fread8(handle), finevibrato, 0) + 1;
  936.       instr[einum].gatetimer = fread8(handle);
  937.       instr[einum].firstwave = fread8(handle);
  938.       fread(&instr[einum].name, MAX_INSTRNAMELEN, 1, handle);
  939.  
  940.       // Erase old tabledata
  941.       deleteinstrtable(einum);
  942.  
  943.       // Load new tabledata
  944.       for (c = 0; c < MAX_TABLES-1; c++)
  945.       {
  946.         int start = gettablelen(c);
  947.         int len = fread8(handle);
  948.  
  949.         if (len)
  950.         {
  951.           for (d = start; (d < start+len) && (d < MAX_TABLELEN); d++)
  952.             ltable[c][d] = fread8(handle);
  953.           while (d < start+len)
  954.           {
  955.             fread8(handle);
  956.             d++;
  957.           }
  958.           for (d = start; (d < start+len) && (d < MAX_TABLELEN); d++)
  959.             rtable[c][d] = fread8(handle);
  960.           while (d < start+len)
  961.           {
  962.             fread8(handle);
  963.             d++;
  964.           }
  965.           for (d = start; (d < start+len) && (d < MAX_TABLELEN); d++)
  966.           {
  967.             if (ltable[c][d] == 0xff)
  968.             {
  969.               if (rtable[c][d])
  970.                 rtable[c][d] = rtable[c][d] - optr[c] + start + 1;
  971.             }
  972.           }
  973.           if (c == PTBL)
  974.           {
  975.               pulsestart = start;
  976.               pulseend = start + len;
  977.           }
  978.           instr[einum].ptr[c] = start + 1;
  979.         }
  980.         else instr[einum].ptr[c] = 0;
  981.       }
  982.     }
  983.     // Goattracker 1.xx import
  984.     if (!memcmp(ident, "GTI!", 4))
  985.     {
  986.  
  987.       unsigned char pulse, pulseadd, pulselimitlow, pulselimithigh, wavelen;
  988.       unsigned char filtertemp[4];
  989.       int fw, fp, ff;
  990.  
  991.       // Erase old tabledata
  992.       deleteinstrtable(einum);
  993.  
  994.       fw = gettablelen(WTBL);
  995.       fp = gettablelen(PTBL);
  996.       ff = gettablelen(FTBL);
  997.  
  998.       instr[einum].ad = fread8(handle);
  999.       instr[einum].sr = fread8(handle);
  1000.       if (multiplier)
  1001.         instr[einum].gatetimer = 2 * multiplier;
  1002.       else
  1003.         instr[einum].gatetimer = 1;
  1004.       instr[einum].firstwave = 0x9;
  1005.       pulse = fread8(handle);
  1006.       pulseadd = fread8(handle);
  1007.       pulselimitlow = fread8(handle);
  1008.       pulselimithigh = fread8(handle);
  1009.       instr[einum].ptr[FTBL] = fread8(handle) ? ff+1 : 0;
  1010.       if (pulse & 1) instr[einum].gatetimer |= 0x80; // "No hardrestart" flag
  1011.         wavelen = fread8(handle)/2;
  1012.       fread(&instr[einum].name, MAX_INSTRNAMELEN, 1, handle);
  1013.       instr[einum].ptr[WTBL] = fw+1;
  1014.  
  1015.       // Convert wavetable
  1016.       for (d = 0; d < wavelen; d++)
  1017.       {
  1018.         if (fw < MAX_TABLELEN)
  1019.         {
  1020.           ltable[WTBL][fw] = fread8(handle);
  1021.           rtable[WTBL][fw] = fread8(handle);
  1022.           if (ltable[WTBL][fw] == 0xff)
  1023.             if (rtable[WTBL][fw]) rtable[WTBL][fw] += instr[einum].ptr[WTBL]-1;
  1024.           fw++;
  1025.         }
  1026.         else
  1027.         {
  1028.           fread8(handle);
  1029.           fread8(handle);
  1030.         }
  1031.       }
  1032.  
  1033.       // Remove empty wavetable afterwards
  1034.       if ((wavelen == 2) && (!ltable[WTBL][fw-2]) && (!rtable[WTBL][fw-2]))
  1035.       {
  1036.         instr[einum].ptr[WTBL] = 0;
  1037.         fw -= 2;
  1038.         ltable[WTBL][fw] = 0;
  1039.         rtable[WTBL][fw] = 0;
  1040.         ltable[WTBL][fw+1] = 0;
  1041.         rtable[WTBL][fw+1] = 0;
  1042.       }
  1043.  
  1044.       // Convert pulsetable
  1045.       pulse &= 0xfe;
  1046.       if (pulse)
  1047.       {
  1048.         int pulsetime, pulsedist, hlpos;
  1049.  
  1050.         // Initial pulse setting
  1051.         if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1052.         pulsestart = fp;
  1053.         instr[einum].ptr[PTBL] = fp+1;
  1054.         ltable[PTBL][fp] = 0x80 | (pulse >> 4);
  1055.         rtable[PTBL][fp] = pulse << 4;
  1056.         fp++;
  1057.  
  1058.         // Pulse modulation
  1059.         if (pulseadd)
  1060.         {
  1061.           int startpulse = pulse*16;
  1062.           int currentpulse = pulse*16;
  1063.           // Phase 1: From startpos to high limit
  1064.           pulsedist = pulselimithigh*16 - currentpulse;
  1065.           if (pulsedist > 0)
  1066.           {
  1067.             pulsetime = pulsedist/pulseadd;
  1068.             currentpulse += pulsetime*pulseadd;
  1069.             while (pulsetime)
  1070.             {
  1071.               int acttime = pulsetime;
  1072.               if (acttime > 127) acttime = 127;
  1073.               if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1074.               ltable[PTBL][fp] = acttime;
  1075.               rtable[PTBL][fp] = pulseadd / 2;
  1076.               fp++;
  1077.               pulsetime -= acttime;
  1078.             }
  1079.           }
  1080.  
  1081.           hlpos = fp;
  1082.           // Phase 2: from high limit to low limit
  1083.           pulsedist = currentpulse - pulselimitlow*16;
  1084.           if (pulsedist > 0)
  1085.           {
  1086.             pulsetime = pulsedist/pulseadd;
  1087.             currentpulse -= pulsetime*pulseadd;
  1088.             while (pulsetime)
  1089.             {
  1090.               int acttime = pulsetime;
  1091.               if (acttime > 127) acttime = 127;
  1092.               if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1093.               ltable[PTBL][fp] = acttime;
  1094.               rtable[PTBL][fp] = -(pulseadd / 2);
  1095.               fp++;
  1096.               pulsetime -= acttime;
  1097.             }
  1098.           }
  1099.  
  1100.           // Phase 3: from low limit back to startpos/high limit
  1101.           if ((startpulse < pulselimithigh*16) && (startpulse > currentpulse))
  1102.           {
  1103.             pulsedist = startpulse - currentpulse;
  1104.             if (pulsedist > 0)
  1105.             {
  1106.               pulsetime = pulsedist/pulseadd;
  1107.               while (pulsetime)
  1108.               {
  1109.                 int acttime = pulsetime;
  1110.                 if (acttime > 127) acttime = 127;
  1111.                 if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1112.                 ltable[PTBL][fp] = acttime;
  1113.                 rtable[PTBL][fp] = pulseadd / 2;
  1114.                 fp++;
  1115.                 pulsetime -= acttime;
  1116.               }
  1117.             }
  1118.             // Pulse jump back to beginning
  1119.             if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1120.             ltable[PTBL][fp] = 0xff;
  1121.             rtable[PTBL][fp] = instr[einum].ptr[PTBL] + 1;
  1122.             fp++;
  1123.           }
  1124.           else
  1125.           {
  1126.             pulsedist = pulselimithigh*16 - currentpulse;
  1127.             if (pulsedist > 0)
  1128.             {
  1129.               pulsetime = pulsedist/pulseadd;
  1130.               while (pulsetime)
  1131.               {
  1132.                 int acttime = pulsetime;
  1133.                 if (acttime > 127) acttime = 127;
  1134.                 if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1135.                 ltable[PTBL][fp] = acttime;
  1136.                 rtable[PTBL][fp] = pulseadd / 2;
  1137.                 fp++;
  1138.                 pulsetime -= acttime;
  1139.               }
  1140.             }
  1141.             // Pulse jump back to beginning
  1142.             if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1143.             ltable[PTBL][fp] = 0xff;
  1144.             rtable[PTBL][fp] = hlpos + 1;
  1145.             fp++;
  1146.           }
  1147.         }
  1148.         else
  1149.         {
  1150.           // Pulse stopped
  1151.           if (fp >= MAX_TABLELEN) goto PULSEDONE;
  1152.           ltable[PTBL][fp] = 0xff;
  1153.           rtable[PTBL][fp] = 0;
  1154.           fp++;
  1155.         }
  1156.         PULSEDONE:
  1157.         pulseend = fp;
  1158.       }
  1159.  
  1160.       // Convert filter (if any)
  1161.       if ((instr[einum].ptr[FTBL]) && (ff < MAX_TABLELEN-2))
  1162.       {
  1163.         fread(filtertemp, sizeof filtertemp, 1, handle);
  1164.         // Filter set
  1165.         if (filtertemp[0])
  1166.         {
  1167.           ltable[FTBL][ff] = 0x80 + (filtertemp[1] & 0x70);
  1168.           rtable[FTBL][ff] = filtertemp[0];
  1169.           ff++;
  1170.           if (filtertemp[2])
  1171.           {
  1172.             ltable[FTBL][ff] = 0x00;
  1173.             rtable[FTBL][ff] = filtertemp[2];
  1174.             ff++;
  1175.           }
  1176.         }
  1177.         else
  1178.         {
  1179.           // Filter modulation
  1180.           int time = filtertemp[1];
  1181.  
  1182.           while (time)
  1183.           {
  1184.             int acttime = time;
  1185.             if (acttime > 127) acttime = 127;
  1186.             ltable[FTBL][ff] = acttime;
  1187.             rtable[FTBL][ff] = filtertemp[2];
  1188.             ff++;
  1189.             time -= acttime;
  1190.           }
  1191.         }
  1192.  
  1193.         // Jump to next step: always end the filter
  1194.         ltable[FTBL][ff] = 0xff;
  1195.         rtable[FTBL][ff] = 0;
  1196.         ff++;
  1197.       }
  1198.     }
  1199.     
  1200.     fclose(handle);
  1201.  
  1202.     // Convert pulsemodulation speed of < v2.4 instruments
  1203.     if ((ident[3] < '4') && (pulsestart != -1))
  1204.     {
  1205.         for (c = pulsestart; (c < pulseend) && (c < MAX_TABLELEN); c++)
  1206.         {
  1207.             if ((ltable[PTBL][c] < 0x80) && (rtable[PTBL][c]))
  1208.             {
  1209.                 int speed = ((signed char)rtable[PTBL][c]);
  1210.                 speed <<= 1;
  1211.                 if (speed > 127) speed = 127;
  1212.                 if (speed < -128) speed = -128;
  1213.                 rtable[PTBL][c] = speed;
  1214.             }
  1215.         }
  1216.     }
  1217.     // Convert old legato/nohr parameters
  1218.     if (ident[3] < '5')
  1219.     {
  1220.       if (instr[einum].firstwave >= 0x80)
  1221.       {
  1222.         instr[einum].firstwave &= 0x7f;
  1223.         instr[einum].gatetimer |= 0x80;
  1224.       }
  1225.       if (!instr[einum].firstwave) instr[einum].gatetimer |= 0x40;
  1226.     }
  1227.   }
  1228. }
  1229.  
  1230. void clearsong(int cs, int cp, int ci, int ct, int cn)
  1231. {
  1232.   int c;
  1233.  
  1234.   if (!(cs | cp | ci | ct | cn)) return;
  1235.  
  1236.   stopsong();
  1237.  
  1238.   masterfader = 0x0f;
  1239.   epmarkchn = -1;
  1240.   etmarknum = -1;
  1241.   esmarkchn = -1;
  1242.   followplay = 0;
  1243.  
  1244.   for (c = 0; c < MAX_CHN; c++)
  1245.   {
  1246.     int d;
  1247.     chn[c].mute = 0;
  1248.     if (multiplier)
  1249.       chn[c].tempo = multiplier*6-1;
  1250.     else
  1251.       chn[c].tempo = 6-1;
  1252.     chn[c].pattptr = 0;
  1253.     if (cs)
  1254.     {
  1255.       memset(loadedsongfilename, 0, sizeof loadedsongfilename);
  1256.       for (d = 0; d < MAX_SONGS; d++)
  1257.       {
  1258.         memset(&songorder[d][c][0], 0, MAX_SONGLEN+2);
  1259.         if (!d)
  1260.         {
  1261.           songorder[d][c][0] = c;
  1262.           songorder[d][c][1] = LOOPSONG;
  1263.         }
  1264.         else
  1265.         {
  1266.           songorder[d][c][0] = LOOPSONG;
  1267.         }
  1268.       }
  1269.       epnum[c] = songorder[0][c][0];
  1270.       espos[c] = 0;
  1271.       esend[c] = 0;
  1272.     }
  1273.   }
  1274.   if (cs)
  1275.   {
  1276.     esview = 0;
  1277.     eseditpos = 0;
  1278.     escolumn = 0;
  1279.     eschn = 0;
  1280.     esnum = 0;
  1281.     eppos = 0;
  1282.     epview =-VISIBLEPATTROWS/2;
  1283.     epcolumn = 0;
  1284.     epchn = 0;
  1285.   }
  1286.   if (cn)
  1287.   {
  1288.     memset(songname, 0, sizeof songname);
  1289.     memset(authorname, 0, sizeof authorname);
  1290.     memset(copyrightname, 0, sizeof copyrightname);
  1291.     enpos = 0;
  1292.   }
  1293.   if (cp)
  1294.   {
  1295.     memset(loadedsongfilename, 0, sizeof loadedsongfilename);
  1296.     for (c = 0; c < MAX_PATT; c++)
  1297.         clearpattern(c);
  1298.   }
  1299.   if (ci)
  1300.   {
  1301.     for (c = 0; c < MAX_INSTR; c++)
  1302.       clearinstr(c);
  1303.     memset(&instrcopybuffer, 0, sizeof(INSTR));
  1304.     eipos = 0;
  1305.     eicolumn = 0;
  1306.     einum = 1;
  1307.   }
  1308.   if (ct == 1)
  1309.   {
  1310.     for (c = MAX_TABLES-1; c >= 0; c--)
  1311.     {
  1312.       memset(ltable[c], 0, MAX_TABLELEN);
  1313.       memset(rtable[c], 0, MAX_TABLELEN);
  1314.       settableview(c, 0);
  1315.     }
  1316.   }
  1317.   countpatternlengths();
  1318. }
  1319.  
  1320. void countpatternlengths(void)
  1321. {
  1322.   int c, d, e;
  1323.  
  1324.   highestusedpattern = 0;
  1325.   highestusedinstr = 0;
  1326.   for (c = 0; c < MAX_PATT; c++)
  1327.   {
  1328.     for (d = 0; d <= MAX_PATTROWS; d++)
  1329.     {
  1330.       if (pattern[c][d*4] == ENDPATT) break;
  1331.       if ((pattern[c][d*4] != REST) || (pattern[c][d*4+1]) || (pattern[c][d*4+2]) || (pattern[c][d*4+3]))
  1332.         highestusedpattern = c;
  1333.       if (pattern[c][d*4+1] > highestusedinstr) highestusedinstr = pattern[c][d*4+1];
  1334.     }
  1335.     pattlen[c] = d;
  1336.   }
  1337.  
  1338.   for (e = 0; e < MAX_SONGS; e++)
  1339.   {
  1340.     for (c = 0; c < MAX_CHN; c++)
  1341.     {
  1342.       for (d = 0; d < MAX_SONGLEN; d++)
  1343.       {
  1344.         if (songorder[e][c][d] >= LOOPSONG) break;
  1345.         if ((songorder[e][c][d] < REPEAT) && (songorder[e][c][d] > highestusedpattern))
  1346.           highestusedpattern = songorder[e][c][d];
  1347.       }
  1348.       songlen[e][c] = d;
  1349.     }
  1350.   }
  1351. }
  1352.  
  1353. void countthispattern(void)
  1354. {
  1355.   int c, d, e;
  1356.  
  1357.   c = epnum[epchn];
  1358.   for (d = 0; d <= MAX_PATTROWS; d++)
  1359.   {
  1360.     if (pattern[c][d*4] == ENDPATT) break;
  1361.   }
  1362.   pattlen[c] = d;
  1363.  
  1364.   e = esnum;
  1365.   c = eschn;
  1366.   for (d = 0; d < MAX_SONGLEN; d++)
  1367.   {
  1368.     if (songorder[e][c][d] >= LOOPSONG) break;
  1369.     if (songorder[e][c][d] > highestusedpattern)
  1370.       highestusedpattern = songorder[e][c][d];
  1371.   }
  1372.   songlen[e][c] = d;
  1373. }
  1374.  
  1375. int insertpattern(int p)
  1376. {
  1377.   int c, d, e;
  1378.  
  1379.   findusedpatterns();
  1380.   if (p >= MAX_PATT-2) return 0;
  1381.   if (pattused[MAX_PATT-1]) return 0;
  1382.   memmove(pattern[p+2], pattern[p+1], (MAX_PATT-p-2)*(MAX_PATTROWS*4+4));  
  1383.   countpatternlengths();
  1384.  
  1385.   for (c = 0; c < MAX_SONGS; c++)
  1386.   {
  1387.     if ((songlen[c][0]) &&
  1388.         (songlen[c][1]) &&
  1389.         (songlen[c][2]))
  1390.     {
  1391.       for (d = 0; d < MAX_CHN; d++)
  1392.       {
  1393.         for (e = 0; e < songlen[c][d]; e++)
  1394.         {
  1395.           if ((songorder[c][d][e] < REPEAT) && (songorder[c][d][e] > p) && (songorder[c][d][e] != MAX_PATT-1))
  1396.             songorder[c][d][e]++;
  1397.         }
  1398.       }
  1399.     }
  1400.   }
  1401.   
  1402.   for (c = 0; c < MAX_CHN; c++)
  1403.   {
  1404.       if ((epnum[c] > p) && (epnum[c] != MAX_PATT-1)) epnum[c]++;
  1405.   }
  1406.  
  1407.   return 1;
  1408. }
  1409.  
  1410. void deletepattern(int p)
  1411. {
  1412.   int c, d, e;
  1413.  
  1414.   if (p == MAX_PATT-1) return;
  1415.  
  1416.   memmove(pattern[p], pattern[p+1], (MAX_PATT-p-1)*(MAX_PATTROWS*4+4));
  1417.   clearpattern(MAX_PATT-1);
  1418.   countpatternlengths();
  1419.  
  1420.   for (c = 0; c < MAX_SONGS; c++)
  1421.   {
  1422.     if ((songlen[c][0]) &&
  1423.         (songlen[c][1]) &&
  1424.         (songlen[c][2]))
  1425.     {
  1426.       for (d = 0; d < MAX_CHN; d++)
  1427.       {
  1428.         for (e = 0; e < songlen[c][d]; e++)
  1429.         {
  1430.           if ((songorder[c][d][e] < REPEAT) && (songorder[c][d][e] > p))
  1431.             songorder[c][d][e]--;
  1432.         }
  1433.       }
  1434.     }
  1435.   }
  1436.   
  1437.   for (c = 0; c < MAX_CHN; c++)
  1438.   {
  1439.       if (epnum[c] > p) epnum[c]--;
  1440.   }
  1441. }
  1442.  
  1443. void clearpattern(int p)
  1444. {
  1445.   int c;
  1446.  
  1447.   memset(pattern[p], 0, MAX_PATTROWS*4);
  1448.   for (c = 0; c < defaultpatternlength; c++) pattern[p][c*4] = REST;
  1449.   for (c = defaultpatternlength; c <= MAX_PATTROWS; c++) pattern[p][c*4] = ENDPATT;
  1450. }
  1451.  
  1452. void findusedpatterns(void)
  1453. {
  1454.   int c, d, e;
  1455.  
  1456.   countpatternlengths();
  1457.   memset(pattused, 0, sizeof pattused);
  1458.   for (c = 0; c < MAX_SONGS; c++)
  1459.   {
  1460.     if ((songlen[c][0]) &&
  1461.         (songlen[c][1]) &&
  1462.         (songlen[c][2]))
  1463.     {
  1464.       for (d = 0; d < MAX_CHN; d++)
  1465.       {
  1466.         for (e = 0; e < songlen[c][d]; e++)
  1467.         {
  1468.           if (songorder[c][d][e] < REPEAT)
  1469.             pattused[songorder[c][d][e]] = 1;
  1470.         }
  1471.       }
  1472.     }
  1473.   }
  1474. }
  1475.  
  1476. void findduplicatepatterns(void)
  1477. {
  1478.   int c, d;
  1479.  
  1480.   findusedpatterns();
  1481.  
  1482.   for (c = 0; c < MAX_PATT; c++)
  1483.   {
  1484.       if (pattused[c])
  1485.       {
  1486.         for (d = c+1; d < MAX_PATT; d++)
  1487.         {
  1488.             if (pattlen[d] == pattlen[c])
  1489.             {
  1490.           if (!memcmp(pattern[c], pattern[d], pattlen[c]*4))
  1491.           {
  1492.               int f, g, h;
  1493.  
  1494.             for (f = 0; f < MAX_SONGS; f++)
  1495.             {
  1496.               if ((songlen[f][0]) &&
  1497.                   (songlen[f][1]) &&
  1498.                   (songlen[f][2]))
  1499.               {
  1500.                 for (g = 0; g < MAX_CHN; g++)
  1501.                 {
  1502.                   for (h = 0; h < songlen[f][g]; h++)
  1503.                   {
  1504.                     if (songorder[f][g][h] == d)
  1505.                       songorder[f][g][h] = c;
  1506.                   }
  1507.                 }
  1508.               }
  1509.             }
  1510.             for (f = 0; f < MAX_CHN; f++)
  1511.                 if (epnum[f] == d) epnum[f] = c;
  1512.           }
  1513.         }
  1514.       }
  1515.     }
  1516.   }
  1517.  
  1518.   findusedpatterns();
  1519. }
  1520.  
  1521. void optimizeeverything(int oi, int ot)
  1522. {
  1523.   int c, d, e;
  1524.  
  1525.   stopsong();
  1526.  
  1527.   findduplicatepatterns();
  1528.  
  1529.   memset(instrused, 0, sizeof instrused);
  1530.  
  1531.   for (c = MAX_PATT-1; c >= 0; c--)
  1532.   {
  1533.     if (pattused[c])
  1534.     {
  1535.       for (d = 0; d < MAX_PATTROWS; d++)
  1536.       {
  1537.         if (pattern[c][d*4] == ENDPATT) break;
  1538.         if (pattern[c][d*4+1])
  1539.           instrused[pattern[c][d*4+1]] = 1;
  1540.       }
  1541.     }
  1542.     else deletepattern(c);
  1543.   }
  1544.  
  1545.   countpatternlengths();
  1546.  
  1547.   if (oi)
  1548.   {
  1549.     for (c = MAX_INSTR-2; c >= 1; c--)
  1550.     {
  1551.       if (!instrused[c])
  1552.       {
  1553.           clearinstr(c);
  1554.  
  1555.         if (c < MAX_INSTR-2)
  1556.         {
  1557.           memmove(&instr[c], &instr[c+1], (MAX_INSTR-2-c) * sizeof(INSTR));
  1558.           clearinstr(MAX_INSTR-2);
  1559.           for (d = 0; d < MAX_PATT; d++)
  1560.           {
  1561.             for (e = 0; e < pattlen[d]; e++)
  1562.             {
  1563.               if ((pattern[d][e*4+1] > c) && (pattern[d][e*4+1] != MAX_INSTR-1))
  1564.                 pattern[d][e*4+1]--;
  1565.             }
  1566.           }
  1567.         }
  1568.       }
  1569.     }
  1570.   }
  1571.  
  1572.   if (ot)
  1573.   {
  1574.     for (c = 0; c < MAX_TABLES; c++) optimizetable(c);
  1575.   }
  1576. }
  1577.  
  1578.