added an old version of mikmod for dos
[dosdemo] / libs / oldmik / src / mloader.c
diff --git a/libs/oldmik/src/mloader.c b/libs/oldmik/src/mloader.c
new file mode 100644 (file)
index 0000000..6e135fc
--- /dev/null
@@ -0,0 +1,406 @@
+/*\r
+\r
+Name:\r
+MLOADER.C\r
+\r
+Description:\r
+These routines are used to access the available module loaders\r
+\r
+Portability:\r
+All systems - all compilers\r
+\r
+*/\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include "mikmod.h"\r
+\r
+\r
+FILE *modfp;\r
+UNIMOD of;\r
+\r
+LOADER *firstloader=NULL;\r
+\r
+\r
+UWORD finetune[16]={\r
+       8363,   8413,   8463,   8529,   8581,   8651,   8723,   8757,\r
+       7895,   7941,   7985,   8046,   8107,   8169,   8232,   8280\r
+};\r
+\r
+\r
+\r
+\r
+\r
+void ML_InfoLoader(void)\r
+{\r
+       int t;\r
+       LOADER *l;\r
+\r
+       /* list all registered devicedrivers: */\r
+\r
+       for(t=1,l=firstloader; l!=NULL; l=l->next, t++){\r
+               printf("%d. %s\n",t,l->version);\r
+       }\r
+}\r
+\r
+\r
+void ML_RegisterLoader(LOADER *ldr)\r
+{\r
+       LOADER *l;\r
+\r
+       if(firstloader==NULL){\r
+               firstloader=ldr;\r
+               ldr->next=NULL;\r
+       }\r
+       else{\r
+               ldr->next=firstloader;\r
+               firstloader=ldr;\r
+       }\r
+}\r
+\r
+\r
+\r
+void *MyMalloc(size_t size)\r
+/*\r
+       Same as malloc, but sets error variable ml_errno when it failed\r
+*/\r
+{\r
+       void *d;\r
+\r
+       d=malloc(size);\r
+       if(d==NULL){\r
+               myerr="Error allocating structure";\r
+       }\r
+       return d;\r
+}\r
+\r
+\r
+\r
+void *MyCalloc(size_t nitems,size_t size)\r
+/*\r
+       Same as calloc, but sets error variable ml_errno when it failed\r
+*/\r
+{\r
+       void *d;\r
+\r
+       d=calloc(nitems,size);\r
+       if(d==NULL){\r
+               myerr="Error allocating structure";\r
+       }\r
+       return d;\r
+}\r
+\r
+\r
+\r
+BOOL ReadComment(UWORD len)\r
+{\r
+       int t;\r
+\r
+       if(len){\r
+                if(!(of.comment=(char *)MyMalloc(len+1))) return 0;\r
+               fread(of.comment,len,1,modfp);\r
+               of.comment[len]=0;\r
+\r
+               /* strip any control-characters in the comment: */\r
+\r
+               for(t=0;t<len;t++){\r
+                       if(of.comment[t]<32) of.comment[t]=' ';\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+\r
+\r
+\r
+BOOL AllocPatterns(void)\r
+{\r
+       int s,t,tracks=0;\r
+\r
+       /* Allocate track sequencing array */\r
+\r
+       if(!(of.patterns=(UWORD *)MyCalloc((ULONG)of.numpat*of.numchn,sizeof(UWORD)))) return 0;\r
+       if(!(of.pattrows=(UWORD *)MyCalloc(of.numpat,sizeof(UWORD)))) return 0;\r
+\r
+       for(t=0;t<of.numpat;t++){\r
+\r
+               of.pattrows[t]=64;\r
+\r
+               for(s=0;s<of.numchn;s++){\r
+                       of.patterns[(t*of.numchn)+s]=tracks++;\r
+               }\r
+       }\r
+\r
+       return 1;\r
+}\r
+\r
+\r
+BOOL AllocTracks(void)\r
+{\r
+       if(!(of.tracks=(UBYTE **)MyCalloc(of.numtrk,sizeof(UBYTE *)))) return 0;\r
+       return 1;\r
+}\r
+\r
+\r
+\r
+BOOL AllocInstruments(void)\r
+{\r
+       UWORD t;\r
+\r
+       if(!(of.instruments=(INSTRUMENT *)MyCalloc(of.numins,sizeof(INSTRUMENT)))) return 0;\r
+       return 1;\r
+}\r
+\r
+\r
+BOOL AllocSamples(INSTRUMENT *i)\r
+{\r
+       UWORD u,n;\r
+\r
+       if(n=i->numsmp){\r
+               if(!(i->samples=(SAMPLE *)MyCalloc(n,sizeof(SAMPLE)))) return 0;\r
+\r
+               for(u=0; u<n; u++){\r
+                       i->samples[u].panning=128;\r
+                       i->samples[u].handle=-1;\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+\r
+\r
+char *DupStr(char *s,UWORD len)\r
+/*\r
+       Creates a CSTR out of a character buffer of 'len' bytes, but strips\r
+       any terminating non-printing characters like 0, spaces etc.\r
+*/\r
+{\r
+       UWORD t;\r
+       char *d=NULL;\r
+\r
+       /* Scan for first printing char in buffer [includes high ascii up to 254] */\r
+\r
+       while(len){\r
+               if(!(s[len-1]>=0 && s[len-1]<=0x20)) break;\r
+               len--;\r
+       }\r
+\r
+       if(len){\r
+\r
+               /* When the buffer wasn't completely empty, allocate\r
+                  a cstring and copy the buffer into that string, except\r
+                  for any control-chars */\r
+\r
+               if((d=(char *)malloc(len+1))!=NULL){\r
+                       for(t=0;t<len;t++) {\r
+                               d[t]=(s[t]>=0 && s[t]<32) ? ' ': s[t];\r
+                       }\r
+                       d[t]=0;\r
+               }\r
+       }\r
+\r
+       return d;\r
+}\r
+\r
+\r
+\r
+BOOL ML_LoadSamples(void)\r
+{\r
+       UWORD t,u;\r
+       INSTRUMENT *i;\r
+       SAMPLE *s;\r
+\r
+       for(t=0;t<of.numins;t++){\r
+\r
+               i=&of.instruments[t];\r
+\r
+               for(u=0; u<i->numsmp; u++){\r
+\r
+                       s=&i->samples[u];\r
+\r
+/*             printf("Loading Sample %d\n",t); */\r
+\r
+               /* sample has to be loaded ? -> increase\r
+                  number of samples and allocate memory and\r
+                  load sample */\r
+\r
+                       if(s->length){\r
+\r
+                               if(s->seekpos){\r
+                                       _mm_fseek(modfp,s->seekpos,SEEK_SET);\r
+                               }\r
+\r
+                               /* Call the sample load routine of the driver module.\r
+                                  It has to return a 'handle' (>=0) that identifies\r
+                                  the sample */\r
+\r
+                               s->handle=MD_SampleLoad(modfp,\r
+                                                                               s->length,\r
+                                                                               s->loopstart,\r
+                                                                               s->loopend,\r
+                                                                               s->flags);\r
+\r
+                               if(s->handle<0) return 0;\r
+                       }\r
+               }\r
+       }\r
+       return 1;\r
+}\r
+\r
+\r
+BOOL ML_LoadHeader(void)\r
+{\r
+       BOOL ok=0;\r
+       LOADER *l;\r
+\r
+       /* Try to find a loader that recognizes the module */\r
+\r
+       for(l=firstloader; l!=NULL; l=l->next){\r
+               _mm_rewind(modfp);\r
+               if(l->Test()) break;\r
+       }\r
+\r
+       if(l==NULL){\r
+               myerr="Unknown module format.";\r
+               return 0;\r
+       }\r
+\r
+       /* init unitrk routines */\r
+\r
+       if(!UniInit()) return 0;\r
+\r
+       /* init module loader */\r
+\r
+       if(l->Init()){\r
+               _mm_rewind(modfp);\r
+                ok=l->Load();\r
+       }\r
+\r
+       l->Cleanup();\r
+\r
+       /* free unitrk allocations */\r
+\r
+       UniCleanup();\r
+       return ok;\r
+}\r
+\r
+\r
+\r
+void ML_XFreeInstrument(INSTRUMENT *i)\r
+{\r
+       UWORD t;\r
+\r
+       if(i->samples!=NULL){\r
+               for(t=0; t<i->numsmp; t++){\r
+                       if(i->samples[t].handle>=0){\r
+                               MD_SampleUnLoad(i->samples[t].handle);\r
+                       }\r
+               }\r
+               free(i->samples);\r
+       }\r
+       if(i->insname!=NULL) free(i->insname);\r
+}\r
+\r
+\r
+void ML_FreeEx(UNIMOD *mf)\r
+{\r
+       UWORD t;\r
+\r
+        if(mf->modtype!=NULL) free(mf->modtype);\r
+       if(mf->patterns!=NULL) free(mf->patterns);\r
+       if(mf->pattrows!=NULL) free(mf->pattrows);\r
+\r
+       if(mf->tracks!=NULL){\r
+               for(t=0;t<mf->numtrk;t++){\r
+                       if(mf->tracks[t]!=NULL) free(mf->tracks[t]);\r
+               }\r
+               free(mf->tracks);\r
+       }\r
+\r
+       if(mf->instruments!=NULL){\r
+               for(t=0;t<mf->numins;t++){\r
+                       ML_XFreeInstrument(&mf->instruments[t]);\r
+               }\r
+               free(mf->instruments);\r
+       }\r
+\r
+       if(mf->songname!=NULL) free(mf->songname);\r
+       if(mf->comment!=NULL) free(mf->comment);\r
+}\r
+\r
+\r
+\r
+/******************************************\r
+\r
+       Next are the user-callable functions\r
+\r
+******************************************/\r
+\r
+\r
+void ML_Free(UNIMOD *mf)\r
+{\r
+       if(mf!=NULL){\r
+               ML_FreeEx(mf);\r
+               free(mf);\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+UNIMOD *ML_LoadFP(FILE *fp)\r
+{\r
+       int t;\r
+       UNIMOD *mf;\r
+\r
+       /* init fileptr, clear errorcode, clear static modfile: */\r
+\r
+       modfp=fp;\r
+       myerr=NULL;\r
+       memset(&of,0,sizeof(UNIMOD));\r
+\r
+       /* init panning array */\r
+\r
+       for(t=0;t<32;t++){\r
+               of.panning[t]=((t+1)&2)?255:0;\r
+       }\r
+\r
+       if(!ML_LoadHeader()){\r
+               ML_FreeEx(&of);\r
+               return NULL;\r
+       }\r
+\r
+       if(!ML_LoadSamples()){\r
+               ML_FreeEx(&of);\r
+               return NULL;\r
+       }\r
+\r
+       if(!(mf=(UNIMOD *)MyCalloc(1,sizeof(UNIMOD)))){\r
+               ML_FreeEx(&of);\r
+               return NULL;\r
+       }\r
+\r
+       /* Copy the static UNIMOD contents\r
+       into the dynamic UNIMOD struct */\r
+\r
+       memcpy(mf,&of,sizeof(UNIMOD));\r
+\r
+       return mf;\r
+}\r
+\r
+\r
+\r
+UNIMOD *ML_LoadFN(char *filename)\r
+{\r
+       FILE *fp;\r
+       UNIMOD *mf;\r
+\r
+       if((fp=fopen(filename,"rb"))==NULL){\r
+               myerr="Error opening file";\r
+               return NULL;\r
+       }\r
+\r
+       mf=ML_LoadFP(fp);\r
+       fclose(fp);\r
+\r
+       return mf;\r
+}\r
+\r