diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2020-08-08 21:56:15 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-08-11 03:29:12 +0000 |
commit | b4e70422a3455e327433a7471c929ef100ef3b10 (patch) | |
tree | e96c5431a1b22af1fcbc628322b79fb8c3162427 /apps/plugins/mikmod/load_it.c | |
parent | 8c7780bafc9eabac6b92cfe5a5a00831c3d5fd9d (diff) | |
download | rockbox-b4e70422a3455e327433a7471c929ef100ef3b10.tar.gz rockbox-b4e70422a3455e327433a7471c929ef100ef3b10.zip |
mikmod: Upgrade mikmod core from v3.2.0 to v3.3.11
* Get rid of the non-functional GT2 loader
* Add the UMX loader
* Add HQ mixer routines (and make it configurable)
* Allow samplerate to be configured at run/playtime
* Support >64KHz mixing/playback
* Correctly restore non-boost status
(The diff to upstream is much smaller now too!)
Change-Id: Iaa4ac901ba9cd4123bb225656976e78271353a72
Diffstat (limited to 'apps/plugins/mikmod/load_it.c')
-rw-r--r-- | apps/plugins/mikmod/load_it.c | 184 |
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 |
47 | extern int fprintf(FILE *, const char *, ...); | 47 | extern int fprintf(FILE *, const char *, ...); |
48 | extern 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 */ | |||
166 | static ITNOTE *last=NULL; /* uncompressing IT's pattern information */ | 165 | static ITNOTE *last=NULL; /* uncompressing IT's pattern information */ |
167 | static int numtrk=0; | 166 | static int numtrk=0; |
168 | static unsigned int old_effect; /* if set, use S3M old-effects stuffs */ | 167 | static unsigned int old_effect; /* if set, use S3M old-effects stuffs */ |
169 | 168 | ||
170 | static CHAR* IT_Version[]={ | 169 | static 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 */ |
180 | static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255}; | 179 | static 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 | */ |
226 | static int IT_GetNumChannels(UWORD patrows) | 232 | static 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 | ||
251 | static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows) | 258 | static 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 | ||
325 | static int IT_ReadPattern(UWORD patrows) | 332 | static 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 | ||
382 | static void LoadMidiString(MREADER* modreader,CHAR* dest) | 402 | static 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 */ |
397 | static void IT_LoadMidiConfiguration(MREADER* modreader) | 418 | static 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 | ||