summaryrefslogtreecommitdiff
path: root/apps/plugins/mikmod/load_it.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mikmod/load_it.c')
-rw-r--r--apps/plugins/mikmod/load_it.c184
1 files changed, 106 insertions, 78 deletions
diff --git a/apps/plugins/mikmod/load_it.c b/apps/plugins/mikmod/load_it.c
index c48d126f77..c1e257fd97 100644
--- a/apps/plugins/mikmod/load_it.c
+++ b/apps/plugins/mikmod/load_it.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: load_it.c,v 1.4 2010/01/12 03:30:32 realtech Exp $ 23 $Id$
24 24
25 Impulse tracker (IT) module loader 25 Impulse tracker (IT) module loader
26 26
@@ -45,7 +45,6 @@
45 45
46#ifdef SUNOS 46#ifdef SUNOS
47extern int fprintf(FILE *, const char *, ...); 47extern int fprintf(FILE *, const char *, ...);
48extern int toupper(int);
49#endif 48#endif
50 49
51/*========== Module structure */ 50/*========== Module structure */
@@ -67,7 +66,7 @@ typedef struct ITHEADER {
67 UBYTE initspeed; 66 UBYTE initspeed;
68 UBYTE inittempo; 67 UBYTE inittempo;
69 UBYTE pansep; /* panning separation between channels */ 68 UBYTE pansep; /* panning separation between channels */
70 UBYTE zerobyte; 69 UBYTE zerobyte;
71 UWORD msglength; 70 UWORD msglength;
72 ULONG msgoffset; 71 ULONG msgoffset;
73 UBYTE blank02[4]; 72 UBYTE blank02[4];
@@ -107,19 +106,19 @@ typedef struct ITINSTHEADER {
107 CHAR filename[12]; /* (char) Instrument filename */ 106 CHAR filename[12]; /* (char) Instrument filename */
108 UBYTE zerobyte; /* (byte) Instrument type (always 0) */ 107 UBYTE zerobyte; /* (byte) Instrument type (always 0) */
109 UBYTE volflg; 108 UBYTE volflg;
110 UBYTE volpts; 109 UBYTE volpts;
111 UBYTE volbeg; /* (byte) Volume loop start (node) */ 110 UBYTE volbeg; /* (byte) Volume loop start (node) */
112 UBYTE volend; /* (byte) Volume loop end (node) */ 111 UBYTE volend; /* (byte) Volume loop end (node) */
113 UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */ 112 UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */
114 UBYTE volsusend; /* (byte) Volume Sustain end (node) */ 113 UBYTE volsusend; /* (byte) Volume Sustain end (node) */
115 UBYTE panflg; 114 UBYTE panflg;
116 UBYTE panpts; 115 UBYTE panpts;
117 UBYTE panbeg; /* (byte) channel loop start (node) */ 116 UBYTE panbeg; /* (byte) channel loop start (node) */
118 UBYTE panend; /* (byte) channel loop end (node) */ 117 UBYTE panend; /* (byte) channel loop end (node) */
119 UBYTE pansusbeg; /* (byte) channel sustain begin (node) */ 118 UBYTE pansusbeg; /* (byte) channel sustain begin (node) */
120 UBYTE pansusend; /* (byte) channel Sustain end (node) */ 119 UBYTE pansusend; /* (byte) channel Sustain end (node) */
121 UBYTE pitflg; 120 UBYTE pitflg;
122 UBYTE pitpts; 121 UBYTE pitpts;
123 UBYTE pitbeg; /* (byte) pitch loop start (node) */ 122 UBYTE pitbeg; /* (byte) pitch loop start (node) */
124 UBYTE pitend; /* (byte) pitch loop end (node) */ 123 UBYTE pitend; /* (byte) pitch loop end (node) */
125 UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */ 124 UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */
@@ -149,7 +148,7 @@ typedef struct ITINSTHEADER {
149 UWORD pantick[ITENVCNT]; /* tick value of panning nodes */ 148 UWORD pantick[ITENVCNT]; /* tick value of panning nodes */
150 SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */ 149 SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */
151 UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */ 150 UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */
152} ITINSTHEADER; 151} ITINSTHEADER;
153 152
154/* unpacked note */ 153/* unpacked note */
155 154
@@ -166,8 +165,8 @@ static UBYTE *mask=NULL; /* arrays allocated to 64 elements and used for */
166static ITNOTE *last=NULL; /* uncompressing IT's pattern information */ 165static ITNOTE *last=NULL; /* uncompressing IT's pattern information */
167static int numtrk=0; 166static int numtrk=0;
168static unsigned int old_effect; /* if set, use S3M old-effects stuffs */ 167static unsigned int old_effect; /* if set, use S3M old-effects stuffs */
169 168
170static CHAR* IT_Version[]={ 169static const CHAR* IT_Version[]={
171 "ImpulseTracker . ", 170 "ImpulseTracker . ",
172 "Compressed ImpulseTracker . ", 171 "Compressed ImpulseTracker . ",
173 "ImpulseTracker 2.14p3", 172 "ImpulseTracker 2.14p3",
@@ -177,7 +176,7 @@ static CHAR* IT_Version[]={
177}; 176};
178 177
179/* table for porta-to-note command within volume/panning column */ 178/* table for porta-to-note command within volume/panning column */
180static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255}; 179static const UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255};
181 180
182/*========== Loader code */ 181/*========== Loader code */
183 182
@@ -212,40 +211,48 @@ static void IT_Cleanup(void)
212 MikMod_free(last); 211 MikMod_free(last);
213 MikMod_free(paraptr); 212 MikMod_free(paraptr);
214 MikMod_free(origpositions); 213 MikMod_free(origpositions);
214 mh=NULL;
215 poslookup=NULL;
216 itpat=NULL;
217 mask=NULL;
218 last=NULL;
219 paraptr=NULL;
220 origpositions=NULL;
215} 221}
216 222
217/* Because so many IT files have 64 channels as the set number used, but really 223/* Because so many IT files have 64 channels as the set number used, but really
218 only use far less (usually from 8 to 24 still), I had to make this function, 224 only use far less (usually from 8 to 24 still), I had to make this function,
219 which determines the number of channels that are actually USED by a pattern. 225 which determines the number of channels that are actually USED by a pattern.
220 226
221 NOTE: You must first seek to the file location of the pattern before calling 227 NOTE: You must first seek to the file location of the pattern before calling
222 this procedure. 228 this procedure.
223 229
224 Returns 1 on error 230 Returns 0 on error
225*/ 231*/
226static int IT_GetNumChannels(UWORD patrows) 232static int IT_GetNumChannels(UWORD patrows)
227{ 233{
228 int row=0,flag,ch; 234 int row=0,flag,ch;
229 235
230 do { 236 do {
231 if((flag=_mm_read_UBYTE(modreader))==EOF) { 237 if(_mm_eof(modreader)) {
232 _mm_errno=MMERR_LOADING_PATTERN; 238 _mm_errno=MMERR_LOADING_PATTERN;
233 return 1; 239 return 0;
234 } 240 }
241 flag=_mm_read_UBYTE(modreader);
235 if(!flag) 242 if(!flag)
236 row++; 243 row++;
237 else { 244 else {
238 ch=(flag-1)&63; 245 ch=(flag-1)&63;
239 remap[ch]=0; 246 remap[ch]=0;
240 if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader); 247 if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader);
241 if(mask[ch]&1) (void)_mm_read_UBYTE(modreader); 248 if(mask[ch]&1) _mm_skip_BYTE(modreader);
242 if(mask[ch]&2) (void)_mm_read_UBYTE(modreader); 249 if(mask[ch]&2) _mm_skip_BYTE(modreader);
243 if(mask[ch]&4) (void)_mm_read_UBYTE(modreader); 250 if(mask[ch]&4) _mm_skip_BYTE(modreader);
244 if(mask[ch]&8) { (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader); } 251 if(mask[ch]&8) { _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); }
245 } 252 }
246 } while(row<patrows); 253 } while(row<patrows);
247 254
248 return 0; 255 return 1;
249} 256}
250 257
251static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows) 258static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
@@ -282,7 +289,7 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
282 /* process volume / panning column 289 /* process volume / panning column
283 volume / panning effects do NOT all share the same memory address 290 volume / panning effects do NOT all share the same memory address
284 yet. */ 291 yet. */
285 if(volpan<=64) 292 if(volpan<=64)
286 UniVolEffect(VOL_VOLUME,volpan); 293 UniVolEffect(VOL_VOLUME,volpan);
287 else if(volpan==65) /* fine volume slide up (65-74) - A0 case */ 294 else if(volpan==65) /* fine volume slide up (65-74) - A0 case */
288 UniVolEffect(VOL_VOLSLIDE,0); 295 UniVolEffect(VOL_VOLSLIDE,0);
@@ -324,16 +331,20 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
324 331
325static int IT_ReadPattern(UWORD patrows) 332static int IT_ReadPattern(UWORD patrows)
326{ 333{
327 int row=0,flag,ch,blah; 334 int row=0,flag,ch;
335 unsigned int blah;
328 ITNOTE *itt=itpat,dummy,*n,*l; 336 ITNOTE *itt=itpat,dummy,*n,*l;
337 ITNOTE *ite=&itpat[200*64 -1];
338 UBYTE *m;
329 339
330 memset(itt,255,200*64*sizeof(ITNOTE)); 340 memset(itt,255,200*64*sizeof(ITNOTE));
331 341
332 do { 342 do {
333 if((flag=_mm_read_UBYTE(modreader))==EOF) { 343 if(_mm_eof(modreader)) {
334 _mm_errno = MMERR_LOADING_PATTERN; 344 _mm_errno = MMERR_LOADING_PATTERN;
335 return 0; 345 return 0;
336 } 346 }
347 flag=_mm_read_UBYTE(modreader);
337 if(!flag) { 348 if(!flag) {
338 itt=&itt[of.numchn]; 349 itt=&itt[of.numchn];
339 row++; 350 row++;
@@ -342,29 +353,38 @@ static int IT_ReadPattern(UWORD patrows)
342 if(ch!=-1) { 353 if(ch!=-1) {
343 n=&itt[ch]; 354 n=&itt[ch];
344 l=&last[ch]; 355 l=&last[ch];
345 } else 356 m=&mask[ch];
357 if(n > ite) { /* malformed file */
358 _mm_errno = MMERR_NOT_A_MODULE;
359 return 0;
360 }
361 } else
362 {
346 n=l=&dummy; 363 n=l=&dummy;
364 blah = 0;
365 m=(UBYTE*)&blah;
366 }
347 367
348 if(flag&128) mask[ch]=_mm_read_UBYTE(modreader); 368 if(flag&128) *m=_mm_read_UBYTE(modreader);
349 if(mask[ch]&1) 369 if(*m&1)
350 /* convert IT note off to internal note off */ 370 /* convert IT note off to internal note off */
351 if((l->note=n->note=_mm_read_UBYTE(modreader))==255) 371 if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
352 l->note=n->note=253; 372 l->note=n->note=253;
353 if(mask[ch]&2) 373 if(*m&2)
354 l->ins=n->ins=_mm_read_UBYTE(modreader); 374 l->ins=n->ins=_mm_read_UBYTE(modreader);
355 if(mask[ch]&4) 375 if(*m&4)
356 l->volpan=n->volpan=_mm_read_UBYTE(modreader); 376 l->volpan=n->volpan=_mm_read_UBYTE(modreader);
357 if(mask[ch]&8) { 377 if(*m&8) {
358 l->cmd=n->cmd=_mm_read_UBYTE(modreader); 378 l->cmd=n->cmd=_mm_read_UBYTE(modreader);
359 l->inf=n->inf=_mm_read_UBYTE(modreader); 379 l->inf=n->inf=_mm_read_UBYTE(modreader);
360 } 380 }
361 if(mask[ch]&16) 381 if(*m&16)
362 n->note=l->note; 382 n->note=l->note;
363 if(mask[ch]&32) 383 if(*m&32)
364 n->ins=l->ins; 384 n->ins=l->ins;
365 if(mask[ch]&64) 385 if(*m&64)
366 n->volpan=l->volpan; 386 n->volpan=l->volpan;
367 if(mask[ch]&128) { 387 if(*m&128) {
368 n->cmd=l->cmd; 388 n->cmd=l->cmd;
369 n->inf=l->inf; 389 n->inf=l->inf;
370 } 390 }
@@ -379,38 +399,39 @@ static int IT_ReadPattern(UWORD patrows)
379 return 1; 399 return 1;
380} 400}
381 401
382static void LoadMidiString(MREADER* modreader,CHAR* dest) 402static void LoadMidiString(MREADER* r,CHAR* dest)
383{ 403{
384 CHAR *cur,*last; 404 CHAR *curp,*lastp;
385 405
386 _mm_read_UBYTES(dest,32,modreader); 406 memset(dest,0,33*sizeof(CHAR));/* caller sends midiline[33] */
387 cur=last=dest; 407 _mm_read_UBYTES(dest,32,r);
408 curp=lastp=dest;
388 /* remove blanks and uppercase all */ 409 /* remove blanks and uppercase all */
389 while(*last) { 410 while(*lastp) {
390 if(isalnum((int)*last)) *(cur++)=toupper((int)*last); 411 if(isalnum((int)*lastp)) *(curp++)=toupper((int)*lastp);
391 last++; 412 lastp++;
392 } 413 }
393 *cur=0; 414 *curp=0;
394} 415}
395 416
396/* Load embedded midi information for resonant filters */ 417/* Load embedded midi information for resonant filters */
397static void IT_LoadMidiConfiguration(MREADER* modreader) 418static void IT_LoadMidiConfiguration(MREADER* r)
398{ 419{
399 int i; 420 int i;
400 421
401 memset(filtermacros,0,sizeof(filtermacros)); 422 memset(filtermacros,0,sizeof(filtermacros));
402 memset(filtersettings,0,sizeof(filtersettings)); 423 memset(filtersettings,0,sizeof(filtersettings));
403 424
404 if (modreader) { /* information is embedded in file */ 425 if (r) { /* information is embedded in file */
405 UWORD dat; 426 UWORD dat;
406 CHAR midiline[33]; 427 CHAR midiline[33];
407 428
408 dat=_mm_read_I_UWORD(modreader); 429 dat=_mm_read_I_UWORD(r);
409 _mm_fseek(modreader,8*dat+0x120,SEEK_CUR); 430 _mm_fseek(r,8*dat+0x120,SEEK_CUR);
410 431
411 /* read midi macros */ 432 /* read midi macros */
412 for(i=0;i<UF_MAXMACRO;i++) { 433 for(i=0;i<UF_MAXMACRO;i++) {
413 LoadMidiString(modreader,midiline); 434 LoadMidiString(r,midiline);
414 if((!strncmp(midiline,"F0F00",5))&& 435 if((!strncmp(midiline,"F0F00",5))&&
415 ((midiline[5]=='0')||(midiline[5]=='1'))) 436 ((midiline[5]=='0')||(midiline[5]=='1')))
416 filtermacros[i]=(midiline[5]-'0')|0x80; 437 filtermacros[i]=(midiline[5]-'0')|0x80;
@@ -418,7 +439,7 @@ static void IT_LoadMidiConfiguration(MREADER* modreader)
418 439
419 /* read standalone filters */ 440 /* read standalone filters */
420 for(i=0x80;i<0x100;i++) { 441 for(i=0x80;i<0x100;i++) {
421 LoadMidiString(modreader,midiline); 442 LoadMidiString(r,midiline);
422 if((!strncmp(midiline,"F0F00",5))&& 443 if((!strncmp(midiline,"F0F00",5))&&
423 ((midiline[5]=='0')||(midiline[5]=='1'))) { 444 ((midiline[5]=='0')||(midiline[5]=='1'))) {
424 filtersettings[i].filter=(midiline[5]-'0')|0x80; 445 filtersettings[i].filter=(midiline[5]-'0')|0x80;
@@ -446,7 +467,7 @@ static int IT_Load(int curious)
446 int t,u,lp; 467 int t,u,lp;
447 INSTRUMENT *d; 468 INSTRUMENT *d;
448 SAMPLE *q; 469 SAMPLE *q;
449 /* int compressed=0; */ 470 /*int compressed=0;*/
450 471
451 numtrk=0; 472 numtrk=0;
452 filters=0; 473 filters=0;
@@ -479,6 +500,10 @@ static int IT_Load(int curious)
479 _mm_errno=MMERR_LOADING_HEADER; 500 _mm_errno=MMERR_LOADING_HEADER;
480 return 0; 501 return 0;
481 } 502 }
503 if(mh->ordnum > 256 || mh->insnum > 255 || mh->smpnum > 255 || mh->patnum > 255) {
504 _mm_errno=MMERR_NOT_A_MODULE;
505 return 0;
506 }
482 507
483 /* set module variables */ 508 /* set module variables */
484 of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */ 509 of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */
@@ -506,11 +531,11 @@ static int IT_Load(int curious)
506 /* 2.16 : IT 2.14p3 with resonant filters */ 531 /* 2.16 : IT 2.14p3 with resonant filters */
507 /* 2.15 : IT 2.14p3 (improved compression) */ 532 /* 2.15 : IT 2.14p3 (improved compression) */
508 if((mh->cwt<=0x219)&&(mh->cwt>=0x217)) 533 if((mh->cwt<=0x219)&&(mh->cwt>=0x217))
509 of.modtype=StrDup(IT_Version[mh->cmwt<0x214?4:5]); 534 of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?4:5]);
510 else if (mh->cwt>=0x215) 535 else if (mh->cwt>=0x215)
511 of.modtype=StrDup(IT_Version[mh->cmwt<0x214?2:3]); 536 of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?2:3]);
512 else { 537 else {
513 of.modtype = StrDup(IT_Version[mh->cmwt<0x214?0:1]); 538 of.modtype = MikMod_strdup(IT_Version[mh->cmwt<0x214?0:1]);
514 of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0'; 539 of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0';
515 of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0'; 540 of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0';
516 of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0'; 541 of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0';
@@ -550,7 +575,7 @@ static int IT_Load(int curious)
550 575
551 /* read the order data */ 576 /* read the order data */
552 if(!AllocPositions(mh->ordnum)) return 0; 577 if(!AllocPositions(mh->ordnum)) return 0;
553 if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0; 578 if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
554 579
555 for(t=0;t<mh->ordnum;t++) { 580 for(t=0;t<mh->ordnum;t++) {
556 origpositions[t]=_mm_read_UBYTE(modreader); 581 origpositions[t]=_mm_read_UBYTE(modreader);
@@ -672,14 +697,14 @@ static int IT_Load(int curious)
672 if(s.flag&2) q->flags|=SF_16BITS; 697 if(s.flag&2) q->flags|=SF_16BITS;
673 if((s.flag&8)&&(mh->cwt>=0x214)) { 698 if((s.flag&8)&&(mh->cwt>=0x214)) {
674 q->flags|=SF_ITPACKED; 699 q->flags|=SF_ITPACKED;
675 /* compressed=1; */ 700 /*compressed=1;*/
676 } 701 }
677 if(s.flag&16) q->flags|=SF_LOOP; 702 if(s.flag&16) q->flags|=SF_LOOP;
678 if(s.flag&64) q->flags|=SF_BIDI; 703 if(s.flag&64) q->flags|=SF_BIDI;
679 704
680 if(mh->cwt>=0x200) { 705 if(mh->cwt>=0x200) {
681 if(s.convert&1) q->flags|=SF_SIGNED; 706 if(s.convert&1) q->flags|=SF_SIGNED;
682 if(s.convert&4) q->flags|=SF_DELTA; 707 if(s.convert&4) q->flags|=SF_DELTA;
683 } 708 }
684 q++; 709 q++;
685 } 710 }
@@ -726,7 +751,7 @@ static int IT_Load(int curious)
726 751
727 ih.trkvers = _mm_read_I_UWORD(modreader); 752 ih.trkvers = _mm_read_I_UWORD(modreader);
728 ih.numsmp = _mm_read_UBYTE(modreader); 753 ih.numsmp = _mm_read_UBYTE(modreader);
729 (void)_mm_read_UBYTE(modreader); 754 _mm_skip_BYTE(modreader);
730 _mm_read_string(ih.name,26,modreader); 755 _mm_read_string(ih.name,26,modreader);
731 _mm_read_UBYTES(ih.blank01,6,modreader); 756 _mm_read_UBYTES(ih.blank01,6,modreader);
732 _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader); 757 _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader);
@@ -736,13 +761,15 @@ static int IT_Load(int curious)
736 for(lp=0;lp<ITENVCNT;lp++) { 761 for(lp=0;lp<ITENVCNT;lp++) {
737 ih.oldvoltick[lp] = _mm_read_UBYTE(modreader); 762 ih.oldvoltick[lp] = _mm_read_UBYTE(modreader);
738 ih.volnode[lp] = _mm_read_UBYTE(modreader); 763 ih.volnode[lp] = _mm_read_UBYTE(modreader);
739 } 764 }
740 } else { 765 } else {
741 /* load IT 2xx volume, pan and pitch envelopes */ 766 /* load IT 2xx volume, pan and pitch envelopes */
742#if defined __STDC__ || defined _MSC_VER || defined MPW_C 767#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
743#define IT_LoadEnvelope(name,type) \ 768#define IT_LoadEnvelope(name,type) \
744 ih. name##flg =_mm_read_UBYTE(modreader); \ 769 ih. name##flg =_mm_read_UBYTE(modreader); \
745 ih. name##pts =_mm_read_UBYTE(modreader); \ 770 ih. name##pts =_mm_read_UBYTE(modreader); \
771 if (ih. name##pts > ITENVCNT) \
772 ih. name##pts = ITENVCNT; \
746 ih. name##beg =_mm_read_UBYTE(modreader); \ 773 ih. name##beg =_mm_read_UBYTE(modreader); \
747 ih. name##end =_mm_read_UBYTE(modreader); \ 774 ih. name##end =_mm_read_UBYTE(modreader); \
748 ih. name##susbeg=_mm_read_UBYTE(modreader); \ 775 ih. name##susbeg=_mm_read_UBYTE(modreader); \
@@ -751,11 +778,13 @@ static int IT_Load(int curious)
751 ih. name##node[lp]=_mm_read_##type (modreader); \ 778 ih. name##node[lp]=_mm_read_##type (modreader); \
752 ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \ 779 ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \
753 } \ 780 } \
754 (void)_mm_read_UBYTE(modreader) 781 _mm_skip_BYTE(modreader)
755#else 782#else
756#define IT_LoadEnvelope(name,type) \ 783#define IT_LoadEnvelope(name,type) \
757 ih. name/**/flg =_mm_read_UBYTE(modreader); \ 784 ih. name/**/flg =_mm_read_UBYTE(modreader); \
758 ih. name/**/pts =_mm_read_UBYTE(modreader); \ 785 ih. name/**/pts =_mm_read_UBYTE(modreader); \
786 if (ih. name/**/pts > ITENVCNT) \
787 ih. name/**/pts = ITENVCNT; \
759 ih. name/**/beg =_mm_read_UBYTE(modreader); \ 788 ih. name/**/beg =_mm_read_UBYTE(modreader); \
760 ih. name/**/end =_mm_read_UBYTE(modreader); \ 789 ih. name/**/end =_mm_read_UBYTE(modreader); \
761 ih. name/**/susbeg=_mm_read_UBYTE(modreader); \ 790 ih. name/**/susbeg=_mm_read_UBYTE(modreader); \
@@ -764,7 +793,7 @@ static int IT_Load(int curious)
764 ih. name/**/node[lp]=_mm_read_/**/type (modreader); \ 793 ih. name/**/node[lp]=_mm_read_/**/type (modreader); \
765 ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \ 794 ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \
766 } \ 795 } \
767 (void)_mm_read_UBYTE(modreader) 796 _mm_skip_BYTE(modreader)
768#endif 797#endif
769 798
770 IT_LoadEnvelope(vol,UBYTE); 799 IT_LoadEnvelope(vol,UBYTE);
@@ -772,7 +801,7 @@ static int IT_Load(int curious)
772 IT_LoadEnvelope(pit,SBYTE); 801 IT_LoadEnvelope(pit,SBYTE);
773#undef IT_LoadEnvelope 802#undef IT_LoadEnvelope
774 } 803 }
775 804
776 if(_mm_eof(modreader)) { 805 if(_mm_eof(modreader)) {
777 _mm_errno = MMERR_LOADING_SAMPLEINFO; 806 _mm_errno = MMERR_LOADING_SAMPLEINFO;
778 return 0; 807 return 0;
@@ -791,10 +820,10 @@ static int IT_Load(int curious)
791 820
792 if(ih.volflg&1) d->volflg|=EF_ON; 821 if(ih.volflg&1) d->volflg|=EF_ON;
793 if(ih.volflg&2) d->volflg|=EF_LOOP; 822 if(ih.volflg&2) d->volflg|=EF_LOOP;
794 if(ih.volflg&4) d->volflg|=EF_SUSTAIN; 823 if(ih.volflg&4) d->volflg|=EF_SUSTAIN;
795 824
796 /* XM conversion of IT envelope Array */ 825 /* XM conversion of IT envelope Array */
797 d->volbeg = ih.volbeg; 826 d->volbeg = ih.volbeg;
798 d->volend = ih.volend; 827 d->volend = ih.volend;
799 d->volsusbeg = ih.volsusbeg; 828 d->volsusbeg = ih.volsusbeg;
800 d->volsusend = ih.volsusend; 829 d->volsusend = ih.volsusend;
@@ -807,7 +836,7 @@ static int IT_Load(int curious)
807 d->volpts++; 836 d->volpts++;
808 } else 837 } else
809 break; 838 break;
810 } 839 }
811 } else { 840 } else {
812 d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2; 841 d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2;
813 if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN; 842 if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN;
@@ -827,7 +856,7 @@ static int IT_Load(int curious)
827 d->rpanvar = ih.rpanvar; 856 d->rpanvar = ih.rpanvar;
828 } 857 }
829 858
830#if defined __STDC__ || defined _MSC_VER || defined MPW_C 859#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
831#define IT_ProcessEnvelope(name) \ 860#define IT_ProcessEnvelope(name) \
832 if(ih. name##flg&1) d-> name##flg|=EF_ON; \ 861 if(ih. name##flg&1) d-> name##flg|=EF_ON; \
833 if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \ 862 if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \
@@ -862,11 +891,7 @@ static int IT_Load(int curious)
862#endif 891#endif
863 892
864 IT_ProcessEnvelope(vol); 893 IT_ProcessEnvelope(vol);
865 894
866 // Secunia SA37775
867 if (ih.volpts>= ENVPOINTS)
868 ih.volpts = ENVPOINTS-1;
869
870 for(u=0;u<ih.volpts;u++) 895 for(u=0;u<ih.volpts;u++)
871 d->volenv[u].val=(ih.volnode[u]<<2); 896 d->volenv[u].val=(ih.volnode[u]<<2);
872 897
@@ -887,7 +912,7 @@ static int IT_Load(int curious)
887#ifdef MIKMOD_DEBUG 912#ifdef MIKMOD_DEBUG
888 { 913 {
889 static int warn=0; 914 static int warn=0;
890 915
891 if(!warn) 916 if(!warn)
892 fprintf(stderr, "\rFilter envelopes not supported yet\n"); 917 fprintf(stderr, "\rFilter envelopes not supported yet\n");
893 warn=1; 918 warn=1;
@@ -908,7 +933,7 @@ static int IT_Load(int curious)
908 } 933 }
909 } 934 }
910 935
911 d++; 936 d++;
912 } 937 }
913 } else if(of.flags & UF_LINEAR) { 938 } else if(of.flags & UF_LINEAR) {
914 if(!AllocInstruments()) return 0; 939 if(!AllocInstruments()) return 0;
@@ -946,12 +971,12 @@ static int IT_Load(int curious)
946 return 0; 971 return 0;
947 } 972 }
948 _mm_read_I_ULONG(modreader); 973 _mm_read_I_ULONG(modreader);
949 if(IT_GetNumChannels(packlen)) return 0; 974 if(!IT_GetNumChannels(packlen)) return 0;
950 } 975 }
951 } 976 }
952 977
953 /* give each of them a different number */ 978 /* give each of them a different number */
954 for(t=0;t<UF_MAXCHAN;t++) 979 for(t=0;t<UF_MAXCHAN;t++)
955 if(!remap[t]) 980 if(!remap[t])
956 remap[t]=of.numchn++; 981 remap[t]=of.numchn++;
957 982
@@ -963,6 +988,8 @@ static int IT_Load(int curious)
963 if(!AllocTracks()) return 0; 988 if(!AllocTracks()) return 0;
964 989
965 for(t=0;t<of.numpat;t++) { 990 for(t=0;t<of.numpat;t++) {
991 UWORD packlen;
992
966 /* seek to pattern position */ 993 /* seek to pattern position */
967 if(!paraptr[mh->insnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */ 994 if(!paraptr[mh->insnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */
968 of.pattrows[t]=64; 995 of.pattrows[t]=64;
@@ -975,7 +1002,8 @@ static int IT_Load(int curious)
975 } 1002 }
976 } else { 1003 } else {
977 _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET); 1004 _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET);
978 (void)_mm_read_I_UWORD(modreader); 1005 packlen=_mm_read_I_UWORD(modreader);
1006 (void)packlen; /* unused */
979 of.pattrows[t]=_mm_read_I_UWORD(modreader); 1007 of.pattrows[t]=_mm_read_I_UWORD(modreader);
980 _mm_read_I_ULONG(modreader); 1008 _mm_read_I_ULONG(modreader);
981 if(!IT_ReadPattern(of.pattrows[t])) return 0; 1009 if(!IT_ReadPattern(of.pattrows[t])) return 0;
@@ -991,7 +1019,7 @@ static CHAR *IT_LoadTitle(void)
991 1019
992 _mm_fseek(modreader,4,SEEK_SET); 1020 _mm_fseek(modreader,4,SEEK_SET);
993 if(!_mm_read_UBYTES(s,26,modreader)) return NULL; 1021 if(!_mm_read_UBYTES(s,26,modreader)) return NULL;
994 1022
995 return(DupStr(s,26,0)); 1023 return(DupStr(s,26,0));
996} 1024}
997 1025