home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ELYVER10.ZIP / MIKXMAS.ZIP / source / mloader.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-29  |  6.3 KB  |  405 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=(char *)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=(UBYTE **)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=(INSTRUMENT *)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=(SAMPLE *)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(char *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]>=0 && s[len-1]<=0x20)) 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=(char *)malloc(len+1))!=NULL){
  193.                         for(t=0;t<len;t++) d[t]=(s[t]>=0 && 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. void ML_FreeEx(UNIMOD *mf)
  302. {
  303.     UWORD t;
  304.  
  305.         if(mf->modtype!=NULL) free(mf->modtype);
  306.     if(mf->patterns!=NULL) free(mf->patterns);
  307.     if(mf->pattrows!=NULL) free(mf->pattrows);
  308.  
  309.     if(mf->tracks!=NULL){
  310.         for(t=0;t<mf->numtrk;t++){
  311.             if(mf->tracks[t]!=NULL) free(mf->tracks[t]);
  312.         }
  313.         free(mf->tracks);
  314.     }
  315.  
  316.     if(mf->instruments!=NULL){
  317.         for(t=0;t<mf->numins;t++){
  318.             ML_XFreeInstrument(&mf->instruments[t]);
  319.         }
  320.         free(mf->instruments);
  321.     }
  322.  
  323.     if(mf->songname!=NULL) free(mf->songname);
  324.     if(mf->comment!=NULL) free(mf->comment);
  325. }
  326.  
  327.  
  328.  
  329. /******************************************
  330.  
  331.     Next are the user-callable functions
  332.  
  333. ******************************************/
  334.  
  335.  
  336. void ML_Free(UNIMOD *mf)
  337. {
  338.     if(mf!=NULL){
  339.         ML_FreeEx(mf);
  340.         free(mf);
  341.     }
  342. }
  343.  
  344.  
  345.  
  346.  
  347. UNIMOD *ML_LoadFP(FILE *fp)
  348. {
  349.     int t;
  350.     UNIMOD *mf;
  351.  
  352.     /* init fileptr, clear errorcode, clear static modfile: */
  353.  
  354.     modfp=fp;
  355.     myerr=NULL;
  356.     memset(&of,0,sizeof(UNIMOD));
  357.  
  358.     /* init panning array */
  359.  
  360.     for(t=0;t<32;t++){
  361.         of.panning[t]=((t+1)&2)?255:0;
  362.     }
  363.  
  364.     if(!ML_LoadHeader()){
  365.         ML_FreeEx(&of);
  366.         return NULL;
  367.     }
  368.  
  369.     if(!ML_LoadSamples()){
  370.         ML_FreeEx(&of);
  371.         return NULL;
  372.     }
  373.  
  374.     if(!(mf=(UNIMOD *)MyCalloc(1,sizeof(UNIMOD)))){
  375.         ML_FreeEx(&of);
  376.         return NULL;
  377.     }
  378.  
  379.     /* Copy the static UNIMOD contents
  380.     into the dynamic UNIMOD struct */
  381.  
  382.     memcpy(mf,&of,sizeof(UNIMOD));
  383.  
  384.     return mf;
  385. }
  386.  
  387.  
  388.  
  389. UNIMOD *ML_LoadFN(char *filename)
  390. {
  391.     FILE *fp;
  392.     UNIMOD *mf;
  393.  
  394.     if((fp=fopen(filename,"rb"))==NULL){
  395.         myerr="Error opening file";
  396.         return NULL;
  397.     }
  398.  
  399.     mf=ML_LoadFP(fp);
  400.     fclose(fp);
  401.  
  402.     return mf;
  403. }
  404.  
  405.