home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / beaversweeper_v101.zip / src / gtkformat.cpp < prev    next >
C/C++ Source or Header  |  2003-01-06  |  16KB  |  542 lines

  1. /*****************************************************************************
  2.  * File        : gtkformat.c                                                       
  3.  * Author(s)   : Fredrik Kling (gnilk@home.se)
  4.  * Original    : 2001-01-27 01:42:43
  5.  * Last edit   : 2001-01-27 19:49:18
  6.  * Description : Holds all system handling of the gtk_format
  7.  *               
  8.  *--------------------------------------------------------------------------- 
  9.  * Changes: 
  10.  * 
  11.  * -- Date -- | -- Name ------- | -- Did what...                              
  12.  * 2001-11-27 | gnilk           | Fixed expanding patterns/seq on loading if smaller..
  13.  * 2001-11-26 | gnilk           | Support for oldversions, and memory loading...
  14.  * 2001-01-27 | gnilk           | Implementation...
  15.  * 
  16.  *****************************************************************************/
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "gtkformat.h"
  20.  
  21. /*
  22.     Format changes:
  23.         0103    
  24.                 * pattern and sequencer length is 16 bit
  25.  
  26.         0102    - First version
  27. */
  28.  
  29. // apa hack!
  30. static HANDLE rfile;
  31.  
  32. static unsigned short load_version;
  33.  
  34. /*
  35.     Reads some "normal" datatypes from within the file
  36. */
  37. static void writeint (HANDLE file,int i)
  38. {
  39.     DWORD num;
  40.     WriteFile (file,&i,sizeof (int),&num,NULL);
  41. }
  42. static void writebyte (HANDLE file,unsigned char i)
  43. {
  44.     DWORD num;
  45.     WriteFile (file,&i,1,&num,NULL);
  46. }
  47. static void writeword (HANDLE file,unsigned short i)
  48. {
  49.   DWORD num;
  50.   WriteFile (file,&i,sizeof (unsigned short),&num,NULL);
  51. }
  52.  
  53. static int readint (HANDLE file)
  54. {
  55.     DWORD num;
  56.     int i;
  57. #ifndef __GTK_MEMREAD__
  58.     ReadFile (file,&i,sizeof (int),&num,NULL);
  59. #else
  60.     int *buf = (int *)rfile;
  61.     i = *buf;
  62.     rfile= (HANDLE)(buf + 1);
  63. #endif
  64.     return i;
  65. }
  66. static unsigned char readbyte (HANDLE file)
  67. {
  68.     DWORD num;
  69.     unsigned char i;
  70. #ifndef __GTK_MEMREAD__
  71.     ReadFile (file,&i,1,&num,NULL);
  72. #else
  73.     unsigned char *pek = (unsigned char *)rfile;
  74.     i = *pek;
  75.     rfile = (HANDLE)(pek + 1);
  76. #endif
  77.     return i;
  78. }
  79. static unsigned short readword (HANDLE file)
  80. {
  81.   DWORD num;
  82.   unsigned short i;
  83. #ifndef __GTK_MEMREAD__
  84.   ReadFile (file,&i,sizeof(unsigned short),&num,NULL);
  85. #else
  86.   unsigned short *pek = (unsigned short *)rfile;
  87.   i = *pek;
  88.   rfile = (HANDLE)(pek + 1);
  89. #endif
  90.   return i;
  91. }
  92.  
  93. static int ismem (char *ptr, char val, int sz)
  94. {
  95.     int i;
  96.     for (i=0;i<sz;i++) if (ptr[i]!=val) return 0;
  97.     return 1;
  98. }
  99. static int checkpos (GTK_PATTERNPOS *ppos)
  100. {
  101.     int flag,i;
  102.     flag = 0;
  103.     for (i=0;i<GTK_DEFAULT_PATCHANNELS;i++)
  104.     {
  105.         if (!ismem ((char *)&ppos[i],0,sizeof (GTK_PATTERNPOS))    )
  106.             flag |= (1<<i);
  107.     }
  108.     return flag;
  109. }
  110.  
  111. void gtk_expand_seq (GTK_SEQCHANNEL *chn,int oldlen)
  112. {
  113.     chn->positions = (GTK_SEQPOS *)realloc(chn->positions,sizeof (GTK_SEQPOS) * chn->len);
  114.     if (chn->len > oldlen)
  115.         memset (&chn->positions[oldlen],0,sizeof (GTK_SEQPOS) * (chn->len - oldlen));   
  116. }
  117. void gtk_expand_pat (GTK_PATTERN *pat, int oldlen)
  118. {
  119.     int i;  
  120.     pat->patterndata = (GTK_PATTERNPOS **)realloc(pat->patterndata,sizeof (GTK_PATTERNPOS *) * pat->len); //GTK_DEFAULT_PATCHANNELS);
  121.         
  122.     // fixed overflow bug.. 2002-03-17. Dan
  123.     for (i=oldlen;i<pat->len;i++)
  124.     {
  125.         pat->patterndata[i] = (GTK_PATTERNPOS *)malloc (sizeof (GTK_PATTERNPOS) * GTK_DEFAULT_PATCHANNELS); //gtk->patterns[i].len);
  126.         memset (pat->patterndata[i],0,sizeof (GTK_PATTERNPOS) * GTK_DEFAULT_PATCHANNELS); // gtk->patterns[i].len);                        
  127.     }
  128.     
  129. }
  130. /*
  131.  
  132.     file layout:
  133.  
  134.     0        GOAT
  135.     4        version (0x0101)
  136.     6        number of seq channels
  137.     7        number of patterns
  138.     8       number of instruments
  139.     9       song BPM
  140.  
  141.  10   sequence tick per row
  142.  11   default pattern tick per row
  143.  12..    seq channel 0 of N in packed form
  144.     X..    Pattern 0 of N in packed form...
  145.  
  146. seqchannel data is stored as:
  147.     0        id of channel (which channel is this),
  148.     1        channel length (number of positions in channel)
  149.     2..    position data in packed form
  150.  
  151.     seq pos data is stored as:
  152.         flag, indicating (bit flags)
  153.             0        no data is stored for this position
  154.             1        pattern number is stored
  155.             2        transpose values is stored
  156.             4        fx parameter is stored
  157.             8        param1 of fx is stored
  158.         0x10    param2 of fx is stored
  159.         0x20    param3 of fx is stored
  160.     0x40    param1 of fx is stored
  161.     0x80    param2 of fx is stored
  162.     0x100    param3 of fx is stored
  163.     
  164.     flag is stored as word..
  165.       number of bytes indicated by the flags (each type has one byte)
  166.         max is: 9 bytes in the order: <pattern><trans><instr><param1><param2><param3><param1><param2><param3>
  167.  
  168.  
  169. pattern data is stored as:
  170.  
  171.     0        id of pattern, important: the sequencer will point to this number
  172.     1        length of pattern positions
  173.     
  174.     each row in a pattern is stored as:
  175.  
  176.     0        flag, indicating which of the 16 channels that are used...
  177.                         if bit=1 pos data is available, bit 0 = pos 0, bit 1 = pos 1, bit 2 = pos 2.. (bit 0 = 0x01)
  178.  
  179.     4        the position data itself is not packed...
  180.             if position data is available it is stored as:
  181.             <note><velocity><fx><param>
  182.  
  183.  
  184. */
  185. static void ReadSongData (HANDLE hFile, GTK *gtk)
  186. {
  187.     DWORD nchn,npat,id;
  188.     unsigned short flag;
  189.     GTK_SEQPOS *spos;
  190.     GTK_PATTERNPOS *ppos;
  191.     DWORD num,k;
  192.     int seqlen,patlen;
  193.     int maxlen;
  194.     int i,j;
  195.  
  196.     nchn = readbyte (hFile);
  197.     npat = readbyte (hFile);
  198.     gtk->num_instruments = readbyte (hFile);
  199.     gtk->def_bpm = readbyte (hFile);
  200.     gtk->def_pattick = readbyte (hFile);
  201.     gtk->internal_seqtick= readbyte (hFile);
  202.     gtk->def_seqtick = GTK_SEQ_MUL * gtk->internal_seqtick;
  203.     seqlen = gtk->channels[0].len;
  204.  
  205.     maxlen = 0;
  206.  
  207.     for (i=0;i<nchn;i++)
  208.     {
  209.         id = readbyte (hFile);
  210.         switch (load_version)
  211.         {
  212.             case 0x0102 :
  213.                 gtk->channels[id].len = readbyte (hFile);
  214.                 break;
  215.             default :
  216.                 gtk->channels[id].len = readword (hFile);
  217.                 if (gtk->channels[id].len != seqlen)
  218.                     gtk_expand_seq (>k->channels[i],seqlen);
  219.  
  220.  
  221.                 
  222.                 break;
  223.         }
  224.         if (gtk->channels[id].len > maxlen)
  225.             maxlen = gtk->channels[id].len;
  226.         for (j=0;j<gtk->channels[id].len;j++)
  227.         {
  228.             spos = >k->channels[id].positions[j];
  229.             flag = readword (hFile);                
  230.             if (flag)
  231.             {
  232.                 if (flag & GTK_FILEFLAG_SEQPOS_PATTERN)
  233.                     spos->pattern = readbyte (hFile);
  234.                 if (flag & GTK_FILEFLAG_SEQPOS_TRANSPOSE)
  235.                     spos->transpose = readbyte (hFile);
  236.                 if (flag & GTK_FILEFLAG_SEQPOS_FX)
  237.                     spos->fx = readbyte (hFile);
  238.                 if (flag & GTK_FILEFLAG_SEQPOS_PARAM1)
  239.                     spos->param1 = readbyte (hFile);
  240.                 if (flag & GTK_FILEFLAG_SEQPOS_PARAM2)
  241.                     spos->param2 = readbyte (hFile);
  242.                 if (flag & GTK_FILEFLAG_SEQPOS_PARAM3)
  243.                     spos->param3 = readbyte (hFile);
  244.                 if (flag & GTK_FILEFLAG_SEQPOS_PARAM4)
  245.                   spos->param4 = readbyte (hFile);
  246.                 if (flag & GTK_FILEFLAG_SEQPOS_PARAM5)
  247.                   spos->param5 = readbyte (hFile);
  248.                 if (flag & GTK_FILEFLAG_SEQPOS_PARAM6)
  249.                   spos->param6 = readbyte (hFile);
  250.             }
  251.         }
  252.     }
  253.  
  254.     // expand all patterns...  if needed..
  255.     for (i=0;i<gtk->num_channels;i++)
  256.     {
  257.         if (gtk->channels[i].len < maxlen)
  258.         {
  259.             int tmp;
  260.             tmp = gtk->channels[i].len;
  261.             gtk->channels[i].len = maxlen;
  262.             gtk_expand_seq(>k->channels[i],tmp);
  263.         }
  264.     }
  265.     
  266.     patlen = gtk->patterns[0].len;
  267.     for (i=0;i<npat;i++)
  268.     {
  269.         // write the "pattern" ID in the file...
  270.         id = readbyte (hFile);
  271.         // write down the pattern length
  272.         switch (load_version)
  273.         {
  274.         case 0x0102 :
  275.             gtk->patterns[id].len = readbyte (hFile);
  276.             break;
  277.         default :
  278.             gtk->patterns[id].len = readword (hFile);
  279.             if (gtk->patterns[id].len != patlen)
  280.                 gtk_expand_pat (>k->patterns[id],patlen);
  281.             break;
  282.         }
  283.         
  284.         for (j=0;j<gtk->patterns[id].len;j++)
  285.         {
  286.             unsigned int posflag;
  287.             // ppos is a one row of position data... (hence: 16 pos)
  288.             ppos = gtk->patterns[id].patterndata[j];
  289.             // read the pos bitfield
  290.             posflag = readint (hFile);
  291.             // if there was any patterndata found at that row
  292.             // loop through all positions and write down thoose with data..
  293.             if (posflag)
  294.                 for (k=0;k<GTK_DEFAULT_PATCHANNELS;k++)
  295.                     if ((posflag >> k) & 1) 
  296.                     {
  297. #ifndef __GTK_MEMREAD__
  298.                         ReadFile (hFile,&ppos[k],sizeof (GTK_PATTERNPOS),&num,NULL); 
  299. #else
  300.                         {
  301.                             BYTE *pek;
  302.                             pek = (BYTE *)rfile;
  303.                             memcpy (&ppos[k],pek,sizeof (GTK_PATTERNPOS));
  304.                             rfile = (HANDLE)(pek + sizeof (GTK_PATTERNPOS));
  305.                         }
  306. #endif
  307.                     }
  308.         }
  309.  
  310.  
  311.  
  312.     }
  313. }
  314.  
  315. static void WriteSongData (HANDLE hFile, GTK *gtk)
  316. {
  317.     int i,j,k;
  318.     int nchn,npat;
  319.     BYTE flag;
  320.     DWORD num;
  321.     int chnlist[16],patlist[256];
  322.     GTK_SEQPOS *spos;
  323.     GTK_PATTERNPOS *ppos;
  324.  
  325.     nchn = npat = 0;
  326.     memset (chnlist,0,sizeof (int) * 16);
  327.     memset (patlist,0,sizeof (int) * 256);
  328.     // calc all patterns in the song...
  329.     for (i=0;i<gtk->num_channels;i++)
  330.     {
  331.         for (j=0;j<gtk->channels[i].len;j++)
  332.         {
  333.             if (gtk->channels[i].positions[j].pattern!=0)
  334.             {
  335.                 if (!chnlist[i]) nchn++;
  336.                 chnlist[i]=1;
  337.                 if (!patlist[gtk->channels[i].positions[j].pattern]) npat++;
  338.                 patlist[gtk->channels[i].positions[j].pattern]=1;
  339.             }
  340.         }
  341.     }
  342.     // write down how many there was...
  343.     writebyte (hFile,nchn);
  344.     writebyte (hFile,npat);
  345.     writebyte (hFile,gtk->num_instruments);
  346.     writebyte (hFile,gtk->def_bpm);
  347.     writebyte (hFile,gtk->def_pattick);
  348.     writebyte (hFile,gtk->internal_seqtick);
  349.     // loop through and store each seq-channel
  350.     for (i=0;i<gtk->num_channels;i++)
  351.     {
  352.         if (chnlist[i])
  353.         {
  354.             writebyte (hFile,i);
  355.             writeword (hFile,gtk->channels[i].len);
  356.             for (j=0;j<gtk->channels[i].len;j++)
  357.             {
  358.                 spos = >k->channels[i].positions[j];
  359.                 flag = GTK_FILEFLAG_SEQPOS_NONE;
  360.                 if (spos->pattern) flag |= GTK_FILEFLAG_SEQPOS_PATTERN;
  361.                 if (spos->transpose) flag |= GTK_FILEFLAG_SEQPOS_TRANSPOSE;
  362.                 if (spos->fx) flag |= GTK_FILEFLAG_SEQPOS_FX;
  363.                 if (spos->param1) flag |= GTK_FILEFLAG_SEQPOS_PARAM1;
  364.                 if (spos->param2) flag |= GTK_FILEFLAG_SEQPOS_PARAM2;
  365.                 if (spos->param3) flag |= GTK_FILEFLAG_SEQPOS_PARAM3;
  366.                 if (spos->param4) flag |= GTK_FILEFLAG_SEQPOS_PARAM4;
  367.                 if (spos->param5) flag |= GTK_FILEFLAG_SEQPOS_PARAM5;
  368.                 if (spos->param6) flag |= GTK_FILEFLAG_SEQPOS_PARAM6;
  369.                 //        writebyte (hFile,flag);
  370.                 writeword (hFile,flag);
  371.         
  372.                 if (flag)
  373.                 {
  374.                     if (flag & GTK_FILEFLAG_SEQPOS_PATTERN)
  375.                         writebyte (hFile,spos->pattern);
  376.                     if (flag & GTK_FILEFLAG_SEQPOS_TRANSPOSE)
  377.                         writebyte (hFile,spos->transpose);
  378.                     if (flag & GTK_FILEFLAG_SEQPOS_FX)
  379.                         writebyte (hFile,spos->fx);
  380.                     if (flag & GTK_FILEFLAG_SEQPOS_PARAM1)
  381.                         writebyte (hFile,spos->param1);
  382.                     if (flag & GTK_FILEFLAG_SEQPOS_PARAM2)
  383.                         writebyte (hFile,spos->param2);
  384.                     if (flag & GTK_FILEFLAG_SEQPOS_PARAM3)
  385.                         writebyte (hFile,spos->param3);
  386.                     if (flag & GTK_FILEFLAG_SEQPOS_PARAM4)
  387.                     writebyte (hFile,spos->param4);
  388.                     if (flag & GTK_FILEFLAG_SEQPOS_PARAM5)
  389.                     writebyte (hFile,spos->param5);
  390.                     if (flag & GTK_FILEFLAG_SEQPOS_PARAM6)
  391.                     writebyte (hFile,spos->param6);
  392.                 }
  393.             } // for (j=0;....
  394.         } // if (chnlist
  395.     }// for (i=0;...
  396.  
  397.  
  398.     // now lets save all patterns in a slightly packed form...
  399.     for (i=0;i<gtk->num_patterns;i++)
  400.     {
  401.     // if we have a pattern that should be stored
  402.         if (patlist[i])
  403.         {
  404.             // write the "pattern" ID in the file...
  405.             writebyte (hFile,i);
  406.             // write down the pattern length
  407.             // !VERSION! changed from byte to word from version 0102
  408.             writeword (hFile,gtk->patterns[i].len);
  409.             for (j=0;j<gtk->patterns[i].len;j++)
  410.             {
  411.                 unsigned int posflag;
  412.                 // ppos is a one row of position data... (hence: 16 pos)
  413.                 ppos = gtk->patterns[i].patterndata[j];
  414.                 // check which rows to save
  415.                 posflag = checkpos (ppos);
  416.                 // write down the bitfiled
  417.                 writeint (hFile,posflag);
  418.                 // if there was any patterndata found at that row
  419.                 // loop through all positions and write down thoose with data..
  420.                 if (posflag)
  421.                     for (k=0;k<GTK_DEFAULT_PATCHANNELS;k++)
  422.                         if ((posflag >> k) & 1) WriteFile (hFile,&ppos[k],sizeof (GTK_PATTERNPOS),&num,NULL);
  423.             }
  424.         }
  425.     }
  426.  
  427.  
  428. }
  429. int gtk_save (GTK *gtk,isSynth *synth,char *fname)
  430. {
  431.     HANDLE hfile;
  432.     DWORD num;
  433.     unsigned short version=GTK_CURRENT_VERSION;
  434.  
  435.     hfile = CreateFile (fname,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  436.     if (hfile == INVALID_HANDLE_VALUE) return 0;
  437.     
  438.     // first write the synths data
  439.     isFile f(hfile,false);
  440.     synth->Save(&f);
  441.     
  442.     WriteFile (hfile,"GOAT",4,&num,NULL);
  443.     WriteFile (hfile,&version,2,&num,NULL);
  444.     WriteSongData (hfile,gtk);
  445.  
  446.     CloseHandle (hfile);
  447.     return 0;    
  448. };
  449.  
  450. GTK *gtk_load (isSynth *synth,char *fname)
  451. {
  452.     HANDLE hfile;
  453.     DWORD num;
  454.     char mod_id[5];
  455.     GTK *gtk;
  456.  
  457.     gtk = NULL;
  458.  
  459. #ifndef __GTK_MEMREAD__
  460.     hfile = CreateFile (fname,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
  461.     if (hfile == INVALID_HANDLE_VALUE)
  462.         return 0;
  463.     memset (mod_id,0,5);
  464.     // first read the synths data
  465.     isFile f(hfile,false);
  466. #else
  467.     hfile = (HANDLE)fname;
  468.     isFile f(hfile,true);
  469. #endif
  470.     synth->Load(&f);
  471.  
  472. #ifndef __GTK_MEMREAD__
  473.     ReadFile (hfile,mod_id,4,&num,NULL);
  474. #else
  475.     {
  476.         DWORD pos;
  477.         pos = f.GetPos();
  478.         BYTE *pek = (BYTE *)hfile;
  479.         hfile = (HANDLE)(pek + pos);
  480.         pek = (BYTE *)hfile;
  481.         memcpy (&mod_id,pek,4);
  482.         rfile = (HANDLE)(pek+4);
  483.     }
  484. #endif
  485.     gtk = NULL;
  486.     if (!memcmp (mod_id,"GOAT",4))
  487.     {
  488.         //ReadFile (hfile,&load_version,2,&num,NULL);
  489.         load_version = readword(hfile);
  490. //        if (version==GTK_CURRENT_VERSION)
  491.         {
  492.             gtk = gtk_create ();
  493.             ReadSongData (hfile,gtk);
  494.         } 
  495.     } else 
  496.         MessageBox( NULL, "Could not load song!", "rARHR", MB_OK );
  497. #ifndef __GTK_MEMREAD__
  498.     CloseHandle (hfile);
  499. #endif
  500.     return gtk;
  501.  
  502. }
  503.  
  504. int gtk_clearmod (GTK *mod)
  505. {
  506.     return 1;
  507. }
  508. GTK *gtk_create (void)
  509. {
  510.     GTK *gtk;
  511.     int i,j;
  512.     gtk = (GTK *)malloc (sizeof (GTK));
  513.     gtk->num_channels = 16;
  514.     gtk->num_patterns = 255;
  515.     gtk->num_instruments=0;
  516.     gtk->def_bpm=GTK_DEFAULT_BPM;
  517.     gtk->def_pattick=GTK_DEFAULT_PATTICK;
  518.     gtk->internal_seqtick = GTK_DEFAULT_SEQTICK;
  519.     gtk->def_seqtick=gtk->internal_seqtick * GTK_SEQ_MUL;
  520.  
  521.     gtk->channels = (GTK_SEQCHANNEL *)malloc (sizeof (GTK_SEQCHANNEL) * gtk->num_channels);
  522.     for (i=0;i<gtk->num_channels;i++)
  523.     {
  524.         gtk->channels[i].len = 64;
  525.         gtk->channels[i].positions = (GTK_SEQPOS *)malloc (sizeof (GTK_SEQPOS) * 64);
  526. //        for (j=0;j<gtk->channels[i].len;j++)
  527.         memset (gtk->channels[i].positions,0,sizeof (GTK_SEQPOS) * gtk->channels[i].len);
  528.     }
  529.  
  530.     gtk->patterns = (GTK_PATTERN *)malloc (sizeof (GTK_PATTERN) * gtk->num_patterns);
  531.     for (i=0;i<gtk->num_patterns;i++)
  532.     {
  533.         gtk->patterns[i].len = 64;
  534.         gtk->patterns[i].patterndata = (GTK_PATTERNPOS **)malloc (sizeof (GTK_PATTERNPOS *) * gtk->patterns[i].len); //GTK_DEFAULT_PATCHANNELS);
  535.         for (j=0;j<gtk->patterns[i].len;j++)
  536.         {
  537.             gtk->patterns[i].patterndata[j] = (GTK_PATTERNPOS *)malloc (sizeof (GTK_PATTERNPOS) * GTK_DEFAULT_PATCHANNELS); //gtk->patterns[i].len);
  538.             memset (gtk->patterns[i].patterndata[j],0,sizeof (GTK_PATTERNPOS) * GTK_DEFAULT_PATCHANNELS); // gtk->patterns[i].len);
  539.         }    
  540.     }
  541.     return gtk;
  542. }