#include #include #include #include #include #include "mtypes.h" #include "mdriver.h" #include "mloader.h" #include "munitrk.h" static LOADER *firstloader=NULL; /* void ML_InfoLoader(void) { int t; LOADER *l; for(t=1,l=firstloader; l!=NULL; l=l->next, t++){ printf("%d. %s\n",t,l->version); } } */ void pascal ML_RegisterLoader(LOADER *ldr) { LOADER *l; if(firstloader==NULL){ firstloader=ldr; ldr->next=NULL; } else{ ldr->next=firstloader; firstloader=ldr; } } void *MyMalloc(size_t size) /* Same as _mm_malloc, but sets error variable ml_errno when it failed */ { void *d; d=_mm_malloc(size); if(d==NULL){ myerr="Error allocating structure"; } return d; } void *MyCalloc(size_t nitems,size_t size) /* Same as _mm_calloc, but sets error variable ml_errno when it failed */ { void *d; d=_mm_calloc(nitems,size); if(d==NULL){ myerr="Error allocating structure"; } return d; } BOOL ReadComment(UWORD len) { int t; if(len){ if(!(oof.comment=(UBYTE *)MyMalloc(len+1))) return 0; _mm_read(modfd,oof.comment,len); oof.comment[len]=0; /* strip any control-characters in the comment: */ for(t=0;tnumsmp){ if(!(i->samples=MyCalloc(n,sizeof(SAMPLE)))) return 0; for(u=0; usamples[u].panning=128; i->samples[u].handle=-1; } } return 1; } char *DupStr(UBYTE *s,UWORD len) /* Creates a CSTR out of a character buffer of 'len' bytes, but strips any terminating non-printing characters like 0, spaces etc. */ { UWORD t; char *d=NULL; // Scan for first printing char in buffer [includes high ascii up to 254] while(len){ if(s[len-1]>0x20 && s[len-1]<0xff) break; len--; } if(len){ /* When the buffer wasn't completely empty, allocate a cstring and copy the buffer into that string, except for any control-chars */ if((d=_mm_malloc(len+1))!=NULL){ for(t=0;tnumsmp; u++){ s=&i->samples[u]; // printf("Loading Sample %d\n",t); /* sample has to be loaded ? -> increase number of samples and allocate memory and load sample */ if(s->length){ if(s->seekpos){ _mm_lseek(modfd,s->seekpos,SEEK_SET); } /* Call the sample load routine of the driver module. It has to return a 'handle' (>=0) that identifies the sample */ s->handle=MD_SampleLoad(modfd, s->length, s->loopstart, s->loopend, s->flags); if(s->handle<0) return 0; } } } return 1; } BOOL ML_LoadHeader(void) { BOOL ok=0; LOADER *l; // Try to find a loader that recognizes the module for(l=firstloader; l!=NULL; l=l->next){ if(l->Test()) break; } if(l==NULL){ myerr="Unknown module format."; return 0; } // init unitrk routines if(!UniInit()) return 0; // init module loader if(l->Init()) ok=l->Load(); l->Cleanup(); // _mm_free unitrk allocations UniCleanup(); return ok; } void ML_XFreeInstrument(INSTRUMENT *i) { UWORD t; if(i->samples!=NULL){ for(t=0; tnumsmp; t++){ if(i->samples[t].handle>=0){ MD_SampleUnLoad(i->samples[t].handle); } } _mm_free(i->samples); } if(i->insname!=NULL) _mm_free(i->insname); } void ML_FreeEx(UNIMOD *mf) { UWORD t; if(mf->modtype!=NULL) _mm_free(mf->modtype); if(mf->patterns!=NULL) _mm_free(mf->patterns); if(mf->pattrows!=NULL) _mm_free(mf->pattrows); if(mf->tracks!=NULL){ for(t=0;tnumtrk;t++){ if(mf->tracks[t]!=NULL) _mm_free(mf->tracks[t]); } _mm_free(mf->tracks); } if(mf->instruments!=NULL){ for(t=0;tnumins;t++){ ML_XFreeInstrument(&mf->instruments[t]); } _mm_free(mf->instruments); } if(mf->songname!=NULL) _mm_free(mf->songname); if(mf->comment!=NULL) _mm_free(mf->comment); } /****************************************** Next are the user-callable functions ******************************************/ void pascal ML_Free(UNIMOD *mf) { if(mf!=NULL){ ML_FreeEx(mf); _mm_free(mf); } } UNIMOD * pascal ML_LoadFD(int fhandle) { int t; UNIMOD *mf; // init fileptr, clear errorcode, clear static modfile: modfd=fhandle; myerr=NULL; _mm_memset(&oof,0,sizeof(UNIMOD)); // init panning array for(t=0;t<32;t++){ oof.panning[t]=((t+1)&2)?255:0; } if(!ML_LoadHeader()){ ML_FreeEx(&oof); return NULL; } if(!ML_LoadSamples()){ ML_FreeEx(&oof); return NULL; } if(!(mf=MyCalloc(1,sizeof(UNIMOD)))){ ML_FreeEx(&oof); return NULL; } /* Copy the static UNIMOD contents into the dynamic UNIMOD struct */ _mm_memcpy(mf,&oof,sizeof(UNIMOD)); return mf; } UNIMOD * pascal ML_LoadFN(char *filename) { int fd; UNIMOD *mf; if((fd=_mm_open(filename,0))<0){ myerr="Error opening file"; return NULL; } mf=ML_LoadFD(fd); _mm_close(fd); return mf; }