home *** CD-ROM | disk | FTP | other *** search
/ PC Loisirs 18 / cd.iso / sharewar / mikm202 / source / mloader.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-18  |  6.0 KB  |  393 lines

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