diff options
Diffstat (limited to 'apps/plugins/mikmod/mloader.c')
-rw-r--r-- | apps/plugins/mikmod/mloader.c | 615 |
1 files changed, 615 insertions, 0 deletions
diff --git a/apps/plugins/mikmod/mloader.c b/apps/plugins/mikmod/mloader.c new file mode 100644 index 0000000000..7bce40578e --- /dev/null +++ b/apps/plugins/mikmod/mloader.c | |||
@@ -0,0 +1,615 @@ | |||
1 | /* MikMod sound library | ||
2 | (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file | ||
3 | AUTHORS for complete list. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU Library General Public License as | ||
7 | published by the Free Software Foundation; either version 2 of | ||
8 | the License, or (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
18 | 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /*============================================================================== | ||
22 | |||
23 | $Id: mloader.c,v 1.3 2005/04/07 19:57:39 realtech Exp $ | ||
24 | |||
25 | These routines are used to access the available module loaders | ||
26 | |||
27 | ==============================================================================*/ | ||
28 | |||
29 | #ifdef HAVE_CONFIG_H | ||
30 | #include "config.h" | ||
31 | #endif | ||
32 | |||
33 | #ifdef HAVE_UNISTD_H | ||
34 | #include <unistd.h> | ||
35 | #endif | ||
36 | |||
37 | #ifdef HAVE_MEMORY_H | ||
38 | #include <memory.h> | ||
39 | #endif | ||
40 | #include <string.h> | ||
41 | |||
42 | #include "mikmod_internals.h" | ||
43 | |||
44 | #ifdef SUNOS | ||
45 | extern int fprintf(FILE *, const char *, ...); | ||
46 | #endif | ||
47 | |||
48 | MREADER *modreader; | ||
49 | MODULE of; | ||
50 | |||
51 | static MLOADER *firstloader=NULL; | ||
52 | |||
53 | UWORD finetune[16]={ | ||
54 | 8363,8413,8463,8529,8581,8651,8723,8757, | ||
55 | 7895,7941,7985,8046,8107,8169,8232,8280 | ||
56 | }; | ||
57 | |||
58 | MIKMODAPI CHAR* MikMod_InfoLoader(void) | ||
59 | { | ||
60 | int len=0; | ||
61 | MLOADER *l; | ||
62 | CHAR *list=NULL; | ||
63 | |||
64 | MUTEX_LOCK(lists); | ||
65 | /* compute size of buffer */ | ||
66 | for(l=firstloader;l;l=l->next) len+=1+(l->next?1:0)+strlen(l->version); | ||
67 | |||
68 | if(len) | ||
69 | if((list=MikMod_malloc(len*sizeof(CHAR)))) { | ||
70 | list[0]=0; | ||
71 | /* list all registered module loders */ | ||
72 | for(l=firstloader;l;l=l->next) | ||
73 | sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version); | ||
74 | } | ||
75 | MUTEX_UNLOCK(lists); | ||
76 | return list; | ||
77 | } | ||
78 | |||
79 | void _mm_registerloader(MLOADER* ldr) | ||
80 | { | ||
81 | MLOADER *cruise=firstloader; | ||
82 | |||
83 | if(cruise) { | ||
84 | while(cruise->next) cruise = cruise->next; | ||
85 | cruise->next=ldr; | ||
86 | } else | ||
87 | firstloader=ldr; | ||
88 | } | ||
89 | |||
90 | MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr) | ||
91 | { | ||
92 | /* if we try to register an invalid loader, or an already registered loader, | ||
93 | ignore this attempt */ | ||
94 | if ((!ldr)||(ldr->next)) | ||
95 | return; | ||
96 | |||
97 | MUTEX_LOCK(lists); | ||
98 | _mm_registerloader(ldr); | ||
99 | MUTEX_UNLOCK(lists); | ||
100 | } | ||
101 | |||
102 | int ReadComment(UWORD len) | ||
103 | { | ||
104 | if(len) { | ||
105 | int i; | ||
106 | |||
107 | if(!(of.comment=(CHAR*)MikMod_malloc(len+1))) return 0; | ||
108 | _mm_read_UBYTES(of.comment,len,modreader); | ||
109 | |||
110 | /* translate IT linefeeds */ | ||
111 | for(i=0;i<len;i++) | ||
112 | if(of.comment[i]=='\r') of.comment[i]='\n'; | ||
113 | |||
114 | of.comment[len]=0; /* just in case */ | ||
115 | } | ||
116 | if(!of.comment[0]) { | ||
117 | MikMod_free(of.comment); | ||
118 | of.comment=NULL; | ||
119 | } | ||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | int ReadLinedComment(UWORD len,UWORD linelen) | ||
124 | { | ||
125 | CHAR *tempcomment,*line,*storage; | ||
126 | UWORD total=0,t,lines; | ||
127 | int i; | ||
128 | |||
129 | lines = (len + linelen - 1) / linelen; | ||
130 | if (len) { | ||
131 | if(!(tempcomment=(CHAR*)MikMod_malloc(len+1))) return 0; | ||
132 | if(!(storage=(CHAR*)MikMod_malloc(linelen+1))) { | ||
133 | MikMod_free(tempcomment); | ||
134 | return 0; | ||
135 | } | ||
136 | memset(tempcomment, ' ', len); | ||
137 | _mm_read_UBYTES(tempcomment,len,modreader); | ||
138 | |||
139 | /* compute message length */ | ||
140 | for(line=tempcomment,total=t=0;t<lines;t++,line+=linelen) { | ||
141 | for(i=linelen;(i>=0)&&(line[i]==' ');i--) line[i]=0; | ||
142 | for(i=0;i<linelen;i++) if (!line[i]) break; | ||
143 | total+=1+i; | ||
144 | } | ||
145 | |||
146 | if(total>lines) { | ||
147 | if(!(of.comment=(CHAR*)MikMod_malloc(total+1))) { | ||
148 | MikMod_free(storage); | ||
149 | MikMod_free(tempcomment); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | /* convert message */ | ||
154 | for(line=tempcomment,t=0;t<lines;t++,line+=linelen) { | ||
155 | for(i=0;i<linelen;i++) if(!(storage[i]=line[i])) break; | ||
156 | storage[i]=0; /* if (i==linelen) */ | ||
157 | strcat(of.comment,storage);strcat(of.comment,"\r"); | ||
158 | } | ||
159 | MikMod_free(storage); | ||
160 | MikMod_free(tempcomment); | ||
161 | } | ||
162 | } | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | int AllocPositions(int total) | ||
167 | { | ||
168 | if(!total) { | ||
169 | _mm_errno=MMERR_NOT_A_MODULE; | ||
170 | return 0; | ||
171 | } | ||
172 | if(!(of.positions=MikMod_calloc(total,sizeof(UWORD)))) return 0; | ||
173 | return 1; | ||
174 | } | ||
175 | |||
176 | int AllocPatterns(void) | ||
177 | { | ||
178 | int s,t,tracks = 0; | ||
179 | |||
180 | if((!of.numpat)||(!of.numchn)) { | ||
181 | _mm_errno=MMERR_NOT_A_MODULE; | ||
182 | return 0; | ||
183 | } | ||
184 | /* Allocate track sequencing array */ | ||
185 | if(!(of.patterns=(UWORD*)MikMod_calloc((ULONG)(of.numpat+1)*of.numchn,sizeof(UWORD)))) return 0; | ||
186 | if(!(of.pattrows=(UWORD*)MikMod_calloc(of.numpat+1,sizeof(UWORD)))) return 0; | ||
187 | |||
188 | for(t=0;t<=of.numpat;t++) { | ||
189 | of.pattrows[t]=64; | ||
190 | for(s=0;s<of.numchn;s++) | ||
191 | of.patterns[(t*of.numchn)+s]=tracks++; | ||
192 | } | ||
193 | |||
194 | return 1; | ||
195 | } | ||
196 | |||
197 | int AllocTracks(void) | ||
198 | { | ||
199 | if(!of.numtrk) { | ||
200 | _mm_errno=MMERR_NOT_A_MODULE; | ||
201 | return 0; | ||
202 | } | ||
203 | if(!(of.tracks=(UBYTE **)MikMod_calloc(of.numtrk,sizeof(UBYTE *)))) return 0; | ||
204 | return 1; | ||
205 | } | ||
206 | |||
207 | int AllocInstruments(void) | ||
208 | { | ||
209 | int t,n; | ||
210 | |||
211 | if(!of.numins) { | ||
212 | _mm_errno=MMERR_NOT_A_MODULE; | ||
213 | return 0; | ||
214 | } | ||
215 | if(!(of.instruments=(INSTRUMENT*)MikMod_calloc(of.numins,sizeof(INSTRUMENT)))) | ||
216 | return 0; | ||
217 | |||
218 | for(t=0;t<of.numins;t++) { | ||
219 | for(n=0;n<INSTNOTES;n++) { | ||
220 | /* Init note / sample lookup table */ | ||
221 | of.instruments[t].samplenote[n] = n; | ||
222 | of.instruments[t].samplenumber[n] = t; | ||
223 | } | ||
224 | of.instruments[t].globvol = 64; | ||
225 | } | ||
226 | return 1; | ||
227 | } | ||
228 | |||
229 | int AllocSamples(void) | ||
230 | { | ||
231 | UWORD u; | ||
232 | |||
233 | if(!of.numsmp) { | ||
234 | _mm_errno=MMERR_NOT_A_MODULE; | ||
235 | return 0; | ||
236 | } | ||
237 | if(!(of.samples=(SAMPLE*)MikMod_calloc(of.numsmp,sizeof(SAMPLE)))) return 0; | ||
238 | |||
239 | for(u=0;u<of.numsmp;u++) { | ||
240 | of.samples[u].panning = 128; /* center */ | ||
241 | of.samples[u].handle = -1; | ||
242 | of.samples[u].globvol = 64; | ||
243 | of.samples[u].volume = 64; | ||
244 | } | ||
245 | return 1; | ||
246 | } | ||
247 | |||
248 | static int ML_LoadSamples(void) | ||
249 | { | ||
250 | SAMPLE *s; | ||
251 | int u; | ||
252 | |||
253 | for(u=of.numsmp,s=of.samples;u;u--,s++) | ||
254 | if(s->length) SL_RegisterSample(s,MD_MUSIC,modreader); | ||
255 | |||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | /* Creates a CSTR out of a character buffer of 'len' bytes, but strips any | ||
260 | terminating non-printing characters like 0, spaces etc. */ | ||
261 | CHAR *DupStr(CHAR* s,UWORD len,int strict) | ||
262 | { | ||
263 | UWORD t; | ||
264 | CHAR *d=NULL; | ||
265 | |||
266 | /* Scan for last printing char in buffer [includes high ascii up to 254] */ | ||
267 | while(len) { | ||
268 | if(s[len-1]>0x20) break; | ||
269 | len--; | ||
270 | } | ||
271 | |||
272 | /* Scan forward for possible NULL character */ | ||
273 | if(strict) { | ||
274 | for(t=0;t<len;t++) if (!s[t]) break; | ||
275 | if (t<len) len=t; | ||
276 | } | ||
277 | |||
278 | /* When the buffer wasn't completely empty, allocate a cstring and copy the | ||
279 | buffer into that string, except for any control-chars */ | ||
280 | if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1)))) { | ||
281 | for(t=0;t<len;t++) d[t]=(s[t]<32)?'.':s[t]; | ||
282 | d[len]=0; | ||
283 | } | ||
284 | return d; | ||
285 | } | ||
286 | |||
287 | CHAR *StrDup(CHAR *s) | ||
288 | { | ||
289 | size_t l = strlen(s) + 1; | ||
290 | CHAR *d = MikMod_malloc(l); | ||
291 | strcpy(d, s); | ||
292 | return d; | ||
293 | } | ||
294 | |||
295 | static void ML_XFreeSample(SAMPLE *s) | ||
296 | { | ||
297 | if(s->handle>=0) | ||
298 | MD_SampleUnload(s->handle); | ||
299 | if(s->samplename) MikMod_free(s->samplename); | ||
300 | } | ||
301 | |||
302 | static void ML_XFreeInstrument(INSTRUMENT *i) | ||
303 | { | ||
304 | if(i->insname) MikMod_free(i->insname); | ||
305 | } | ||
306 | |||
307 | static void ML_FreeEx(MODULE *mf) | ||
308 | { | ||
309 | UWORD t; | ||
310 | |||
311 | if(mf->songname) MikMod_free(mf->songname); | ||
312 | if(mf->comment) MikMod_free(mf->comment); | ||
313 | |||
314 | if(mf->modtype) MikMod_free(mf->modtype); | ||
315 | if(mf->positions) MikMod_free(mf->positions); | ||
316 | if(mf->patterns) MikMod_free(mf->patterns); | ||
317 | if(mf->pattrows) MikMod_free(mf->pattrows); | ||
318 | |||
319 | if(mf->tracks) { | ||
320 | for(t=0;t<mf->numtrk;t++) | ||
321 | if(mf->tracks[t]) MikMod_free(mf->tracks[t]); | ||
322 | MikMod_free(mf->tracks); | ||
323 | } | ||
324 | if(mf->instruments) { | ||
325 | for(t=0;t<mf->numins;t++) | ||
326 | ML_XFreeInstrument(&mf->instruments[t]); | ||
327 | MikMod_free(mf->instruments); | ||
328 | } | ||
329 | if(mf->samples) { | ||
330 | for(t=0;t<mf->numsmp;t++) | ||
331 | if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]); | ||
332 | MikMod_free(mf->samples); | ||
333 | } | ||
334 | memset(mf,0,sizeof(MODULE)); | ||
335 | if(mf!=&of) MikMod_free(mf); | ||
336 | } | ||
337 | |||
338 | static MODULE *ML_AllocUniMod(void) | ||
339 | { | ||
340 | MODULE *mf; | ||
341 | |||
342 | return (mf=MikMod_malloc(sizeof(MODULE))); | ||
343 | } | ||
344 | |||
345 | void Player_Free_internal(MODULE *mf) | ||
346 | { | ||
347 | if(mf) { | ||
348 | Player_Exit_internal(mf); | ||
349 | ML_FreeEx(mf); | ||
350 | } | ||
351 | } | ||
352 | |||
353 | MIKMODAPI void Player_Free(MODULE *mf) | ||
354 | { | ||
355 | MUTEX_LOCK(vars); | ||
356 | Player_Free_internal(mf); | ||
357 | MUTEX_UNLOCK(vars); | ||
358 | } | ||
359 | |||
360 | static CHAR* Player_LoadTitle_internal(MREADER *reader) | ||
361 | { | ||
362 | MLOADER *l; | ||
363 | |||
364 | modreader=reader; | ||
365 | _mm_errno = 0; | ||
366 | _mm_critical = 0; | ||
367 | _mm_iobase_setcur(modreader); | ||
368 | |||
369 | /* Try to find a loader that recognizes the module */ | ||
370 | for(l=firstloader;l;l=l->next) { | ||
371 | _mm_rewind(modreader); | ||
372 | if(l->Test()) break; | ||
373 | } | ||
374 | |||
375 | if(!l) { | ||
376 | _mm_errno = MMERR_NOT_A_MODULE; | ||
377 | if(_mm_errorhandler) _mm_errorhandler(); | ||
378 | return NULL; | ||
379 | } | ||
380 | |||
381 | return l->LoadTitle(); | ||
382 | } | ||
383 | |||
384 | MIKMODAPI CHAR* Player_LoadTitleFP(int fp) | ||
385 | { | ||
386 | CHAR* result=NULL; | ||
387 | MREADER* reader; | ||
388 | |||
389 | if(fp && (reader=_mm_new_file_reader(fp))) { | ||
390 | MUTEX_LOCK(lists); | ||
391 | result=Player_LoadTitle_internal(reader); | ||
392 | MUTEX_UNLOCK(lists); | ||
393 | _mm_delete_file_reader(reader); | ||
394 | } | ||
395 | return result; | ||
396 | } | ||
397 | |||
398 | MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len) | ||
399 | { | ||
400 | CHAR *result=NULL; | ||
401 | MREADER* reader; | ||
402 | |||
403 | if ((reader=_mm_new_mem_reader(buffer,len))) | ||
404 | { | ||
405 | MUTEX_LOCK(lists); | ||
406 | result=Player_LoadTitle_internal(reader); | ||
407 | MUTEX_UNLOCK(lists); | ||
408 | _mm_delete_mem_reader(reader); | ||
409 | } | ||
410 | |||
411 | |||
412 | return result; | ||
413 | } | ||
414 | |||
415 | MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader) | ||
416 | { | ||
417 | CHAR *result=NULL; | ||
418 | |||
419 | if (reader) { | ||
420 | MUTEX_LOCK(lists); | ||
421 | result=Player_LoadTitle_internal(reader); | ||
422 | MUTEX_UNLOCK(lists); | ||
423 | } | ||
424 | return result; | ||
425 | } | ||
426 | |||
427 | MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename) | ||
428 | { | ||
429 | CHAR* result=NULL; | ||
430 | int fp; | ||
431 | MREADER* reader; | ||
432 | |||
433 | if((fp=_mm_fopen(filename,"rb"))) { | ||
434 | if((reader=_mm_new_file_reader(fp))) { | ||
435 | MUTEX_LOCK(lists); | ||
436 | result=Player_LoadTitle_internal(reader); | ||
437 | MUTEX_UNLOCK(lists); | ||
438 | _mm_delete_file_reader(reader); | ||
439 | } | ||
440 | _mm_fclose(fp); | ||
441 | } | ||
442 | return result; | ||
443 | } | ||
444 | |||
445 | /* Loads a module given an reader */ | ||
446 | MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curious) | ||
447 | { | ||
448 | int t; | ||
449 | MLOADER *l; | ||
450 | int ok; | ||
451 | MODULE *mf; | ||
452 | |||
453 | modreader = reader; | ||
454 | _mm_errno = 0; | ||
455 | _mm_critical = 0; | ||
456 | _mm_iobase_setcur(modreader); | ||
457 | |||
458 | /* Try to find a loader that recognizes the module */ | ||
459 | for(l=firstloader;l;l=l->next) { | ||
460 | _mm_rewind(modreader); | ||
461 | if(l->Test()) break; | ||
462 | } | ||
463 | |||
464 | if(!l) { | ||
465 | _mm_errno = MMERR_NOT_A_MODULE; | ||
466 | if(_mm_errorhandler) _mm_errorhandler(); | ||
467 | _mm_rewind(modreader);_mm_iobase_revert(modreader); | ||
468 | return NULL; | ||
469 | } | ||
470 | |||
471 | /* init unitrk routines */ | ||
472 | if(!UniInit()) { | ||
473 | if(_mm_errorhandler) _mm_errorhandler(); | ||
474 | _mm_rewind(modreader);_mm_iobase_revert(modreader); | ||
475 | return NULL; | ||
476 | } | ||
477 | |||
478 | /* init the module structure with vanilla settings */ | ||
479 | memset(&of,0,sizeof(MODULE)); | ||
480 | of.bpmlimit = 33; | ||
481 | of.initvolume = 128; | ||
482 | for (t = 0; t < UF_MAXCHAN; t++) of.chanvol[t] = 64; | ||
483 | for (t = 0; t < UF_MAXCHAN; t++) | ||
484 | of.panning[t] = ((t + 1) & 2) ? PAN_RIGHT : PAN_LEFT; | ||
485 | |||
486 | /* init module loader and load the header / patterns */ | ||
487 | if (!l->Init || l->Init()) { | ||
488 | _mm_rewind(modreader); | ||
489 | ok = l->Load(curious); | ||
490 | if (ok) { | ||
491 | /* propagate inflags=flags for in-module samples */ | ||
492 | for (t = 0; t < of.numsmp; t++) | ||
493 | if (of.samples[t].inflags == 0) | ||
494 | of.samples[t].inflags = of.samples[t].flags; | ||
495 | } | ||
496 | } else | ||
497 | ok = 0; | ||
498 | |||
499 | /* free loader and unitrk allocations */ | ||
500 | if (l->Cleanup) l->Cleanup(); | ||
501 | UniCleanup(); | ||
502 | |||
503 | if(!ok) { | ||
504 | ML_FreeEx(&of); | ||
505 | if(_mm_errorhandler) _mm_errorhandler(); | ||
506 | _mm_rewind(modreader);_mm_iobase_revert(modreader); | ||
507 | return NULL; | ||
508 | } | ||
509 | |||
510 | if(!ML_LoadSamples()) { | ||
511 | ML_FreeEx(&of); | ||
512 | if(_mm_errorhandler) _mm_errorhandler(); | ||
513 | _mm_rewind(modreader);_mm_iobase_revert(modreader); | ||
514 | return NULL; | ||
515 | } | ||
516 | |||
517 | if(!(mf=ML_AllocUniMod())) { | ||
518 | ML_FreeEx(&of); | ||
519 | _mm_rewind(modreader);_mm_iobase_revert(modreader); | ||
520 | if(_mm_errorhandler) _mm_errorhandler(); | ||
521 | return NULL; | ||
522 | } | ||
523 | |||
524 | /* If the module doesn't have any specific panning, create a | ||
525 | MOD-like panning, with the channels half-separated. */ | ||
526 | if (!(of.flags & UF_PANNING)) | ||
527 | for (t = 0; t < of.numchn; t++) | ||
528 | of.panning[t] = ((t + 1) & 2) ? PAN_HALFRIGHT : PAN_HALFLEFT; | ||
529 | |||
530 | /* Copy the static MODULE contents into the dynamic MODULE struct. */ | ||
531 | memcpy(mf,&of,sizeof(MODULE)); | ||
532 | |||
533 | if(maxchan>0) { | ||
534 | if(!(mf->flags&UF_NNA)&&(mf->numchn<maxchan)) | ||
535 | maxchan = mf->numchn; | ||
536 | else | ||
537 | if((mf->numvoices)&&(mf->numvoices<maxchan)) | ||
538 | maxchan = mf->numvoices; | ||
539 | |||
540 | if(maxchan<mf->numchn) mf->flags |= UF_NNA; | ||
541 | |||
542 | if(MikMod_SetNumVoices_internal(maxchan,-1)) { | ||
543 | _mm_iobase_revert(modreader); | ||
544 | Player_Free(mf); | ||
545 | return NULL; | ||
546 | } | ||
547 | } | ||
548 | if(SL_LoadSamples()) { | ||
549 | _mm_iobase_revert(modreader); | ||
550 | Player_Free_internal(mf); | ||
551 | return NULL; | ||
552 | } | ||
553 | if(Player_Init(mf)) { | ||
554 | _mm_iobase_revert(modreader); | ||
555 | Player_Free_internal(mf); | ||
556 | mf=NULL; | ||
557 | } | ||
558 | _mm_iobase_revert(modreader); | ||
559 | return mf; | ||
560 | } | ||
561 | |||
562 | MIKMODAPI MODULE* Player_LoadGeneric(MREADER *reader,int maxchan,int curious) | ||
563 | { | ||
564 | MODULE* result; | ||
565 | |||
566 | MUTEX_LOCK(vars); | ||
567 | MUTEX_LOCK(lists); | ||
568 | result=Player_LoadGeneric_internal(reader,maxchan,curious); | ||
569 | MUTEX_UNLOCK(lists); | ||
570 | MUTEX_UNLOCK(vars); | ||
571 | |||
572 | return result; | ||
573 | } | ||
574 | |||
575 | MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curious) | ||
576 | { | ||
577 | MODULE* result=NULL; | ||
578 | MREADER* reader; | ||
579 | |||
580 | if ((reader=_mm_new_mem_reader(buffer, len))) { | ||
581 | result=Player_LoadGeneric(reader,maxchan,curious); | ||
582 | _mm_delete_mem_reader(reader); | ||
583 | } | ||
584 | return result; | ||
585 | } | ||
586 | |||
587 | /* Loads a module given a file pointer. | ||
588 | File is loaded from the current file seek position. */ | ||
589 | MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious) | ||
590 | { | ||
591 | MODULE* result=NULL; | ||
592 | struct MREADER* reader=_mm_new_file_reader (fp); | ||
593 | |||
594 | if (reader) { | ||
595 | result=Player_LoadGeneric(reader,maxchan,curious); | ||
596 | _mm_delete_file_reader(reader); | ||
597 | } | ||
598 | return result; | ||
599 | } | ||
600 | |||
601 | /* Open a module via its filename. The loader will initialize the specified | ||
602 | song-player 'player'. */ | ||
603 | MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,int curious) | ||
604 | { | ||
605 | int fp; | ||
606 | MODULE *mf=NULL; | ||
607 | |||
608 | if((fp=_mm_fopen(filename,"rb"))) { | ||
609 | mf=Player_LoadFP(fp,maxchan,curious); | ||
610 | _mm_fclose(fp); | ||
611 | } | ||
612 | return mf; | ||
613 | } | ||
614 | |||
615 | /* ex:set ts=4: */ | ||