7 These routines are used to access the available module loaders
\r
10 All systems - all compilers
\r
22 LOADER *firstloader=NULL;
\r
25 UWORD finetune[16]={
\r
26 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757,
\r
27 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280
\r
34 void ML_InfoLoader(void)
\r
39 /* list all registered devicedrivers: */
\r
41 for(t=1,l=firstloader; l!=NULL; l=l->next, t++){
\r
42 printf("%d. %s\n",t,l->version);
\r
47 void ML_RegisterLoader(LOADER *ldr)
\r
51 if(firstloader==NULL){
\r
56 ldr->next=firstloader;
\r
63 void *MyMalloc(size_t size)
\r
65 Same as malloc, but sets error variable ml_errno when it failed
\r
72 myerr="Error allocating structure";
\r
79 void *MyCalloc(size_t nitems,size_t size)
\r
81 Same as calloc, but sets error variable ml_errno when it failed
\r
86 d=calloc(nitems,size);
\r
88 myerr="Error allocating structure";
\r
95 BOOL ReadComment(UWORD len)
\r
100 if(!(of.comment=(char *)MyMalloc(len+1))) return 0;
\r
101 fread(of.comment,len,1,modfp);
\r
104 /* strip any control-characters in the comment: */
\r
106 for(t=0;t<len;t++){
\r
107 if(of.comment[t]<32) of.comment[t]=' ';
\r
115 BOOL AllocPatterns(void)
\r
119 /* Allocate track sequencing array */
\r
121 if(!(of.patterns=(UWORD *)MyCalloc((ULONG)of.numpat*of.numchn,sizeof(UWORD)))) return 0;
\r
122 if(!(of.pattrows=(UWORD *)MyCalloc(of.numpat,sizeof(UWORD)))) return 0;
\r
124 for(t=0;t<of.numpat;t++){
\r
128 for(s=0;s<of.numchn;s++){
\r
129 of.patterns[(t*of.numchn)+s]=tracks++;
\r
137 BOOL AllocTracks(void)
\r
139 if(!(of.tracks=(UBYTE **)MyCalloc(of.numtrk,sizeof(UBYTE *)))) return 0;
\r
145 BOOL AllocInstruments(void)
\r
149 if(!(of.instruments=(INSTRUMENT *)MyCalloc(of.numins,sizeof(INSTRUMENT)))) return 0;
\r
154 BOOL AllocSamples(INSTRUMENT *i)
\r
159 if(!(i->samples=(SAMPLE *)MyCalloc(n,sizeof(SAMPLE)))) return 0;
\r
161 for(u=0; u<n; u++){
\r
162 i->samples[u].panning=128;
\r
163 i->samples[u].handle=-1;
\r
170 char *DupStr(char *s,UWORD len)
\r
172 Creates a CSTR out of a character buffer of 'len' bytes, but strips
\r
173 any terminating non-printing characters like 0, spaces etc.
\r
179 /* Scan for first printing char in buffer [includes high ascii up to 254] */
\r
182 if(!(s[len-1]>=0 && s[len-1]<=0x20)) break;
\r
188 /* When the buffer wasn't completely empty, allocate
\r
189 a cstring and copy the buffer into that string, except
\r
190 for any control-chars */
\r
192 if((d=(char *)malloc(len+1))!=NULL){
\r
193 for(t=0;t<len;t++) d[t]=(s[t]>=0 && s[t]<32) ? ' ': s[t];
\r
203 BOOL ML_LoadSamples(void)
\r
209 for(t=0;t<of.numins;t++){
\r
211 i=&of.instruments[t];
\r
213 for(u=0; u<i->numsmp; u++){
\r
217 /* printf("Loading Sample %d\n",t); */
\r
219 /* sample has to be loaded ? -> increase
\r
220 number of samples and allocate memory and
\r
226 _mm_fseek(modfp,s->seekpos,SEEK_SET);
\r
229 /* Call the sample load routine of the driver module.
\r
230 It has to return a 'handle' (>=0) that identifies
\r
233 s->handle=MD_SampleLoad(modfp,
\r
239 if(s->handle<0) return 0;
\r
247 BOOL ML_LoadHeader(void)
\r
252 /* Try to find a loader that recognizes the module */
\r
254 for(l=firstloader; l!=NULL; l=l->next){
\r
256 if(l->Test()) break;
\r
260 myerr="Unknown module format.";
\r
264 /* init unitrk routines */
\r
266 if(!UniInit()) return 0;
\r
268 /* init module loader */
\r
277 /* free unitrk allocations */
\r
285 void ML_XFreeInstrument(INSTRUMENT *i)
\r
289 if(i->samples!=NULL){
\r
290 for(t=0; t<i->numsmp; t++){
\r
291 if(i->samples[t].handle>=0){
\r
292 MD_SampleUnLoad(i->samples[t].handle);
\r
297 if(i->insname!=NULL) free(i->insname);
\r
301 void ML_FreeEx(UNIMOD *mf)
\r
305 if(mf->modtype!=NULL) free(mf->modtype);
\r
306 if(mf->patterns!=NULL) free(mf->patterns);
\r
307 if(mf->pattrows!=NULL) free(mf->pattrows);
\r
309 if(mf->tracks!=NULL){
\r
310 for(t=0;t<mf->numtrk;t++){
\r
311 if(mf->tracks[t]!=NULL) free(mf->tracks[t]);
\r
316 if(mf->instruments!=NULL){
\r
317 for(t=0;t<mf->numins;t++){
\r
318 ML_XFreeInstrument(&mf->instruments[t]);
\r
320 free(mf->instruments);
\r
323 if(mf->songname!=NULL) free(mf->songname);
\r
324 if(mf->comment!=NULL) free(mf->comment);
\r
329 /******************************************
\r
331 Next are the user-callable functions
\r
333 ******************************************/
\r
336 void ML_Free(UNIMOD *mf)
\r
347 UNIMOD *ML_LoadFP(FILE *fp)
\r
352 /* init fileptr, clear errorcode, clear static modfile: */
\r
356 memset(&of,0,sizeof(UNIMOD));
\r
358 /* init panning array */
\r
361 of.panning[t]=((t+1)&2)?255:0;
\r
364 if(!ML_LoadHeader()){
\r
369 if(!ML_LoadSamples()){
\r
374 if(!(mf=(UNIMOD *)MyCalloc(1,sizeof(UNIMOD)))){
\r
379 /* Copy the static UNIMOD contents
\r
380 into the dynamic UNIMOD struct */
\r
382 memcpy(mf,&of,sizeof(UNIMOD));
\r
389 UNIMOD *ML_LoadFN(char *filename)
\r
394 if((fp=fopen(filename,"rb"))==NULL){
\r
395 myerr="Error opening file";
\r