summaryrefslogtreecommitdiff
path: root/apps/plugins/mikmod/load_amf.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mikmod/load_amf.c')
-rw-r--r--apps/plugins/mikmod/load_amf.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/apps/plugins/mikmod/load_amf.c b/apps/plugins/mikmod/load_amf.c
index 32067602f2..ba1f59a5be 100644
--- a/apps/plugins/mikmod/load_amf.c
+++ b/apps/plugins/mikmod/load_amf.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,8 +20,6 @@
20 20
21/*============================================================================== 21/*==============================================================================
22 22
23 $Id: load_amf.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
24
25 DMP Advanced Module Format loader 23 DMP Advanced Module Format loader
26 24
27==============================================================================*/ 25==============================================================================*/
@@ -112,9 +110,11 @@ static void AMF_Cleanup(void)
112{ 110{
113 MikMod_free(mh); 111 MikMod_free(mh);
114 MikMod_free(track); 112 MikMod_free(track);
113 mh=NULL;
114 track=NULL;
115} 115}
116 116
117static int AMF_UnpackTrack(MREADER* modreader) 117static int AMF_UnpackTrack(MREADER* r)
118{ 118{
119 ULONG tracksize; 119 ULONG tracksize;
120 UBYTE row,cmd; 120 UBYTE row,cmd;
@@ -124,20 +124,20 @@ static int AMF_UnpackTrack(MREADER* modreader)
124 memset(track,0,64*sizeof(AMFNOTE)); 124 memset(track,0,64*sizeof(AMFNOTE));
125 125
126 /* read packed track */ 126 /* read packed track */
127 if (modreader) { 127 if (r) {
128 tracksize=_mm_read_I_UWORD(modreader); 128 tracksize=_mm_read_I_UWORD(r);
129 tracksize+=((ULONG)_mm_read_UBYTE(modreader))<<16; 129 tracksize+=((ULONG)_mm_read_UBYTE(r))<<16;
130 if (tracksize) 130 if (tracksize)
131 while(tracksize--) { 131 while(tracksize--) {
132 row=_mm_read_UBYTE(modreader); 132 row=_mm_read_UBYTE(r);
133 cmd=_mm_read_UBYTE(modreader); 133 cmd=_mm_read_UBYTE(r);
134 arg=_mm_read_SBYTE(modreader); 134 arg=_mm_read_SBYTE(r);
135 /* unexpected end of track */ 135 /* unexpected end of track */
136 if(!tracksize) { 136 if(!tracksize) {
137 if((row==0xff)&&(cmd==0xff)&&(arg==-1)) 137 if((row==0xff)&&(cmd==0xff)&&(arg==-1))
138 break; 138 break;
139 /* the last triplet should be FF FF FF, but this is not 139 /* the last triplet should be FF FF FF, but this is not
140 always the case... maybe a bug in m2amf ? 140 always the case... maybe a bug in m2amf ?
141 else 141 else
142 return 0; 142 return 0;
143 */ 143 */
@@ -164,7 +164,7 @@ static int AMF_UnpackTrack(MREADER* modreader)
164 if (cmd==0x83) { 164 if (cmd==0x83) {
165 /* volume without note */ 165 /* volume without note */
166 track[row].volume=(UBYTE)arg+1; 166 track[row].volume=(UBYTE)arg+1;
167 } else 167 } else
168 if (cmd==0xff) { 168 if (cmd==0xff) {
169 /* apparently, some M2AMF version fail to estimate the 169 /* apparently, some M2AMF version fail to estimate the
170 size of the compressed patterns correctly, and end 170 size of the compressed patterns correctly, and end
@@ -322,7 +322,7 @@ static UBYTE* AMF_ConvertTrack(void)
322 of.flags |= UF_PANNING; 322 of.flags |= UF_PANNING;
323 break; 323 break;
324 } 324 }
325 325
326 } 326 }
327 if (track[row].volume) UniVolEffect(VOL_VOLUME,track[row].volume-1); 327 if (track[row].volume) UniVolEffect(VOL_VOLUME,track[row].volume-1);
328 UniNewline(); 328 UniNewline();
@@ -333,13 +333,13 @@ static UBYTE* AMF_ConvertTrack(void)
333static int AMF_Load(int curious) 333static int AMF_Load(int curious)
334{ 334{
335 int u,defaultpanning; 335 int u,defaultpanning;
336 unsigned int t,realtrackcnt,realsmpcnt; 336 unsigned int t,realtrackcnt,realsmpcnt;
337 AMFSAMPLE s; 337 AMFSAMPLE s;
338 SAMPLE *q; 338 SAMPLE *q;
339 UWORD *track_remap; 339 UWORD *track_remap;
340 ULONG samplepos; 340 ULONG samplepos, fileend;
341 int channel_remap[16]; 341 int channel_remap[16];
342 (void)curious; 342 (void)curious;
343 343
344 /* try to read module header */ 344 /* try to read module header */
345 _mm_read_UBYTES(mh->id,3,modreader); 345 _mm_read_UBYTES(mh->id,3,modreader);
@@ -386,7 +386,7 @@ static int AMF_Load(int curious)
386 of.inittempo = mh->songbpm; 386 of.inittempo = mh->songbpm;
387 AMF_Version[AMFTEXTLEN-3]='0'+(mh->version/10); 387 AMF_Version[AMFTEXTLEN-3]='0'+(mh->version/10);
388 AMF_Version[AMFTEXTLEN-1]='0'+(mh->version%10); 388 AMF_Version[AMFTEXTLEN-1]='0'+(mh->version%10);
389 of.modtype = StrDup(AMF_Version); 389 of.modtype = MikMod_strdup(AMF_Version);
390 of.numchn = mh->numchannels; 390 of.numchn = mh->numchannels;
391 of.numtrk = mh->numorders*mh->numchannels; 391 of.numtrk = mh->numorders*mh->numchannels;
392 if (mh->numtracks>of.numtrk) 392 if (mh->numtracks>of.numtrk)
@@ -400,7 +400,7 @@ static int AMF_Load(int curious)
400 /* XXX whenever possible, we should try to determine the original format. 400 /* XXX whenever possible, we should try to determine the original format.
401 Here we assume it was S3M-style wrt bpmlimit... */ 401 Here we assume it was S3M-style wrt bpmlimit... */
402 of.bpmlimit = 32; 402 of.bpmlimit = 32;
403 403
404 /* 404 /*
405 * Play with the panning table. Although the AMF format embeds a 405 * Play with the panning table. Although the AMF format embeds a
406 * panning table, if the module was a MOD or an S3M with default 406 * panning table, if the module was a MOD or an S3M with default
@@ -466,7 +466,10 @@ static int AMF_Load(int curious)
466 s.c2spd =_mm_read_I_UWORD(modreader); 466 s.c2spd =_mm_read_I_UWORD(modreader);
467 if(s.c2spd==8368) s.c2spd=8363; 467 if(s.c2spd==8368) s.c2spd=8363;
468 s.volume =_mm_read_UBYTE(modreader); 468 s.volume =_mm_read_UBYTE(modreader);
469 if(mh->version>=11) { 469 /* "the tribal zone.amf" and "the way its gonna b.amf" by Maelcum
470 * are the only version 10 files I can find, and they have 32 bit
471 * reppos and repend, not 16. */
472 if(mh->version>=10) {/* was 11 */
470 s.reppos =_mm_read_I_ULONG(modreader); 473 s.reppos =_mm_read_I_ULONG(modreader);
471 s.repend =_mm_read_I_ULONG(modreader); 474 s.repend =_mm_read_I_ULONG(modreader);
472 } else { 475 } else {
@@ -475,7 +478,7 @@ static int AMF_Load(int curious)
475 } 478 }
476 479
477 if(_mm_eof(modreader)) { 480 if(_mm_eof(modreader)) {
478 _mm_errno = MMERR_LOADING_SAMPLEINFO; 481 _mm_errno = MMERR_LOADING_SAMPLEINFO;
479 return 0; 482 return 0;
480 } 483 }
481 484
@@ -493,7 +496,7 @@ static int AMF_Load(int curious)
493 } 496 }
494 497
495 /* read track table */ 498 /* read track table */
496 if(!(track_remap=MikMod_calloc(mh->numtracks+1,sizeof(UWORD)))) 499 if(!(track_remap=(UWORD*)MikMod_calloc(mh->numtracks+1,sizeof(UWORD))))
497 return 0; 500 return 0;
498 _mm_read_I_UWORDS(track_remap+1,mh->numtracks,modreader); 501 _mm_read_I_UWORDS(track_remap+1,mh->numtracks,modreader);
499 if(_mm_eof(modreader)) { 502 if(_mm_eof(modreader)) {
@@ -505,9 +508,14 @@ static int AMF_Load(int curious)
505 for(realtrackcnt=t=0;t<=mh->numtracks;t++) 508 for(realtrackcnt=t=0;t<=mh->numtracks;t++)
506 if (realtrackcnt<track_remap[t]) 509 if (realtrackcnt<track_remap[t])
507 realtrackcnt=track_remap[t]; 510 realtrackcnt=track_remap[t];
511 if (realtrackcnt > (int)mh->numtracks) {
512 MikMod_free(track_remap);
513 _mm_errno=MMERR_NOT_A_MODULE;
514 return 0;
515 }
508 for(t=0;t<of.numpat*of.numchn;t++) 516 for(t=0;t<of.numpat*of.numchn;t++)
509 of.patterns[t]=(of.patterns[t]<=mh->numtracks)? 517 of.patterns[t]=(of.patterns[t]<=mh->numtracks)?
510 track_remap[of.patterns[t]]-1:(int)realtrackcnt; 518 track_remap[of.patterns[t]]-1:(int)realtrackcnt;
511 519
512 MikMod_free(track_remap); 520 MikMod_free(track_remap);
513 521
@@ -531,18 +539,32 @@ static int AMF_Load(int curious)
531 for(t=realtrackcnt;t<of.numtrk;t++) of.tracks[t]=NULL; 539 for(t=realtrackcnt;t<of.numtrk;t++) of.tracks[t]=NULL;
532 540
533 /* compute sample offsets */ 541 /* compute sample offsets */
542 if(_mm_eof(modreader)) goto fail;
534 samplepos=_mm_ftell(modreader); 543 samplepos=_mm_ftell(modreader);
544 _mm_fseek(modreader,0,SEEK_END);
545 fileend=_mm_ftell(modreader);
546 _mm_fseek(modreader,samplepos,SEEK_SET);
535 for(realsmpcnt=t=0;t<of.numsmp;t++) 547 for(realsmpcnt=t=0;t<of.numsmp;t++)
536 if(realsmpcnt<of.samples[t].seekpos) 548 if(realsmpcnt<of.samples[t].seekpos)
537 realsmpcnt=of.samples[t].seekpos; 549 realsmpcnt=of.samples[t].seekpos;
538 for(t=1;t<=realsmpcnt;t++) { 550 for(t=1;t<=realsmpcnt;t++) {
539 q=of.samples; 551 q=of.samples;
540 while(q->seekpos!=t) q++; 552 u=0;
553 while(q->seekpos!=t) {
554 if(++u==of.numsmp)
555 goto fail;
556 q++;
557 }
541 q->seekpos=samplepos; 558 q->seekpos=samplepos;
542 samplepos+=q->length; 559 samplepos+=q->length;
543 } 560 }
544 561 if(samplepos>fileend)
562 goto fail;
563
545 return 1; 564 return 1;
565fail:
566 _mm_errno = MMERR_LOADING_SAMPLEINFO;
567 return 0;
546} 568}
547 569
548static CHAR *AMF_LoadTitle(void) 570static CHAR *AMF_LoadTitle(void)