diff options
Diffstat (limited to 'apps/plugins/mikmod/mloader.c')
-rw-r--r-- | apps/plugins/mikmod/mloader.c | 319 |
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 | ||
51 | static MLOADER *firstloader=NULL; | 51 | static MLOADER *firstloader=NULL; |
52 | 52 | ||
53 | UWORD finetune[16]={ | 53 | #ifndef NO_DEPACKERS |
54 | static MUNPACKER unpackers[] = { | ||
55 | PP20_Unpack, | ||
56 | MMCMP_Unpack, | ||
57 | XPK_Unpack, | ||
58 | S404_Unpack, | ||
59 | NULL | ||
60 | }; | ||
61 | #endif | ||
62 | |||
63 | const 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 | ||
90 | MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr) | 103 | MIKMODAPI 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 | ||
123 | int ReadLinedComment(UWORD len,UWORD linelen) | 136 | int 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) | |||
207 | int AllocInstruments(void) | 220 | int 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. */ |
261 | CHAR *DupStr(CHAR* s,UWORD len,int strict) | 274 | CHAR *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 | ||
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) | 300 | static 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 | ||
302 | static void ML_XFreeInstrument(INSTRUMENT *i) | 309 | static void ML_XFreeInstrument(INSTRUMENT *i) |
303 | { | 310 | { |
304 | if(i->insname) MikMod_free(i->insname); | 311 | MikMod_free(i->insname); |
305 | } | 312 | } |
306 | 313 | ||
307 | static void ML_FreeEx(MODULE *mf) | 314 | static 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 | ||
338 | static MODULE *ML_AllocUniMod(void) | 347 | static MODULE *ML_AllocUniMod(void) |
339 | { | 348 | { |
340 | MODULE *mf; | 349 | return (MODULE *) MikMod_malloc(sizeof(MODULE)); |
350 | } | ||
351 | |||
352 | #ifndef NO_DEPACKERS | ||
353 | static 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 | ||
345 | static void Player_Free_internal(MODULE *mf) | 368 | static void Player_Free_internal(MODULE *mf) |
346 | { | 369 | { |
@@ -360,25 +383,50 @@ MIKMODAPI void Player_Free(MODULE *mf) | |||
360 | static CHAR* Player_LoadTitle_internal(MREADER *reader) | 383 | static 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 | ||
384 | MIKMODAPI CHAR* Player_LoadTitleFP(int fp) | 432 | MIKMODAPI 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 | ||
415 | MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader) | 463 | MIKMODAPI 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 | ||
427 | MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename) | 475 | MIKMODAPI 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 | |||
589 | MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious) | 666 | MIKMODAPI 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'. */ |
603 | MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,int curious) | 680 | MIKMODAPI 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 | } |