home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / vrac / mikmod43.zip / MODLOAD.C < prev    next >
C/C++ Source or Header  |  1994-04-28  |  11KB  |  542 lines

  1. /*
  2.     MODLOAD.C
  3.  
  4.     Or how to load a module in C. Progged by MikMak :)
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <alloc.h>
  12. #include "mytypes.h"
  13. #include "modload.h"
  14.  
  15.  
  16. char protracker[]="Protracker";
  17. char startracker[]="Startracker";
  18. char fasttracker[]="Fasttracker";
  19. char ins15tracker[]="15-instrument";
  20.  
  21.  
  22. MODTYPE modtypes[]={
  23.     "M.K.",4,protracker,    // protracker 4 channel
  24.     "M!K!",4,protracker,    // protracker 4 channel
  25.     "FLT4",4,startracker,   // startracker 4 channel
  26.     "FLT8",8,startracker,   // startracker 8 channel
  27.     "4CHN",4,fasttracker,   // fasttracker 4 channel
  28.     "6CHN",6,fasttracker,   // fasttracker 6 channel
  29.     "8CHN",8,fasttracker,   // fasttracker 8 channel
  30.     "    ",4,ins15tracker    // 15-instrument 4 channel
  31. };
  32.  
  33.  
  34. int (*SampleLoader)(FILE *fp,SAMPLEINFO *smp);        // The callback sample load routine
  35. void (*SampleUnLoader)(int handle,SAMPLEINFO *smp);    // The callback sample unload routine
  36.  
  37. int ml_errno;
  38. int ml_load15flag=0;
  39.  
  40. char *ml_errlist[]={
  41.     "No error",
  42.     "Failed allocating MODFILE structure",
  43.     "Error opening modfile",
  44.     "Error loading module header",
  45.     "Unknown type of module",
  46.     "Failed allocating pattern",
  47.     "EOF while loading pattern",
  48.     "Sample load failed"
  49. };
  50.  
  51.  
  52. enum {
  53.     ERROR_OKAY=0,
  54.     ERROR_ALLOC_STRUCT,
  55.     ERROR_OPENING_FILE,
  56.     ERROR_LOADING_HEADER,
  57.     ERROR_NOT_A_MODULE,
  58.     ERROR_ALLOC_PATTERN,
  59.     ERROR_EOF_PATTERNS,
  60.     ERROR_SAMPLE_FAILED
  61. };
  62.  
  63.  
  64.  
  65. /*
  66.  
  67. Old (amiga) noteinfo:
  68.  
  69.  _____byte 1_____   byte2_    _____byte 3_____   byte4_
  70. /                \ /      \  /                \ /      \
  71. 0000          0000-00000000  0000          0000-00000000
  72.  
  73. Upper four    12 bits for    Lower four    Effect command.
  74. bits of sam-  note period.   bits of sam-
  75. ple number.                  ple number.
  76.  
  77.  
  78.  
  79. Format for MIKMOD upto version 0.3:
  80.  
  81.  
  82.  _byte 1_   _byte 2_   __byte 3_   _byte 4_
  83. /        \ /        \ /         \ /        \
  84.  00000000   00000000   0000 0000   00000000
  85.   Sample    note nr.   zero  fx     fx data
  86.  
  87. Sample ranges from 0 to 31
  88.  
  89. Note number 0 means no note. ranges from 1 to 36
  90.  
  91.  
  92.  
  93. MIKMOD 0.4 format (same as PS16 format) :
  94.  
  95. ┌─Upper two bits of instrument
  96. │ Period
  97. │   ││
  98. ├┐┌─┴┴─┐
  99. 00111111    period means note .. just to be clear
  100.  
  101. 11111111
  102. ┌──┐┌──┐
  103. Ins  Efx
  104.  
  105. 11111111
  106. ────────
  107. Data
  108.  
  109. */
  110.  
  111.  
  112.  
  113.  
  114. // Periodtable for Tuning 0, Normal
  115.  
  116. UWORD pertab[60]={
  117.     1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906,
  118.     856,808,762,720,678,640,604,570,538,508,480,453,
  119.     428,404,381,360,339,320,302,285,269,254,240,226,
  120.     214,202,190,180,170,160,151,143,135,127,120,113,
  121.     107,101,95,90,85,80,75,71,67,63,60,56
  122. };
  123.  
  124.  
  125.  
  126. void ConvertPattern(UBYTE *dest,UBYTE *srce,UWORD notes)
  127. /*
  128.     Translates an amiga type pattern to a pattern with note-numbers
  129.     instead of note-periods
  130. */
  131. {
  132.     UBYTE instrument,effect,effdat,note;
  133.     UWORD period;
  134.  
  135.     while(notes--){
  136.  
  137.         /* extract the various information from the 4 bytes that
  138.            make up a single note */
  139.  
  140.         instrument=(srce[0]&0x10)|(srce[2]>>4);
  141.         period=(((UWORD)srce[0]&0xf)<<8)+srce[1];
  142.         effect=srce[2]&0xf;
  143.         effdat=srce[3];
  144.  
  145.         // Convert the period to a note number
  146.  
  147.         if(period!=0){
  148.             for(note=0;note<60;note++){
  149.                 if(period>=pertab[note]) break;
  150.             }
  151.             if(note==60) note=0;    // couldn't find period, kill note
  152.             else note++;
  153.         }
  154.         else note=0;
  155.  
  156.         // And assemble the bits to the new 3-byte format
  157.  
  158.         dest[0]=((instrument&0x30)<<2)|note;
  159.         dest[1]=((instrument&0xf)<<4)|effect;
  160.         dest[2]=effdat;
  161.  
  162.         srce+=4;
  163.         dest+=3;
  164.     }
  165. }
  166.  
  167.  
  168.  
  169. UWORD rword(UWORD p)
  170. /*
  171.     Motorola word -> intel word
  172. */
  173. {
  174.     return( ((p&0x00ff)<<8) | ((p&0xff00)>>8) );
  175. }
  176.  
  177.  
  178.  
  179. void cword(UWORD *p)
  180. {
  181.     *p=rword(*p);
  182. }
  183.  
  184.  
  185.  
  186.  
  187. void ConvertStr(char *d,char *s,int len)
  188. {
  189.     strncpy(d,s,len);
  190.     d[len]='\0';
  191. }
  192.  
  193.  
  194.  
  195. void Convert15To31(OLDMODULEHEADER *a,MODULEHEADER *b)
  196. /*
  197.     Converts a 15-instrument module header into a 31 intrument header
  198. */
  199. {
  200.     b->songlength=a->songlength;
  201.     b->magic1=a->magic1;
  202.     memcpy(b->positions,a->positions,128);            // copy positions
  203.     memset(b->magic2,0,4);                             // clear magic2
  204.     memset(&b->samples[15],0,16*sizeof(MSAMPINFO));    // clear samples 15-31
  205. }
  206.  
  207.  
  208.  
  209. int Check15Inst(OLDMODULEHEADER *mh)
  210. /*
  211.     Check if it's a 15 inst. module.. you could also check if the instrument
  212.     names contain valid ascii but that still doesn't mean you can be sure
  213.     that it's a 15-instrument mod.
  214. */
  215. {
  216.     int t;
  217.     for(t=0;t<15;t++){
  218.  
  219.         // all finetunes should be zero
  220.         if(mh->samples[t].finetune!=0) return 0;
  221.  
  222.         // all volumes should be <=64
  223.         if(mh->samples[t].volume>64) return 0;
  224.     }
  225.     if(mh->magic1>127) return 0;    // and magic1 should be <128
  226.     return 1;
  227. }
  228.  
  229.  
  230. int ML_OpenModFile(MODFILE *mf,char filename[],FILE *ufp)
  231. {
  232.     int t,modtype=0;
  233.     MODULEHEADER mh;    // raw as-is module header
  234.     SAMPLEINFO *d;      // new sampleinfo structure
  235.     MSAMPINFO *s;       // old module sampleinfo
  236.  
  237.     memset(&mh,0,sizeof(MODULEHEADER));
  238.  
  239.     // Open modfile, if not already open
  240.  
  241.     mf->userfp=1;
  242.  
  243.     if(ufp==NULL){
  244.         ufp=fopen(filename,"rb");
  245.         mf->userfp=0;
  246.     }
  247.  
  248.     mf->fp=ufp;
  249.  
  250.  
  251.     // Check if file was opened
  252.  
  253.     if(ufp==NULL){
  254.         ml_errno=ERROR_OPENING_FILE;
  255.         return 0;
  256.     }
  257.  
  258.     // try to read module header
  259.  
  260.     if(!fread(&mh,sizeof(MODULEHEADER),1,ufp)){
  261.         ml_errno=ERROR_LOADING_HEADER;
  262.         return 0;
  263.     }
  264.  
  265.     // find out which ID string
  266.  
  267.     for(modtype=0;modtype<7;modtype++){
  268.         if(!memcmp(mh.magic2,modtypes[modtype].id,4)) break;
  269.     }
  270.  
  271.     if(modtype==7){
  272.  
  273.         // unknown modtype, so check if it's a 15-instrument file
  274.  
  275.         if(ml_load15flag && Check15Inst((OLDMODULEHEADER *)&mh)){
  276.             Convert15To31((OLDMODULEHEADER *)&mh,&mh);
  277.             fseek(ufp,sizeof(OLDMODULEHEADER),SEEK_SET);
  278.         }
  279.         else{
  280.             ml_errno=ERROR_NOT_A_MODULE;
  281.             return 0;
  282.         }
  283.     }
  284.  
  285.     // sample info to intel format
  286.  
  287.     for(t=0;t<31;t++){
  288.         cword(&mh.samples[t].length);
  289.         cword(&mh.samples[t].reppos);
  290.         cword(&mh.samples[t].replen);
  291.     }
  292.  
  293.     /* set module variables */
  294.  
  295.     mf->numchn=modtypes[modtype].channels;      // get number of channels
  296.     mf->modtype=modtypes[modtype].name;         // get ascii type of mod
  297.     ConvertStr(mf->songname,mh.songname,20);     // make a cstr of songname
  298.     mf->songlength=mh.songlength;                // copy the songlength
  299.     memcpy(mf->positions,mh.positions,128);      // copy the position array
  300.  
  301.     /* Count the number of patterns */
  302.  
  303.     mf->numpat=0;
  304.  
  305.     for(t=0;t<128;t++){        // <-- BUGFIX... have to check ALL positions
  306.         if(mf->positions[t] > mf->numpat){
  307.             mf->numpat=mf->positions[t];
  308.         }
  309.     }
  310.     mf->numpat++;
  311.  
  312.     // Finally, init the sampleinfo structures
  313.  
  314.     mf->numsmp=0;   // reset number of samples
  315.     s=mh.samples;   // init source pointer
  316.     d=mf->samples;  // init dest pointer
  317.  
  318.     for(t=0;t<31;t++){
  319.  
  320.         // convert the samplename
  321.  
  322.         ConvertStr(d->samplename,s->samplename,22);
  323.  
  324.         /* init the sampleinfo variables and
  325.            convert the size pointers to longword format */
  326.  
  327.         d->finetune=s->finetune;
  328.         d->volume=s->volume;
  329.         d->reppos=s->reppos<<1;
  330.         d->replen=s->replen<<1;
  331.         d->length=s->length<<1;
  332.  
  333.         /* fix replen if reppos+replen>length */
  334.  
  335.         if((d->reppos+d->replen)>d->length) d->replen=d->length-d->reppos;
  336.  
  337.         /* samplesize>0 ? -> increase
  338.          number of samples */
  339.  
  340.         if(d->length!=0) mf->numsmp++;
  341.  
  342.         s++;    // point to next source sampleinfo
  343.         d++;    // point to next destiny sampleinfo
  344.     }
  345.     return 1;
  346. }
  347.  
  348.  
  349.  
  350.  
  351.  
  352. int ML_LoadPatterns(MODFILE *mf)
  353. /*
  354.     Loads all patterns of a modfile and converts them into the
  355.     3 byte format.
  356. */
  357. {
  358.     int t;
  359.     void *patbuf;
  360.  
  361.     /* Allocate temporary buffer for loading
  362.        and converting the patterns */
  363.  
  364.     if((patbuf=malloc(64U*4*mf->numchn))==NULL){
  365.         ml_errno=ERROR_ALLOC_PATTERN;
  366.         return 0;
  367.     }
  368.  
  369.     for(t=0;t<mf->numpat;t++){
  370.  
  371.         /* For each pattern, allocate a chunk
  372.            of memory */
  373.  
  374.         if((mf->patterns[t]=malloc(64U*3*mf->numchn))==NULL){
  375.             ml_errno=ERROR_ALLOC_PATTERN;
  376.             break;
  377.         }
  378.  
  379.         /* Load the pattern into the temp buffer
  380.            and convert it into the 3-byte format */
  381.  
  382.         if(fread(patbuf,64U*4*mf->numchn,1,mf->fp)!=1){
  383.             ml_errno=ERROR_EOF_PATTERNS;
  384.             break;
  385.         }
  386.  
  387.         ConvertPattern(mf->patterns[t],patbuf,64U*mf->numchn);
  388.     }
  389.  
  390.     // free temp buffer
  391.  
  392.     free(patbuf);
  393.  
  394.     return(t==mf->numpat);
  395. }
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402. int ML_LoadSamples(MODFILE *mf)
  403. {
  404.     int t,handle;
  405.  
  406.     for(t=0;t<31;t++){
  407.  
  408.         /* sample has to be loaded ? -> increase
  409.            number of samples and allocate memory and
  410.            load sample */
  411.  
  412.         if(mf->samples[t].length!=0){
  413.  
  414.             /* Call the user-supplied sample load routine.
  415.                It has to return a handle that identifies the sample */
  416.  
  417.             handle=SampleLoader(mf->fp,&mf->samples[t]);
  418.  
  419.             if(handle<0){                          // error ?
  420.                 ml_errno=ERROR_SAMPLE_FAILED;
  421.                 return 0;
  422.             }
  423.             else{
  424.                 mf->samples[t].handle=handle;    // no error
  425.             }
  426.         }
  427.     }
  428.  
  429.     if(!mf->userfp){        // if it wasn't a user supplied filehandle
  430.         fclose(mf->fp);        // then close the file
  431.         mf->fp=NULL;        //
  432.     }
  433.     return 1;
  434. }
  435.  
  436.  
  437.  
  438.  
  439. void ML_FreePatterns(MODFILE *mf)
  440. {
  441.     int t;
  442.  
  443.     for(t=0;t<128;t++){
  444.         if(mf->patterns[t]!=NULL) free(mf->patterns[t]);
  445.     }
  446. }
  447.  
  448.  
  449.  
  450. void ML_FreeSamples(MODFILE *mf)
  451. {
  452.     int t;
  453.  
  454.     for(t=0;t<31;t++){
  455.         if(mf->samples[t].handle>=0) SampleUnLoader(mf->samples[t].handle,&mf->samples[t]);
  456.     }
  457. }
  458.  
  459.  
  460.  
  461. void ML_FreeModFile(MODFILE *mf)
  462. {
  463.     ML_FreeSamples(mf);
  464.     ML_FreePatterns(mf);
  465.     if(!mf->userfp && mf->fp!=NULL) fclose(mf->fp);
  466. }
  467.  
  468.  
  469.  
  470.  
  471. /******************************************
  472.  
  473.     Next are the user-callable functions
  474.  
  475. ******************************************/
  476.  
  477.  
  478. void ML_Load15(int yesno)
  479. {
  480.     ml_load15flag=yesno;
  481. }
  482.  
  483.  
  484. void ML_Free(MODFILE *mf)
  485. {
  486.     ML_FreeModFile(mf);
  487.     free(mf);
  488. }
  489.  
  490.  
  491. int ML_Load(MODFILE *mf)
  492. {
  493.     if(!ML_LoadPatterns(mf)) return 0;
  494.     if(!ML_LoadSamples(mf)) return 0;
  495.     return 1;
  496. }
  497.  
  498.  
  499. MODFILE *ML_Open(char filename[],FILE *fp)
  500. {
  501.     int t;
  502.     MODFILE *mf;
  503.  
  504.     ml_errno=0;
  505.  
  506.     mf=malloc(sizeof(MODFILE));
  507.     if(mf==NULL){
  508.         ml_errno=ERROR_ALLOC_STRUCT;
  509.         return NULL;
  510.     }
  511.  
  512.     // reset some structures
  513.  
  514.     mf->fp=NULL;
  515.     for(t=0;t<128;t++) mf->patterns[t]=NULL;
  516.     for(t=0;t<31;t++)  mf->samples[t].handle=-1;
  517.  
  518.     if(!ML_OpenModFile(mf,filename,fp)){
  519.         ML_Free(mf);
  520.         return NULL;
  521.     }
  522.     return mf;
  523. }
  524.  
  525.  
  526. void ML_RegisterLoader(int (*Loader)(FILE *fp,SAMPLEINFO *smp))
  527. {
  528.     SampleLoader=Loader;
  529. }
  530.  
  531.  
  532. void ML_RegisterUnLoader(void (*UnLoader)(int handle,SAMPLEINFO *smp))
  533. {
  534.     SampleUnLoader=UnLoader;
  535. }
  536.  
  537.  
  538. const char *ML_Error(void)
  539. {
  540.     return(ml_errlist[ml_errno]);
  541. }
  542.