summaryrefslogtreecommitdiff
path: root/apps/plugins/mikmod/mloader.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mikmod/mloader.c')
-rw-r--r--apps/plugins/mikmod/mloader.c319
1 files changed, 198 insertions, 121 deletions
diff --git a/apps/plugins/mikmod/mloader.c b/apps/plugins/mikmod/mloader.c
index 5f58d8102f..9ea9489272 100644
--- a/apps/plugins/mikmod/mloader.c
+++ b/apps/plugins/mikmod/mloader.c
@@ -6,12 +6,12 @@
6 it under the terms of the GNU Library General Public License as 6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of 7 published by the Free Software Foundation; either version 2 of
8 the License, or (at your option) any later version. 8 the License, or (at your option) any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Library General Public License for more details. 13 GNU Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public 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 16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -20,7 +20,7 @@
20 20
21/*============================================================================== 21/*==============================================================================
22 22
23 $Id: mloader.c,v 1.3 2005/04/07 19:57:39 realtech Exp $ 23 $Id$
24 24
25 These routines are used to access the available module loaders 25 These routines are used to access the available module loaders
26 26
@@ -50,7 +50,17 @@ MODULE of;
50 50
51static MLOADER *firstloader=NULL; 51static MLOADER *firstloader=NULL;
52 52
53UWORD finetune[16]={ 53#ifndef NO_DEPACKERS
54static MUNPACKER unpackers[] = {
55 PP20_Unpack,
56 MMCMP_Unpack,
57 XPK_Unpack,
58 S404_Unpack,
59 NULL
60};
61#endif
62
63const UWORD finetune[16] = {
54 8363,8413,8463,8529,8581,8651,8723,8757, 64 8363,8413,8463,8529,8581,8651,8723,8757,
55 7895,7941,7985,8046,8107,8169,8232,8280 65 7895,7941,7985,8046,8107,8169,8232,8280
56}; 66};
@@ -63,15 +73,18 @@ MIKMODAPI CHAR* MikMod_InfoLoader(void)
63 73
64 MUTEX_LOCK(lists); 74 MUTEX_LOCK(lists);
65 /* compute size of buffer */ 75 /* compute size of buffer */
66 for(l=firstloader;l;l=l->next) len+=1+(l->next?1:0)+strlen(l->version); 76 for(l = firstloader; l; l = l->next)
77 len += 1 + (l->next ? 1 : 0) + strlen(l->version);
67 78
68 if(len) 79 if(len)
69 if((list=MikMod_malloc(len*sizeof(CHAR)))) { 80 if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
70 list[0]=0; 81 CHAR *list_end = list;
71 /* list all registered module loders */ 82 list[0] = 0;
72 for(l=firstloader;l;l=l->next) 83 /* list all registered module loders */
73 sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version); 84 for(l = firstloader; l; l = l->next) {
85 list_end += sprintf(list_end, "%s%s", l->version, (l->next) ? "\n" : "");
74 } 86 }
87 }
75 MUTEX_UNLOCK(lists); 88 MUTEX_UNLOCK(lists);
76 return list; 89 return list;
77} 90}
@@ -84,7 +97,7 @@ void _mm_registerloader(MLOADER* ldr)
84 while(cruise->next) cruise = cruise->next; 97 while(cruise->next) cruise = cruise->next;
85 cruise->next=ldr; 98 cruise->next=ldr;
86 } else 99 } else
87 firstloader=ldr; 100 firstloader=ldr;
88} 101}
89 102
90MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr) 103MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr)
@@ -106,7 +119,7 @@ int ReadComment(UWORD len)
106 119
107 if(!(of.comment=(CHAR*)MikMod_malloc(len+1))) return 0; 120 if(!(of.comment=(CHAR*)MikMod_malloc(len+1))) return 0;
108 _mm_read_UBYTES(of.comment,len,modreader); 121 _mm_read_UBYTES(of.comment,len,modreader);
109 122
110 /* translate IT linefeeds */ 123 /* translate IT linefeeds */
111 for(i=0;i<len;i++) 124 for(i=0;i<len;i++)
112 if(of.comment[i]=='\r') of.comment[i]='\n'; 125 if(of.comment[i]=='\r') of.comment[i]='\n';
@@ -122,44 +135,44 @@ int ReadComment(UWORD len)
122 135
123int ReadLinedComment(UWORD len,UWORD linelen) 136int ReadLinedComment(UWORD len,UWORD linelen)
124{ 137{
125 CHAR *tempcomment,*line,*storage; 138 /* Adapted from the OpenMPT project, C'ified. */
126 UWORD total=0,t,lines; 139 CHAR *buf, *storage, *p;
127 int i; 140 size_t numlines, line, fpos, cpos, lpos, cnt;
128 141
129 lines = (len + linelen - 1) / linelen; 142 if (!linelen) return 0;
130 if (len) { 143 if (!len) return 1;
131 if(!(tempcomment=(CHAR*)MikMod_malloc(len+1))) return 0; 144
132 if(!(storage=(CHAR*)MikMod_malloc(linelen+1))) { 145 if (!(buf = (CHAR *) MikMod_malloc(len))) return 0;
133 MikMod_free(tempcomment); 146 numlines = (len + linelen - 1) / linelen;
134 return 0; 147 cnt = (linelen + 1) * numlines;
135 } 148 if (!(storage = (CHAR *) MikMod_malloc(cnt + 1))) {
136 memset(tempcomment, ' ', len); 149 MikMod_free(buf);
137 _mm_read_UBYTES(tempcomment,len,modreader); 150 return 0;
138 151 }
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 152
153 /* convert message */ 153 _mm_read_UBYTES(buf,len,modreader);
154 for(line=tempcomment,t=0;t<lines;t++,line+=linelen) { 154 storage[cnt] = 0;
155 for(i=0;i<linelen;i++) if(!(storage[i]=line[i])) break; 155 for (line = 0, fpos = 0, cpos = 0; line < numlines; line++, fpos += linelen, cpos += (linelen + 1))
156 storage[i]=0; /* if (i==linelen) */ 156 {
157 strcat(of.comment,storage);strcat(of.comment,"\r"); 157 cnt = len - fpos;
158 if (cnt > linelen) cnt = linelen;
159 p = storage + cpos;
160 memcpy(p, buf + fpos, cnt);
161 p[cnt] = '\r';
162 /* fix weird chars */
163 for (lpos = 0; lpos < linelen; lpos++, p++) {
164 switch (*p) {
165 case '\0':
166 case '\n':
167 case '\r':
168 *p = ' ';
169 break;
158 } 170 }
159 MikMod_free(storage);
160 MikMod_free(tempcomment);
161 } 171 }
162 } 172 }
173
174 of.comment = storage;
175 MikMod_free(buf);
163 return 1; 176 return 1;
164} 177}
165 178
@@ -169,7 +182,7 @@ int AllocPositions(int total)
169 _mm_errno=MMERR_NOT_A_MODULE; 182 _mm_errno=MMERR_NOT_A_MODULE;
170 return 0; 183 return 0;
171 } 184 }
172 if(!(of.positions=MikMod_calloc(total,sizeof(UWORD)))) return 0; 185 if(!(of.positions=(UWORD*)MikMod_calloc(total,sizeof(UWORD)))) return 0;
173 return 1; 186 return 1;
174} 187}
175 188
@@ -207,7 +220,7 @@ int AllocTracks(void)
207int AllocInstruments(void) 220int AllocInstruments(void)
208{ 221{
209 int t,n; 222 int t,n;
210 223
211 if(!of.numins) { 224 if(!of.numins) {
212 _mm_errno=MMERR_NOT_A_MODULE; 225 _mm_errno=MMERR_NOT_A_MODULE;
213 return 0; 226 return 0;
@@ -216,11 +229,11 @@ int AllocInstruments(void)
216 return 0; 229 return 0;
217 230
218 for(t=0;t<of.numins;t++) { 231 for(t=0;t<of.numins;t++) {
219 for(n=0;n<INSTNOTES;n++) { 232 for(n=0;n<INSTNOTES;n++) {
220 /* Init note / sample lookup table */ 233 /* Init note / sample lookup table */
221 of.instruments[t].samplenote[n] = n; 234 of.instruments[t].samplenote[n] = n;
222 of.instruments[t].samplenumber[n] = t; 235 of.instruments[t].samplenumber[n] = t;
223 } 236 }
224 of.instruments[t].globvol = 64; 237 of.instruments[t].globvol = 64;
225 } 238 }
226 return 1; 239 return 1;
@@ -257,8 +270,8 @@ static int ML_LoadSamples(void)
257} 270}
258 271
259/* Creates a CSTR out of a character buffer of 'len' bytes, but strips any 272/* Creates a CSTR out of a character buffer of 'len' bytes, but strips any
260 terminating non-printing characters like 0, spaces etc. */ 273 terminating non-printing characters like 0, spaces etc. */
261CHAR *DupStr(CHAR* s,UWORD len,int strict) 274CHAR *DupStr(const CHAR* s, UWORD len, int strict)
262{ 275{
263 UWORD t; 276 UWORD t;
264 CHAR *d=NULL; 277 CHAR *d=NULL;
@@ -277,48 +290,42 @@ CHAR *DupStr(CHAR* s,UWORD len,int strict)
277 290
278 /* When the buffer wasn't completely empty, allocate a cstring and copy the 291 /* When the buffer wasn't completely empty, allocate a cstring and copy the
279 buffer into that string, except for any control-chars */ 292 buffer into that string, except for any control-chars */
280 if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1)))) { 293 if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1))) != NULL) {
281 for(t=0;t<len;t++) d[t]=(s[t]<32)?'.':s[t]; 294 for(t=0;t<len;t++) d[t]=(s[t]<32)?'.':s[t];
282 d[len]=0; 295 d[len]=0;
283 } 296 }
284 return d; 297 return d;
285} 298}
286 299
287CHAR *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
295static void ML_XFreeSample(SAMPLE *s) 300static void ML_XFreeSample(SAMPLE *s)
296{ 301{
297 if(s->handle>=0) 302 if(s->handle>=0)
298 MD_SampleUnload(s->handle); 303 MD_SampleUnload(s->handle);
299 if(s->samplename) MikMod_free(s->samplename); 304
305/* moved samplename freeing to our caller ML_FreeEx(),
306 * because we are called conditionally. */
300} 307}
301 308
302static void ML_XFreeInstrument(INSTRUMENT *i) 309static void ML_XFreeInstrument(INSTRUMENT *i)
303{ 310{
304 if(i->insname) MikMod_free(i->insname); 311 MikMod_free(i->insname);
305} 312}
306 313
307static void ML_FreeEx(MODULE *mf) 314static void ML_FreeEx(MODULE *mf)
308{ 315{
309 UWORD t; 316 UWORD t;
310 317
311 if(mf->songname) MikMod_free(mf->songname); 318 MikMod_free(mf->songname);
312 if(mf->comment) MikMod_free(mf->comment); 319 MikMod_free(mf->comment);
313 320
314 if(mf->modtype) MikMod_free(mf->modtype); 321 MikMod_free(mf->modtype);
315 if(mf->positions) MikMod_free(mf->positions); 322 MikMod_free(mf->positions);
316 if(mf->patterns) MikMod_free(mf->patterns); 323 MikMod_free(mf->patterns);
317 if(mf->pattrows) MikMod_free(mf->pattrows); 324 MikMod_free(mf->pattrows);
318 325
319 if(mf->tracks) { 326 if(mf->tracks) {
320 for(t=0;t<mf->numtrk;t++) 327 for(t=0;t<mf->numtrk;t++)
321 if(mf->tracks[t]) MikMod_free(mf->tracks[t]); 328 MikMod_free(mf->tracks[t]);
322 MikMod_free(mf->tracks); 329 MikMod_free(mf->tracks);
323 } 330 }
324 if(mf->instruments) { 331 if(mf->instruments) {
@@ -327,8 +334,10 @@ static void ML_FreeEx(MODULE *mf)
327 MikMod_free(mf->instruments); 334 MikMod_free(mf->instruments);
328 } 335 }
329 if(mf->samples) { 336 if(mf->samples) {
330 for(t=0;t<mf->numsmp;t++) 337 for(t=0;t<mf->numsmp;t++) {
338 MikMod_free(mf->samples[t].samplename);
331 if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]); 339 if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]);
340 }
332 MikMod_free(mf->samples); 341 MikMod_free(mf->samples);
333 } 342 }
334 memset(mf,0,sizeof(MODULE)); 343 memset(mf,0,sizeof(MODULE));
@@ -337,10 +346,24 @@ static void ML_FreeEx(MODULE *mf)
337 346
338static MODULE *ML_AllocUniMod(void) 347static MODULE *ML_AllocUniMod(void)
339{ 348{
340 MODULE *mf; 349 return (MODULE *) MikMod_malloc(sizeof(MODULE));
350}
351
352#ifndef NO_DEPACKERS
353static int ML_TryUnpack(MREADER *reader,void **out,long *outlen)
354{
355 int i;
341 356
342 return (mf=MikMod_malloc(sizeof(MODULE))); 357 *out = NULL;
358 *outlen = 0;
359
360 for(i=0;unpackers[i]!=NULL;++i) {
361 _mm_rewind(reader);
362 if(unpackers[i](reader,out,outlen)) return 1;
363 }
364 return 0;
343} 365}
366#endif
344 367
345static void Player_Free_internal(MODULE *mf) 368static void Player_Free_internal(MODULE *mf)
346{ 369{
@@ -360,25 +383,50 @@ MIKMODAPI void Player_Free(MODULE *mf)
360static CHAR* Player_LoadTitle_internal(MREADER *reader) 383static CHAR* Player_LoadTitle_internal(MREADER *reader)
361{ 384{
362 MLOADER *l; 385 MLOADER *l;
386 CHAR *title;
387 #ifndef NO_DEPACKERS
388 void *unpk;
389 long newlen;
390 #endif
363 391
364 modreader=reader; 392 modreader=reader;
365 _mm_errno = 0; 393 _mm_errno = 0;
366 _mm_critical = 0; 394 _mm_critical = 0;
367 _mm_iobase_setcur(modreader); 395 _mm_iobase_setcur(modreader);
368 396
397 #ifndef NO_DEPACKERS
398 if(ML_TryUnpack(modreader,&unpk,&newlen)) {
399 if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
400 modreader=reader;
401 MikMod_free(unpk);
402 return NULL;
403 }
404 }
405 #endif
406
369 /* Try to find a loader that recognizes the module */ 407 /* Try to find a loader that recognizes the module */
370 for(l=firstloader;l;l=l->next) { 408 for(l=firstloader;l;l=l->next) {
371 _mm_rewind(modreader); 409 _mm_rewind(modreader);
372 if(l->Test()) break; 410 if(l->Test()) break;
373 } 411 }
374 412
375 if(!l) { 413 if(l) {
414 title = l->LoadTitle();
415 }
416 else {
376 _mm_errno = MMERR_NOT_A_MODULE; 417 _mm_errno = MMERR_NOT_A_MODULE;
377 if(_mm_errorhandler) _mm_errorhandler(); 418 if(_mm_errorhandler) _mm_errorhandler();
378 return NULL; 419 title = NULL;
379 } 420 }
380 421
381 return l->LoadTitle(); 422 #ifndef NO_DEPACKERS
423 if (modreader!=reader) {
424 _mm_delete_mem_reader(modreader);
425 modreader=reader;
426 MikMod_free(unpk);
427 }
428 #endif
429 return title;
382} 430}
383 431
384MIKMODAPI CHAR* Player_LoadTitleFP(int fp) 432MIKMODAPI CHAR* Player_LoadTitleFP(int fp)
@@ -386,7 +434,7 @@ MIKMODAPI CHAR* Player_LoadTitleFP(int fp)
386 CHAR* result=NULL; 434 CHAR* result=NULL;
387 MREADER* reader; 435 MREADER* reader;
388 436
389 if(fp && (reader=_mm_new_file_reader(fp))) { 437 if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
390 MUTEX_LOCK(lists); 438 MUTEX_LOCK(lists);
391 result=Player_LoadTitle_internal(reader); 439 result=Player_LoadTitle_internal(reader);
392 MUTEX_UNLOCK(lists); 440 MUTEX_UNLOCK(lists);
@@ -400,22 +448,22 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
400 CHAR *result=NULL; 448 CHAR *result=NULL;
401 MREADER* reader; 449 MREADER* reader;
402 450
403 if ((reader=_mm_new_mem_reader(buffer,len))) 451 if (!buffer || len <= 0) return NULL;
452 if ((reader=_mm_new_mem_reader(buffer,len)) != NULL)
404 { 453 {
405 MUTEX_LOCK(lists); 454 MUTEX_LOCK(lists);
406 result=Player_LoadTitle_internal(reader); 455 result=Player_LoadTitle_internal(reader);
407 MUTEX_UNLOCK(lists); 456 MUTEX_UNLOCK(lists);
408 _mm_delete_mem_reader(reader); 457 _mm_delete_mem_reader(reader);
409 } 458 }
410 459
411
412 return result; 460 return result;
413} 461}
414 462
415MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader) 463MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
416{ 464{
417 CHAR *result=NULL; 465 CHAR *result=NULL;
418 466
419 if (reader) { 467 if (reader) {
420 MUTEX_LOCK(lists); 468 MUTEX_LOCK(lists);
421 result=Player_LoadTitle_internal(reader); 469 result=Player_LoadTitle_internal(reader);
@@ -424,14 +472,14 @@ MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
424 return result; 472 return result;
425} 473}
426 474
427MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename) 475MIKMODAPI CHAR* Player_LoadTitle(const CHAR* filename)
428{ 476{
429 CHAR* result=NULL; 477 CHAR* result=NULL;
430 int fp; 478 int fp;
431 MREADER* reader; 479 MREADER* reader;
432 480
433 if((fp=_mm_fopen(filename,"rb"))) { 481 if((fp=_mm_fopen(filename,"rb")) >= 0) {
434 if((reader=_mm_new_file_reader(fp))) { 482 if((reader=_mm_new_file_reader(fp)) != NULL) {
435 MUTEX_LOCK(lists); 483 MUTEX_LOCK(lists);
436 result=Player_LoadTitle_internal(reader); 484 result=Player_LoadTitle_internal(reader);
437 MUTEX_UNLOCK(lists); 485 MUTEX_UNLOCK(lists);
@@ -449,12 +497,26 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
449 MLOADER *l; 497 MLOADER *l;
450 int ok; 498 int ok;
451 MODULE *mf; 499 MODULE *mf;
500 #ifndef NO_DEPACKERS
501 void *unpk;
502 long newlen;
503 #endif
452 504
453 modreader = reader; 505 modreader = reader;
454 _mm_errno = 0; 506 _mm_errno = 0;
455 _mm_critical = 0; 507 _mm_critical = 0;
456 _mm_iobase_setcur(modreader); 508 _mm_iobase_setcur(modreader);
457 509
510 #ifndef NO_DEPACKERS
511 if(ML_TryUnpack(modreader,&unpk,&newlen)) {
512 if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
513 modreader=reader;
514 MikMod_free(unpk);
515 return NULL;
516 }
517 }
518 #endif
519
458 /* Try to find a loader that recognizes the module */ 520 /* Try to find a loader that recognizes the module */
459 for(l=firstloader;l;l=l->next) { 521 for(l=firstloader;l;l=l->next) {
460 _mm_rewind(modreader); 522 _mm_rewind(modreader);
@@ -463,15 +525,31 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
463 525
464 if(!l) { 526 if(!l) {
465 _mm_errno = MMERR_NOT_A_MODULE; 527 _mm_errno = MMERR_NOT_A_MODULE;
528 #ifndef NO_DEPACKERS
529 if(modreader!=reader) {
530 _mm_delete_mem_reader(modreader);
531 modreader=reader;
532 MikMod_free(unpk);
533 }
534 #endif
466 if(_mm_errorhandler) _mm_errorhandler(); 535 if(_mm_errorhandler) _mm_errorhandler();
467 _mm_rewind(modreader);_mm_iobase_revert(modreader); 536 _mm_rewind(modreader);
537 _mm_iobase_revert(modreader);
468 return NULL; 538 return NULL;
469 } 539 }
470 540
471 /* init unitrk routines */ 541 /* init unitrk routines */
472 if(!UniInit()) { 542 if(!UniInit()) {
543 #ifndef NO_DEPACKERS
544 if(modreader!=reader) {
545 _mm_delete_mem_reader(modreader);
546 modreader=reader;
547 MikMod_free(unpk);
548 }
549 #endif
473 if(_mm_errorhandler) _mm_errorhandler(); 550 if(_mm_errorhandler) _mm_errorhandler();
474 _mm_rewind(modreader);_mm_iobase_revert(modreader); 551 _mm_rewind(modreader);
552 _mm_iobase_revert(modreader);
475 return NULL; 553 return NULL;
476 } 554 }
477 555
@@ -487,7 +565,7 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
487 if (!l->Init || l->Init()) { 565 if (!l->Init || l->Init()) {
488 _mm_rewind(modreader); 566 _mm_rewind(modreader);
489 ok = l->Load(curious); 567 ok = l->Load(curious);
490 if (ok) { 568 if (ok) {
491 /* propagate inflags=flags for in-module samples */ 569 /* propagate inflags=flags for in-module samples */
492 for (t = 0; t < of.numsmp; t++) 570 for (t = 0; t < of.numsmp; t++)
493 if (of.samples[t].inflags == 0) 571 if (of.samples[t].inflags == 0)
@@ -500,27 +578,23 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
500 if (l->Cleanup) l->Cleanup(); 578 if (l->Cleanup) l->Cleanup();
501 UniCleanup(); 579 UniCleanup();
502 580
581 if(ok) ok = ML_LoadSamples();
582 if(ok) ok = ((mf=ML_AllocUniMod()) != NULL);
503 if(!ok) { 583 if(!ok) {
504 ML_FreeEx(&of); 584 ML_FreeEx(&of);
585 #ifndef NO_DEPACKERS
586 if(modreader!=reader) {
587 _mm_delete_mem_reader(modreader);
588 modreader=reader;
589 MikMod_free(unpk);
590 }
591 #endif
505 if(_mm_errorhandler) _mm_errorhandler(); 592 if(_mm_errorhandler) _mm_errorhandler();
506 _mm_rewind(modreader);_mm_iobase_revert(modreader); 593 _mm_rewind(modreader);
507 return NULL; 594 _mm_iobase_revert(modreader);
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; 595 return NULL;
515 } 596 }
516 597
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 598 /* If the module doesn't have any specific panning, create a
525 MOD-like panning, with the channels half-separated. */ 599 MOD-like panning, with the channels half-separated. */
526 if (!(of.flags & UF_PANNING)) 600 if (!(of.flags & UF_PANNING))
@@ -539,23 +613,25 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
539 613
540 if(maxchan<mf->numchn) mf->flags |= UF_NNA; 614 if(maxchan<mf->numchn) mf->flags |= UF_NNA;
541 615
542 if(MikMod_SetNumVoices_internal(maxchan,-1)) { 616 ok = !MikMod_SetNumVoices_internal(maxchan,-1);
543 _mm_iobase_revert(modreader);
544 Player_Free(mf);
545 return NULL;
546 }
547 } 617 }
548 if(SL_LoadSamples()) { 618
549 _mm_iobase_revert(modreader); 619 if(ok) ok = !SL_LoadSamples();
550 Player_Free_internal(mf); 620 if(ok) ok = !Player_Init(mf);
551 return NULL; 621
622 #ifndef NO_DEPACKERS
623 if(modreader!=reader) {
624 _mm_delete_mem_reader(modreader);
625 modreader=reader;
626 MikMod_free(unpk);
552 } 627 }
553 if(Player_Init(mf)) { 628 #endif
554 _mm_iobase_revert(modreader); 629 _mm_iobase_revert(modreader);
630
631 if(!ok) {
555 Player_Free_internal(mf); 632 Player_Free_internal(mf);
556 mf=NULL; 633 return NULL;
557 } 634 }
558 _mm_iobase_revert(modreader);
559 return mf; 635 return mf;
560} 636}
561 637
@@ -577,7 +653,8 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curi
577 MODULE* result=NULL; 653 MODULE* result=NULL;
578 MREADER* reader; 654 MREADER* reader;
579 655
580 if ((reader=_mm_new_mem_reader(buffer, len))) { 656 if (!buffer || len <= 0) return NULL;
657 if ((reader=_mm_new_mem_reader(buffer, len)) != NULL) {
581 result=Player_LoadGeneric(reader,maxchan,curious); 658 result=Player_LoadGeneric(reader,maxchan,curious);
582 _mm_delete_mem_reader(reader); 659 _mm_delete_mem_reader(reader);
583 } 660 }
@@ -589,9 +666,9 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curi
589MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious) 666MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious)
590{ 667{
591 MODULE* result=NULL; 668 MODULE* result=NULL;
592 struct MREADER* reader=_mm_new_file_reader (fp); 669 struct MREADER* reader;
593 670
594 if (reader) { 671 if (fp && (reader=_mm_new_file_reader(fp)) != NULL) {
595 result=Player_LoadGeneric(reader,maxchan,curious); 672 result=Player_LoadGeneric(reader,maxchan,curious);
596 _mm_delete_file_reader(reader); 673 _mm_delete_file_reader(reader);
597 } 674 }
@@ -600,12 +677,12 @@ MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious)
600 677
601/* Open a module via its filename. The loader will initialize the specified 678/* Open a module via its filename. The loader will initialize the specified
602 song-player 'player'. */ 679 song-player 'player'. */
603MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,int curious) 680MIKMODAPI MODULE* Player_Load(const CHAR* filename,int maxchan,int curious)
604{ 681{
605 int fp; 682 int fp;
606 MODULE *mf=NULL; 683 MODULE *mf=NULL;
607 684
608 if((fp=_mm_fopen(filename,"rb"))) { 685 if((fp=_mm_fopen(filename,"rb")) >= 0) {
609 mf=Player_LoadFP(fp,maxchan,curious); 686 mf=Player_LoadFP(fp,maxchan,curious);
610 _mm_fclose(fp); 687 _mm_fclose(fp);
611 } 688 }