home *** CD-ROM | disk | FTP | other *** search
/ The Games Machine 25 / GNOME_DEMO.iso / amiga / music / mikmod.lzx / mikmod / mloader.c < prev    next >
C/C++ Source or Header  |  1999-01-06  |  6KB  |  407 lines

  1. /*
  2.  
  3. Name:
  4. MLOADER.C
  5.  
  6. Description:
  7. These routines are used to access the available module loaders
  8.  
  9. Portability:
  10. All systems - all compilers
  11.  
  12. */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include "mikmod.h"
  17.  
  18.  
  19. FILE *modfp;
  20. UNIMOD of;
  21.  
  22. LOADER *firstloader=NULL;
  23.  
  24.  
  25. UWORD finetune[16]={
  26.     8363,    8413,    8463,    8529,    8581,    8651,    8723,    8757,
  27.     7895,    7941,    7985,    8046,    8107,    8169,    8232,    8280
  28. };
  29.  
  30.  
  31.  
  32.  
  33.  
  34. void ML_InfoLoader(void)
  35. {
  36.     int t;
  37.     LOADER *l;
  38.  
  39.     /* list all registered devicedrivers: */
  40.  
  41.     for(t=1,l=firstloader; l!=NULL; l=l->next, t++){
  42.         printf("%d. %s\n",t,l->version);
  43.     }
  44. }
  45.  
  46.  
  47. void ML_RegisterLoader(LOADER *ldr)
  48. {
  49.     LOADER *l;
  50.  
  51.     if(firstloader==NULL){
  52.         firstloader=ldr;
  53.         ldr->next=NULL;
  54.     }
  55.     else{
  56.         ldr->next=firstloader;
  57.         firstloader=ldr;
  58.     }
  59. }
  60.  
  61.  
  62.  
  63. void *MyMalloc(size_t size)
  64. /*
  65.     Same as malloc, but sets error variable ml_errno when it failed
  66. */
  67. {
  68.     void *d;
  69.  
  70.     d=malloc(size);
  71.     if(d==NULL){
  72.         myerr="Error allocating structure";
  73.     }
  74.     return d;
  75. }
  76.  
  77.  
  78.  
  79. void *MyCalloc(size_t nitems,size_t size)
  80. /*
  81.     Same as calloc, but sets error variable ml_errno when it failed
  82. */
  83. {
  84.     void *d;
  85.  
  86.     d=calloc(nitems,size);
  87.     if(d==NULL){
  88.         myerr="Error allocating structure";
  89.     }
  90.     return d;
  91. }
  92.  
  93.  
  94.  
  95. BOOL ReadComment(UWORD len)
  96. {
  97.     int t;
  98.  
  99.     if(len){
  100.         if(!(of.comment=(UBYTE *)MyMalloc(len+1))) return 0;
  101.         fread(of.comment,len,1,modfp);
  102.         of.comment[len]=0;
  103.  
  104.         /* strip any control-characters in the comment: */
  105.  
  106.         for(t=0;t<len;t++){
  107.             if(of.comment[t]<32) of.comment[t]=' ';
  108.         }
  109.     }
  110.     return 1;
  111. }
  112.  
  113.  
  114.  
  115. BOOL AllocPatterns(void)
  116. {
  117.     int s,t,tracks=0;
  118.  
  119.     /* Allocate track sequencing array */
  120.  
  121.     if(!(of.patterns=(UWORD *)MyCalloc((ULONG)of.numpat*of.numchn,sizeof(UWORD)))) return 0;
  122.     if(!(of.pattrows=(UWORD *)MyCalloc(of.numpat,sizeof(UWORD)))) return 0;
  123.  
  124.     for(t=0;t<of.numpat;t++){
  125.  
  126.         of.pattrows[t]=64;
  127.  
  128.         for(s=0;s<of.numchn;s++){
  129.             of.patterns[(t*of.numchn)+s]=tracks++;
  130.         }
  131.     }
  132.  
  133.     return 1;
  134. }
  135.  
  136.  
  137. BOOL AllocTracks(void)
  138. {
  139.     if(!(of.tracks=MyCalloc(of.numtrk,sizeof(UBYTE *)))) return 0;
  140.     return 1;
  141. }
  142.  
  143.  
  144.  
  145. BOOL AllocInstruments(void)
  146. {
  147.     UWORD t;
  148.  
  149.     if(!(of.instruments=MyCalloc(of.numins,sizeof(INSTRUMENT)))) return 0;
  150.     return 1;
  151. }
  152.  
  153.  
  154. BOOL AllocSamples(INSTRUMENT *i)
  155. {
  156.     UWORD u,n;
  157.  
  158.     if(n=i->numsmp){
  159.         if(!(i->samples=MyCalloc(n,sizeof(SAMPLE)))) return 0;
  160.  
  161.         for(u=0; u<n; u++){
  162.             i->samples[u].panning=128;
  163.             i->samples[u].handle=-1;
  164.         }
  165.     }
  166.     return 1;
  167. }
  168.  
  169.  
  170. char *DupStr(UBYTE *s,UWORD len)
  171. /*
  172.     Creates a CSTR out of a character buffer of 'len' bytes, but strips
  173.     any terminating non-printing characters like 0, spaces etc.
  174. */
  175. {
  176.     UWORD t;
  177.     char *d=NULL;
  178.  
  179.     /* Scan for first printing char in buffer [includes high ascii up to 254] */
  180.  
  181.     while(len){
  182.         if(s[len-1]>0x20 && s[len-1]<0xff) break;
  183.         len--;
  184.     }
  185.  
  186.     if(len){
  187.  
  188.         /* When the buffer wasn't completely empty, allocate
  189.            a cstring and copy the buffer into that string, except
  190.            for any control-chars */
  191.  
  192.         if((d=malloc(len+1))!=NULL){
  193.             for(t=0;t<len;t++) d[t]=(s[t]<32) ? ' ': s[t];
  194.             d[t]=0;
  195.         }
  196.     }
  197.  
  198.     return d;
  199. }
  200.  
  201.  
  202.  
  203. BOOL ML_LoadSamples(void)
  204. {
  205.     UWORD t,u;
  206.     INSTRUMENT *i;
  207.     SAMPLE *s;
  208.  
  209.     for(t=0;t<of.numins;t++){
  210.  
  211.         i=&of.instruments[t];
  212.  
  213.         for(u=0; u<i->numsmp; u++){
  214.  
  215.             s=&i->samples[u];
  216.  
  217. /*        printf("Loading Sample %d\n",t); */
  218.  
  219.         /* sample has to be loaded ? -> increase
  220.            number of samples and allocate memory and
  221.            load sample */
  222.  
  223.             if(s->length){
  224.  
  225.                 if(s->seekpos){
  226.                     _mm_fseek(modfp,s->seekpos,SEEK_SET);
  227.                 }
  228.  
  229.                 /* Call the sample load routine of the driver module.
  230.                    It has to return a 'handle' (>=0) that identifies
  231.                    the sample */
  232.  
  233.                 s->handle=MD_SampleLoad(modfp,
  234.                                         s->length,
  235.                                         s->loopstart,
  236.                                         s->loopend,
  237.                                         s->flags);
  238.  
  239.                 if(s->handle<0) return 0;
  240.             }
  241.         }
  242.     }
  243.     return 1;
  244. }
  245.  
  246.  
  247. BOOL ML_LoadHeader(void)
  248. {
  249.     BOOL ok=0;
  250.     LOADER *l;
  251.  
  252.     /* Try to find a loader that recognizes the module */
  253.  
  254.     for(l=firstloader; l!=NULL; l=l->next){
  255.         _mm_rewind(modfp);
  256.         if(l->Test()) break;
  257.     }
  258.  
  259.     if(l==NULL){
  260.         myerr="Unknown module format.";
  261.         return 0;
  262.     }
  263.  
  264.     /* init unitrk routines */
  265.  
  266.     if(!UniInit()) return 0;
  267.  
  268.     /* init module loader */
  269.  
  270.     if(l->Init()){
  271.         _mm_rewind(modfp);
  272.          ok=l->Load();
  273.     }
  274.  
  275.     l->Cleanup();
  276.  
  277.     /* free unitrk allocations */
  278.  
  279.     UniCleanup();
  280.     return ok;
  281. }
  282.  
  283.  
  284.  
  285. void ML_XFreeInstrument(INSTRUMENT *i)
  286. {
  287.     UWORD t;
  288.  
  289.     if(i->samples!=NULL){
  290.         for(t=0; t<i->numsmp; t++){
  291.             if(i->samples[t].handle>=0){
  292.                 MD_SampleUnLoad(i->samples[t].handle);
  293.             }
  294.         }
  295.         free(i->samples);
  296.     }
  297.     if(i->insname!=NULL) free(i->insname);
  298. }
  299.  
  300.  
  301.  
  302. void ML_FreeEx(UNIMOD *mf)
  303. {
  304.     UWORD t;
  305.  
  306.     if(mf->modtype!=NULL) free(mf->modtype);
  307.  
  308.     if(mf->patterns!=NULL) free(mf->patterns);
  309.     if(mf->pattrows!=NULL) free(mf->pattrows);
  310.  
  311.     if(mf->tracks!=NULL){
  312.         for(t=0;t<mf->numtrk;t++){
  313.             if(mf->tracks[t]!=NULL) free(mf->tracks[t]);
  314.         }
  315.         free(mf->tracks);
  316.     }
  317.  
  318.     if(mf->instruments!=NULL){
  319.         for(t=0;t<mf->numins;t++){
  320.             ML_XFreeInstrument(&mf->instruments[t]);
  321.         }
  322.         free(mf->instruments);
  323.     }
  324.  
  325.     if(mf->songname!=NULL) free(mf->songname);
  326.     if(mf->comment!=NULL) free(mf->comment);
  327. }
  328.  
  329.  
  330.  
  331. /******************************************
  332.  
  333.     Next are the user-callable functions
  334.  
  335. ******************************************/
  336.  
  337.  
  338. void ML_Free(UNIMOD *mf)
  339. {
  340.     if(mf!=NULL){
  341.         ML_FreeEx(mf);
  342.         free(mf);
  343.     }
  344. }
  345.  
  346.  
  347.  
  348.  
  349. UNIMOD *ML_LoadFP(FILE *fp)
  350. {
  351.     int t;
  352.     UNIMOD *mf;
  353.  
  354.     /* init fileptr, clear errorcode, clear static modfile: */
  355.  
  356.     modfp=fp;
  357.     myerr=NULL;
  358.     memset(&of,0,sizeof(UNIMOD));
  359.  
  360.     /* init panning array */
  361.  
  362.     for(t=0;t<32;t++){
  363.         of.panning[t]=((t+1)&2)?255:0;
  364.     }
  365.  
  366.     if(!ML_LoadHeader()){
  367.         ML_FreeEx(&of);
  368.         return NULL;
  369.     }
  370.  
  371.     if(!ML_LoadSamples()){
  372.         ML_FreeEx(&of);
  373.         return NULL;
  374.     }
  375.  
  376.     if(!(mf=MyCalloc(1,sizeof(UNIMOD)))){
  377.         ML_FreeEx(&of);
  378.         return NULL;
  379.     }
  380.  
  381.     /* Copy the static UNIMOD contents
  382.     into the dynamic UNIMOD struct */
  383.  
  384.     memcpy(mf,&of,sizeof(UNIMOD));
  385.  
  386.     return mf;
  387. }
  388.  
  389.  
  390.  
  391. UNIMOD *ML_LoadFN(char *filename)
  392. {
  393.     FILE *fp;
  394.     UNIMOD *mf;
  395.  
  396.     if((fp=fopen(filename,"rb"))==NULL){
  397.         myerr="Error opening file";
  398.         return NULL;
  399.     }
  400.  
  401.     mf=ML_LoadFP(fp);
  402.     fclose(fp);
  403.  
  404.     return mf;
  405. }
  406.  
  407.