diff options
Diffstat (limited to 'apps/plugins')
42 files changed, 5082 insertions, 2852 deletions
diff --git a/apps/plugins/mikmod/SOURCES b/apps/plugins/mikmod/SOURCES index 1de5bb2149..bea10f9a29 100644 --- a/apps/plugins/mikmod/SOURCES +++ b/apps/plugins/mikmod/SOURCES | |||
@@ -5,7 +5,6 @@ load_asy.c | |||
5 | load_dsm.c | 5 | load_dsm.c |
6 | load_far.c | 6 | load_far.c |
7 | load_gdm.c | 7 | load_gdm.c |
8 | load_gt2.c | ||
9 | load_imf.c | 8 | load_imf.c |
10 | load_it.c | 9 | load_it.c |
11 | load_m15.c | 10 | load_m15.c |
@@ -17,6 +16,7 @@ load_s3m.c | |||
17 | load_stm.c | 16 | load_stm.c |
18 | load_stx.c | 17 | load_stx.c |
19 | load_ult.c | 18 | load_ult.c |
19 | load_umx.c | ||
20 | load_uni.c | 20 | load_uni.c |
21 | load_xm.c | 21 | load_xm.c |
22 | mdreg.c | 22 | mdreg.c |
@@ -34,6 +34,7 @@ sloader.c | |||
34 | strdup.c | 34 | strdup.c |
35 | strstr.c | 35 | strstr.c |
36 | virtch.c | 36 | virtch.c |
37 | virtch2.c | ||
37 | virtch_common.c | 38 | virtch_common.c |
38 | mikmod.c | 39 | mikmod.c |
39 | 40 | ||
diff --git a/apps/plugins/mikmod/load_669.c b/apps/plugins/mikmod/load_669.c index 000e51d985..0872043f65 100644 --- a/apps/plugins/mikmod/load_669.c +++ b/apps/plugins/mikmod/load_669.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_669.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id: $ |
24 | 24 | ||
25 | Composer 669 module loader | 25 | Composer 669 module loader |
26 | 26 | ||
@@ -49,11 +49,11 @@ extern int fprintf(FILE *, const char *, ...); | |||
49 | /*========== Module structure */ | 49 | /*========== Module structure */ |
50 | 50 | ||
51 | /* header */ | 51 | /* header */ |
52 | typedef struct S69HEADER { | 52 | typedef struct S69HEADER { |
53 | UBYTE marker[2]; | 53 | UBYTE marker[2]; |
54 | CHAR message[108]; | 54 | CHAR message[108]; |
55 | UBYTE nos; | 55 | UBYTE nos; |
56 | UBYTE rbnop; | 56 | UBYTE RBnop; |
57 | UBYTE looporder; | 57 | UBYTE looporder; |
58 | UBYTE orders[0x80]; | 58 | UBYTE orders[0x80]; |
59 | UBYTE tempos[0x80]; | 59 | UBYTE tempos[0x80]; |
@@ -81,7 +81,7 @@ static S69NOTE* s69pat=NULL; | |||
81 | static S69HEADER* mh=NULL; | 81 | static S69HEADER* mh=NULL; |
82 | 82 | ||
83 | /* file type identification */ | 83 | /* file type identification */ |
84 | static CHAR* S69_Version[]={ | 84 | static const CHAR* S69_Version[]={ |
85 | "Composer 669", | 85 | "Composer 669", |
86 | "Extended 669" | 86 | "Extended 669" |
87 | }; | 87 | }; |
@@ -134,6 +134,8 @@ static void S69_Cleanup(void) | |||
134 | { | 134 | { |
135 | MikMod_free(s69pat); | 135 | MikMod_free(s69pat); |
136 | MikMod_free(mh); | 136 | MikMod_free(mh); |
137 | mh=NULL; | ||
138 | s69pat=NULL; | ||
137 | } | 139 | } |
138 | 140 | ||
139 | static int S69_LoadPatterns(void) | 141 | static int S69_LoadPatterns(void) |
@@ -142,7 +144,7 @@ static int S69_LoadPatterns(void) | |||
142 | UBYTE note,inst,vol,effect,lastfx,lastval; | 144 | UBYTE note,inst,vol,effect,lastfx,lastval; |
143 | S69NOTE *cur; | 145 | S69NOTE *cur; |
144 | int tracks=0; | 146 | int tracks=0; |
145 | 147 | ||
146 | if(!AllocPatterns()) return 0; | 148 | if(!AllocPatterns()) return 0; |
147 | if(!AllocTracks()) return 0; | 149 | if(!AllocTracks()) return 0; |
148 | 150 | ||
@@ -226,7 +228,7 @@ static int S69_LoadPatterns(void) | |||
226 | case 5: /* set speed */ | 228 | case 5: /* set speed */ |
227 | if (effect) | 229 | if (effect) |
228 | UniPTEffect(0xf,effect); | 230 | UniPTEffect(0xf,effect); |
229 | else | 231 | else |
230 | if(mh->marker[0]!=0x69) { | 232 | if(mh->marker[0]!=0x69) { |
231 | #ifdef MIKMOD_DEBUG | 233 | #ifdef MIKMOD_DEBUG |
232 | fprintf(stderr,"\r669: unsupported super fast tempo at pat=%d row=%d chan=%d\n", | 234 | fprintf(stderr,"\r669: unsupported super fast tempo at pat=%d row=%d chan=%d\n", |
@@ -250,13 +252,13 @@ static int S69_Load(int curious) | |||
250 | int i; | 252 | int i; |
251 | SAMPLE *current; | 253 | SAMPLE *current; |
252 | S69SAMPLE sample; | 254 | S69SAMPLE sample; |
253 | (void)curious; | 255 | (void)curious; |
254 | 256 | ||
255 | /* module header */ | 257 | /* module header */ |
256 | _mm_read_UBYTES(mh->marker,2,modreader); | 258 | _mm_read_UBYTES(mh->marker,2,modreader); |
257 | _mm_read_UBYTES(mh->message,108,modreader); | 259 | _mm_read_UBYTES(mh->message,108,modreader); |
258 | mh->nos=_mm_read_UBYTE(modreader); | 260 | mh->nos=_mm_read_UBYTE(modreader); |
259 | mh->rbnop=_mm_read_UBYTE(modreader); | 261 | mh->RBnop=_mm_read_UBYTE(modreader); |
260 | mh->looporder=_mm_read_UBYTE(modreader); | 262 | mh->looporder=_mm_read_UBYTE(modreader); |
261 | _mm_read_UBYTES(mh->orders,0x80,modreader); | 263 | _mm_read_UBYTES(mh->orders,0x80,modreader); |
262 | for(i=0;i<0x80;i++) | 264 | for(i=0;i<0x80;i++) |
@@ -281,9 +283,9 @@ static int S69_Load(int curious) | |||
281 | of.initspeed=4; | 283 | of.initspeed=4; |
282 | of.inittempo=78; | 284 | of.inittempo=78; |
283 | of.songname=DupStr(mh->message,36,1); | 285 | of.songname=DupStr(mh->message,36,1); |
284 | of.modtype=StrDup(S69_Version[memcmp(mh->marker,"JN",2)==0]); | 286 | of.modtype=MikMod_strdup(S69_Version[memcmp(mh->marker,"JN",2)==0]); |
285 | of.numchn=8; | 287 | of.numchn=8; |
286 | of.numpat=mh->rbnop; | 288 | of.numpat=mh->RBnop; |
287 | of.numins=of.numsmp=mh->nos; | 289 | of.numins=of.numsmp=mh->nos; |
288 | of.numtrk=of.numchn*of.numpat; | 290 | of.numtrk=of.numchn*of.numpat; |
289 | of.flags=UF_XMPERIODS|UF_LINEAR; | 291 | of.flags=UF_XMPERIODS|UF_LINEAR; |
@@ -292,7 +294,7 @@ static int S69_Load(int curious) | |||
292 | for(i=36+35;(i>=36+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; | 294 | for(i=36+35;(i>=36+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; |
293 | for(i=72+35;(i>=72+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; | 295 | for(i=72+35;(i>=72+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; |
294 | if((mh->message[0])||(mh->message[36])||(mh->message[72])) | 296 | if((mh->message[0])||(mh->message[36])||(mh->message[72])) |
295 | if((of.comment=(CHAR*)MikMod_malloc(3*(36+1)+1))) { | 297 | if((of.comment=(CHAR*)MikMod_malloc(3*(36+1)+1)) != NULL) { |
296 | strncpy(of.comment,mh->message,36); | 298 | strncpy(of.comment,mh->message,36); |
297 | strcat(of.comment,"\r"); | 299 | strcat(of.comment,"\r"); |
298 | if (mh->message[36]) strncat(of.comment,mh->message+36,36); | 300 | if (mh->message[36]) strncat(of.comment,mh->message+36,36); |
@@ -304,7 +306,7 @@ static int S69_Load(int curious) | |||
304 | 306 | ||
305 | if(!AllocPositions(0x80)) return 0; | 307 | if(!AllocPositions(0x80)) return 0; |
306 | for(i=0;i<0x80;i++) { | 308 | for(i=0;i<0x80;i++) { |
307 | if(mh->orders[i]>=mh->rbnop) break; | 309 | if(mh->orders[i]>=mh->RBnop) break; |
308 | of.positions[i]=mh->orders[i]; | 310 | of.positions[i]=mh->orders[i]; |
309 | } | 311 | } |
310 | of.numpos=i; | 312 | of.numpos=i; |
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 | ||
117 | static int AMF_UnpackTrack(MREADER* modreader) | 117 | static 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) | |||
333 | static int AMF_Load(int curious) | 333 | static 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; |
565 | fail: | ||
566 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | ||
567 | return 0; | ||
546 | } | 568 | } |
547 | 569 | ||
548 | static CHAR *AMF_LoadTitle(void) | 570 | static CHAR *AMF_LoadTitle(void) |
diff --git a/apps/plugins/mikmod/load_asy.c b/apps/plugins/mikmod/load_asy.c index 46e899f6bd..48d746c8e8 100644 --- a/apps/plugins/mikmod/load_asy.c +++ b/apps/plugins/mikmod/load_asy.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,15 +20,15 @@ | |||
20 | 20 | ||
21 | /*============================================================================== | 21 | /*============================================================================== |
22 | 22 | ||
23 | $Id: load_asy.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | ASYLUM Music Format v1.0 (.amf) loader | 25 | ASYLUM Music Format v1.0 (.amf) loader |
26 | adapted from load_mod.c by Raphael Assenat <raph@raphnet.net>, | 26 | adapted from load_mod.c by Raphael Assenat <raph@raphnet.net>, |
27 | with the help of the AMF2MOD utility sourcecode, | 27 | with the help of the AMF2MOD utility sourcecode, |
28 | written to convert crusader's amf files into 8 | 28 | written to convert crusader's amf files into 8 |
29 | channels mod file in 1995 by Mr. P / Powersource | 29 | channels mod file in 1995 by Mr. P / Powersource |
30 | mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca | 30 | mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca |
31 | 31 | ||
32 | 32 | ||
33 | ==============================================================================*/ | 33 | ==============================================================================*/ |
34 | 34 | ||
@@ -76,8 +76,9 @@ typedef struct MODNOTE { | |||
76 | 76 | ||
77 | /* This table is taken from AMF2MOD.C | 77 | /* This table is taken from AMF2MOD.C |
78 | * written in 1995 by Mr. P / Powersource | 78 | * written in 1995 by Mr. P / Powersource |
79 | * mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca */ | 79 | * mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca */ |
80 | UWORD periodtable[]={6848,6464,6096,5760,5424,5120,4832,4560,4304, | 80 | static const UWORD periodtable[] = { |
81 | 6848,6464,6096,5760,5424,5120,4832,4560,4304, | ||
81 | 4064,3840,3628,3424,3232,3048,2880,2712,2560, | 82 | 4064,3840,3628,3424,3232,3048,2880,2712,2560, |
82 | 2416,2280,2152,2032,1920,1814,1712,1616,1524, | 83 | 2416,2280,2152,2032,1920,1814,1712,1616,1524, |
83 | 1440,1356,1280,1208,1140,1076,1016, 960, 907, | 84 | 1440,1356,1280,1208,1140,1076,1016, 960, 907, |
@@ -108,7 +109,7 @@ static int ASY_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr) | |||
108 | modtype = 1; | 109 | modtype = 1; |
109 | return 1; | 110 | return 1; |
110 | } | 111 | } |
111 | 112 | ||
112 | return 0; | 113 | return 0; |
113 | } | 114 | } |
114 | 115 | ||
@@ -140,14 +141,16 @@ static void ASY_Cleanup(void) | |||
140 | { | 141 | { |
141 | MikMod_free(mh); | 142 | MikMod_free(mh); |
142 | MikMod_free(patbuf); | 143 | MikMod_free(patbuf); |
144 | mh = NULL; | ||
145 | patbuf = NULL; | ||
143 | } | 146 | } |
144 | 147 | ||
145 | static void ConvertNote(MODNOTE *n) | 148 | static int ConvertNote(MODNOTE *n) |
146 | { | 149 | { |
147 | UBYTE instrument, effect, effdat, note; | 150 | UBYTE instrument, effect, effdat, note; |
148 | UWORD period; | 151 | UWORD period; |
149 | UBYTE lastnote = 0; | 152 | UBYTE lastnote = 0; |
150 | 153 | ||
151 | instrument = n->b&0x1f; | 154 | instrument = n->b&0x1f; |
152 | effect = n->c; | 155 | effect = n->c; |
153 | effdat = n->d; | 156 | effdat = n->d; |
@@ -158,10 +161,10 @@ static void ConvertNote(MODNOTE *n) | |||
158 | } else { | 161 | } else { |
159 | period = 0; | 162 | period = 0; |
160 | } | 163 | } |
161 | 164 | ||
162 | /* Convert the period to a note number */ | 165 | /* Convert the period to a note number */ |
163 | note = 0; | 166 | note = 0; |
164 | if (period) | 167 | if (period) |
165 | { | 168 | { |
166 | for (note = 0; note < 7 * OCTAVE; note++) | 169 | for (note = 0; note < 7 * OCTAVE; note++) |
167 | if (period >= npertab[note]) | 170 | if (period >= npertab[note]) |
@@ -186,8 +189,8 @@ static void ConvertNote(MODNOTE *n) | |||
186 | UniInstrument(instrument - 1); | 189 | UniInstrument(instrument - 1); |
187 | /* ...otherwise, only adjust volume... */ | 190 | /* ...otherwise, only adjust volume... */ |
188 | else { | 191 | else { |
189 | /* ...unless an effect was specified, | 192 | /* ...unless an effect was specified, |
190 | * which forces a new note to be | 193 | * which forces a new note to be |
191 | * played */ | 194 | * played */ |
192 | if (effect || effdat) { | 195 | if (effect || effdat) { |
193 | UniInstrument(instrument - 1); | 196 | UniInstrument(instrument - 1); |
@@ -218,7 +221,15 @@ static void ConvertNote(MODNOTE *n) | |||
218 | if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0)) | 221 | if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0)) |
219 | effdat &= 0xf0; | 222 | effdat &= 0xf0; |
220 | 223 | ||
224 | if (effect == 0x1b) { | ||
225 | return 0; /* UniEffect(UNI_S3MEFFECTQ,dat) ? */ | ||
226 | } | ||
227 | if (effect > 0xf) { | ||
228 | return 0; /* return -1 to fail? */ | ||
229 | } | ||
230 | |||
221 | UniPTEffect(effect, effdat); | 231 | UniPTEffect(effect, effdat); |
232 | return 0; | ||
222 | } | 233 | } |
223 | 234 | ||
224 | static UBYTE *ConvertTrack(MODNOTE *n) | 235 | static UBYTE *ConvertTrack(MODNOTE *n) |
@@ -227,7 +238,8 @@ static UBYTE *ConvertTrack(MODNOTE *n) | |||
227 | 238 | ||
228 | UniReset(); | 239 | UniReset(); |
229 | for (t = 0; t < 64; t++) { | 240 | for (t = 0; t < 64; t++) { |
230 | ConvertNote(n); | 241 | if (ConvertNote(n) < 0) |
242 | return NULL; | ||
231 | UniNewline(); | 243 | UniNewline(); |
232 | n += of.numchn; | 244 | n += of.numchn; |
233 | } | 245 | } |
@@ -237,8 +249,7 @@ static UBYTE *ConvertTrack(MODNOTE *n) | |||
237 | /* Loads all patterns of a modfile and converts them into the 3 byte format. */ | 249 | /* Loads all patterns of a modfile and converts them into the 3 byte format. */ |
238 | static int ML_LoadPatterns(void) | 250 | static int ML_LoadPatterns(void) |
239 | { | 251 | { |
240 | int t, tracks = 0; | 252 | unsigned int t, s, tracks = 0; |
241 | unsigned int s; | ||
242 | 253 | ||
243 | if (!AllocPatterns()) { | 254 | if (!AllocPatterns()) { |
244 | return 0; | 255 | return 0; |
@@ -246,7 +257,7 @@ static int ML_LoadPatterns(void) | |||
246 | if (!AllocTracks()) { | 257 | if (!AllocTracks()) { |
247 | return 0; | 258 | return 0; |
248 | } | 259 | } |
249 | 260 | ||
250 | /* Allocate temporary buffer for loading and converting the patterns */ | 261 | /* Allocate temporary buffer for loading and converting the patterns */ |
251 | if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE)))) | 262 | if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE)))) |
252 | return 0; | 263 | return 0; |
@@ -278,31 +289,31 @@ static int ASY_Load(int curious) | |||
278 | MSAMPINFO *s; | 289 | MSAMPINFO *s; |
279 | CHAR *descr=asylum; | 290 | CHAR *descr=asylum; |
280 | ULONG seekpos; | 291 | ULONG seekpos; |
281 | (void)curious; | 292 | (void)curious; |
282 | 293 | ||
283 | // no title in asylum amf files :( | 294 | /* no title in asylum amf files :( */ |
284 | strcpy(mh->songname, ""); | 295 | mh->songname[0] = '\0'; |
285 | 296 | ||
286 | _mm_fseek(modreader, 0x23, SEEK_SET); | 297 | _mm_fseek(modreader, 0x23, SEEK_SET); |
287 | mh->num_patterns = _mm_read_UBYTE(modreader); | 298 | mh->num_patterns = _mm_read_UBYTE(modreader); |
288 | mh->num_orders = _mm_read_UBYTE(modreader); | 299 | mh->num_orders = _mm_read_UBYTE(modreader); |
289 | 300 | ||
290 | // skip unknown byte | 301 | /* skip unknown byte */ |
291 | (void)_mm_read_UBYTE(modreader); | 302 | _mm_skip_BYTE(modreader); |
292 | _mm_read_UBYTES(mh->positions, 256, modreader); | 303 | _mm_read_UBYTES(mh->positions, 256, modreader); |
293 | 304 | ||
294 | /* read samples headers*/ | 305 | /* read samples headers*/ |
295 | for (t = 0; t < 64; t++) { | 306 | for (t = 0; t < 64; t++) { |
296 | s = &mh->samples[t]; | 307 | s = &mh->samples[t]; |
297 | 308 | ||
298 | _mm_fseek(modreader, 0x126 + (t*37), SEEK_SET); | 309 | _mm_fseek(modreader, 0x126 + (t*37), SEEK_SET); |
299 | 310 | ||
300 | _mm_read_string(s->samplename, 22, modreader); | 311 | _mm_read_string(s->samplename, 22, modreader); |
301 | s->samplename[21] = 0; /* just in case */ | 312 | s->samplename[21] = 0; /* just in case */ |
302 | 313 | ||
303 | s->finetune = _mm_read_UBYTE(modreader); | 314 | s->finetune = _mm_read_UBYTE(modreader); |
304 | s->volume = _mm_read_UBYTE(modreader); | 315 | s->volume = _mm_read_UBYTE(modreader); |
305 | (void)_mm_read_UBYTE(modreader); // skip unknown byte | 316 | _mm_skip_BYTE(modreader);/* skip unknown byte */ |
306 | s->length = _mm_read_I_ULONG(modreader); | 317 | s->length = _mm_read_I_ULONG(modreader); |
307 | s->reppos = _mm_read_I_ULONG(modreader); | 318 | s->reppos = _mm_read_I_ULONG(modreader); |
308 | s->replen = _mm_read_I_ULONG(modreader); | 319 | s->replen = _mm_read_I_ULONG(modreader); |
@@ -324,12 +335,16 @@ static int ASY_Load(int curious) | |||
324 | of.numpat = mh->num_patterns; | 335 | of.numpat = mh->num_patterns; |
325 | of.numtrk = of.numpat * of.numchn; | 336 | of.numtrk = of.numpat * of.numchn; |
326 | 337 | ||
327 | |||
328 | /* Copy positions (orders) */ | 338 | /* Copy positions (orders) */ |
329 | if (!AllocPositions(of.numpos)) | 339 | if (!AllocPositions(of.numpos)) |
330 | return 0; | 340 | return 0; |
331 | for (t = 0; t < of.numpos; t++) { | 341 | for (t = 0; t < of.numpos; t++) { |
332 | of.positions[t] = mh->positions[t]; | 342 | of.positions[t] = mh->positions[t]; |
343 | if (of.positions[t]>of.numpat) { /* SANITIY CHECK */ | ||
344 | /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/ | ||
345 | _mm_errno = MMERR_LOADING_HEADER; | ||
346 | return 0; | ||
347 | } | ||
333 | } | 348 | } |
334 | 349 | ||
335 | /* Finally, init the sampleinfo structures */ | 350 | /* Finally, init the sampleinfo structures */ |
@@ -343,7 +358,7 @@ static int ASY_Load(int curious) | |||
343 | for (t = 0; t < of.numins; t++) { | 358 | for (t = 0; t < of.numins; t++) { |
344 | /* convert the samplename */ | 359 | /* convert the samplename */ |
345 | q->samplename = DupStr(s->samplename, 23, 1); | 360 | q->samplename = DupStr(s->samplename, 23, 1); |
346 | 361 | ||
347 | /* init the sampleinfo variables */ | 362 | /* init the sampleinfo variables */ |
348 | q->speed = finetune[s->finetune & 0xf]; | 363 | q->speed = finetune[s->finetune & 0xf]; |
349 | q->volume = s->volume & 0x7f; | 364 | q->volume = s->volume & 0x7f; |
@@ -351,16 +366,16 @@ static int ASY_Load(int curious) | |||
351 | q->loopstart = (ULONG)s->reppos; | 366 | q->loopstart = (ULONG)s->reppos; |
352 | q->loopend = (ULONG)q->loopstart + (s->replen); | 367 | q->loopend = (ULONG)q->loopstart + (s->replen); |
353 | q->length = (ULONG)s->length; | 368 | q->length = (ULONG)s->length; |
354 | 369 | ||
355 | q->flags = SF_SIGNED; | 370 | q->flags = SF_SIGNED; |
356 | 371 | ||
357 | q->seekpos = seekpos; | 372 | q->seekpos = seekpos; |
358 | seekpos += q->length; | 373 | seekpos += q->length; |
359 | 374 | ||
360 | if ((s->replen) > 2) { | 375 | if ((s->replen) > 2) { |
361 | q->flags |= SF_LOOP; | 376 | q->flags |= SF_LOOP; |
362 | } | 377 | } |
363 | 378 | ||
364 | /* fix replen if repend > length */ | 379 | /* fix replen if repend > length */ |
365 | if (q->loopend > q->length) | 380 | if (q->loopend > q->length) |
366 | q->loopend = q->length; | 381 | q->loopend = q->length; |
@@ -369,7 +384,7 @@ static int ASY_Load(int curious) | |||
369 | q++; | 384 | q++; |
370 | } | 385 | } |
371 | 386 | ||
372 | of.modtype = StrDup(descr); | 387 | of.modtype = MikMod_strdup(descr); |
373 | 388 | ||
374 | if (!ML_LoadPatterns()) | 389 | if (!ML_LoadPatterns()) |
375 | return 0; | 390 | return 0; |
@@ -379,9 +394,7 @@ static int ASY_Load(int curious) | |||
379 | 394 | ||
380 | static CHAR *ASY_LoadTitle(void) | 395 | static CHAR *ASY_LoadTitle(void) |
381 | { | 396 | { |
382 | CHAR *s = ""; // no titles | 397 | return MikMod_strdup(""); |
383 | |||
384 | return (DupStr(s, 21, 1)); | ||
385 | } | 398 | } |
386 | 399 | ||
387 | /*========== Loader information */ | 400 | /*========== Loader information */ |
diff --git a/apps/plugins/mikmod/load_dsm.c b/apps/plugins/mikmod/load_dsm.c index 59abf0bcfe..e995f7dfad 100644 --- a/apps/plugins/mikmod/load_dsm.c +++ b/apps/plugins/mikmod/load_dsm.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_dsm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | DSIK internal format (DSM) module loader | 25 | DSIK internal format (DSM) module loader |
26 | 26 | ||
@@ -89,9 +89,9 @@ typedef struct DSMNOTE { | |||
89 | 89 | ||
90 | /*========== Loader variables */ | 90 | /*========== Loader variables */ |
91 | 91 | ||
92 | static CHAR* SONGID="SONG"; | 92 | static const CHAR* SONGID="SONG"; |
93 | static CHAR* INSTID="INST"; | 93 | static const CHAR* INSTID="INST"; |
94 | static CHAR* PATTID="PATT"; | 94 | static const CHAR* PATTID="PATT"; |
95 | 95 | ||
96 | static UBYTE blockid[4]; | 96 | static UBYTE blockid[4]; |
97 | static ULONG blockln; | 97 | static ULONG blockln; |
@@ -101,7 +101,7 @@ static DSMNOTE* dsmbuf=NULL; | |||
101 | 101 | ||
102 | static CHAR DSM_Version[]="DSIK DSM-format"; | 102 | static CHAR DSM_Version[]="DSIK DSM-format"; |
103 | 103 | ||
104 | static unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'}; | 104 | static const unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'}; |
105 | 105 | ||
106 | /*========== Loader code */ | 106 | /*========== Loader code */ |
107 | 107 | ||
@@ -126,6 +126,8 @@ static void DSM_Cleanup(void) | |||
126 | { | 126 | { |
127 | MikMod_free(dsmbuf); | 127 | MikMod_free(dsmbuf); |
128 | MikMod_free(mh); | 128 | MikMod_free(mh); |
129 | dsmbuf = NULL; | ||
130 | mh = NULL; | ||
129 | } | 131 | } |
130 | 132 | ||
131 | static int GetBlockHeader(void) | 133 | static int GetBlockHeader(void) |
@@ -133,7 +135,7 @@ static int GetBlockHeader(void) | |||
133 | /* make sure we're at the right position for reading the | 135 | /* make sure we're at the right position for reading the |
134 | next riff block, no matter how many bytes read */ | 136 | next riff block, no matter how many bytes read */ |
135 | _mm_fseek(modreader, blocklp+blockln, SEEK_SET); | 137 | _mm_fseek(modreader, blocklp+blockln, SEEK_SET); |
136 | 138 | ||
137 | while(1) { | 139 | while(1) { |
138 | _mm_read_UBYTES(blockid,4,modreader); | 140 | _mm_read_UBYTES(blockid,4,modreader); |
139 | blockln=_mm_read_I_ULONG(modreader); | 141 | blockln=_mm_read_I_ULONG(modreader); |
@@ -237,7 +239,7 @@ static int DSM_Load(int curious) | |||
237 | DSMINST s; | 239 | DSMINST s; |
238 | SAMPLE *q; | 240 | SAMPLE *q; |
239 | int cursmp=0,curpat=0,track=0; | 241 | int cursmp=0,curpat=0,track=0; |
240 | (void)curious; | 242 | (void)curious; |
241 | 243 | ||
242 | blocklp=0; | 244 | blocklp=0; |
243 | blockln=12; | 245 | blockln=12; |
@@ -266,7 +268,7 @@ static int DSM_Load(int curious) | |||
266 | /* set module variables */ | 268 | /* set module variables */ |
267 | of.initspeed=mh->speed; | 269 | of.initspeed=mh->speed; |
268 | of.inittempo=mh->bpm; | 270 | of.inittempo=mh->bpm; |
269 | of.modtype=StrDup(DSM_Version); | 271 | of.modtype=MikMod_strdup(DSM_Version); |
270 | of.numchn=mh->numtrk; | 272 | of.numchn=mh->numtrk; |
271 | of.numpat=mh->numpat; | 273 | of.numpat=mh->numpat; |
272 | of.numtrk=of.numchn*of.numpat; | 274 | of.numtrk=of.numchn*of.numpat; |
@@ -286,6 +288,11 @@ static int DSM_Load(int curious) | |||
286 | for(t=0;t<mh->numord;t++) { | 288 | for(t=0;t<mh->numord;t++) { |
287 | int order=mh->orders[t]; | 289 | int order=mh->orders[t]; |
288 | if(order==255) order=LAST_PATTERN; | 290 | if(order==255) order=LAST_PATTERN; |
291 | else if (of.positions[t]>of.numpat) { /* SANITIY CHECK */ | ||
292 | /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/ | ||
293 | _mm_errno = MMERR_LOADING_HEADER; | ||
294 | return 0; | ||
295 | } | ||
289 | of.positions[of.numpos]=order; | 296 | of.positions[of.numpos]=order; |
290 | if(mh->orders[t]<254) of.numpos++; | 297 | if(mh->orders[t]<254) of.numpos++; |
291 | } | 298 | } |
@@ -344,7 +351,7 @@ static CHAR *DSM_LoadTitle(void) | |||
344 | 351 | ||
345 | _mm_fseek(modreader,12,SEEK_SET); | 352 | _mm_fseek(modreader,12,SEEK_SET); |
346 | if(!_mm_read_UBYTES(s,28,modreader)) return NULL; | 353 | if(!_mm_read_UBYTES(s,28,modreader)) return NULL; |
347 | 354 | ||
348 | return(DupStr(s,28,1)); | 355 | return(DupStr(s,28,1)); |
349 | } | 356 | } |
350 | 357 | ||
diff --git a/apps/plugins/mikmod/load_far.c b/apps/plugins/mikmod/load_far.c index 2a1a44eda9..643cf15d49 100644 --- a/apps/plugins/mikmod/load_far.c +++ b/apps/plugins/mikmod/load_far.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_far.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Farandole (FAR) module loader | 25 | Farandole (FAR) module loader |
26 | 26 | ||
@@ -92,7 +92,7 @@ static FARHEADER1 *mh1 = NULL; | |||
92 | static FARHEADER2 *mh2 = NULL; | 92 | static FARHEADER2 *mh2 = NULL; |
93 | static FARNOTE *pat = NULL; | 93 | static FARNOTE *pat = NULL; |
94 | 94 | ||
95 | static unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26}; | 95 | static const unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26}; |
96 | 96 | ||
97 | /*========== Loader code */ | 97 | /*========== Loader code */ |
98 | 98 | ||
@@ -119,6 +119,9 @@ static void FAR_Cleanup(void) | |||
119 | MikMod_free(mh1); | 119 | MikMod_free(mh1); |
120 | MikMod_free(mh2); | 120 | MikMod_free(mh2); |
121 | MikMod_free(pat); | 121 | MikMod_free(pat); |
122 | mh1 = NULL; | ||
123 | mh2 = NULL; | ||
124 | pat = NULL; | ||
122 | } | 125 | } |
123 | 126 | ||
124 | static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows) | 127 | static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows) |
@@ -180,7 +183,7 @@ static int FAR_Load(int curious) | |||
180 | FARSAMPLE s; | 183 | FARSAMPLE s; |
181 | FARNOTE *crow; | 184 | FARNOTE *crow; |
182 | UBYTE smap[8]; | 185 | UBYTE smap[8]; |
183 | (void)curious; | 186 | (void)curious; |
184 | 187 | ||
185 | /* try to read module header (first part) */ | 188 | /* try to read module header (first part) */ |
186 | _mm_read_UBYTES(mh1->id,4,modreader); | 189 | _mm_read_UBYTES(mh1->id,4,modreader); |
@@ -196,7 +199,7 @@ static int FAR_Load(int curious) | |||
196 | mh1->stlen = _mm_read_I_UWORD (modreader); | 199 | mh1->stlen = _mm_read_I_UWORD (modreader); |
197 | 200 | ||
198 | /* init modfile data */ | 201 | /* init modfile data */ |
199 | of.modtype = StrDup(FAR_Version); | 202 | of.modtype = MikMod_strdup(FAR_Version); |
200 | of.songname = DupStr(mh1->songname,40,1); | 203 | of.songname = DupStr(mh1->songname,40,1); |
201 | of.numchn = 16; | 204 | of.numchn = 16; |
202 | of.initspeed = mh1->speed; | 205 | of.initspeed = mh1->speed; |
@@ -207,7 +210,12 @@ static int FAR_Load(int curious) | |||
207 | 210 | ||
208 | /* read songtext into comment field */ | 211 | /* read songtext into comment field */ |
209 | if(mh1->stlen) | 212 | if(mh1->stlen) |
210 | if (!ReadLinedComment(mh1->stlen, 66)) return 0; | 213 | if (!ReadLinedComment(mh1->stlen, 132)) return 0; |
214 | |||
215 | if(_mm_eof(modreader)) { | ||
216 | _mm_errno = MMERR_LOADING_HEADER; | ||
217 | return 0; | ||
218 | } | ||
211 | 219 | ||
212 | /* try to read module header (second part) */ | 220 | /* try to read module header (second part) */ |
213 | _mm_read_UBYTES(mh2->orders,256,modreader); | 221 | _mm_read_UBYTES(mh2->orders,256,modreader); |
@@ -238,12 +246,14 @@ static int FAR_Load(int curious) | |||
238 | if(!AllocPatterns()) return 0; | 246 | if(!AllocPatterns()) return 0; |
239 | 247 | ||
240 | for(t=0;t<of.numpat;t++) { | 248 | for(t=0;t<of.numpat;t++) { |
241 | UBYTE rows=0/* ,tempo */; | 249 | UBYTE rows=0; |
250 | UBYTE tempo; | ||
242 | 251 | ||
243 | memset(pat,0,256*16*4*sizeof(FARNOTE)); | 252 | memset(pat,0,256*16*4*sizeof(FARNOTE)); |
244 | if(mh2->patsiz[t]) { | 253 | if(mh2->patsiz[t]) { |
245 | rows = _mm_read_UBYTE(modreader); | 254 | rows = _mm_read_UBYTE(modreader); |
246 | /* tempo = */ (void)_mm_read_UBYTE(modreader); | 255 | tempo = _mm_read_UBYTE(modreader); |
256 | (void)tempo; /* unused */ | ||
247 | 257 | ||
248 | crow = pat; | 258 | crow = pat; |
249 | /* file often allocates 64 rows even if there are less in pattern */ | 259 | /* file often allocates 64 rows even if there are less in pattern */ |
@@ -284,7 +294,7 @@ static int FAR_Load(int curious) | |||
284 | of.numins = 0; | 294 | of.numins = 0; |
285 | for(t=0;t<64;t++) | 295 | for(t=0;t<64;t++) |
286 | if(smap[t>>3]&(1<<(t&7))) of.numins=t+1; | 296 | if(smap[t>>3]&(1<<(t&7))) of.numins=t+1; |
287 | of.numsmp = of.numins; | 297 | of.numsmp = of.numins; |
288 | 298 | ||
289 | /* alloc sample structs */ | 299 | /* alloc sample structs */ |
290 | if(!AllocSamples()) return 0; | 300 | if(!AllocSamples()) return 0; |
@@ -314,8 +324,8 @@ static int FAR_Load(int curious) | |||
314 | 324 | ||
315 | q->seekpos = _mm_ftell(modreader); | 325 | q->seekpos = _mm_ftell(modreader); |
316 | _mm_fseek(modreader,q->length,SEEK_CUR); | 326 | _mm_fseek(modreader,q->length,SEEK_CUR); |
317 | } else | 327 | } else |
318 | q->samplename = DupStr(NULL,0,0); | 328 | q->samplename = MikMod_strdup(""); |
319 | q++; | 329 | q++; |
320 | } | 330 | } |
321 | return 1; | 331 | return 1; |
@@ -327,8 +337,8 @@ static CHAR *FAR_LoadTitle(void) | |||
327 | 337 | ||
328 | _mm_fseek(modreader,4,SEEK_SET); | 338 | _mm_fseek(modreader,4,SEEK_SET); |
329 | if(!_mm_read_UBYTES(s,40,modreader)) return NULL; | 339 | if(!_mm_read_UBYTES(s,40,modreader)) return NULL; |
330 | 340 | ||
331 | return(DupStr(s,40,1)); | 341 | return (DupStr(s,40,1)); |
332 | } | 342 | } |
333 | 343 | ||
334 | /*========== Loader information */ | 344 | /*========== Loader information */ |
diff --git a/apps/plugins/mikmod/load_gdm.c b/apps/plugins/mikmod/load_gdm.c index 694d534236..5f06f9c70b 100644 --- a/apps/plugins/mikmod/load_gdm.c +++ b/apps/plugins/mikmod/load_gdm.c | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | /*============================================================================== | 21 | /*============================================================================== |
22 | 22 | ||
23 | $Id: load_gdm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | General DigiMusic (GDM) module loader | 25 | General DigiMusic (GDM) module loader |
26 | 26 | ||
@@ -114,7 +114,7 @@ typedef struct GDMSAMPLE { | |||
114 | static GDMHEADER *mh=NULL; /* pointer to GDM header */ | 114 | static GDMHEADER *mh=NULL; /* pointer to GDM header */ |
115 | static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */ | 115 | static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */ |
116 | 116 | ||
117 | CHAR GDM_Version[]="General DigiMusic 1.xx"; | 117 | static CHAR GDM_Version[]="General DigiMusic 1.xx"; |
118 | 118 | ||
119 | static int GDM_Test(void) | 119 | static int GDM_Test(void) |
120 | { | 120 | { |
@@ -146,36 +146,45 @@ static void GDM_Cleanup(void) | |||
146 | { | 146 | { |
147 | MikMod_free(mh); | 147 | MikMod_free(mh); |
148 | MikMod_free(gdmbuf); | 148 | MikMod_free(gdmbuf); |
149 | mh=NULL; | ||
150 | gdmbuf=NULL; | ||
149 | } | 151 | } |
150 | 152 | ||
151 | static int GDM_ReadPattern(void) | 153 | static int GDM_ReadPattern(void) |
152 | { | 154 | { |
153 | int pos,flag,ch,i,maxch; | 155 | int pos,flag,ch,i; |
154 | GDMNOTE n; | 156 | GDMNOTE n; |
155 | UWORD length,x=0; | 157 | SLONG length,x=0; |
156 | 158 | ||
157 | /* get pattern length */ | 159 | /* get pattern length */ |
158 | length=_mm_read_I_UWORD(modreader)-2; | 160 | length=(SLONG)_mm_read_I_UWORD(modreader); |
161 | length-=2; | ||
159 | 162 | ||
160 | /* clear pattern data */ | 163 | /* clear pattern data */ |
161 | memset(gdmbuf,255,32*64*sizeof(GDMNOTE)); | 164 | memset(gdmbuf,255,32*64*sizeof(GDMNOTE)); |
162 | pos=0; | 165 | pos=0; |
163 | maxch=0; | ||
164 | 166 | ||
165 | while (x<length) { | 167 | while (x<length) { |
166 | memset(&n,255,sizeof(GDMNOTE)); | 168 | memset(&n,255,sizeof(GDMNOTE)); |
167 | flag=_mm_read_UBYTE(modreader); | 169 | flag=_mm_read_UBYTE(modreader); |
168 | x++; | 170 | x++; |
169 | 171 | ||
170 | if (_mm_eof(modreader)) { | 172 | if (_mm_eof(modreader)) |
171 | _mm_errno=MMERR_LOADING_PATTERN; | ||
172 | return 0; | 173 | return 0; |
173 | } | ||
174 | 174 | ||
175 | ch=flag&31; | 175 | ch=flag&31; |
176 | if (ch>maxch) maxch=ch; | 176 | if (ch > of.numchn) |
177 | return 0; | ||
178 | |||
177 | if (!flag) { | 179 | if (!flag) { |
178 | pos++; | 180 | pos++; |
181 | if (x==length) { | ||
182 | if (pos > 64) | ||
183 | return 0; | ||
184 | } else { | ||
185 | if (pos >= 64) | ||
186 | return 0; | ||
187 | } | ||
179 | continue; | 188 | continue; |
180 | } | 189 | } |
181 | if (flag&0x60) { | 190 | if (flag&0x60) { |
@@ -343,7 +352,7 @@ static int GDM_Load(int curious) | |||
343 | SAMPLE *q; | 352 | SAMPLE *q; |
344 | GDMSAMPLE s; | 353 | GDMSAMPLE s; |
345 | ULONG position; | 354 | ULONG position; |
346 | (void)curious; | 355 | (void)curious; |
347 | 356 | ||
348 | /* read header */ | 357 | /* read header */ |
349 | _mm_read_string(mh->id1,4,modreader); | 358 | _mm_read_string(mh->id1,4,modreader); |
@@ -390,7 +399,7 @@ static int GDM_Load(int curious) | |||
390 | } | 399 | } |
391 | 400 | ||
392 | /* now we fill */ | 401 | /* now we fill */ |
393 | of.modtype=StrDup(GDM_Version); | 402 | of.modtype=MikMod_strdup(GDM_Version); |
394 | of.modtype[18]=mh->majorver+'0'; | 403 | of.modtype[18]=mh->majorver+'0'; |
395 | of.modtype[20]=mh->minorver/10+'0'; | 404 | of.modtype[20]=mh->minorver/10+'0'; |
396 | of.modtype[21]=mh->minorver%10+'0'; | 405 | of.modtype[21]=mh->minorver%10+'0'; |
diff --git a/apps/plugins/mikmod/load_gt2.c b/apps/plugins/mikmod/load_gt2.c deleted file mode 100644 index 26b4d1f59a..0000000000 --- a/apps/plugins/mikmod/load_gt2.c +++ /dev/null | |||
@@ -1,375 +0,0 @@ | |||
1 | /* MikMod sound library | ||
2 | (c) 2003-2004 Raphael Assenat and others - see file | ||
3 | AUTHORS for complete list. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU Library General Public License as | ||
7 | published by the Free Software Foundation; either version 2 of | ||
8 | the License, or (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU Library General Public License for more details. | ||
14 | |||
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 | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
18 | 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /*============================================================================== | ||
22 | |||
23 | $Id: load_gt2.c,v 1.2 2005/03/30 19:09:35 realtech Exp $ | ||
24 | |||
25 | Graoumf tracker format (.GT2) | ||
26 | |||
27 | ==============================================================================*/ | ||
28 | |||
29 | #ifdef HAVE_CONFIG_H | ||
30 | #include "config.h" | ||
31 | #endif | ||
32 | |||
33 | #ifdef HAVE_UNISTD_H | ||
34 | #include <unistd.h> | ||
35 | #endif | ||
36 | |||
37 | #include <ctype.h> | ||
38 | #include <stdio.h> | ||
39 | #ifdef HAVE_MEMORY_H | ||
40 | #include <memory.h> | ||
41 | #endif | ||
42 | #include <string.h> | ||
43 | |||
44 | #include "mikmod_internals.h" | ||
45 | |||
46 | typedef struct GT_NOTE { | ||
47 | UBYTE note; /* 24-127, 48 is middle C-2. 0 for no note */ | ||
48 | UBYTE inst; /* instrument, 1-255, 0 for none */ | ||
49 | UWORD effect; /* 0 for no FX */ | ||
50 | UBYTE vv; /* volume, 1-255, 0 for no volume */ | ||
51 | } GT_NOTE; | ||
52 | |||
53 | /* general info chunk */ | ||
54 | typedef struct GT2_CHUNK { | ||
55 | UBYTE magic[4]; /* must be 'GT2' */ | ||
56 | UBYTE version; /* 01 = v0.7, 02=v0.726, 03=v0.731 */ | ||
57 | ULONG chunk_size; | ||
58 | CHAR module_name[33]; /* 32 bytes in file */ | ||
59 | CHAR comments_author[161]; /* 160 bytes in file */ | ||
60 | UBYTE date_day; | ||
61 | UBYTE date_month; | ||
62 | UWORD date_year; | ||
63 | CHAR tracker_name[25]; /* 24 in file */ | ||
64 | UWORD initial_speed; | ||
65 | UWORD initial_tempo; | ||
66 | UWORD initial_master_volume; /* 000 - fff */ | ||
67 | UWORD num_voices; /* for the following panning section */ | ||
68 | UWORD *voice_pannings; /* 000 - 800 - fff */ | ||
69 | } GT2_CHUNK; | ||
70 | |||
71 | /* track volume chunk */ | ||
72 | typedef struct TVOL_CHUNK { | ||
73 | UBYTE id[4]; /* must be TVOL */ | ||
74 | ULONG chunk_size; | ||
75 | UWORD num_tracks; /* for the following array */ | ||
76 | UWORD *track_volumes; /* 0000 - 1000 - FFFF */ | ||
77 | } TVOL_CHUNK; | ||
78 | |||
79 | /* extra-comment chunk */ | ||
80 | typedef struct XCOM_CHUNK { | ||
81 | UBYTE id[4]; /* must be XCOM */ | ||
82 | ULONG chunk_size; | ||
83 | ULONG comment_len; | ||
84 | CHAR *comment; /* comment_len + 1 allocated */ | ||
85 | } XCOM_CHUNK; | ||
86 | |||
87 | /* song chunk */ | ||
88 | typedef struct SONG_CHUNK { | ||
89 | UBYTE id[4]; /* must be SONG */ | ||
90 | ULONG chunk_size; | ||
91 | UWORD song_length; | ||
92 | UWORD song_repeat_point; | ||
93 | UWORD *patterns; /* pattern numbers */ | ||
94 | } SONG_CHUNK; | ||
95 | |||
96 | /* pattern set chunk */ | ||
97 | typedef struct PATS_CHUNK { | ||
98 | UBYTE id[4]; /* must be PATS */ | ||
99 | ULONG chunk_size; | ||
100 | UWORD num_tracks; /* total number of tracks for the song */ | ||
101 | UWORD num_patterns; /* number of patterns saved */ | ||
102 | } PATS_CHUNK; | ||
103 | |||
104 | /* pattern chunk */ | ||
105 | typedef struct PATD_CHUNK { | ||
106 | UBYTE id[4]; /* must be PATD */ | ||
107 | ULONG chunk_size; | ||
108 | UWORD pattern_number; | ||
109 | CHAR pattern_name[17]; /* 16 in file */ | ||
110 | UWORD codage_version; /* only 0 expected for now */ | ||
111 | /* version 0 (full pattern) */ | ||
112 | UWORD num_lines; | ||
113 | UWORD num_tracks; | ||
114 | GT_NOTE *notes; /* sizeof(GT_NOTE) * num_lines * num_tracks */ | ||
115 | } PATD_CHUNK; | ||
116 | |||
117 | /* instrument set chunk */ | ||
118 | typedef struct ORCH_CHUNK { | ||
119 | UBYTE id[4]; /* must be ORCH */ | ||
120 | ULONG chunk_size; | ||
121 | UWORD num_instruments; /* number of instruments saved */ | ||
122 | } ORCH_CHUNK; | ||
123 | |||
124 | typedef struct INST_NOTE { | ||
125 | UBYTE samp_number;/* sample number for midi note */ | ||
126 | CHAR tranp; /* transposition for note */ | ||
127 | } INST_NOTE; | ||
128 | |||
129 | /* instrument chunk */ | ||
130 | typedef struct INST_CHUNK { | ||
131 | UBYTE id[4]; /* must be INST */ | ||
132 | ULONG chunk_size; | ||
133 | UWORD instrument_number; | ||
134 | CHAR name[29]; /* 28 in file */ | ||
135 | UWORD type; /* 0 = sample */ | ||
136 | UWORD volume; /* volume, 0-255 */ | ||
137 | UWORD auto_panning; /* autopanning, 000 - 800 - fff, -1 no autopanning */ | ||
138 | UWORD volume_enveloppe_number; | ||
139 | UWORD tone_enveloppe_number; | ||
140 | UWORD pan_enveloppe_number; | ||
141 | UBYTE reserved[10]; | ||
142 | INST_NOTE note[128]; | ||
143 | } INST_CHUNK; | ||
144 | |||
145 | typedef struct SAMP_CHUNK { | ||
146 | UBYTE id[4]; /* must be SAMP */ | ||
147 | ULONG chunk_size; | ||
148 | UWORD sample_number; | ||
149 | CHAR name[29]; /* 28 in file */ | ||
150 | UWORD flags; /* bit0: 0 = mono, 1 = stereo bit1: 0 normal loop, bit2: ping pong loop */ | ||
151 | UWORD autopanning; /* 000 - 800 - fff */ | ||
152 | UWORD num_bits; /* 8 or 16 */ | ||
153 | UWORD rate; /* between 2000 and 65000 */ | ||
154 | ULONG length; /* bytes */ | ||
155 | ULONG loop_start; /* bytes */ | ||
156 | ULONG loop_len; /* bytes */ | ||
157 | UWORD volume; /* 0 - 255 */ | ||
158 | UWORD finetune; /* (-8..+7 -> -1..+7/8 halftone) */ | ||
159 | UWORD codage; /* 0 */ | ||
160 | UBYTE *data; | ||
161 | } SAMP_CHUNK; | ||
162 | |||
163 | typedef struct xENV_CHUNK { | ||
164 | UBYTE id[4]; /* must be VENV, TENV or PENV */ | ||
165 | ULONG chunk_size; | ||
166 | UWORD envelope_number; | ||
167 | CHAR name[21]; /* 20 in file */ | ||
168 | UWORD keyoff_offset; | ||
169 | UBYTE *data; | ||
170 | } xENV_CHUNK; | ||
171 | |||
172 | typedef struct ENDC_CHUNK { | ||
173 | UBYTE id[4]; /* must be ENDC */ | ||
174 | ULONG chunk_size; | ||
175 | ULONG total_module_size; | ||
176 | } ENDC_CHUNK; | ||
177 | |||
178 | |||
179 | typedef union GT_CHUNK | ||
180 | { | ||
181 | UBYTE id[4]; /* must be TVOL */ | ||
182 | GT2_CHUNK gt2; | ||
183 | TVOL_CHUNK tvol; | ||
184 | XCOM_CHUNK xcom; | ||
185 | SONG_CHUNK song; | ||
186 | PATS_CHUNK pats; | ||
187 | PATD_CHUNK patd; | ||
188 | ORCH_CHUNK orch; | ||
189 | INST_CHUNK inst; | ||
190 | SAMP_CHUNK samp; | ||
191 | xENV_CHUNK xenv; | ||
192 | ENDC_CHUNK endc; | ||
193 | } GT_CHUNK; | ||
194 | |||
195 | static GT_CHUNK *loadChunk(void) | ||
196 | { | ||
197 | GT_CHUNK *new_chunk = MikMod_malloc(sizeof(GT_CHUNK)); | ||
198 | |||
199 | /* the file chunk id only use 3 bytes, others 4 */ | ||
200 | _mm_read_UBYTES(new_chunk->id, 3, modreader); | ||
201 | if (! (new_chunk->id[0]=='G' && | ||
202 | new_chunk->id[1]=='T' && | ||
203 | new_chunk->id[2]=='2') | ||
204 | ) | ||
205 | { | ||
206 | _mm_read_UBYTES(&new_chunk->id[3], 1, modreader); | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | new_chunk->id[3] = ' '; | ||
211 | } | ||
212 | |||
213 | printf(">> %c%c%c%c\n", new_chunk->id[0], new_chunk->id[1], new_chunk->id[2], new_chunk->id[3]); | ||
214 | |||
215 | if (!memcmp(new_chunk, "GT2", 3)) { | ||
216 | _mm_read_UBYTES(&new_chunk->gt2.version, 1, modreader); | ||
217 | _mm_read_M_ULONGS(&new_chunk->gt2.chunk_size, 1, modreader); | ||
218 | new_chunk->gt2.module_name[32] = 0; | ||
219 | _mm_read_UBYTES(&new_chunk->gt2.module_name, 32, modreader); | ||
220 | new_chunk->gt2.comments_author[160] = 0; | ||
221 | _mm_read_UBYTES(&new_chunk->gt2.comments_author, 160, modreader); | ||
222 | _mm_read_UBYTES(&new_chunk->gt2.date_day, 1, modreader); | ||
223 | _mm_read_UBYTES(&new_chunk->gt2.date_month, 1, modreader); | ||
224 | _mm_read_M_UWORDS(&new_chunk->gt2.date_year, 1, modreader); | ||
225 | new_chunk->gt2.tracker_name[24] = 0; | ||
226 | _mm_read_UBYTES(&new_chunk->gt2.tracker_name, 24, modreader); | ||
227 | _mm_read_M_UWORDS(&new_chunk->gt2.initial_speed, 1, modreader); | ||
228 | _mm_read_M_UWORDS(&new_chunk->gt2.initial_tempo, 1, modreader); | ||
229 | _mm_read_M_UWORDS(&new_chunk->gt2.initial_master_volume, 1, modreader); | ||
230 | _mm_read_M_UWORDS(&new_chunk->gt2.num_voices, 1, modreader); | ||
231 | new_chunk->gt2.voice_pannings = MikMod_malloc(2*new_chunk->gt2.num_voices); | ||
232 | _mm_read_M_UWORDS(new_chunk->gt2.voice_pannings, new_chunk->gt2.num_voices, modreader); | ||
233 | return new_chunk; | ||
234 | } | ||
235 | |||
236 | if (!memcmp(new_chunk, "TVOL", 4)) { | ||
237 | new_chunk->tvol.chunk_size = _mm_read_M_ULONG(modreader); | ||
238 | new_chunk->tvol.num_tracks = _mm_read_M_UWORD(modreader); | ||
239 | new_chunk->tvol.track_volumes = MikMod_malloc(new_chunk->tvol.num_tracks * 2); | ||
240 | _mm_read_M_UWORDS(new_chunk->tvol.track_volumes, new_chunk->tvol.num_tracks, modreader); | ||
241 | return new_chunk; | ||
242 | } | ||
243 | |||
244 | if (!memcmp(new_chunk, "XCOM", 4)) { | ||
245 | new_chunk->xcom.chunk_size = _mm_read_M_ULONG(modreader); | ||
246 | new_chunk->xcom.comment_len = _mm_read_M_ULONG(modreader); | ||
247 | new_chunk->xcom.comment = MikMod_malloc(new_chunk->xcom.comment_len + 1); | ||
248 | _mm_read_UBYTES(new_chunk->xcom.comment, new_chunk->xcom.comment_len, modreader); | ||
249 | return new_chunk; | ||
250 | } | ||
251 | |||
252 | if (!memcmp(new_chunk, "SONG", 4)) { | ||
253 | new_chunk->song.chunk_size = _mm_read_M_ULONG(modreader); | ||
254 | new_chunk->song.song_length = _mm_read_M_UWORD(modreader); | ||
255 | new_chunk->song.song_repeat_point = _mm_read_M_UWORD(modreader); | ||
256 | new_chunk->song.patterns = MikMod_malloc(2*new_chunk->song.song_length); | ||
257 | _mm_read_M_UWORDS(new_chunk->song.patterns, new_chunk->song.song_length, modreader); | ||
258 | return new_chunk; | ||
259 | } | ||
260 | |||
261 | if (!memcmp(new_chunk, "PATS", 4)) { | ||
262 | new_chunk->pats.chunk_size = _mm_read_M_ULONG(modreader); | ||
263 | new_chunk->pats.num_tracks = _mm_read_M_UWORD(modreader); | ||
264 | new_chunk->pats.num_patterns = _mm_read_M_UWORD(modreader); | ||
265 | return new_chunk; | ||
266 | } | ||
267 | |||
268 | if (!memcmp(new_chunk, "PATD", 4)) { | ||
269 | new_chunk->patd.chunk_size = _mm_read_M_ULONG(modreader); | ||
270 | new_chunk->patd.pattern_number = _mm_read_M_UWORD(modreader); | ||
271 | new_chunk->patd.pattern_name[16] = 0; | ||
272 | _mm_read_UBYTES(new_chunk->patd.pattern_name, 16, modreader); | ||
273 | new_chunk->patd.codage_version = _mm_read_M_UWORD(modreader); | ||
274 | new_chunk->patd.num_lines = _mm_read_M_UWORD(modreader); | ||
275 | new_chunk->patd.num_tracks = _mm_read_M_UWORD(modreader); | ||
276 | new_chunk->patd.notes = MikMod_malloc(5 * | ||
277 | new_chunk->patd.num_lines * | ||
278 | new_chunk->patd.num_tracks); | ||
279 | _mm_read_UBYTES(new_chunk->patd.notes, | ||
280 | new_chunk->patd.num_lines * new_chunk->patd.num_tracks * 5, | ||
281 | modreader); | ||
282 | return new_chunk; | ||
283 | } | ||
284 | |||
285 | if (!memcmp(new_chunk, "ORCH", 4)) { | ||
286 | new_chunk->orch.chunk_size = _mm_read_M_ULONG(modreader); | ||
287 | new_chunk->orch.num_instruments = _mm_read_M_UWORD(modreader); | ||
288 | return new_chunk; | ||
289 | } | ||
290 | if (!memcmp(new_chunk, "INST", 4)) { | ||
291 | return new_chunk; | ||
292 | } | ||
293 | if (!memcmp(new_chunk, "SAMP", 4)) { | ||
294 | return new_chunk; | ||
295 | } | ||
296 | if (!memcmp(new_chunk, "VENV", 4)) { | ||
297 | return new_chunk; | ||
298 | } | ||
299 | if (!memcmp(new_chunk, "TENV", 4)) { | ||
300 | return new_chunk; | ||
301 | } | ||
302 | if (!memcmp(new_chunk, "PENV", 4)) { | ||
303 | return new_chunk; | ||
304 | } | ||
305 | if (!memcmp(new_chunk, "ENDC", 4)) { | ||
306 | return new_chunk; | ||
307 | } | ||
308 | |||
309 | printf("?? %c%c%c%c\n", new_chunk->id[0], new_chunk->id[1], new_chunk->id[2], new_chunk->id[3]); | ||
310 | |||
311 | MikMod_free(new_chunk); | ||
312 | return NULL; // unknown chunk | ||
313 | } | ||
314 | |||
315 | static int GT2_Init(void) | ||
316 | { | ||
317 | return 1; | ||
318 | } | ||
319 | |||
320 | static int GT2_Test(void) | ||
321 | { | ||
322 | UBYTE magic[3]; | ||
323 | _mm_fseek(modreader, 0, SEEK_SET); | ||
324 | |||
325 | _mm_read_UBYTES(magic, 3, modreader); | ||
326 | |||
327 | if (magic[0] == 'G' && magic[1] == 'T' && magic[2] == '2') { return 1; } | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int GT2_Load(int curious) | ||
333 | { | ||
334 | GT_CHUNK *tmp; | ||
335 | (void)curious; | ||
336 | |||
337 | _mm_fseek(modreader, 0, SEEK_SET); | ||
338 | while ( (tmp = loadChunk() )) | ||
339 | { | ||
340 | printf("%c%c%c%c\n", tmp->id[0], tmp->id[1], tmp->id[2], tmp->id[3]); | ||
341 | |||
342 | } | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static void GT2_Cleanup(void) | ||
348 | { | ||
349 | } | ||
350 | |||
351 | static CHAR *GT2_LoadTitle(void) | ||
352 | { | ||
353 | CHAR title[33]; | ||
354 | _mm_fseek(modreader, 8, SEEK_SET); | ||
355 | |||
356 | _mm_read_UBYTES(title, 32, modreader); | ||
357 | title[32]=0; | ||
358 | |||
359 | return (DupStr(title, 32, 1)); | ||
360 | } | ||
361 | |||
362 | |||
363 | MIKMODAPI MLOADER load_gt2 = { | ||
364 | NULL, | ||
365 | "Graoumf Tracker 2 module", | ||
366 | "Graoumf Tracker 2", | ||
367 | GT2_Init, | ||
368 | GT2_Test, | ||
369 | GT2_Load, | ||
370 | GT2_Cleanup, | ||
371 | GT2_LoadTitle | ||
372 | }; | ||
373 | |||
374 | |||
375 | |||
diff --git a/apps/plugins/mikmod/load_imf.c b/apps/plugins/mikmod/load_imf.c index 9c93d97e23..39cdf5464d 100644 --- a/apps/plugins/mikmod/load_imf.c +++ b/apps/plugins/mikmod/load_imf.c | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | /*============================================================================== | 21 | /*============================================================================== |
22 | 22 | ||
23 | $Id: load_imf.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Imago Orpheus (IMF) module loader | 25 | Imago Orpheus (IMF) module loader |
26 | 26 | ||
@@ -127,12 +127,36 @@ static IMFHEADER *mh=NULL; | |||
127 | 127 | ||
128 | static int IMF_Test(void) | 128 | static int IMF_Test(void) |
129 | { | 129 | { |
130 | UBYTE id[4]; | 130 | UBYTE buf[512], *p; |
131 | int t, chn; | ||
131 | 132 | ||
132 | _mm_fseek(modreader,0x3c,SEEK_SET); | 133 | _mm_fseek(modreader,0x3c,SEEK_SET); |
133 | if(!_mm_read_UBYTES(id,4,modreader)) return 0; | 134 | if (!_mm_read_UBYTES(buf,4,modreader)) return 0; |
134 | if(!memcmp(id,"IM10",4)) return 1; | 135 | if (memcmp(buf,"IM10",4) != 0) return 0; /* no magic */ |
135 | return 0; | 136 | |
137 | _mm_fseek(modreader,32,SEEK_SET); | ||
138 | if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad ordnum */ | ||
139 | if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad patnum */ | ||
140 | if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad insnum */ | ||
141 | |||
142 | _mm_fseek(modreader,64,SEEK_SET); | ||
143 | if(!_mm_read_UBYTES(buf,512,modreader)) return 0; | ||
144 | /* verify channel status */ | ||
145 | for (t = 0, chn = 0, p = &buf[15]; t < 512; t += 16, p += 16) { | ||
146 | switch (*p) { | ||
147 | case 0: /* channel enabled */ | ||
148 | case 1: /* channel muted */ | ||
149 | chn++; | ||
150 | break; | ||
151 | case 2: /* channel disabled */ | ||
152 | break; | ||
153 | default: /* bad status value */ | ||
154 | return 0; | ||
155 | } | ||
156 | } | ||
157 | if(!chn) return 0; /* no channels found */ | ||
158 | |||
159 | return 1; | ||
136 | } | 160 | } |
137 | 161 | ||
138 | static int IMF_Init(void) | 162 | static int IMF_Init(void) |
@@ -149,6 +173,8 @@ static void IMF_Cleanup(void) | |||
149 | 173 | ||
150 | MikMod_free(imfpat); | 174 | MikMod_free(imfpat); |
151 | MikMod_free(mh); | 175 | MikMod_free(mh); |
176 | imfpat=NULL; | ||
177 | mh=NULL; | ||
152 | } | 178 | } |
153 | 179 | ||
154 | static int IMF_ReadPattern(SLONG size,UWORD rows) | 180 | static int IMF_ReadPattern(SLONG size,UWORD rows) |
@@ -388,7 +414,7 @@ static int IMF_Load(int curious) | |||
388 | ULONG *nextwav=NULL; | 414 | ULONG *nextwav=NULL; |
389 | UWORD wavcnt=0; | 415 | UWORD wavcnt=0; |
390 | UBYTE id[4]; | 416 | UBYTE id[4]; |
391 | (void)curious; | 417 | (void)curious; |
392 | 418 | ||
393 | /* try to read the module header */ | 419 | /* try to read the module header */ |
394 | _mm_read_string(mh->songname,32,modreader); | 420 | _mm_read_string(mh->songname,32,modreader); |
@@ -410,7 +436,7 @@ static int IMF_Load(int curious) | |||
410 | 436 | ||
411 | /* set module variables */ | 437 | /* set module variables */ |
412 | of.songname=DupStr(mh->songname,31,1); | 438 | of.songname=DupStr(mh->songname,31,1); |
413 | of.modtype=StrDup(IMF_Version); | 439 | of.modtype=MikMod_strdup(IMF_Version); |
414 | of.numpat=mh->patnum; | 440 | of.numpat=mh->patnum; |
415 | of.numins=mh->insnum; | 441 | of.numins=mh->insnum; |
416 | of.reppos=0; | 442 | of.reppos=0; |
@@ -467,6 +493,13 @@ static int IMF_Load(int curious) | |||
467 | if(!AllocPositions(of.numpos)) return 0; | 493 | if(!AllocPositions(of.numpos)) return 0; |
468 | for(t=u=0;t<mh->ordnum;t++) | 494 | for(t=u=0;t<mh->ordnum;t++) |
469 | if(mh->orders[t]!=0xff) of.positions[u++]=mh->orders[t]; | 495 | if(mh->orders[t]!=0xff) of.positions[u++]=mh->orders[t]; |
496 | for(t=0;t<of.numpos;t++) { | ||
497 | if (of.positions[t]>of.numpat) { /* SANITIY CHECK */ | ||
498 | /* fprintf(stderr,"position[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/ | ||
499 | _mm_errno = MMERR_LOADING_HEADER; | ||
500 | return 0; | ||
501 | } | ||
502 | } | ||
470 | 503 | ||
471 | /* load pattern info */ | 504 | /* load pattern info */ |
472 | of.numtrk=of.numpat*of.numchn; | 505 | of.numtrk=of.numpat*of.numchn; |
@@ -509,16 +542,16 @@ static int IMF_Load(int curious) | |||
509 | _mm_read_I_UWORDS(ih.panenv,IMFENVCNT,modreader); | 542 | _mm_read_I_UWORDS(ih.panenv,IMFENVCNT,modreader); |
510 | _mm_read_I_UWORDS(ih.pitenv,IMFENVCNT,modreader); | 543 | _mm_read_I_UWORDS(ih.pitenv,IMFENVCNT,modreader); |
511 | 544 | ||
512 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 545 | #if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C |
513 | #define IMF_FinishLoadingEnvelope(name) \ | 546 | #define IMF_FinishLoadingEnvelope(name) \ |
514 | ih. name##pts=_mm_read_UBYTE(modreader); \ | 547 | ih. name##pts=_mm_read_UBYTE(modreader); \ |
515 | ih. name##sus=_mm_read_UBYTE(modreader); \ | 548 | ih. name##sus=_mm_read_UBYTE(modreader); \ |
516 | ih. name##beg=_mm_read_UBYTE(modreader); \ | 549 | ih. name##beg=_mm_read_UBYTE(modreader); \ |
517 | ih. name##end=_mm_read_UBYTE(modreader); \ | 550 | ih. name##end=_mm_read_UBYTE(modreader); \ |
518 | ih. name##flg=_mm_read_UBYTE(modreader); \ | 551 | ih. name##flg=_mm_read_UBYTE(modreader); \ |
519 | (void)_mm_read_UBYTE(modreader); \ | 552 | _mm_skip_BYTE(modreader); \ |
520 | (void)_mm_read_UBYTE(modreader); \ | 553 | _mm_skip_BYTE(modreader); \ |
521 | (void)_mm_read_UBYTE(modreader) | 554 | _mm_skip_BYTE(modreader) |
522 | #else | 555 | #else |
523 | #define IMF_FinishLoadingEnvelope(name) \ | 556 | #define IMF_FinishLoadingEnvelope(name) \ |
524 | ih. name/**/pts=_mm_read_UBYTE(modreader); \ | 557 | ih. name/**/pts=_mm_read_UBYTE(modreader); \ |
@@ -526,9 +559,9 @@ static int IMF_Load(int curious) | |||
526 | ih. name/**/beg=_mm_read_UBYTE(modreader); \ | 559 | ih. name/**/beg=_mm_read_UBYTE(modreader); \ |
527 | ih. name/**/end=_mm_read_UBYTE(modreader); \ | 560 | ih. name/**/end=_mm_read_UBYTE(modreader); \ |
528 | ih. name/**/flg=_mm_read_UBYTE(modreader); \ | 561 | ih. name/**/flg=_mm_read_UBYTE(modreader); \ |
529 | (void)_mm_read_UBYTE(modreader); \ | 562 | _mm_skip_BYTE(modreader); \ |
530 | (void)_mm_read_UBYTE(modreader); \ | 563 | _mm_skip_BYTE(modreader); \ |
531 | (void)_mm_read_UBYTE(modreader) | 564 | _mm_skip_BYTE(modreader) |
532 | #endif | 565 | #endif |
533 | 566 | ||
534 | IMF_FinishLoadingEnvelope(vol); | 567 | IMF_FinishLoadingEnvelope(vol); |
@@ -541,7 +574,7 @@ static int IMF_Load(int curious) | |||
541 | _mm_read_UBYTES(id,4,modreader); | 574 | _mm_read_UBYTES(id,4,modreader); |
542 | /* Looks like Imago Orpheus forgets the signature for empty | 575 | /* Looks like Imago Orpheus forgets the signature for empty |
543 | instruments following a multi-sample instrument... */ | 576 | instruments following a multi-sample instrument... */ |
544 | if(memcmp(id,"II10",4) && | 577 | if(memcmp(id,"II10",4) && |
545 | (oldnumsmp && memcmp(id,"\x0\x0\x0\x0",4))) { | 578 | (oldnumsmp && memcmp(id,"\x0\x0\x0\x0",4))) { |
546 | if(nextwav) MikMod_free(nextwav); | 579 | if(nextwav) MikMod_free(nextwav); |
547 | if(wh) MikMod_free(wh); | 580 | if(wh) MikMod_free(wh); |
@@ -562,7 +595,7 @@ static int IMF_Load(int curious) | |||
562 | d->samplenumber[u]=ih.what[u]>ih.numsmp?0xffff:ih.what[u]+of.numsmp; | 595 | d->samplenumber[u]=ih.what[u]>ih.numsmp?0xffff:ih.what[u]+of.numsmp; |
563 | d->volfade=ih.volfade; | 596 | d->volfade=ih.volfade; |
564 | 597 | ||
565 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 598 | #if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C |
566 | #define IMF_ProcessEnvelope(name) \ | 599 | #define IMF_ProcessEnvelope(name) \ |
567 | for (u = 0; u < (IMFENVCNT >> 1); u++) { \ | 600 | for (u = 0; u < (IMFENVCNT >> 1); u++) { \ |
568 | d-> name##env[u].pos = ih. name##env[u << 1]; \ | 601 | d-> name##env[u].pos = ih. name##env[u << 1]; \ |
@@ -613,12 +646,12 @@ static int IMF_Load(int curious) | |||
613 | /* allocate more room for sample information if necessary */ | 646 | /* allocate more room for sample information if necessary */ |
614 | if(of.numsmp+u==wavcnt) { | 647 | if(of.numsmp+u==wavcnt) { |
615 | wavcnt+=IMF_SMPINCR; | 648 | wavcnt+=IMF_SMPINCR; |
616 | if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))) { | 649 | if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))) { |
617 | if(wh) MikMod_free(wh); | 650 | if(wh) MikMod_free(wh); |
618 | _mm_errno=MMERR_OUT_OF_MEMORY; | 651 | _mm_errno=MMERR_OUT_OF_MEMORY; |
619 | return 0; | 652 | return 0; |
620 | } | 653 | } |
621 | if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) { | 654 | if(!(wh=(IMFWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) { |
622 | MikMod_free(nextwav); | 655 | MikMod_free(nextwav); |
623 | _mm_errno=MMERR_OUT_OF_MEMORY; | 656 | _mm_errno=MMERR_OUT_OF_MEMORY; |
624 | return 0; | 657 | return 0; |
@@ -627,7 +660,7 @@ static int IMF_Load(int curious) | |||
627 | } | 660 | } |
628 | 661 | ||
629 | _mm_read_string(s->samplename,13,modreader); | 662 | _mm_read_string(s->samplename,13,modreader); |
630 | (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader); | 663 | _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); |
631 | s->length =_mm_read_I_ULONG(modreader); | 664 | s->length =_mm_read_I_ULONG(modreader); |
632 | s->loopstart =_mm_read_I_ULONG(modreader); | 665 | s->loopstart =_mm_read_I_ULONG(modreader); |
633 | s->loopend =_mm_read_I_ULONG(modreader); | 666 | s->loopend =_mm_read_I_ULONG(modreader); |
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 | ||
diff --git a/apps/plugins/mikmod/load_m15.c b/apps/plugins/mikmod/load_m15.c index b5d5329bf0..2359175bb3 100644 --- a/apps/plugins/mikmod/load_m15.c +++ b/apps/plugins/mikmod/load_m15.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_m15.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | 15 instrument MOD loader | 25 | 15 instrument MOD loader |
26 | Also supports Ultimate Sound Tracker (old M15 format) | 26 | Also supports Ultimate Sound Tracker (old M15 format) |
@@ -79,33 +79,31 @@ static int ust_loader = 0; /* if TRUE, load as an ust module. */ | |||
79 | 79 | ||
80 | /* known file formats which can confuse the loader */ | 80 | /* known file formats which can confuse the loader */ |
81 | #define REJECT 2 | 81 | #define REJECT 2 |
82 | static char *signatures[REJECT]={ | 82 | static const char *signatures[REJECT]={ |
83 | "CAKEWALK", /* cakewalk midi files */ | 83 | "CAKEWALK", /* cakewalk midi files */ |
84 | "SZDD" /* Microsoft compressed files */ | 84 | "SZDD" /* Microsoft compressed files */ |
85 | }; | 85 | }; |
86 | static int siglen[REJECT]={8,4}; | 86 | static const int siglen[REJECT]={8,4}; |
87 | 87 | ||
88 | /*========== Loader code */ | 88 | /*========== Loader code */ |
89 | 89 | ||
90 | static int LoadModuleHeader(MODULEHEADER *mh) | 90 | static int LoadModuleHeader(MODULEHEADER *h) |
91 | { | 91 | { |
92 | int t,u; | 92 | int t,u; |
93 | 93 | ||
94 | _mm_read_string(mh->songname,20,modreader); | 94 | _mm_read_string(h->songname,20,modreader); |
95 | mh->songname[20]=0; /* just in case */ | ||
96 | 95 | ||
97 | /* sanity check : title should contain printable characters and a bunch | 96 | /* sanity check : title should contain printable characters and a bunch |
98 | of null chars */ | 97 | of null chars */ |
99 | for(t=0;t<20;t++) | 98 | for(t=0;t<20;t++) |
100 | if((mh->songname[t])&&(mh->songname[t]<32)) return 0; | 99 | if((h->songname[t])&&(h->songname[t]<32)) return 0; |
101 | for(t=0;(mh->songname[t])&&(t<20);t++); | 100 | for(t=0;(h->songname[t])&&(t<20);t++); |
102 | if(t<20) for(;t<20;t++) if(mh->songname[t]) return 0; | 101 | if(t<20) for(;t<20;t++) if(h->songname[t]) return 0; |
103 | 102 | ||
104 | for(t=0;t<15;t++) { | 103 | for(t=0;t<15;t++) { |
105 | MSAMPINFO *s=&mh->samples[t]; | 104 | MSAMPINFO *s=&h->samples[t]; |
106 | 105 | ||
107 | _mm_read_string(s->samplename,22,modreader); | 106 | _mm_read_string(s->samplename,22,modreader); |
108 | s->samplename[22]=0; /* just in case */ | ||
109 | s->length =_mm_read_M_UWORD(modreader); | 107 | s->length =_mm_read_M_UWORD(modreader); |
110 | s->finetune =_mm_read_UBYTE(modreader); | 108 | s->finetune =_mm_read_UBYTE(modreader); |
111 | s->volume =_mm_read_UBYTE(modreader); | 109 | s->volume =_mm_read_UBYTE(modreader); |
@@ -123,26 +121,26 @@ static int LoadModuleHeader(MODULEHEADER *mh) | |||
123 | if(s->finetune>>4) return 0; | 121 | if(s->finetune>>4) return 0; |
124 | } | 122 | } |
125 | 123 | ||
126 | mh->songlength =_mm_read_UBYTE(modreader); | 124 | h->songlength =_mm_read_UBYTE(modreader); |
127 | mh->magic1 =_mm_read_UBYTE(modreader); /* should be 127 */ | 125 | h->magic1 =_mm_read_UBYTE(modreader); /* should be 127 */ |
128 | 126 | ||
129 | /* sanity check : no more than 128 positions, restart position in range */ | 127 | /* sanity check : no more than 128 positions, restart position in range */ |
130 | if((!mh->songlength)||(mh->songlength>128)) return 0; | 128 | if((!h->songlength)||(h->songlength>128)) return 0; |
131 | /* values encountered so far are 0x6a and 0x78 */ | 129 | /* values encountered so far are 0x6a and 0x78 */ |
132 | if(((mh->magic1&0xf8)!=0x78)&&(mh->magic1!=0x6a)&&(mh->magic1>mh->songlength)) return 0; | 130 | if(((h->magic1&0xf8)!=0x78)&&(h->magic1!=0x6a)&&(h->magic1>h->songlength)) return 0; |
133 | 131 | ||
134 | _mm_read_UBYTES(mh->positions,128,modreader); | 132 | _mm_read_UBYTES(h->positions,128,modreader); |
135 | 133 | ||
136 | /* sanity check : pattern range is 0..63 */ | 134 | /* sanity check : pattern range is 0..63 */ |
137 | for(t=0;t<128;t++) | 135 | for(t=0;t<128;t++) |
138 | if(mh->positions[t]>63) return 0; | 136 | if(h->positions[t]>63) return 0; |
139 | 137 | ||
140 | return(!_mm_eof(modreader)); | 138 | return(!_mm_eof(modreader)); |
141 | } | 139 | } |
142 | 140 | ||
143 | /* Checks the patterns in the modfile for UST / 15-inst indications. | 141 | /* Checks the patterns in the modfile for UST / 15-inst indications. |
144 | For example, if an effect 3xx is found, it is assumed that the song | 142 | For example, if an effect 3xx is found, it is assumed that the song |
145 | is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST. | 143 | is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST. |
146 | 144 | ||
147 | Returns: 0 indecisive; 1 = UST; 2 = 15-inst */ | 145 | Returns: 0 indecisive; 1 = UST; 2 = 15-inst */ |
148 | static int CheckPatternType(int numpat) | 146 | static int CheckPatternType(int numpat) |
@@ -152,7 +150,7 @@ static int CheckPatternType(int numpat) | |||
152 | 150 | ||
153 | for(t=0;t<numpat*(64U*4);t++) { | 151 | for(t=0;t<numpat*(64U*4);t++) { |
154 | /* Load the pattern into the temp buffer and scan it */ | 152 | /* Load the pattern into the temp buffer and scan it */ |
155 | (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader); | 153 | _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); |
156 | eff = _mm_read_UBYTE(modreader); | 154 | eff = _mm_read_UBYTE(modreader); |
157 | dat = _mm_read_UBYTE(modreader); | 155 | dat = _mm_read_UBYTE(modreader); |
158 | 156 | ||
@@ -177,55 +175,56 @@ static int CheckPatternType(int numpat) | |||
177 | static int M15_Test(void) | 175 | static int M15_Test(void) |
178 | { | 176 | { |
179 | int t, numpat; | 177 | int t, numpat; |
180 | MODULEHEADER mh; | 178 | MODULEHEADER h; |
181 | 179 | ||
182 | ust_loader = 0; | 180 | ust_loader = 0; |
183 | if(!LoadModuleHeader(&mh)) return 0; | 181 | memset(&h, 0, sizeof(MODULEHEADER)); |
182 | if(!LoadModuleHeader(&h)) return 0; | ||
184 | 183 | ||
185 | /* reject other file types */ | 184 | /* reject other file types */ |
186 | for(t=0;t<REJECT;t++) | 185 | for(t=0;t<REJECT;t++) |
187 | if(!memcmp(mh.songname,signatures[t],siglen[t])) return 0; | 186 | if(!memcmp(h.songname,signatures[t],siglen[t])) return 0; |
188 | 187 | ||
189 | if(mh.magic1>127) return 0; | 188 | if(h.magic1>127) return 0; |
190 | if((!mh.songlength)||(mh.songlength>mh.magic1)) return 0; | 189 | if((!h.songlength)||(h.songlength>h.magic1)) return 0; |
191 | 190 | ||
192 | for(t=0;t<15;t++) { | 191 | for(t=0;t<15;t++) { |
193 | /* all finetunes should be zero */ | 192 | /* all finetunes should be zero */ |
194 | if(mh.samples[t].finetune) return 0; | 193 | if(h.samples[t].finetune) return 0; |
195 | 194 | ||
196 | /* all volumes should be <= 64 */ | 195 | /* all volumes should be <= 64 */ |
197 | if(mh.samples[t].volume>64) return 0; | 196 | if(h.samples[t].volume>64) return 0; |
198 | 197 | ||
199 | /* all instrument names should begin with s, st-, or a number */ | 198 | /* all instrument names should begin with s, st-, or a number */ |
200 | if((mh.samples[t].samplename[0]=='s')|| | 199 | if((h.samples[t].samplename[0]=='s')|| |
201 | (mh.samples[t].samplename[0]=='S')) { | 200 | (h.samples[t].samplename[0]=='S')) { |
202 | if((memcmp(mh.samples[t].samplename,"st-",3)) && | 201 | if((memcmp(h.samples[t].samplename,"st-",3)) && |
203 | (memcmp(mh.samples[t].samplename,"ST-",3)) && | 202 | (memcmp(h.samples[t].samplename,"ST-",3)) && |
204 | (*mh.samples[t].samplename)) | 203 | (*h.samples[t].samplename)) |
205 | ust_loader = 1; | 204 | ust_loader = 1; |
206 | } else | 205 | } else |
207 | if(!isdigit((int)mh.samples[t].samplename[0])) | 206 | if(!isdigit((int)h.samples[t].samplename[0])) |
208 | ust_loader = 1; | 207 | ust_loader = 1; |
209 | 208 | ||
210 | if(mh.samples[t].length>4999||mh.samples[t].reppos>9999) { | 209 | if(h.samples[t].length>4999||h.samples[t].reppos>9999) { |
211 | ust_loader = 0; | 210 | ust_loader = 0; |
212 | if(mh.samples[t].length>32768) return 0; | 211 | if(h.samples[t].length>32768) return 0; |
213 | } | 212 | } |
214 | 213 | ||
215 | /* if loop information is incorrect as words, but correct as bytes, | 214 | /* if loop information is incorrect as words, but correct as bytes, |
216 | this is likely to be an ust-style module */ | 215 | this is likely to be an ust-style module */ |
217 | if((mh.samples[t].reppos+mh.samples[t].replen>mh.samples[t].length)&& | 216 | if((h.samples[t].reppos+h.samples[t].replen>h.samples[t].length)&& |
218 | (mh.samples[t].reppos+mh.samples[t].replen<(mh.samples[t].length<<1))){ | 217 | (h.samples[t].reppos+h.samples[t].replen<(h.samples[t].length<<1))) { |
219 | ust_loader = 1; | 218 | ust_loader = 1; |
220 | return 1; | 219 | return 1; |
221 | } | 220 | } |
222 | 221 | ||
223 | if(!ust_loader) return 1; | 222 | if(!ust_loader) return 1; |
224 | } | 223 | } |
225 | 224 | ||
226 | for(numpat=0,t=0;t<mh.songlength;t++) | 225 | for(numpat=0,t=0;t<h.songlength;t++) |
227 | if(mh.positions[t]>numpat) | 226 | if(h.positions[t]>numpat) |
228 | numpat = mh.positions[t]; | 227 | numpat = h.positions[t]; |
229 | numpat++; | 228 | numpat++; |
230 | switch(CheckPatternType(numpat)) { | 229 | switch(CheckPatternType(numpat)) { |
231 | case 0: /* indecisive, so check more clues... */ | 230 | case 0: /* indecisive, so check more clues... */ |
@@ -242,7 +241,7 @@ static int M15_Test(void) | |||
242 | 241 | ||
243 | static int M15_Init(void) | 242 | static int M15_Init(void) |
244 | { | 243 | { |
245 | if(!(mh=(MODULEHEADER*)MikMod_malloc(sizeof(MODULEHEADER)))) return 0; | 244 | if(!(mh=(MODULEHEADER*)MikMod_calloc(1,sizeof(MODULEHEADER)))) return 0; |
246 | return 1; | 245 | return 1; |
247 | } | 246 | } |
248 | 247 | ||
@@ -250,6 +249,8 @@ static void M15_Cleanup(void) | |||
250 | { | 249 | { |
251 | MikMod_free(mh); | 250 | MikMod_free(mh); |
252 | MikMod_free(patbuf); | 251 | MikMod_free(patbuf); |
252 | mh=NULL; | ||
253 | patbuf=NULL; | ||
253 | } | 254 | } |
254 | 255 | ||
255 | /* | 256 | /* |
@@ -331,7 +332,7 @@ static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect) | |||
331 | case 1: | 332 | case 1: |
332 | UniPTEffect(0,effdat); | 333 | UniPTEffect(0,effdat); |
333 | break; | 334 | break; |
334 | case 2: | 335 | case 2: |
335 | if(effdat&0xf) UniPTEffect(1,effdat&0xf); | 336 | if(effdat&0xf) UniPTEffect(1,effdat&0xf); |
336 | else if(effdat>>2) UniPTEffect(2,effdat>>2); | 337 | else if(effdat>>2) UniPTEffect(2,effdat>>2); |
337 | break; | 338 | break; |
@@ -351,7 +352,7 @@ static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect) | |||
351 | } | 352 | } |
352 | if (effect == 8) | 353 | if (effect == 8) |
353 | of.flags |= UF_PANNING; | 354 | of.flags |= UF_PANNING; |
354 | 355 | ||
355 | return effect; | 356 | return effect; |
356 | } | 357 | } |
357 | 358 | ||
@@ -372,8 +373,7 @@ static UBYTE *M15_ConvertTrack(MODNOTE* n) | |||
372 | /* Loads all patterns of a modfile and converts them into the 3 byte format. */ | 373 | /* Loads all patterns of a modfile and converts them into the 3 byte format. */ |
373 | static int M15_LoadPatterns(void) | 374 | static int M15_LoadPatterns(void) |
374 | { | 375 | { |
375 | int t,tracks=0; | 376 | unsigned int t,s,tracks=0; |
376 | unsigned int s; | ||
377 | 377 | ||
378 | if(!AllocPatterns()) return 0; | 378 | if(!AllocPatterns()) return 0; |
379 | if(!AllocTracks()) return 0; | 379 | if(!AllocTracks()) return 0; |
@@ -398,9 +398,10 @@ static int M15_LoadPatterns(void) | |||
398 | 398 | ||
399 | static int M15_Load(int curious) | 399 | static int M15_Load(int curious) |
400 | { | 400 | { |
401 | int t,scan; | 401 | unsigned int t,scan; |
402 | SAMPLE *q; | 402 | SAMPLE *q; |
403 | MSAMPINFO *s; | 403 | MSAMPINFO *s; |
404 | (void)curious; | ||
404 | 405 | ||
405 | /* try to read module header */ | 406 | /* try to read module header */ |
406 | if(!LoadModuleHeader(mh)) { | 407 | if(!LoadModuleHeader(mh)) { |
@@ -409,14 +410,14 @@ static int M15_Load(int curious) | |||
409 | } | 410 | } |
410 | 411 | ||
411 | if(ust_loader) | 412 | if(ust_loader) |
412 | of.modtype = StrDup("Ultimate Soundtracker"); | 413 | of.modtype = MikMod_strdup("Ultimate Soundtracker"); |
413 | else | 414 | else |
414 | of.modtype = StrDup("Soundtracker"); | 415 | of.modtype = MikMod_strdup("Soundtracker"); |
415 | 416 | ||
416 | /* set module variables */ | 417 | /* set module variables */ |
417 | of.initspeed = 6; | 418 | of.initspeed = 6; |
418 | of.inittempo = 125; | 419 | of.inittempo = 125; |
419 | of.numchn = 4; | 420 | of.numchn = 4; |
420 | of.songname = DupStr(mh->songname,21,1); | 421 | of.songname = DupStr(mh->songname,21,1); |
421 | of.numpos = mh->songlength; | 422 | of.numpos = mh->songlength; |
422 | of.reppos = 0; | 423 | of.reppos = 0; |
@@ -467,7 +468,7 @@ static int M15_Load(int curious) | |||
467 | q->length = s->length<<1; | 468 | q->length = s->length<<1; |
468 | 469 | ||
469 | q->flags = SF_SIGNED; | 470 | q->flags = SF_SIGNED; |
470 | if(ust_loader) q->flags |= SF_UST_LOOP; | 471 | if(ust_loader) q->flags |= SF_UST_LOOP; |
471 | if(s->replen>2) q->flags |= SF_LOOP; | 472 | if(s->replen>2) q->flags |= SF_LOOP; |
472 | 473 | ||
473 | s++; | 474 | s++; |
diff --git a/apps/plugins/mikmod/load_med.c b/apps/plugins/mikmod/load_med.c index aafb6602a6..a6af8c06cb 100644 --- a/apps/plugins/mikmod/load_med.c +++ b/apps/plugins/mikmod/load_med.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_med.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Amiga MED module loader | 25 | Amiga MED module loader |
26 | 26 | ||
@@ -189,6 +189,12 @@ static void MED_Cleanup(void) | |||
189 | MikMod_free(ba); | 189 | MikMod_free(ba); |
190 | MikMod_free(mmd0pat); | 190 | MikMod_free(mmd0pat); |
191 | MikMod_free(mmd1pat); | 191 | MikMod_free(mmd1pat); |
192 | me = NULL; | ||
193 | mh = NULL; | ||
194 | ms = NULL; | ||
195 | ba = NULL; | ||
196 | mmd0pat = NULL; | ||
197 | mmd1pat = NULL; | ||
192 | } | 198 | } |
193 | 199 | ||
194 | static void EffectCvt(UBYTE eff, UBYTE dat) | 200 | static void EffectCvt(UBYTE eff, UBYTE dat) |
@@ -338,7 +344,13 @@ static int LoadMEDPatterns(void) | |||
338 | of.numchn = numtracks; | 344 | of.numchn = numtracks; |
339 | if (numlines > maxlines) | 345 | if (numlines > maxlines) |
340 | maxlines = numlines; | 346 | maxlines = numlines; |
347 | /* sanity check */ | ||
348 | if (numtracks > 64) | ||
349 | return 0; | ||
341 | } | 350 | } |
351 | /* sanity check */ | ||
352 | if (! of.numchn) /* docs say 4, 8, 12 or 16 */ | ||
353 | return 0; | ||
342 | 354 | ||
343 | of.numtrk = of.numpat * of.numchn; | 355 | of.numtrk = of.numpat * of.numchn; |
344 | if (!AllocTracks()) | 356 | if (!AllocTracks()) |
@@ -346,10 +358,8 @@ static int LoadMEDPatterns(void) | |||
346 | if (!AllocPatterns()) | 358 | if (!AllocPatterns()) |
347 | return 0; | 359 | return 0; |
348 | 360 | ||
349 | if (! | 361 | if (!(mmd0pat = (MMD0NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), sizeof(MMD0NOTE)))) |
350 | (mmd0pat = | 362 | return 0; |
351 | (MMD0NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), | ||
352 | sizeof(MMD0NOTE)))) return 0; | ||
353 | 363 | ||
354 | /* second read: read and convert patterns */ | 364 | /* second read: read and convert patterns */ |
355 | for (t = 0; t < of.numpat; t++) { | 365 | for (t = 0; t < of.numpat; t++) { |
@@ -388,7 +398,15 @@ static int LoadMMD1Patterns(void) | |||
388 | of.numchn = numtracks; | 398 | of.numchn = numtracks; |
389 | if (numlines > maxlines) | 399 | if (numlines > maxlines) |
390 | maxlines = numlines; | 400 | maxlines = numlines; |
401 | /* sanity check */ | ||
402 | if (numtracks > 64) | ||
403 | return 0; | ||
404 | if (numlines >= 3200) /* per docs */ | ||
405 | return 0; | ||
391 | } | 406 | } |
407 | /* sanity check */ | ||
408 | if (! of.numchn) /* docs say 4, 8, 12 or 16 */ | ||
409 | return 0; | ||
392 | 410 | ||
393 | of.numtrk = of.numpat * of.numchn; | 411 | of.numtrk = of.numpat * of.numchn; |
394 | if (!AllocTracks()) | 412 | if (!AllocTracks()) |
@@ -396,10 +414,8 @@ static int LoadMMD1Patterns(void) | |||
396 | if (!AllocPatterns()) | 414 | if (!AllocPatterns()) |
397 | return 0; | 415 | return 0; |
398 | 416 | ||
399 | if (! | 417 | if (!(mmd1pat = (MMD1NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), sizeof(MMD1NOTE)))) |
400 | (mmd1pat = | 418 | return 0; |
401 | (MMD1NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), | ||
402 | sizeof(MMD1NOTE)))) return 0; | ||
403 | 419 | ||
404 | /* second read: really read and convert patterns */ | 420 | /* second read: really read and convert patterns */ |
405 | for (t = 0; t < of.numpat; t++) { | 421 | for (t = 0; t < of.numpat; t++) { |
@@ -471,6 +487,11 @@ static int MED_Load(int curious) | |||
471 | ms->numblocks = _mm_read_M_UWORD(modreader); | 487 | ms->numblocks = _mm_read_M_UWORD(modreader); |
472 | ms->songlen = _mm_read_M_UWORD(modreader); | 488 | ms->songlen = _mm_read_M_UWORD(modreader); |
473 | _mm_read_UBYTES(ms->playseq, 256, modreader); | 489 | _mm_read_UBYTES(ms->playseq, 256, modreader); |
490 | /* sanity check */ | ||
491 | if (ms->numblocks > 255 || ms->songlen > 256) { | ||
492 | _mm_errno = MMERR_NOT_A_MODULE; | ||
493 | return 0; | ||
494 | } | ||
474 | ms->deftempo = _mm_read_M_UWORD(modreader); | 495 | ms->deftempo = _mm_read_M_UWORD(modreader); |
475 | ms->playtransp = _mm_read_SBYTE(modreader); | 496 | ms->playtransp = _mm_read_SBYTE(modreader); |
476 | ms->flags = _mm_read_UBYTE(modreader); | 497 | ms->flags = _mm_read_UBYTE(modreader); |
@@ -479,6 +500,11 @@ static int MED_Load(int curious) | |||
479 | _mm_read_UBYTES(ms->trkvol, 16, modreader); | 500 | _mm_read_UBYTES(ms->trkvol, 16, modreader); |
480 | ms->mastervol = _mm_read_UBYTE(modreader); | 501 | ms->mastervol = _mm_read_UBYTE(modreader); |
481 | ms->numsamples = _mm_read_UBYTE(modreader); | 502 | ms->numsamples = _mm_read_UBYTE(modreader); |
503 | /* sanity check */ | ||
504 | if (ms->numsamples > 64) { | ||
505 | _mm_errno = MMERR_NOT_A_MODULE; | ||
506 | return 0; | ||
507 | } | ||
482 | 508 | ||
483 | /* check for a bad header */ | 509 | /* check for a bad header */ |
484 | if (_mm_eof(modreader)) { | 510 | if (_mm_eof(modreader)) { |
@@ -505,6 +531,14 @@ static int MED_Load(int curious) | |||
505 | me->songname = _mm_read_M_ULONG(modreader); | 531 | me->songname = _mm_read_M_ULONG(modreader); |
506 | me->songnamelen = _mm_read_M_ULONG(modreader); | 532 | me->songnamelen = _mm_read_M_ULONG(modreader); |
507 | me->dumps = _mm_read_M_ULONG(modreader); | 533 | me->dumps = _mm_read_M_ULONG(modreader); |
534 | /* sanity check */ | ||
535 | if (me->annolen > 0xffff) { | ||
536 | _mm_errno = MMERR_NOT_A_MODULE; | ||
537 | return 0; | ||
538 | } | ||
539 | /* truncate insane songnamelen (fail instead??) */ | ||
540 | if (me->songnamelen > 256) | ||
541 | me->songnamelen = 256; | ||
508 | } | 542 | } |
509 | 543 | ||
510 | /* seek to and read the samplepointer array */ | 544 | /* seek to and read the samplepointer array */ |
@@ -526,8 +560,14 @@ static int MED_Load(int curious) | |||
526 | /* copy song positions */ | 560 | /* copy song positions */ |
527 | if (!AllocPositions(ms->songlen)) | 561 | if (!AllocPositions(ms->songlen)) |
528 | return 0; | 562 | return 0; |
529 | for (t = 0; t < ms->songlen; t++) | 563 | for (t = 0; t < ms->songlen; t++) { |
530 | of.positions[t] = ms->playseq[t]; | 564 | of.positions[t] = ms->playseq[t]; |
565 | if (of.positions[t]>ms->numblocks) { /* SANITIY CHECK */ | ||
566 | /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],ms->numblocks);*/ | ||
567 | _mm_errno = MMERR_LOADING_HEADER; | ||
568 | return 0; | ||
569 | } | ||
570 | } | ||
531 | 571 | ||
532 | decimalvolumes = (ms->flags & 0x10) ? 0 : 1; | 572 | decimalvolumes = (ms->flags & 0x10) ? 0 : 1; |
533 | bpmtempos = (ms->flags2 & 0x20) ? 1 : 0; | 573 | bpmtempos = (ms->flags2 & 0x20) ? 1 : 0; |
@@ -571,7 +611,7 @@ static int MED_Load(int curious) | |||
571 | of.flags |= UF_HIGHBPM; | 611 | of.flags |= UF_HIGHBPM; |
572 | } | 612 | } |
573 | MED_Version[12] = mh->id; | 613 | MED_Version[12] = mh->id; |
574 | of.modtype = StrDup(MED_Version); | 614 | of.modtype = MikMod_strdup(MED_Version); |
575 | of.numchn = 0; /* will be counted later */ | 615 | of.numchn = 0; /* will be counted later */ |
576 | of.numpat = ms->numblocks; | 616 | of.numpat = ms->numblocks; |
577 | of.numpos = ms->songlen; | 617 | of.numpos = ms->songlen; |
@@ -582,7 +622,7 @@ static int MED_Load(int curious) | |||
582 | char *name; | 622 | char *name; |
583 | 623 | ||
584 | _mm_fseek(modreader, me->songname, SEEK_SET); | 624 | _mm_fseek(modreader, me->songname, SEEK_SET); |
585 | name = MikMod_malloc(me->songnamelen); | 625 | name = (char *) MikMod_malloc(me->songnamelen); |
586 | _mm_read_UBYTES(name, me->songnamelen, modreader); | 626 | _mm_read_UBYTES(name, me->songnamelen, modreader); |
587 | of.songname = DupStr(name, me->songnamelen, 1); | 627 | of.songname = DupStr(name, me->songnamelen, 1); |
588 | MikMod_free(name); | 628 | MikMod_free(name); |
@@ -684,17 +724,17 @@ static CHAR *MED_LoadTitle(void) | |||
684 | { | 724 | { |
685 | ULONG posit, namelen; | 725 | ULONG posit, namelen; |
686 | CHAR *name, *retvalue = NULL; | 726 | CHAR *name, *retvalue = NULL; |
687 | 727 | ||
688 | _mm_fseek(modreader, 0x20, SEEK_SET); | 728 | _mm_fseek(modreader, 0x20, SEEK_SET); |
689 | posit = _mm_read_M_ULONG(modreader); | 729 | posit = _mm_read_M_ULONG(modreader); |
690 | 730 | ||
691 | if (posit) { | 731 | if (posit) { |
692 | _mm_fseek(modreader, posit + 0x2C, SEEK_SET); | 732 | _mm_fseek(modreader, posit + 0x2C, SEEK_SET); |
693 | posit = _mm_read_M_ULONG(modreader); | 733 | posit = _mm_read_M_ULONG(modreader); |
694 | namelen = _mm_read_M_ULONG(modreader); | 734 | namelen = _mm_read_M_ULONG(modreader); |
695 | 735 | ||
696 | _mm_fseek(modreader, posit, SEEK_SET); | 736 | _mm_fseek(modreader, posit, SEEK_SET); |
697 | name = MikMod_malloc(namelen); | 737 | name = (CHAR*) MikMod_malloc(namelen); |
698 | _mm_read_UBYTES(name, namelen, modreader); | 738 | _mm_read_UBYTES(name, namelen, modreader); |
699 | retvalue = DupStr(name, namelen, 1); | 739 | retvalue = DupStr(name, namelen, 1); |
700 | MikMod_free(name); | 740 | MikMod_free(name); |
diff --git a/apps/plugins/mikmod/load_mod.c b/apps/plugins/mikmod/load_mod.c index 6075e9c7e1..0fe0dcd595 100644 --- a/apps/plugins/mikmod/load_mod.c +++ b/apps/plugins/mikmod/load_mod.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_mod.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Generic MOD loader (Protracker, StarTracker, FastTracker, etc) | 25 | Generic MOD loader (Protracker, StarTracker, FastTracker, etc) |
26 | 26 | ||
@@ -108,7 +108,7 @@ static int MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr) | |||
108 | *numchn = 4; | 108 | *numchn = 4; |
109 | return 1; | 109 | return 1; |
110 | } | 110 | } |
111 | 111 | ||
112 | /* Star Tracker */ | 112 | /* Star Tracker */ |
113 | if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) && | 113 | if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) && |
114 | (isdigit(id[3]))) { | 114 | (isdigit(id[3]))) { |
@@ -190,6 +190,8 @@ static void MOD_Cleanup(void) | |||
190 | { | 190 | { |
191 | MikMod_free(mh); | 191 | MikMod_free(mh); |
192 | MikMod_free(patbuf); | 192 | MikMod_free(patbuf); |
193 | mh=NULL; | ||
194 | patbuf=NULL; | ||
193 | } | 195 | } |
194 | 196 | ||
195 | /* | 197 | /* |
@@ -277,7 +279,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect) | |||
277 | /* Handle ``heavy'' volumes correctly */ | 279 | /* Handle ``heavy'' volumes correctly */ |
278 | if ((effect == 0xc) && (effdat > 0x40)) | 280 | if ((effect == 0xc) && (effdat > 0x40)) |
279 | effdat = 0x40; | 281 | effdat = 0x40; |
280 | 282 | ||
281 | /* An isolated 100, 200 or 300 effect should be ignored (no | 283 | /* An isolated 100, 200 or 300 effect should be ignored (no |
282 | "standalone" porta memory in mod files). However, a sequence such | 284 | "standalone" porta memory in mod files). However, a sequence such |
283 | as 1XX, 100, 100, 100 is fine. */ | 285 | as 1XX, 100, 100, 100 is fine. */ |
@@ -288,7 +290,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect) | |||
288 | UniPTEffect(effect, effdat); | 290 | UniPTEffect(effect, effdat); |
289 | if (effect == 8) | 291 | if (effect == 8) |
290 | of.flags |= UF_PANNING; | 292 | of.flags |= UF_PANNING; |
291 | 293 | ||
292 | return effect; | 294 | return effect; |
293 | } | 295 | } |
294 | 296 | ||
@@ -309,14 +311,13 @@ static UBYTE *ConvertTrack(MODNOTE *n, int numchn) | |||
309 | /* Loads all patterns of a modfile and converts them into the 3 byte format. */ | 311 | /* Loads all patterns of a modfile and converts them into the 3 byte format. */ |
310 | static int ML_LoadPatterns(void) | 312 | static int ML_LoadPatterns(void) |
311 | { | 313 | { |
312 | int t, tracks = 0; | 314 | unsigned int t, s, tracks = 0; |
313 | unsigned int s; | ||
314 | 315 | ||
315 | if (!AllocPatterns()) | 316 | if (!AllocPatterns()) |
316 | return 0; | 317 | return 0; |
317 | if (!AllocTracks()) | 318 | if (!AllocTracks()) |
318 | return 0; | 319 | return 0; |
319 | 320 | ||
320 | /* Allocate temporary buffer for loading and converting the patterns */ | 321 | /* Allocate temporary buffer for loading and converting the patterns */ |
321 | if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE)))) | 322 | if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE)))) |
322 | return 0; | 323 | return 0; |
@@ -385,10 +386,10 @@ static int MOD_Load(int curious) | |||
385 | 386 | ||
386 | mh->songlength = _mm_read_UBYTE(modreader); | 387 | mh->songlength = _mm_read_UBYTE(modreader); |
387 | 388 | ||
388 | /* this fixes mods which declare more than 128 positions. | 389 | /* this fixes mods which declare more than 128 positions. |
389 | * eg: beatwave.mod */ | 390 | * eg: beatwave.mod */ |
390 | if (mh->songlength > 128) { mh->songlength = 128; } | 391 | if (mh->songlength > 128) { mh->songlength = 128; } |
391 | 392 | ||
392 | mh->magic1 = _mm_read_UBYTE(modreader); | 393 | mh->magic1 = _mm_read_UBYTE(modreader); |
393 | _mm_read_UBYTES(mh->positions, 128, modreader); | 394 | _mm_read_UBYTES(mh->positions, 128, modreader); |
394 | _mm_read_UBYTES(mh->magic2, 4, modreader); | 395 | _mm_read_UBYTES(mh->magic2, 4, modreader); |
@@ -477,11 +478,11 @@ static int MOD_Load(int curious) | |||
477 | q++; | 478 | q++; |
478 | } | 479 | } |
479 | 480 | ||
480 | of.modtype = StrDup(descr); | 481 | of.modtype = MikMod_strdup(descr); |
481 | 482 | ||
482 | if (!ML_LoadPatterns()) | 483 | if (!ML_LoadPatterns()) |
483 | return 0; | 484 | return 0; |
484 | 485 | ||
485 | return 1; | 486 | return 1; |
486 | } | 487 | } |
487 | 488 | ||
diff --git a/apps/plugins/mikmod/load_mtm.c b/apps/plugins/mikmod/load_mtm.c index 6c9fb30846..5620575a10 100644 --- a/apps/plugins/mikmod/load_mtm.c +++ b/apps/plugins/mikmod/load_mtm.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_mtm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | MTM module loader | 25 | MTM module loader |
26 | 26 | ||
@@ -108,6 +108,8 @@ static void MTM_Cleanup(void) | |||
108 | { | 108 | { |
109 | MikMod_free(mtmtrk); | 109 | MikMod_free(mtmtrk); |
110 | MikMod_free(mh); | 110 | MikMod_free(mh); |
111 | mtmtrk=NULL; | ||
112 | mh=NULL; | ||
111 | } | 113 | } |
112 | 114 | ||
113 | static UBYTE* MTM_Convert(void) | 115 | static UBYTE* MTM_Convert(void) |
@@ -145,7 +147,7 @@ static int MTM_Load(int curious) | |||
145 | int t,u; | 147 | int t,u; |
146 | MTMSAMPLE s; | 148 | MTMSAMPLE s; |
147 | SAMPLE *q; | 149 | SAMPLE *q; |
148 | (void)curious; | 150 | (void)curious; |
149 | 151 | ||
150 | /* try to read module header */ | 152 | /* try to read module header */ |
151 | _mm_read_UBYTES(mh->id,3,modreader); | 153 | _mm_read_UBYTES(mh->id,3,modreader); |
@@ -169,7 +171,7 @@ static int MTM_Load(int curious) | |||
169 | /* set module variables */ | 171 | /* set module variables */ |
170 | of.initspeed = 6; | 172 | of.initspeed = 6; |
171 | of.inittempo = 125; | 173 | of.inittempo = 125; |
172 | of.modtype = StrDup(MTM_Version); | 174 | of.modtype = MikMod_strdup(MTM_Version); |
173 | of.numchn = mh->numchannels; | 175 | of.numchn = mh->numchannels; |
174 | of.numtrk = mh->numtracks+1; /* get number of channels */ | 176 | of.numtrk = mh->numtracks+1; /* get number of channels */ |
175 | of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */ | 177 | of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */ |
@@ -193,7 +195,7 @@ static int MTM_Load(int curious) | |||
193 | s.attribute =_mm_read_UBYTE(modreader); | 195 | s.attribute =_mm_read_UBYTE(modreader); |
194 | 196 | ||
195 | if(_mm_eof(modreader)) { | 197 | if(_mm_eof(modreader)) { |
196 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | 198 | _mm_errno = MMERR_LOADING_SAMPLEINFO; |
197 | return 0; | 199 | return 0; |
198 | } | 200 | } |
199 | 201 | ||
@@ -218,9 +220,15 @@ static int MTM_Load(int curious) | |||
218 | } | 220 | } |
219 | 221 | ||
220 | if(!AllocPositions(of.numpos)) return 0; | 222 | if(!AllocPositions(of.numpos)) return 0; |
221 | for(t=0;t<of.numpos;t++) | 223 | for(t=0;t<of.numpos;t++) { |
222 | of.positions[t]=_mm_read_UBYTE(modreader); | 224 | of.positions[t]=_mm_read_UBYTE(modreader); |
223 | for(;t<128;t++) (void)_mm_read_UBYTE(modreader); | 225 | if (of.positions[t]>of.numpat) { /* SANITIY CHECK */ |
226 | /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/ | ||
227 | _mm_errno = MMERR_LOADING_HEADER; | ||
228 | return 0; | ||
229 | } | ||
230 | } | ||
231 | for(;t<128;t++) _mm_skip_BYTE(modreader); | ||
224 | if(_mm_eof(modreader)) { | 232 | if(_mm_eof(modreader)) { |
225 | _mm_errno = MMERR_LOADING_HEADER; | 233 | _mm_errno = MMERR_LOADING_HEADER; |
226 | return 0; | 234 | return 0; |
@@ -231,12 +239,12 @@ static int MTM_Load(int curious) | |||
231 | 239 | ||
232 | of.tracks[0]=MTM_Convert(); /* track 0 is empty */ | 240 | of.tracks[0]=MTM_Convert(); /* track 0 is empty */ |
233 | for(t=1;t<of.numtrk;t++) { | 241 | for(t=1;t<of.numtrk;t++) { |
234 | int s; | 242 | int s_idx; |
235 | 243 | ||
236 | for(s=0;s<64;s++) { | 244 | for(s_idx=0;s_idx<64;s_idx++) { |
237 | mtmtrk[s].a=_mm_read_UBYTE(modreader); | 245 | mtmtrk[s_idx].a=_mm_read_UBYTE(modreader); |
238 | mtmtrk[s].b=_mm_read_UBYTE(modreader); | 246 | mtmtrk[s_idx].b=_mm_read_UBYTE(modreader); |
239 | mtmtrk[s].c=_mm_read_UBYTE(modreader); | 247 | mtmtrk[s_idx].c=_mm_read_UBYTE(modreader); |
240 | } | 248 | } |
241 | 249 | ||
242 | if(_mm_eof(modreader)) { | 250 | if(_mm_eof(modreader)) { |
diff --git a/apps/plugins/mikmod/load_okt.c b/apps/plugins/mikmod/load_okt.c index 6a40b5fe03..a0eee7f56e 100644 --- a/apps/plugins/mikmod/load_okt.c +++ b/apps/plugins/mikmod/load_okt.c | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | /*============================================================================== | 21 | /*============================================================================== |
22 | 22 | ||
23 | $Id: load_okt.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Oktalyzer (OKT) module loader | 25 | Oktalyzer (OKT) module loader |
26 | 26 | ||
@@ -203,7 +203,7 @@ static int OKT_doSAMP(int len) | |||
203 | s.len = _mm_read_M_ULONG(modreader); | 203 | s.len = _mm_read_M_ULONG(modreader); |
204 | s.loopbeg = _mm_read_M_UWORD(modreader) * 2; | 204 | s.loopbeg = _mm_read_M_UWORD(modreader) * 2; |
205 | s.looplen = _mm_read_M_UWORD(modreader) * 2; | 205 | s.looplen = _mm_read_M_UWORD(modreader) * 2; |
206 | (void)_mm_read_UBYTE(modreader); | 206 | _mm_skip_BYTE(modreader); |
207 | s.volume = _mm_read_UBYTE(modreader); | 207 | s.volume = _mm_read_UBYTE(modreader); |
208 | _mm_read_M_UWORD(modreader); | 208 | _mm_read_M_UWORD(modreader); |
209 | 209 | ||
@@ -314,6 +314,7 @@ static int OKT_doPBOD(int patnum) | |||
314 | } | 314 | } |
315 | MikMod_free(patbuf); | 315 | MikMod_free(patbuf); |
316 | MikMod_free(okttrk); | 316 | MikMod_free(okttrk); |
317 | okttrk = NULL; | ||
317 | return 1; | 318 | return 1; |
318 | } | 319 | } |
319 | 320 | ||
@@ -330,28 +331,28 @@ static int OKT_Load(int curious) | |||
330 | int seen_cmod = 0, seen_samp = 0, seen_slen = 0, seen_plen = 0, seen_patt | 331 | int seen_cmod = 0, seen_samp = 0, seen_slen = 0, seen_plen = 0, seen_patt |
331 | = 0, seen_spee = 0; | 332 | = 0, seen_spee = 0; |
332 | int patnum = 0, insnum = 0; | 333 | int patnum = 0, insnum = 0; |
333 | (void)curious; | 334 | (void)curious; |
334 | 335 | ||
335 | /* skip OKTALYZER header */ | 336 | /* skip OKTALYZER header */ |
336 | _mm_fseek(modreader, 8, SEEK_SET); | 337 | _mm_fseek(modreader, 8, SEEK_SET); |
337 | of.songname = StrDup(""); | 338 | of.songname = MikMod_strdup(""); |
338 | 339 | ||
339 | of.modtype = StrDup("Amiga Oktalyzer"); | 340 | of.modtype = MikMod_strdup("Amiga Oktalyzer"); |
340 | of.numpos = of.reppos = 0; | 341 | of.numpos = of.reppos = 0; |
341 | 342 | ||
342 | /* default values */ | 343 | /* default values */ |
343 | of.initspeed = 6; | 344 | of.initspeed = 6; |
344 | of.inittempo = 125; | 345 | of.inittempo = 125; |
345 | 346 | ||
346 | while (1) { | 347 | while (1) { |
347 | /* read block header */ | 348 | /* read block header */ |
348 | _mm_read_UBYTES(id, 4, modreader); | 349 | _mm_read_UBYTES(id, 4, modreader); |
349 | len = _mm_read_M_ULONG(modreader); | 350 | len = _mm_read_M_ULONG(modreader); |
350 | 351 | ||
351 | if (_mm_eof(modreader)) | 352 | if (_mm_eof(modreader)) |
352 | break; | 353 | break; |
353 | fp = _mm_ftell(modreader); | 354 | fp = _mm_ftell(modreader); |
354 | 355 | ||
355 | if (!memcmp(id, "CMOD", 4)) { | 356 | if (!memcmp(id, "CMOD", 4)) { |
356 | if (!seen_cmod) { | 357 | if (!seen_cmod) { |
357 | OKT_doCMOD(); | 358 | OKT_doCMOD(); |
@@ -442,7 +443,7 @@ static int OKT_Load(int curious) | |||
442 | 443 | ||
443 | static CHAR *OKT_LoadTitle(void) | 444 | static CHAR *OKT_LoadTitle(void) |
444 | { | 445 | { |
445 | return StrDup(""); | 446 | return MikMod_strdup(""); |
446 | } | 447 | } |
447 | 448 | ||
448 | /*========== Loader information */ | 449 | /*========== Loader information */ |
diff --git a/apps/plugins/mikmod/load_s3m.c b/apps/plugins/mikmod/load_s3m.c index e162388f15..076159afc5 100644 --- a/apps/plugins/mikmod/load_s3m.c +++ b/apps/plugins/mikmod/load_s3m.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_s3m.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Screamtracker (S3M) module loader | 25 | Screamtracker (S3M) module loader |
26 | 26 | ||
@@ -104,7 +104,7 @@ static unsigned int tracker; /* tracker id */ | |||
104 | 104 | ||
105 | /* tracker identifiers */ | 105 | /* tracker identifiers */ |
106 | #define NUMTRACKERS 4 | 106 | #define NUMTRACKERS 4 |
107 | static CHAR* S3M_Version[] = { | 107 | static const CHAR * S3M_Version[] = { |
108 | "Screamtracker x.xx", | 108 | "Screamtracker x.xx", |
109 | "Imago Orpheus x.xx (S3M format)", | 109 | "Imago Orpheus x.xx (S3M format)", |
110 | "Impulse Tracker x.xx (S3M format)", | 110 | "Impulse Tracker x.xx (S3M format)", |
@@ -113,7 +113,7 @@ static CHAR* S3M_Version[] = { | |||
113 | "Impulse Tracker 2.14p4 (S3M format)" | 113 | "Impulse Tracker 2.14p4 (S3M format)" |
114 | }; | 114 | }; |
115 | /* version number position in above array */ | 115 | /* version number position in above array */ |
116 | static int numeric[NUMTRACKERS]={14,14,16,16}; | 116 | static const int numeric[NUMTRACKERS]={14,14,16,16}; |
117 | 117 | ||
118 | /*========== Loader code */ | 118 | /*========== Loader code */ |
119 | 119 | ||
@@ -144,6 +144,11 @@ static void S3M_Cleanup(void) | |||
144 | MikMod_free(poslookup); | 144 | MikMod_free(poslookup); |
145 | MikMod_free(mh); | 145 | MikMod_free(mh); |
146 | MikMod_free(origpositions); | 146 | MikMod_free(origpositions); |
147 | s3mbuf=NULL; | ||
148 | paraptr=NULL; | ||
149 | poslookup=NULL; | ||
150 | mh=NULL; | ||
151 | origpositions=NULL; | ||
147 | } | 152 | } |
148 | 153 | ||
149 | /* Because so many s3m files have 16 channels as the set number used, but really | 154 | /* Because so many s3m files have 16 channels as the set number used, but really |
@@ -154,9 +159,9 @@ static void S3M_Cleanup(void) | |||
154 | global variable 'remap' | 159 | global variable 'remap' |
155 | 160 | ||
156 | NOTE: You must first seek to the file location of the pattern before calling | 161 | NOTE: You must first seek to the file location of the pattern before calling |
157 | this procedure. | 162 | this procedure. |
158 | 163 | ||
159 | Returns 1 on fail. */ | 164 | Returns 0 on fail. */ |
160 | static int S3M_GetNumChannels(void) | 165 | static int S3M_GetNumChannels(void) |
161 | { | 166 | { |
162 | int row=0,flag,ch; | 167 | int row=0,flag,ch; |
@@ -166,19 +171,19 @@ static int S3M_GetNumChannels(void) | |||
166 | 171 | ||
167 | if(_mm_eof(modreader)) { | 172 | if(_mm_eof(modreader)) { |
168 | _mm_errno = MMERR_LOADING_PATTERN; | 173 | _mm_errno = MMERR_LOADING_PATTERN; |
169 | return 1; | 174 | return 0; |
170 | } | 175 | } |
171 | 176 | ||
172 | if(flag) { | 177 | if(flag) { |
173 | ch=flag&31; | 178 | ch=flag&31; |
174 | if(mh->channels[ch]<32) remap[ch] = 0; | 179 | if(mh->channels[ch]<32) remap[ch] = 0; |
175 | if(flag&32) {(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);} | 180 | if(flag&32) {_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);} |
176 | if(flag&64) (void)_mm_read_UBYTE(modreader); | 181 | if(flag&64) _mm_skip_BYTE(modreader); |
177 | if(flag&128){(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);} | 182 | if(flag&128){_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);} |
178 | } else row++; | 183 | } else row++; |
179 | } | 184 | } |
180 | return 0; | 185 | return 1; |
181 | } | 186 | } |
182 | 187 | ||
183 | static int S3M_ReadPattern(void) | 188 | static int S3M_ReadPattern(void) |
184 | { | 189 | { |
@@ -282,6 +287,10 @@ static int S3M_Load(int curious) | |||
282 | _mm_errno = MMERR_LOADING_HEADER; | 287 | _mm_errno = MMERR_LOADING_HEADER; |
283 | return 0; | 288 | return 0; |
284 | } | 289 | } |
290 | if(mh->ordnum > 255 || mh->insnum > 255 || mh->patnum > 255) { | ||
291 | _mm_errno = MMERR_NOT_A_MODULE; | ||
292 | return 0; | ||
293 | } | ||
285 | 294 | ||
286 | /* then we can decide the module type */ | 295 | /* then we can decide the module type */ |
287 | tracker=mh->tracker>>12; | 296 | tracker=mh->tracker>>12; |
@@ -294,7 +303,7 @@ static int S3M_Load(int curious) | |||
294 | tracker=NUMTRACKERS; /* IT 2.14p3 */ | 303 | tracker=NUMTRACKERS; /* IT 2.14p3 */ |
295 | else tracker--; | 304 | else tracker--; |
296 | } | 305 | } |
297 | of.modtype = StrDup(S3M_Version[tracker]); | 306 | of.modtype = MikMod_strdup(S3M_Version[tracker]); |
298 | if(tracker<NUMTRACKERS) { | 307 | if(tracker<NUMTRACKERS) { |
299 | of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0'; | 308 | of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0'; |
300 | of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0'; | 309 | of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0'; |
@@ -315,7 +324,7 @@ static int S3M_Load(int curious) | |||
315 | 324 | ||
316 | /* read the order data */ | 325 | /* read the order data */ |
317 | if(!AllocPositions(mh->ordnum)) return 0; | 326 | if(!AllocPositions(mh->ordnum)) return 0; |
318 | if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0; | 327 | if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0; |
319 | 328 | ||
320 | for(t=0;t<mh->ordnum;t++) { | 329 | for(t=0;t<mh->ordnum;t++) { |
321 | origpositions[t]=_mm_read_UBYTE(modreader); | 330 | origpositions[t]=_mm_read_UBYTE(modreader); |
@@ -374,7 +383,8 @@ static int S3M_Load(int curious) | |||
374 | _mm_read_string(s.scrs,4,modreader); | 383 | _mm_read_string(s.scrs,4,modreader); |
375 | 384 | ||
376 | /* ScreamTracker imposes a 64000 bytes (not 64k !) limit */ | 385 | /* ScreamTracker imposes a 64000 bytes (not 64k !) limit */ |
377 | if (s.length > 64000) | 386 | /* enforce it, if we'll use S3MIT_SCREAM in S3M_ConvertTrack() */ |
387 | if (s.length > 64000 && tracker == 1) | ||
378 | s.length = 64000; | 388 | s.length = 64000; |
379 | 389 | ||
380 | if(_mm_eof(modreader)) { | 390 | if(_mm_eof(modreader)) { |
@@ -388,7 +398,7 @@ static int S3M_Load(int curious) | |||
388 | q->loopstart = s.loopbeg; | 398 | q->loopstart = s.loopbeg; |
389 | q->loopend = s.loopend; | 399 | q->loopend = s.loopend; |
390 | q->volume = s.volume; | 400 | q->volume = s.volume; |
391 | q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4; | 401 | q->seekpos = (((ULONG)s.memsegh)<<16|s.memsegl)<<4; |
392 | 402 | ||
393 | if(s.flags&1) q->flags |= SF_LOOP; | 403 | if(s.flags&1) q->flags |= SF_LOOP; |
394 | if(s.flags&4) q->flags |= SF_16BITS; | 404 | if(s.flags&4) q->flags |= SF_16BITS; |
@@ -406,16 +416,16 @@ static int S3M_Load(int curious) | |||
406 | for(t=0;t<of.numpat;t++) { | 416 | for(t=0;t<of.numpat;t++) { |
407 | /* seek to pattern position (+2 skip pattern length) */ | 417 | /* seek to pattern position (+2 skip pattern length) */ |
408 | _mm_fseek(modreader,(long)((paraptr[of.numins+t])<<4)+2,SEEK_SET); | 418 | _mm_fseek(modreader,(long)((paraptr[of.numins+t])<<4)+2,SEEK_SET); |
409 | if(S3M_GetNumChannels()) return 0; | 419 | if(!S3M_GetNumChannels()) return 0; |
410 | } | 420 | } |
411 | 421 | ||
412 | /* build the remap array */ | 422 | /* build the remap array */ |
413 | for(t=0;t<32;t++) | 423 | for(t=0;t<32;t++) |
414 | if(!remap[t]) | 424 | if(!remap[t]) |
415 | remap[t]=of.numchn++; | 425 | remap[t]=of.numchn++; |
416 | 426 | ||
417 | /* set panning positions after building remap chart! */ | 427 | /* set panning positions after building remap chart! */ |
418 | for(t=0;t<32;t++) | 428 | for(t=0;t<32;t++) |
419 | if((mh->channels[t]<32)&&(remap[t]!=-1)) { | 429 | if((mh->channels[t]<32)&&(remap[t]!=-1)) { |
420 | if(mh->channels[t]<8) | 430 | if(mh->channels[t]<8) |
421 | of.panning[remap[t]]=0x30; | 431 | of.panning[remap[t]]=0x30; |
diff --git a/apps/plugins/mikmod/load_stm.c b/apps/plugins/mikmod/load_stm.c index 994b0e5355..c62a6d7f36 100644 --- a/apps/plugins/mikmod/load_stm.c +++ b/apps/plugins/mikmod/load_stm.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_stm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Screamtracker 2 (STM) module loader | 25 | Screamtracker 2 (STM) module loader |
26 | 26 | ||
@@ -74,7 +74,7 @@ typedef struct STMHEADER { | |||
74 | UBYTE ver_minor; | 74 | UBYTE ver_minor; |
75 | UBYTE inittempo; /* initspeed= stm inittempo>>4 */ | 75 | UBYTE inittempo; /* initspeed= stm inittempo>>4 */ |
76 | UBYTE numpat; /* number of patterns */ | 76 | UBYTE numpat; /* number of patterns */ |
77 | UBYTE globalvol; | 77 | UBYTE globalvol; |
78 | UBYTE reserved[13]; | 78 | UBYTE reserved[13]; |
79 | STMSAMPLE sample[31]; /* STM sample data */ | 79 | STMSAMPLE sample[31]; /* STM sample data */ |
80 | UBYTE patorder[128]; /* Docs say 64 - actually 128 */ | 80 | UBYTE patorder[128]; /* Docs say 64 - actually 128 */ |
@@ -90,7 +90,7 @@ static STMNOTE *stmbuf = NULL; | |||
90 | static STMHEADER *mh = NULL; | 90 | static STMHEADER *mh = NULL; |
91 | 91 | ||
92 | /* tracker identifiers */ | 92 | /* tracker identifiers */ |
93 | static CHAR* STM_Version[STM_NTRACKERS] = { | 93 | static const CHAR * STM_Version[STM_NTRACKERS] = { |
94 | "Screamtracker 2", | 94 | "Screamtracker 2", |
95 | "Converted by MOD2STM (STM format)", | 95 | "Converted by MOD2STM (STM format)", |
96 | "Wuzamod (STM format)" | 96 | "Wuzamod (STM format)" |
@@ -103,6 +103,7 @@ static int STM_Test(void) | |||
103 | UBYTE str[44]; | 103 | UBYTE str[44]; |
104 | int t; | 104 | int t; |
105 | 105 | ||
106 | memset(str,0,44); | ||
106 | _mm_fseek(modreader,20,SEEK_SET); | 107 | _mm_fseek(modreader,20,SEEK_SET); |
107 | _mm_read_UBYTES(str,44,modreader); | 108 | _mm_read_UBYTES(str,44,modreader); |
108 | if(str[9]!=2) return 0; /* STM Module = filetype 2 */ | 109 | if(str[9]!=2) return 0; /* STM Module = filetype 2 */ |
@@ -110,7 +111,7 @@ static int STM_Test(void) | |||
110 | /* Prevent false positives for S3M files */ | 111 | /* Prevent false positives for S3M files */ |
111 | if(!memcmp(str+40,"SCRM",4)) | 112 | if(!memcmp(str+40,"SCRM",4)) |
112 | return 0; | 113 | return 0; |
113 | 114 | ||
114 | for (t=0;t<STM_NTRACKERS;t++) | 115 | for (t=0;t<STM_NTRACKERS;t++) |
115 | if(!memcmp(str,STM_Signatures[t],8)) | 116 | if(!memcmp(str,STM_Signatures[t],8)) |
116 | return 1; | 117 | return 1; |
@@ -130,6 +131,8 @@ static void STM_Cleanup(void) | |||
130 | { | 131 | { |
131 | MikMod_free(mh); | 132 | MikMod_free(mh); |
132 | MikMod_free(stmbuf); | 133 | MikMod_free(stmbuf); |
134 | mh=NULL; | ||
135 | stmbuf=NULL; | ||
133 | } | 136 | } |
134 | 137 | ||
135 | static void STM_ConvertNote(STMNOTE *n) | 138 | static void STM_ConvertNote(STMNOTE *n) |
@@ -145,7 +148,7 @@ static void STM_ConvertNote(STMNOTE *n) | |||
145 | 148 | ||
146 | if((ins)&&(ins<32)) UniInstrument(ins-1); | 149 | if((ins)&&(ins<32)) UniInstrument(ins-1); |
147 | 150 | ||
148 | /* special values of [SBYTE0] are handled here | 151 | /* special values of [SBYTE0] are handled here |
149 | we have no idea if these strange values will ever be encountered. | 152 | we have no idea if these strange values will ever be encountered. |
150 | but it appears as those stms sound correct. */ | 153 | but it appears as those stms sound correct. */ |
151 | if((note==254)||(note==252)) { | 154 | if((note==254)||(note==252)) { |
@@ -224,8 +227,7 @@ static UBYTE *STM_ConvertTrack(STMNOTE *n) | |||
224 | 227 | ||
225 | static int STM_LoadPatterns(void) | 228 | static int STM_LoadPatterns(void) |
226 | { | 229 | { |
227 | int t,tracks=0; | 230 | unsigned int t,s,tracks=0; |
228 | unsigned int s; | ||
229 | 231 | ||
230 | if(!AllocPatterns()) return 0; | 232 | if(!AllocPatterns()) return 0; |
231 | if(!AllocTracks()) return 0; | 233 | if(!AllocTracks()) return 0; |
@@ -252,10 +254,10 @@ static int STM_LoadPatterns(void) | |||
252 | 254 | ||
253 | static int STM_Load(int curious) | 255 | static int STM_Load(int curious) |
254 | { | 256 | { |
255 | int t; | 257 | int t; |
256 | ULONG MikMod_ISA; /* We must generate our own ISA, it's not stored in stm */ | 258 | ULONG MikMod_ISA; /* We must generate our own ISA, it's not stored in stm */ |
257 | SAMPLE *q; | 259 | SAMPLE *q; |
258 | (void)curious; | 260 | (void)curious; |
259 | 261 | ||
260 | /* try to read stm header */ | 262 | /* try to read stm header */ |
261 | _mm_read_string(mh->songname,20,modreader); | 263 | _mm_read_string(mh->songname,20,modreader); |
@@ -272,6 +274,10 @@ static int STM_Load(int curious) | |||
272 | mh->numpat =_mm_read_UBYTE(modreader); | 274 | mh->numpat =_mm_read_UBYTE(modreader); |
273 | mh->globalvol =_mm_read_UBYTE(modreader); | 275 | mh->globalvol =_mm_read_UBYTE(modreader); |
274 | _mm_read_UBYTES(mh->reserved,13,modreader); | 276 | _mm_read_UBYTES(mh->reserved,13,modreader); |
277 | if(mh->numpat > 128) { | ||
278 | _mm_errno = MMERR_NOT_A_MODULE; | ||
279 | return 0; | ||
280 | } | ||
275 | 281 | ||
276 | for(t=0;t<31;t++) { | 282 | for(t=0;t<31;t++) { |
277 | STMSAMPLE *s=&mh->sample[t]; /* STM sample data */ | 283 | STMSAMPLE *s=&mh->sample[t]; /* STM sample data */ |
@@ -299,9 +305,7 @@ static int STM_Load(int curious) | |||
299 | /* set module variables */ | 305 | /* set module variables */ |
300 | for(t=0;t<STM_NTRACKERS;t++) | 306 | for(t=0;t<STM_NTRACKERS;t++) |
301 | if(!memcmp(mh->trackername,STM_Signatures[t],8)) break; | 307 | if(!memcmp(mh->trackername,STM_Signatures[t],8)) break; |
302 | if(t == STM_NTRACKERS) | 308 | of.modtype = MikMod_strdup(STM_Version[t]); |
303 | return 0; | ||
304 | of.modtype = StrDup(STM_Version[t]); | ||
305 | of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */ | 309 | of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */ |
306 | of.numpat = mh->numpat; | 310 | of.numpat = mh->numpat; |
307 | of.inittempo = 125; /* mh->inittempo+0x1c; */ | 311 | of.inittempo = 125; /* mh->inittempo+0x1c; */ |
@@ -316,7 +320,10 @@ static int STM_Load(int curious) | |||
316 | /* 99 terminates the patorder list */ | 320 | /* 99 terminates the patorder list */ |
317 | while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) { | 321 | while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) { |
318 | of.positions[t]=mh->patorder[t]; | 322 | of.positions[t]=mh->patorder[t]; |
319 | t++; | 323 | if(++t == 0x80) { |
324 | _mm_errno = MMERR_NOT_A_MODULE; | ||
325 | return 0; | ||
326 | } | ||
320 | } | 327 | } |
321 | if(mh->patorder[t]<=99) t++; | 328 | if(mh->patorder[t]<=99) t++; |
322 | of.numpos=t; | 329 | of.numpos=t; |
@@ -334,7 +341,7 @@ static int STM_Load(int curious) | |||
334 | q->speed = (mh->sample[t].c2spd * 8363) / 8448; | 341 | q->speed = (mh->sample[t].c2spd * 8363) / 8448; |
335 | q->volume = mh->sample[t].volume; | 342 | q->volume = mh->sample[t].volume; |
336 | q->length = mh->sample[t].length; | 343 | q->length = mh->sample[t].length; |
337 | if (/*(!mh->sample[t].volume)||*/(q->length==1)) q->length=0; | 344 | if (/*!mh->sample[t].volume || */q->length==1) q->length=0; |
338 | q->loopstart = mh->sample[t].loopbeg; | 345 | q->loopstart = mh->sample[t].loopbeg; |
339 | q->loopend = mh->sample[t].loopend; | 346 | q->loopend = mh->sample[t].loopend; |
340 | q->seekpos = MikMod_ISA; | 347 | q->seekpos = MikMod_ISA; |
@@ -374,5 +381,4 @@ MIKMODAPI MLOADER load_stm={ | |||
374 | STM_LoadTitle | 381 | STM_LoadTitle |
375 | }; | 382 | }; |
376 | 383 | ||
377 | |||
378 | /* ex:set ts=4: */ | 384 | /* ex:set ts=4: */ |
diff --git a/apps/plugins/mikmod/load_stx.c b/apps/plugins/mikmod/load_stx.c index ac6e51f4c7..db25813342 100644 --- a/apps/plugins/mikmod/load_stx.c +++ b/apps/plugins/mikmod/load_stx.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_stx.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | STMIK 0.2 (STX) module loader | 25 | STMIK 0.2 (STX) module loader |
26 | 26 | ||
@@ -114,13 +114,14 @@ static int STX_Test(void) | |||
114 | UBYTE id[8]; | 114 | UBYTE id[8]; |
115 | int t; | 115 | int t; |
116 | 116 | ||
117 | memset(id,0,8); | ||
117 | _mm_fseek(modreader,0x3C,SEEK_SET); | 118 | _mm_fseek(modreader,0x3C,SEEK_SET); |
118 | if(!_mm_read_UBYTES(id,4,modreader)) return 0; | 119 | if(!_mm_read_UBYTES(id,4,modreader)) return 0; |
119 | if(memcmp(id,"SCRM",4)) return 0; | 120 | if(memcmp(id,"SCRM",4)) return 0; |
120 | 121 | ||
121 | _mm_fseek(modreader,0x14,SEEK_SET); | 122 | _mm_fseek(modreader,0x14,SEEK_SET); |
122 | if(!_mm_read_UBYTES(id,8,modreader)) return 0; | 123 | if(!_mm_read_UBYTES(id,8,modreader)) return 0; |
123 | 124 | ||
124 | for(t=0;t<STM_NTRACKERS;t++) | 125 | for(t=0;t<STM_NTRACKERS;t++) |
125 | if(!memcmp(id,STM_Signatures[t],8)) return 1; | 126 | if(!memcmp(id,STM_Signatures[t],8)) return 1; |
126 | 127 | ||
@@ -143,6 +144,10 @@ static void STX_Cleanup(void) | |||
143 | MikMod_free(paraptr); | 144 | MikMod_free(paraptr); |
144 | MikMod_free(poslookup); | 145 | MikMod_free(poslookup); |
145 | MikMod_free(mh); | 146 | MikMod_free(mh); |
147 | stxbuf=NULL; | ||
148 | paraptr=NULL; | ||
149 | poslookup=NULL; | ||
150 | mh=NULL; | ||
146 | } | 151 | } |
147 | 152 | ||
148 | static int STX_ReadPattern(void) | 153 | static int STX_ReadPattern(void) |
@@ -297,6 +302,11 @@ static int STX_Load(int curious) | |||
297 | _mm_errno = MMERR_LOADING_HEADER; | 302 | _mm_errno = MMERR_LOADING_HEADER; |
298 | return 0; | 303 | return 0; |
299 | } | 304 | } |
305 | if(mh->ordnum > 256 || !mh->insnum || mh->insnum > 256 || | ||
306 | mh->patnum > 254 || !mh->patnum) { | ||
307 | _mm_errno = MMERR_NOT_A_MODULE; | ||
308 | return 0; | ||
309 | } | ||
300 | 310 | ||
301 | /* set module variables */ | 311 | /* set module variables */ |
302 | of.songname = DupStr(mh->songname,20,1); | 312 | of.songname = DupStr(mh->songname,20,1); |
@@ -323,10 +333,10 @@ static int STX_Load(int curious) | |||
323 | version=_mm_read_I_UWORD(modreader); | 333 | version=_mm_read_I_UWORD(modreader); |
324 | if(version==mh->patsize) { | 334 | if(version==mh->patsize) { |
325 | version = 0x10; | 335 | version = 0x10; |
326 | of.modtype = StrDup("STMIK 0.2 (STM2STX 1.0)"); | 336 | of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.0)"); |
327 | } else { | 337 | } else { |
328 | version = 0x11; | 338 | version = 0x11; |
329 | of.modtype = StrDup("STMIK 0.2 (STM2STX 1.1)"); | 339 | of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.1)"); |
330 | } | 340 | } |
331 | 341 | ||
332 | /* read the order data */ | 342 | /* read the order data */ |
@@ -343,7 +353,7 @@ static int STX_Load(int curious) | |||
343 | if(order==255) order=LAST_PATTERN; | 353 | if(order==255) order=LAST_PATTERN; |
344 | of.positions[of.numpos]=order; | 354 | of.positions[of.numpos]=order; |
345 | poslookup[t]=of.numpos; /* bug fix for freaky S3Ms */ | 355 | poslookup[t]=of.numpos; /* bug fix for freaky S3Ms */ |
346 | if(of.positions[t]<254) of.numpos++; | 356 | if(of.positions[t]<254) of.numpos++; |
347 | else | 357 | else |
348 | /* special end of song pattern */ | 358 | /* special end of song pattern */ |
349 | if((order==LAST_PATTERN)&&(!curious)) break; | 359 | if((order==LAST_PATTERN)&&(!curious)) break; |
@@ -389,7 +399,7 @@ static int STX_Load(int curious) | |||
389 | q->loopstart = s.loopbeg; | 399 | q->loopstart = s.loopbeg; |
390 | q->loopend = s.loopend; | 400 | q->loopend = s.loopend; |
391 | q->volume = s.volume; | 401 | q->volume = s.volume; |
392 | q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4; | 402 | q->seekpos = (((ULONG)s.memsegh)<<16|s.memsegl)<<4; |
393 | q->flags |= SF_SIGNED; | 403 | q->flags |= SF_SIGNED; |
394 | 404 | ||
395 | if(s.flags&1) q->flags |= SF_LOOP; | 405 | if(s.flags&1) q->flags |= SF_LOOP; |
diff --git a/apps/plugins/mikmod/load_ult.c b/apps/plugins/mikmod/load_ult.c index f56c2df06b..1d4e5cf72b 100644 --- a/apps/plugins/mikmod/load_ult.c +++ b/apps/plugins/mikmod/load_ult.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_ult.c,v 1.3 2010/01/12 03:30:32 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Ultratracker (ULT) module loader | 25 | Ultratracker (ULT) module loader |
26 | 26 | ||
@@ -80,7 +80,7 @@ typedef struct ULTEVENT { | |||
80 | #define ULTS_REVERSE 16 | 80 | #define ULTS_REVERSE 16 |
81 | 81 | ||
82 | #define ULT_VERSION_LEN 18 | 82 | #define ULT_VERSION_LEN 18 |
83 | static CHAR ULT_Version[ULT_VERSION_LEN]="Ultra Tracker v1.x"; | 83 | static CHAR ULT_Version[ULT_VERSION_LEN+1]="Ultra Tracker v1.x"; |
84 | 84 | ||
85 | static ULTEVENT ev; | 85 | static ULTEVENT ev; |
86 | 86 | ||
@@ -130,8 +130,8 @@ static int ULT_Load(int curious) | |||
130 | SAMPLE *q; | 130 | SAMPLE *q; |
131 | ULTSAMPLE s; | 131 | ULTSAMPLE s; |
132 | ULTHEADER mh; | 132 | ULTHEADER mh; |
133 | UBYTE nos,noc,rbnop; | 133 | UBYTE nos,noc,RBnop; |
134 | (void)curious; | 134 | (void)curious; |
135 | 135 | ||
136 | /* try to read module header */ | 136 | /* try to read module header */ |
137 | _mm_read_string(mh.id,15,modreader); | 137 | _mm_read_string(mh.id,15,modreader); |
@@ -207,29 +207,37 @@ static int ULT_Load(int curious) | |||
207 | if(!AllocPositions(256)) return 0; | 207 | if(!AllocPositions(256)) return 0; |
208 | for(t=0;t<256;t++) | 208 | for(t=0;t<256;t++) |
209 | of.positions[t]=_mm_read_UBYTE(modreader); | 209 | of.positions[t]=_mm_read_UBYTE(modreader); |
210 | for(t=0;t<256;t++) | 210 | |
211 | noc=_mm_read_UBYTE(modreader); | ||
212 | RBnop=_mm_read_UBYTE(modreader); | ||
213 | |||
214 | of.numchn=++noc; | ||
215 | of.numpat=++RBnop; | ||
216 | of.numtrk=of.numchn*of.numpat; | ||
217 | |||
218 | for(t=0;t<256;t++) { | ||
211 | if(of.positions[t]==255) { | 219 | if(of.positions[t]==255) { |
212 | of.positions[t]=LAST_PATTERN; | 220 | of.positions[t]=LAST_PATTERN; |
213 | break; | 221 | break; |
214 | } | 222 | } |
223 | if (of.positions[t]>of.numpat) { /* SANITIY CHECK */ | ||
224 | /* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/ | ||
225 | _mm_errno = MMERR_LOADING_HEADER; | ||
226 | return 0; | ||
227 | } | ||
228 | } | ||
215 | of.numpos=t; | 229 | of.numpos=t; |
216 | 230 | ||
217 | noc=_mm_read_UBYTE(modreader); | ||
218 | rbnop=_mm_read_UBYTE(modreader); | ||
219 | |||
220 | of.numchn=++noc; | ||
221 | of.numpat=++rbnop; | ||
222 | of.numtrk=of.numchn*of.numpat; | ||
223 | if(!AllocTracks()) return 0; | 231 | if(!AllocTracks()) return 0; |
224 | if(!AllocPatterns()) return 0; | 232 | if(!AllocPatterns()) return 0; |
225 | for(u=0;u<of.numchn;u++) | 233 | for(u=0;u<of.numchn;u++) |
226 | for(t=0;t<of.numpat;t++) | 234 | for(t=0;t<of.numpat;t++) |
227 | of.patterns[(t*of.numchn)+u]=tracks++; | 235 | of.patterns[(t*of.numchn)+u]=tracks++; |
228 | 236 | ||
229 | // SA37775 | 237 | /* Secunia SA37775 / CVE-2009-3996 */ |
230 | if (of.numchn>=UF_MAXCHAN) | 238 | if (of.numchn>=UF_MAXCHAN) |
231 | of.numchn=UF_MAXCHAN - 1; | 239 | of.numchn=UF_MAXCHAN - 1; |
232 | 240 | ||
233 | /* read pan position table for v1.5 and higher */ | 241 | /* read pan position table for v1.5 and higher */ |
234 | if(mh.id[14]>='3') { | 242 | if(mh.id[14]>='3') { |
235 | for(t=0;t<of.numchn;t++) of.panning[t]=_mm_read_UBYTE(modreader)<<4; | 243 | for(t=0;t<of.numchn;t++) of.panning[t]=_mm_read_UBYTE(modreader)<<4; |
@@ -313,7 +321,7 @@ static int ULT_Load(int curious) | |||
313 | return 1; | 321 | return 1; |
314 | } | 322 | } |
315 | 323 | ||
316 | static CHAR *ULT_LoadTitle(void) | 324 | static CHAR * ULT_LoadTitle(void) |
317 | { | 325 | { |
318 | CHAR s[32]; | 326 | CHAR s[32]; |
319 | 327 | ||
diff --git a/apps/plugins/mikmod/load_umx.c b/apps/plugins/mikmod/load_umx.c new file mode 100644 index 0000000000..1a0535affd --- /dev/null +++ b/apps/plugins/mikmod/load_umx.c | |||
@@ -0,0 +1,476 @@ | |||
1 | /* MikMod sound library | ||
2 | * (c) 2003-2004 Raphael Assenat and others - see file | ||
3 | * AUTHORS for complete list. | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU Library General Public License as | ||
7 | * published by the Free Software Foundation; either version 2 of | ||
8 | * the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Library General Public License for more details. | ||
14 | * | ||
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 | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
18 | * 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* Epic Games Unreal UMX container loading for libmikmod | ||
22 | * Written by O. Sezer <sezero@users.sourceforge.net> | ||
23 | * | ||
24 | * Records data type/offset info in its Test() function, then acts | ||
25 | * as a middle-man, forwarding calls to the real loader units. It | ||
26 | * requires that the MREADER implementation in use always respects | ||
27 | * its iobase fields. Like all other libmikmod loaders, this code | ||
28 | * is not reentrant yet. | ||
29 | * | ||
30 | * UPKG parsing partially based on Unreal Media Ripper (UMR) v0.3 | ||
31 | * by Andy Ward <wardwh@swbell.net>, with additional updates | ||
32 | * by O. Sezer - see git repo at https://github.com/sezero/umr/ | ||
33 | * | ||
34 | * The cheaper way, i.e. linear search of music object like libxmp | ||
35 | * and libmodplug does, is possible. With this however we're using | ||
36 | * the embedded offset, size and object type directly from the umx | ||
37 | * file, and I feel safer with it. | ||
38 | */ | ||
39 | |||
40 | #ifdef HAVE_CONFIG_H | ||
41 | #include "config.h" | ||
42 | #endif | ||
43 | |||
44 | #include <stddef.h> | ||
45 | #include <stdio.h> | ||
46 | #include <string.h> | ||
47 | |||
48 | #include "mikmod_internals.h" | ||
49 | |||
50 | |||
51 | /*========== upkg defs */ | ||
52 | |||
53 | typedef SLONG fci_t; /* FCompactIndex */ | ||
54 | |||
55 | #define UPKG_HDR_TAG 0x9e2a83c1 | ||
56 | |||
57 | struct _genhist { /* for upkg versions >= 68 */ | ||
58 | SLONG export_count; | ||
59 | SLONG name_count; | ||
60 | }; | ||
61 | |||
62 | struct upkg_hdr { | ||
63 | ULONG tag; /* UPKG_HDR_TAG */ | ||
64 | SLONG file_version; | ||
65 | ULONG pkg_flags; | ||
66 | SLONG name_count; /* number of names in name table (>= 0) */ | ||
67 | SLONG name_offset; /* offset to name table (>= 0) */ | ||
68 | SLONG export_count; /* num. exports in export table (>= 0) */ | ||
69 | SLONG export_offset; /* offset to export table (>= 0) */ | ||
70 | SLONG import_count; /* num. imports in export table (>= 0) */ | ||
71 | SLONG import_offset; /* offset to import table (>= 0) */ | ||
72 | |||
73 | /* number of GUIDs in heritage table (>= 1) and table's offset: | ||
74 | * only with versions < 68. */ | ||
75 | SLONG heritage_count; | ||
76 | SLONG heritage_offset; | ||
77 | /* with versions >= 68: a GUID, a dword for generation count | ||
78 | * and export_count and name_count dwords for each generation: */ | ||
79 | ULONG guid[4]; | ||
80 | SLONG generation_count; | ||
81 | #define UPKG_HDR_SIZE 64 /* 64 bytes up until here */ | ||
82 | /*struct _genhist *gen;*/ | ||
83 | }; | ||
84 | /* compile time assert for upkg_hdr size */ | ||
85 | /*typedef int _check_hdrsize[2 * (offsetof(struct upkg_hdr, gen) == UPKG_HDR_SIZE) - 1];*/ | ||
86 | typedef int _check_hdrsize[2 * (sizeof(struct upkg_hdr) == UPKG_HDR_SIZE) - 1]; | ||
87 | |||
88 | /*========== Supported content types */ | ||
89 | |||
90 | #define UMUSIC_IT 0 | ||
91 | #define UMUSIC_S3M 1 | ||
92 | #define UMUSIC_XM 2 | ||
93 | #define UMUSIC_MOD 3 | ||
94 | |||
95 | static const char *mustype[] = { | ||
96 | "IT", "S3M", "XM", "MOD", | ||
97 | NULL | ||
98 | }; | ||
99 | |||
100 | /*========== UPKG parsing */ | ||
101 | |||
102 | /* decode an FCompactIndex. | ||
103 | * original documentation by Tim Sweeney was at | ||
104 | * http://unreal.epicgames.com/Packages.htm | ||
105 | * also see Unreal Wiki: | ||
106 | * http://wiki.beyondunreal.com/Legacy:Package_File_Format/Data_Details | ||
107 | */ | ||
108 | static fci_t get_fci (const char *in, int *pos) | ||
109 | { | ||
110 | SLONG a; | ||
111 | int size; | ||
112 | |||
113 | size = 1; | ||
114 | a = in[0] & 0x3f; | ||
115 | |||
116 | if (in[0] & 0x40) { | ||
117 | size++; | ||
118 | a |= (in[1] & 0x7f) << 6; | ||
119 | |||
120 | if (in[1] & 0x80) { | ||
121 | size++; | ||
122 | a |= (in[2] & 0x7f) << 13; | ||
123 | |||
124 | if (in[2] & 0x80) { | ||
125 | size++; | ||
126 | a |= (in[3] & 0x7f) << 20; | ||
127 | |||
128 | if (in[3] & 0x80) { | ||
129 | size++; | ||
130 | a |= (in[4] & 0x3f) << 27; | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (in[0] & 0x80) | ||
137 | a = -a; | ||
138 | |||
139 | *pos += size; | ||
140 | |||
141 | return a; | ||
142 | } | ||
143 | |||
144 | static int get_objtype (SLONG ofs, int type) | ||
145 | { | ||
146 | char sig[16]; | ||
147 | _retry: | ||
148 | _mm_fseek(modreader, ofs, SEEK_SET); | ||
149 | _mm_read_UBYTES(sig, 16, modreader); | ||
150 | if (type == UMUSIC_IT) { | ||
151 | if (memcmp(sig, "IMPM", 4) == 0) | ||
152 | return UMUSIC_IT; | ||
153 | return -1; | ||
154 | } | ||
155 | if (type == UMUSIC_XM) { | ||
156 | if (memcmp(sig, "Extended Module:", 16) != 0) | ||
157 | return -1; | ||
158 | _mm_read_UBYTES(sig, 16, modreader); | ||
159 | if (sig[0] != ' ') return -1; | ||
160 | _mm_read_UBYTES(sig, 16, modreader); | ||
161 | if (sig[5] != 0x1a) return -1; | ||
162 | return UMUSIC_XM; | ||
163 | } | ||
164 | |||
165 | _mm_fseek(modreader, ofs + 44, SEEK_SET); | ||
166 | _mm_read_UBYTES(sig, 4, modreader); | ||
167 | if (type == UMUSIC_S3M) { | ||
168 | if (memcmp(sig, "SCRM", 4) == 0) | ||
169 | return UMUSIC_S3M; | ||
170 | /*return -1;*/ | ||
171 | /* SpaceMarines.umx and Starseek.umx from Return to NaPali | ||
172 | * report as "s3m" whereas the actual music format is "it" */ | ||
173 | type = UMUSIC_IT; | ||
174 | goto _retry; | ||
175 | } | ||
176 | |||
177 | _mm_fseek(modreader, ofs + 1080, SEEK_SET); | ||
178 | _mm_read_UBYTES(sig, 4, modreader); | ||
179 | if (type == UMUSIC_MOD) { | ||
180 | if (memcmp(sig, "M.K.", 4) == 0 || memcmp(sig, "M!K!", 4) == 0) | ||
181 | return UMUSIC_MOD; | ||
182 | return -1; | ||
183 | } | ||
184 | |||
185 | return -1; | ||
186 | } | ||
187 | |||
188 | static int read_export (const struct upkg_hdr *hdr, | ||
189 | SLONG *ofs, SLONG *objsize) | ||
190 | { | ||
191 | char buf[40]; | ||
192 | int idx = 0, t; | ||
193 | |||
194 | _mm_fseek(modreader, *ofs, SEEK_SET); | ||
195 | if (!_mm_read_UBYTES(buf, 40, modreader)) | ||
196 | return -1; | ||
197 | |||
198 | if (hdr->file_version < 40) idx += 8; /* 00 00 00 00 00 00 00 00 */ | ||
199 | if (hdr->file_version < 60) idx += 16; /* 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 */ | ||
200 | get_fci(&buf[idx], &idx); /* skip junk */ | ||
201 | t = get_fci(&buf[idx], &idx); /* type_name */ | ||
202 | if (hdr->file_version > 61) idx += 4; /* skip export size */ | ||
203 | *objsize = get_fci(&buf[idx], &idx); | ||
204 | *ofs += idx; /* offset for real data */ | ||
205 | |||
206 | return t; /* return type_name index */ | ||
207 | } | ||
208 | |||
209 | static int read_typname(const struct upkg_hdr *hdr, | ||
210 | int idx, char *out) | ||
211 | { | ||
212 | int i, s; | ||
213 | long l; | ||
214 | char buf[64]; | ||
215 | |||
216 | if (idx >= hdr->name_count) return -1; | ||
217 | buf[63] = '\0'; | ||
218 | for (i = 0, l = 0; i <= idx; i++) { | ||
219 | _mm_fseek(modreader, hdr->name_offset + l, SEEK_SET); | ||
220 | _mm_read_UBYTES(buf, 63, modreader); | ||
221 | if (hdr->file_version >= 64) { | ||
222 | s = *(signed char *)buf; /* numchars *including* terminator */ | ||
223 | if (s <= 0 || s > 64) return -1; | ||
224 | l += s + 5; /* 1 for buf[0], 4 for int32_t name_flags */ | ||
225 | } else { | ||
226 | l += (long)strlen(buf); | ||
227 | l += 5; /* 1 for terminator, 4 for int32_t name_flags */ | ||
228 | } | ||
229 | } | ||
230 | |||
231 | strcpy(out, (hdr->file_version >= 64)? &buf[1] : buf); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int probe_umx (const struct upkg_hdr *hdr, | ||
236 | SLONG *ofs, SLONG *objsize) | ||
237 | { | ||
238 | int i, idx, t; | ||
239 | SLONG s, pos; | ||
240 | long fsiz; | ||
241 | char buf[64]; | ||
242 | |||
243 | idx = 0; | ||
244 | _mm_fseek(modreader, 0, SEEK_END); | ||
245 | fsiz = _mm_ftell(modreader); | ||
246 | |||
247 | /* Find the offset and size of the first IT, S3M or XM | ||
248 | * by parsing the exports table. The umx files should | ||
249 | * have only one export. Kran32.umx from Unreal has two, | ||
250 | * but both pointing to the same music. */ | ||
251 | if (hdr->export_offset >= fsiz) return -1; | ||
252 | memset(buf, 0, 64); | ||
253 | _mm_fseek(modreader, hdr->export_offset, SEEK_SET); | ||
254 | _mm_read_UBYTES(buf, 64, modreader); | ||
255 | |||
256 | get_fci(&buf[idx], &idx); /* skip class_index */ | ||
257 | get_fci(&buf[idx], &idx); /* skip super_index */ | ||
258 | if (hdr->file_version >= 60) idx += 4; /* skip int32 package_index */ | ||
259 | get_fci(&buf[idx], &idx); /* skip object_name */ | ||
260 | idx += 4; /* skip int32 object_flags */ | ||
261 | |||
262 | s = get_fci(&buf[idx], &idx); /* get serial_size */ | ||
263 | if (s <= 0) return -1; | ||
264 | pos = get_fci(&buf[idx],&idx); /* get serial_offset */ | ||
265 | if (pos < 0 || pos > fsiz - 40) return -1; | ||
266 | |||
267 | if ((t = read_export(hdr, &pos, &s)) < 0) return -1; | ||
268 | if (s <= 0 || s > fsiz - pos) return -1; | ||
269 | |||
270 | if (read_typname(hdr, t, buf) < 0) return -1; | ||
271 | for (i = 0; mustype[i] != NULL; i++) { | ||
272 | if (!strcasecmp(buf, mustype[i])) { | ||
273 | t = i; | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | if (mustype[i] == NULL) return -1; | ||
278 | if ((t = get_objtype(pos, t)) < 0) return -1; | ||
279 | |||
280 | *ofs = pos; | ||
281 | *objsize = s; | ||
282 | return t; | ||
283 | } | ||
284 | |||
285 | static SLONG probe_header (void *header) | ||
286 | { | ||
287 | struct upkg_hdr *hdr; | ||
288 | unsigned char *p; | ||
289 | ULONG *swp; | ||
290 | int i; | ||
291 | |||
292 | /* byte swap the header - all members are 32 bit LE values */ | ||
293 | p = (unsigned char *) header; | ||
294 | swp = (ULONG *) header; | ||
295 | for (i = 0; i < UPKG_HDR_SIZE/4; i++, p += 4) { | ||
296 | swp[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | ||
297 | } | ||
298 | |||
299 | hdr = (struct upkg_hdr *) header; | ||
300 | if (hdr->tag != UPKG_HDR_TAG) { | ||
301 | return -1; | ||
302 | } | ||
303 | if (hdr->name_count < 0 || | ||
304 | hdr->name_offset < 0 || | ||
305 | hdr->export_count < 0 || | ||
306 | hdr->export_offset < 0 || | ||
307 | hdr->import_count < 0 || | ||
308 | hdr->import_offset < 0 ) { | ||
309 | return -1; | ||
310 | } | ||
311 | |||
312 | switch (hdr->file_version) { | ||
313 | case 35: case 37: /* Unreal beta - */ | ||
314 | case 40: case 41: /* 1998 */ | ||
315 | case 61:/* Unreal */ | ||
316 | case 62:/* Unreal Tournament */ | ||
317 | case 63:/* Return to NaPali */ | ||
318 | case 64:/* Unreal Tournament */ | ||
319 | case 66:/* Unreal Tournament */ | ||
320 | case 68:/* Unreal Tournament */ | ||
321 | case 69:/* Tactical Ops */ | ||
322 | case 83:/* Mobile Forces */ | ||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | return -1; | ||
327 | } | ||
328 | |||
329 | static int process_upkg (SLONG *ofs, SLONG *objsize) | ||
330 | { | ||
331 | char header[UPKG_HDR_SIZE]; | ||
332 | |||
333 | if (!_mm_read_UBYTES(header, UPKG_HDR_SIZE, modreader)) | ||
334 | return -1; | ||
335 | if (probe_header(header) < 0) | ||
336 | return -1; | ||
337 | |||
338 | return probe_umx((struct upkg_hdr *)header, ofs, objsize); | ||
339 | } | ||
340 | |||
341 | /*========== Loader vars */ | ||
342 | |||
343 | typedef struct _umx_info { | ||
344 | int type; | ||
345 | SLONG ofs, size; | ||
346 | MLOADER* loader; | ||
347 | } umx_info; | ||
348 | |||
349 | static umx_info *umx_data = NULL; | ||
350 | |||
351 | /*========== Loader code */ | ||
352 | |||
353 | /* Without Test() being called first, Load[Title] is never called. | ||
354 | * A Test() is always followed by either a Load() or a LoadTitle(). | ||
355 | * A Load() is always followed by Cleanup() regardless of success. | ||
356 | * | ||
357 | * Therefore, in between Test() and LoadTitle() or Load()/Cleanup(), | ||
358 | * we must remember the type and the offset of the umx music data, | ||
359 | * and always clear it when returning from LoadTitle() or Cleanup(). | ||
360 | */ | ||
361 | |||
362 | static int UMX_Test(void) | ||
363 | { | ||
364 | int type; | ||
365 | SLONG ofs = 0, size = 0; | ||
366 | |||
367 | if (umx_data) { | ||
368 | #ifdef MIKMOD_DEBUG | ||
369 | fprintf(stderr, "UMX_Test called while a previous instance is active\n"); | ||
370 | #endif | ||
371 | MikMod_free(umx_data); | ||
372 | umx_data = NULL; | ||
373 | } | ||
374 | |||
375 | _mm_fseek(modreader, 0, SEEK_SET); | ||
376 | type = process_upkg(&ofs, &size); | ||
377 | if (type < 0 || type > UMUSIC_MOD) | ||
378 | return 0; | ||
379 | |||
380 | umx_data = (umx_info*) MikMod_calloc(1, sizeof(umx_info)); | ||
381 | if (!umx_data) return 0; | ||
382 | |||
383 | umx_data->type = type; | ||
384 | umx_data->ofs = ofs; | ||
385 | umx_data->size = size; | ||
386 | switch (type) { | ||
387 | case UMUSIC_IT: | ||
388 | umx_data->loader = &load_it; | ||
389 | break; | ||
390 | case UMUSIC_S3M: | ||
391 | umx_data->loader = &load_s3m; | ||
392 | break; | ||
393 | case UMUSIC_XM: | ||
394 | umx_data->loader = &load_xm; | ||
395 | break; | ||
396 | case UMUSIC_MOD: | ||
397 | umx_data->loader = &load_mod; | ||
398 | break; | ||
399 | } | ||
400 | |||
401 | return 1; | ||
402 | } | ||
403 | |||
404 | static int UMX_Init(void) | ||
405 | { | ||
406 | if (!umx_data || !umx_data->loader) | ||
407 | return 0; | ||
408 | |||
409 | if (umx_data->loader->Init) | ||
410 | return umx_data->loader->Init(); | ||
411 | |||
412 | return 1; | ||
413 | } | ||
414 | |||
415 | static void UMX_Cleanup(void) | ||
416 | { | ||
417 | if (!umx_data) return; | ||
418 | |||
419 | if (umx_data->loader && umx_data->loader->Cleanup) | ||
420 | umx_data->loader->Cleanup(); | ||
421 | |||
422 | MikMod_free(umx_data); | ||
423 | umx_data = NULL; | ||
424 | } | ||
425 | |||
426 | static int UMX_Load(int curious) | ||
427 | { | ||
428 | if (!umx_data || !umx_data->loader) | ||
429 | return 0; | ||
430 | |||
431 | _mm_fseek(modreader, umx_data->ofs, SEEK_SET); | ||
432 | /* set reader iobase to the umx object offset */ | ||
433 | _mm_iobase_revert(modreader); | ||
434 | _mm_iobase_setcur(modreader); | ||
435 | |||
436 | return umx_data->loader->Load(curious); | ||
437 | } | ||
438 | |||
439 | static CHAR *UMX_LoadTitle(void) | ||
440 | { | ||
441 | CHAR *title; | ||
442 | |||
443 | if (!umx_data) return NULL; | ||
444 | |||
445 | if (!umx_data->loader) { | ||
446 | title = NULL; | ||
447 | } | ||
448 | else { | ||
449 | _mm_fseek(modreader, umx_data->ofs, SEEK_SET); | ||
450 | /* set reader iobase to the umx object offset */ | ||
451 | _mm_iobase_revert(modreader); | ||
452 | _mm_iobase_setcur(modreader); | ||
453 | |||
454 | title = umx_data->loader->LoadTitle(); | ||
455 | } | ||
456 | |||
457 | MikMod_free(umx_data); | ||
458 | umx_data = NULL; | ||
459 | |||
460 | return title; | ||
461 | } | ||
462 | |||
463 | /*========== Loader information */ | ||
464 | |||
465 | MIKMODAPI MLOADER load_umx = { | ||
466 | NULL, | ||
467 | "UMX", | ||
468 | "UMX (Unreal UMX container)", | ||
469 | UMX_Init, | ||
470 | UMX_Test, | ||
471 | UMX_Load, | ||
472 | UMX_Cleanup, | ||
473 | UMX_LoadTitle | ||
474 | }; | ||
475 | |||
476 | /* ex:set ts=8: */ | ||
diff --git a/apps/plugins/mikmod/load_uni.c b/apps/plugins/mikmod/load_uni.c index 7bedd8f16c..834fd3a85a 100644 --- a/apps/plugins/mikmod/load_uni.c +++ b/apps/plugins/mikmod/load_uni.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_uni.c,v 1.3 2005/04/07 19:57:38 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | UNIMOD (libmikmod's and APlayer's internal module format) loader | 25 | UNIMOD (libmikmod's and APlayer's internal module format) loader |
26 | 26 | ||
@@ -94,18 +94,18 @@ static UNISMP05 *wh=NULL,*s=NULL; | |||
94 | 94 | ||
95 | /*========== Loader code */ | 95 | /*========== Loader code */ |
96 | 96 | ||
97 | static char* readstring(void) | 97 | static char * readstring(void) |
98 | { | 98 | { |
99 | char *s=NULL; | 99 | char *str=NULL; |
100 | UWORD len; | 100 | UWORD len; |
101 | 101 | ||
102 | len=_mm_read_I_UWORD(modreader); | 102 | len=_mm_read_I_UWORD(modreader); |
103 | if(len) { | 103 | if(len) { |
104 | s=MikMod_malloc(len+1); | 104 | str=(char *) MikMod_malloc(len+1); |
105 | _mm_read_UBYTES(s,len,modreader); | 105 | _mm_read_UBYTES(str,len,modreader); |
106 | s[len]=0; | 106 | str[len]=0; |
107 | } | 107 | } |
108 | return s; | 108 | return str; |
109 | } | 109 | } |
110 | 110 | ||
111 | static int UNI_Test(void) | 111 | static int UNI_Test(void) |
@@ -133,7 +133,7 @@ static int UNI_Init(void) | |||
133 | static void UNI_Cleanup(void) | 133 | static void UNI_Cleanup(void) |
134 | { | 134 | { |
135 | MikMod_free(wh); | 135 | MikMod_free(wh); |
136 | s=NULL; | 136 | wh = s = NULL; |
137 | } | 137 | } |
138 | 138 | ||
139 | static UBYTE* readtrack(void) | 139 | static UBYTE* readtrack(void) |
@@ -148,7 +148,7 @@ static UBYTE* readtrack(void) | |||
148 | len=_mm_read_I_UWORD(modreader); | 148 | len=_mm_read_I_UWORD(modreader); |
149 | 149 | ||
150 | if(!len) return NULL; | 150 | if(!len) return NULL; |
151 | if(!(t=MikMod_malloc(len))) return NULL; | 151 | if(!(t=(UBYTE*)MikMod_malloc(len))) return NULL; |
152 | _mm_read_UBYTES(t,len,modreader); | 152 | _mm_read_UBYTES(t,len,modreader); |
153 | 153 | ||
154 | /* Check if the track is correct */ | 154 | /* Check if the track is correct */ |
@@ -221,65 +221,65 @@ static UBYTE* readtrack(void) | |||
221 | static int loadsmp6(void) | 221 | static int loadsmp6(void) |
222 | { | 222 | { |
223 | int t; | 223 | int t; |
224 | SAMPLE *s; | 224 | SAMPLE *sptr; |
225 | 225 | ||
226 | s=of.samples; | 226 | sptr=of.samples; |
227 | for(t=0;t<of.numsmp;t++,s++) { | 227 | for(t=0;t<of.numsmp;t++,sptr++) { |
228 | int flags; | 228 | int flags; |
229 | 229 | ||
230 | flags = _mm_read_M_UWORD(modreader); | 230 | flags = _mm_read_M_UWORD(modreader); |
231 | s->flags=0; | 231 | sptr->flags=0; |
232 | if(flags&0x0004) s->flags|=SF_STEREO; | 232 | if(flags&0x0004) sptr->flags|=SF_STEREO; |
233 | if(flags&0x0002) s->flags|=SF_SIGNED; | 233 | if(flags&0x0002) sptr->flags|=SF_SIGNED; |
234 | if(flags&0x0001) s->flags|=SF_16BITS; | 234 | if(flags&0x0001) sptr->flags|=SF_16BITS; |
235 | /* convert flags */ | 235 | /* convert flags */ |
236 | if(universion>=0x104) { | 236 | if(universion>=0x104) { |
237 | if(flags&0x2000) s->flags|=SF_UST_LOOP; | 237 | if(flags&0x2000) sptr->flags|=SF_UST_LOOP; |
238 | if(flags&0x1000) s->flags|=SF_OWNPAN; | 238 | if(flags&0x1000) sptr->flags|=SF_OWNPAN; |
239 | if(flags&0x0800) s->flags|=SF_SUSTAIN; | 239 | if(flags&0x0800) sptr->flags|=SF_SUSTAIN; |
240 | if(flags&0x0400) s->flags|=SF_REVERSE; | 240 | if(flags&0x0400) sptr->flags|=SF_REVERSE; |
241 | if(flags&0x0200) s->flags|=SF_BIDI; | 241 | if(flags&0x0200) sptr->flags|=SF_BIDI; |
242 | if(flags&0x0100) s->flags|=SF_LOOP; | 242 | if(flags&0x0100) sptr->flags|=SF_LOOP; |
243 | if(flags&0x0020) s->flags|=SF_ITPACKED; | 243 | if(flags&0x0020) sptr->flags|=SF_ITPACKED; |
244 | if(flags&0x0010) s->flags|=SF_DELTA; | 244 | if(flags&0x0010) sptr->flags|=SF_DELTA; |
245 | if(flags&0x0008) s->flags|=SF_BIG_ENDIAN; | 245 | if(flags&0x0008) sptr->flags|=SF_BIG_ENDIAN; |
246 | } else if(universion>=0x102) { | 246 | } else if(universion>=0x102) { |
247 | if(flags&0x0800) s->flags|=SF_UST_LOOP; | 247 | if(flags&0x0800) sptr->flags|=SF_UST_LOOP; |
248 | if(flags&0x0400) s->flags|=SF_OWNPAN; | 248 | if(flags&0x0400) sptr->flags|=SF_OWNPAN; |
249 | if(flags&0x0200) s->flags|=SF_SUSTAIN; | 249 | if(flags&0x0200) sptr->flags|=SF_SUSTAIN; |
250 | if(flags&0x0100) s->flags|=SF_REVERSE; | 250 | if(flags&0x0100) sptr->flags|=SF_REVERSE; |
251 | if(flags&0x0080) s->flags|=SF_BIDI; | 251 | if(flags&0x0080) sptr->flags|=SF_BIDI; |
252 | if(flags&0x0040) s->flags|=SF_LOOP; | 252 | if(flags&0x0040) sptr->flags|=SF_LOOP; |
253 | if(flags&0x0020) s->flags|=SF_ITPACKED; | 253 | if(flags&0x0020) sptr->flags|=SF_ITPACKED; |
254 | if(flags&0x0010) s->flags|=SF_DELTA; | 254 | if(flags&0x0010) sptr->flags|=SF_DELTA; |
255 | if(flags&0x0008) s->flags|=SF_BIG_ENDIAN; | 255 | if(flags&0x0008) sptr->flags|=SF_BIG_ENDIAN; |
256 | } else { | 256 | } else { |
257 | if(flags&0x400) s->flags|=SF_UST_LOOP; | 257 | if(flags&0x400) sptr->flags|=SF_UST_LOOP; |
258 | if(flags&0x200) s->flags|=SF_OWNPAN; | 258 | if(flags&0x200) sptr->flags|=SF_OWNPAN; |
259 | if(flags&0x100) s->flags|=SF_REVERSE; | 259 | if(flags&0x100) sptr->flags|=SF_REVERSE; |
260 | if(flags&0x080) s->flags|=SF_SUSTAIN; | 260 | if(flags&0x080) sptr->flags|=SF_SUSTAIN; |
261 | if(flags&0x040) s->flags|=SF_BIDI; | 261 | if(flags&0x040) sptr->flags|=SF_BIDI; |
262 | if(flags&0x020) s->flags|=SF_LOOP; | 262 | if(flags&0x020) sptr->flags|=SF_LOOP; |
263 | if(flags&0x010) s->flags|=SF_BIG_ENDIAN; | 263 | if(flags&0x010) sptr->flags|=SF_BIG_ENDIAN; |
264 | if(flags&0x008) s->flags|=SF_DELTA; | 264 | if(flags&0x008) sptr->flags|=SF_DELTA; |
265 | } | 265 | } |
266 | 266 | ||
267 | s->speed = _mm_read_M_ULONG(modreader); | 267 | sptr->speed = _mm_read_M_ULONG(modreader); |
268 | s->volume = _mm_read_UBYTE(modreader); | 268 | sptr->volume = _mm_read_UBYTE(modreader); |
269 | s->panning = _mm_read_M_UWORD(modreader); | 269 | sptr->panning = _mm_read_M_UWORD(modreader); |
270 | s->length = _mm_read_M_ULONG(modreader); | 270 | sptr->length = _mm_read_M_ULONG(modreader); |
271 | s->loopstart = _mm_read_M_ULONG(modreader); | 271 | sptr->loopstart = _mm_read_M_ULONG(modreader); |
272 | s->loopend = _mm_read_M_ULONG(modreader); | 272 | sptr->loopend = _mm_read_M_ULONG(modreader); |
273 | s->susbegin = _mm_read_M_ULONG(modreader); | 273 | sptr->susbegin = _mm_read_M_ULONG(modreader); |
274 | s->susend = _mm_read_M_ULONG(modreader); | 274 | sptr->susend = _mm_read_M_ULONG(modreader); |
275 | s->globvol = _mm_read_UBYTE(modreader); | 275 | sptr->globvol = _mm_read_UBYTE(modreader); |
276 | s->vibflags = _mm_read_UBYTE(modreader); | 276 | sptr->vibflags = _mm_read_UBYTE(modreader); |
277 | s->vibtype = _mm_read_UBYTE(modreader); | 277 | sptr->vibtype = _mm_read_UBYTE(modreader); |
278 | s->vibsweep = _mm_read_UBYTE(modreader); | 278 | sptr->vibsweep = _mm_read_UBYTE(modreader); |
279 | s->vibdepth = _mm_read_UBYTE(modreader); | 279 | sptr->vibdepth = _mm_read_UBYTE(modreader); |
280 | s->vibrate = _mm_read_UBYTE(modreader); | 280 | sptr->vibrate = _mm_read_UBYTE(modreader); |
281 | 281 | ||
282 | s->samplename=readstring(); | 282 | sptr->samplename=readstring(); |
283 | 283 | ||
284 | if(_mm_eof(modreader)) { | 284 | if(_mm_eof(modreader)) { |
285 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | 285 | _mm_errno = MMERR_LOADING_SAMPLEINFO; |
@@ -308,7 +308,7 @@ static int loadinstr6(void) | |||
308 | i->rpanvar = _mm_read_UBYTE(modreader); | 308 | i->rpanvar = _mm_read_UBYTE(modreader); |
309 | i->volfade = _mm_read_M_UWORD(modreader); | 309 | i->volfade = _mm_read_M_UWORD(modreader); |
310 | 310 | ||
311 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 311 | #if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C |
312 | #define UNI_LoadEnvelope6(name) \ | 312 | #define UNI_LoadEnvelope6(name) \ |
313 | i-> name##flg=_mm_read_UBYTE(modreader); \ | 313 | i-> name##flg=_mm_read_UBYTE(modreader); \ |
314 | i-> name##pts=_mm_read_UBYTE(modreader); \ | 314 | i-> name##pts=_mm_read_UBYTE(modreader); \ |
@@ -373,7 +373,7 @@ static int loadinstr5(void) | |||
373 | for(u=0;u<96;u++) | 373 | for(u=0;u<96;u++) |
374 | i->samplenumber[u]=of.numsmp+_mm_read_UBYTE(modreader); | 374 | i->samplenumber[u]=of.numsmp+_mm_read_UBYTE(modreader); |
375 | 375 | ||
376 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 376 | #if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C |
377 | #define UNI_LoadEnvelope5(name) \ | 377 | #define UNI_LoadEnvelope5(name) \ |
378 | i-> name##flg=_mm_read_UBYTE(modreader); \ | 378 | i-> name##flg=_mm_read_UBYTE(modreader); \ |
379 | i-> name##pts=_mm_read_UBYTE(modreader); \ | 379 | i-> name##pts=_mm_read_UBYTE(modreader); \ |
@@ -415,7 +415,7 @@ static int loadinstr5(void) | |||
415 | /* Allocate more room for sample information if necessary */ | 415 | /* Allocate more room for sample information if necessary */ |
416 | if(of.numsmp+u==wavcnt) { | 416 | if(of.numsmp+u==wavcnt) { |
417 | wavcnt+=UNI_SMPINCR; | 417 | wavcnt+=UNI_SMPINCR; |
418 | if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(UNISMP05)))) { | 418 | if(!(wh=(UNISMP05*)MikMod_realloc(wh,wavcnt*sizeof(UNISMP05)))) { |
419 | _mm_errno=MMERR_OUT_OF_MEMORY; | 419 | _mm_errno=MMERR_OUT_OF_MEMORY; |
420 | return 0; | 420 | return 0; |
421 | } | 421 | } |
@@ -447,7 +447,7 @@ static int loadinstr5(void) | |||
447 | 447 | ||
448 | /* sanity check */ | 448 | /* sanity check */ |
449 | if(!of.numsmp) { | 449 | if(!of.numsmp) { |
450 | if(wh) { MikMod_free(wh);wh=NULL; } | 450 | MikMod_free(wh);wh=NULL; |
451 | _mm_errno=MMERR_LOADING_SAMPLEINFO; | 451 | _mm_errno=MMERR_LOADING_SAMPLEINFO; |
452 | return 0; | 452 | return 0; |
453 | } | 453 | } |
@@ -504,8 +504,8 @@ static int UNI_Load(int curious) | |||
504 | char *modtype,*oldtype=NULL; | 504 | char *modtype,*oldtype=NULL; |
505 | INSTRUMENT *d; | 505 | INSTRUMENT *d; |
506 | SAMPLE *q; | 506 | SAMPLE *q; |
507 | (void)curious; | 507 | (void)curious; |
508 | 508 | ||
509 | /* read module header */ | 509 | /* read module header */ |
510 | _mm_read_UBYTES(mh.id,4,modreader); | 510 | _mm_read_UBYTES(mh.id,4,modreader); |
511 | if(mh.id[3]!='N') | 511 | if(mh.id[3]!='N') |
@@ -514,11 +514,11 @@ static int UNI_Load(int curious) | |||
514 | universion=0x100; | 514 | universion=0x100; |
515 | 515 | ||
516 | if(universion>=6) { | 516 | if(universion>=6) { |
517 | if (universion==6) | 517 | if (universion==6) { |
518 | (void)_mm_read_UBYTE(modreader); | 518 | _mm_skip_BYTE(modreader); |
519 | else | 519 | } else { |
520 | universion=_mm_read_M_UWORD(modreader); | 520 | universion=_mm_read_M_UWORD(modreader); |
521 | 521 | } | |
522 | mh.flags =_mm_read_M_UWORD(modreader); | 522 | mh.flags =_mm_read_M_UWORD(modreader); |
523 | mh.numchn =_mm_read_UBYTE(modreader); | 523 | mh.numchn =_mm_read_UBYTE(modreader); |
524 | mh.numvoices =_mm_read_UBYTE(modreader); | 524 | mh.numvoices =_mm_read_UBYTE(modreader); |
@@ -556,7 +556,7 @@ static int UNI_Load(int curious) | |||
556 | mh.flags &= UF_XMPERIODS | UF_LINEAR; | 556 | mh.flags &= UF_XMPERIODS | UF_LINEAR; |
557 | mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING; | 557 | mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING; |
558 | } | 558 | } |
559 | 559 | ||
560 | /* set module parameters */ | 560 | /* set module parameters */ |
561 | of.flags =mh.flags; | 561 | of.flags =mh.flags; |
562 | of.numchn =mh.numchn; | 562 | of.numchn =mh.numchn; |
@@ -578,21 +578,21 @@ static int UNI_Load(int curious) | |||
578 | oldtype=readstring(); | 578 | oldtype=readstring(); |
579 | if(oldtype) { | 579 | if(oldtype) { |
580 | size_t len=strlen(oldtype)+20; | 580 | size_t len=strlen(oldtype)+20; |
581 | if(!(modtype=MikMod_malloc(len))) return 0; | 581 | if(!(modtype=(char*)MikMod_malloc(len))) return 0; |
582 | #ifdef HAVE_SNPRINTF | 582 | #ifdef HAVE_SNPRINTF |
583 | snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); | 583 | snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); |
584 | #else | 584 | #else |
585 | sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); | 585 | sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); |
586 | #endif | 586 | #endif |
587 | } else { | 587 | } else { |
588 | if(!(modtype=MikMod_malloc(10))) return 0; | 588 | if(!(modtype=(char*)MikMod_malloc(10))) return 0; |
589 | #ifdef HAVE_SNPRINTF | 589 | #ifdef HAVE_SNPRINTF |
590 | snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); | 590 | snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); |
591 | #else | 591 | #else |
592 | sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); | 592 | sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); |
593 | #endif | 593 | #endif |
594 | } | 594 | } |
595 | of.modtype=StrDup(modtype); | 595 | of.modtype=MikMod_strdup(modtype); |
596 | MikMod_free(modtype);MikMod_free(oldtype); | 596 | MikMod_free(modtype);MikMod_free(oldtype); |
597 | of.comment=readstring(); | 597 | of.comment=readstring(); |
598 | 598 | ||
@@ -624,9 +624,14 @@ static int UNI_Load(int curious) | |||
624 | for(t=0;t<of.numchn;t++) of.panning[t]=mh.panning[t]; | 624 | for(t=0;t<of.numchn;t++) of.panning[t]=mh.panning[t]; |
625 | } | 625 | } |
626 | /* convert the ``end of song'' pattern code if necessary */ | 626 | /* convert the ``end of song'' pattern code if necessary */ |
627 | if(universion<0x106) | 627 | for(t=0;t<of.numpos;t++) { |
628 | for(t=0;t<of.numpos;t++) | 628 | if(universion<0x106 && of.positions[t]==255) of.positions[t]=LAST_PATTERN; |
629 | if(of.positions[t]==255) of.positions[t]=LAST_PATTERN; | 629 | else if (of.positions[t]>of.numpat) { /* SANITIY CHECK */ |
630 | /* fprintf(stderr,"position[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/ | ||
631 | _mm_errno = MMERR_LOADING_HEADER; | ||
632 | return 0; | ||
633 | } | ||
634 | } | ||
630 | 635 | ||
631 | /* instruments and samples */ | 636 | /* instruments and samples */ |
632 | if(universion>=6) { | 637 | if(universion>=6) { |
@@ -642,7 +647,7 @@ static int UNI_Load(int curious) | |||
642 | if(!AllocInstruments()) return 0; | 647 | if(!AllocInstruments()) return 0; |
643 | if(!loadinstr5()) return 0; | 648 | if(!loadinstr5()) return 0; |
644 | if(!AllocSamples()) { | 649 | if(!AllocSamples()) { |
645 | if(wh) { MikMod_free(wh);wh=NULL; } | 650 | MikMod_free(wh);wh=NULL; |
646 | return 0; | 651 | return 0; |
647 | } | 652 | } |
648 | if(!loadsmp5()) return 0; | 653 | if(!loadsmp5()) return 0; |
diff --git a/apps/plugins/mikmod/load_xm.c b/apps/plugins/mikmod/load_xm.c index ffbd6dff4d..3eb0803668 100644 --- a/apps/plugins/mikmod/load_xm.c +++ b/apps/plugins/mikmod/load_xm.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_xm.c,v 1.5 2008/02/29 18:49:03 denis111 Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Fasttracker (XM) module loader | 25 | Fasttracker (XM) module loader |
26 | 26 | ||
@@ -59,7 +59,7 @@ typedef struct XMHEADER { | |||
59 | UWORD numchn; /* Number of channels (2,4,6,8,10,...,32) */ | 59 | UWORD numchn; /* Number of channels (2,4,6,8,10,...,32) */ |
60 | UWORD numpat; /* Number of patterns (max 256) */ | 60 | UWORD numpat; /* Number of patterns (max 256) */ |
61 | UWORD numins; /* Number of instruments (max 128) */ | 61 | UWORD numins; /* Number of instruments (max 128) */ |
62 | UWORD flags; | 62 | UWORD flags; |
63 | UWORD tempo; /* Default tempo */ | 63 | UWORD tempo; /* Default tempo */ |
64 | UWORD bpm; /* Default BPM */ | 64 | UWORD bpm; /* Default BPM */ |
65 | UBYTE orders[256]; /* Pattern order table */ | 65 | UBYTE orders[256]; /* Pattern order table */ |
@@ -129,7 +129,7 @@ typedef struct XMNOTE { | |||
129 | static XMNOTE *xmpat=NULL; | 129 | static XMNOTE *xmpat=NULL; |
130 | static XMHEADER *mh=NULL; | 130 | static XMHEADER *mh=NULL; |
131 | 131 | ||
132 | /* increment unit for sample array MikMod_reallocation */ | 132 | /* increment unit for sample array reallocation */ |
133 | #define XM_SMPINCR 64 | 133 | #define XM_SMPINCR 64 |
134 | static ULONG *nextwav=NULL; | 134 | static ULONG *nextwav=NULL; |
135 | static XMWAVHEADER *wh=NULL,*s=NULL; | 135 | static XMWAVHEADER *wh=NULL,*s=NULL; |
@@ -155,6 +155,7 @@ static int XM_Init(void) | |||
155 | static void XM_Cleanup(void) | 155 | static void XM_Cleanup(void) |
156 | { | 156 | { |
157 | MikMod_free(mh); | 157 | MikMod_free(mh); |
158 | mh=NULL; | ||
158 | } | 159 | } |
159 | 160 | ||
160 | static int XM_ReadNote(XMNOTE* n) | 161 | static int XM_ReadNote(XMNOTE* n) |
@@ -359,8 +360,8 @@ static int LoadPatterns(int dummypat) | |||
359 | return 0; | 360 | return 0; |
360 | 361 | ||
361 | /* when packsize is 0, don't try to load a pattern.. it's empty. */ | 362 | /* when packsize is 0, don't try to load a pattern.. it's empty. */ |
362 | if(ph.packsize) | 363 | if(ph.packsize) |
363 | for(u=0;u<ph.numrows;u++) | 364 | for(u=0;u<ph.numrows;u++) |
364 | for(v=0;v<of.numchn;v++) { | 365 | for(v=0;v<of.numchn;v++) { |
365 | if(!ph.packsize) break; | 366 | if(!ph.packsize) break; |
366 | 367 | ||
@@ -443,11 +444,17 @@ static void FixEnvelope(ENVPT *cur, int pts) | |||
443 | 444 | ||
444 | static int LoadInstruments(void) | 445 | static int LoadInstruments(void) |
445 | { | 446 | { |
446 | int t,u, ck; | 447 | long filend,ck; |
448 | int t,u; | ||
447 | INSTRUMENT *d; | 449 | INSTRUMENT *d; |
448 | ULONG next=0; | 450 | ULONG next=0; |
449 | UWORD wavcnt=0; | 451 | UWORD wavcnt=0; |
450 | 452 | ||
453 | ck = _mm_ftell(modreader); | ||
454 | _mm_fseek(modreader,0,SEEK_END); | ||
455 | filend = _mm_ftell(modreader); | ||
456 | _mm_fseek(modreader,ck,SEEK_SET); | ||
457 | |||
451 | if(!AllocInstruments()) return 0; | 458 | if(!AllocInstruments()) return 0; |
452 | d=of.instruments; | 459 | d=of.instruments; |
453 | for(t=0;t<of.numins;t++,d++) { | 460 | for(t=0;t<of.numins;t++,d++) { |
@@ -461,12 +468,9 @@ static int LoadInstruments(void) | |||
461 | ih.size = _mm_read_I_ULONG(modreader); | 468 | ih.size = _mm_read_I_ULONG(modreader); |
462 | headend += ih.size; | 469 | headend += ih.size; |
463 | ck = _mm_ftell(modreader); | 470 | ck = _mm_ftell(modreader); |
464 | _mm_fseek(modreader,0,SEEK_END); | 471 | if ((headend<0) || (filend<headend) || (headend<ck)) { |
465 | if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) { | ||
466 | _mm_fseek(modreader,ck,SEEK_SET); | ||
467 | break; | 472 | break; |
468 | } | 473 | } |
469 | _mm_fseek(modreader,ck,SEEK_SET); | ||
470 | _mm_read_string(ih.name, 22, modreader); | 474 | _mm_read_string(ih.name, 22, modreader); |
471 | ih.type = _mm_read_UBYTE(modreader); | 475 | ih.type = _mm_read_UBYTE(modreader); |
472 | ih.numsmp = _mm_read_I_UWORD(modreader); | 476 | ih.numsmp = _mm_read_I_UWORD(modreader); |
@@ -500,7 +504,11 @@ static int LoadInstruments(void) | |||
500 | 504 | ||
501 | /* read the remainder of the header | 505 | /* read the remainder of the header |
502 | (2 bytes for 1.03, 22 for 1.04) */ | 506 | (2 bytes for 1.03, 22 for 1.04) */ |
503 | if (headend>=_mm_ftell(modreader)) for(u=headend-_mm_ftell(modreader);u;u--) (void)_mm_read_UBYTE(modreader); | 507 | if (headend>=_mm_ftell(modreader)) { |
508 | for(u=headend-_mm_ftell(modreader);u;u--) { | ||
509 | _mm_skip_BYTE(modreader); | ||
510 | } | ||
511 | } | ||
504 | 512 | ||
505 | /* we can't trust the envelope point count here, as some | 513 | /* we can't trust the envelope point count here, as some |
506 | modules have incorrect values (K_OSPACE.XM reports 32 volume | 514 | modules have incorrect values (K_OSPACE.XM reports 32 volume |
@@ -509,8 +517,8 @@ static int LoadInstruments(void) | |||
509 | if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2; | 517 | if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2; |
510 | 518 | ||
511 | if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) { | 519 | if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) { |
512 | if(nextwav) { MikMod_free(nextwav);nextwav=NULL; } | 520 | MikMod_free(nextwav);nextwav=NULL; |
513 | if(wh) { MikMod_free(wh);wh=NULL; } | 521 | MikMod_free(wh);wh=NULL; |
514 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | 522 | _mm_errno = MMERR_LOADING_SAMPLEINFO; |
515 | return 0; | 523 | return 0; |
516 | } | 524 | } |
@@ -519,7 +527,7 @@ static int LoadInstruments(void) | |||
519 | d->samplenumber[u]=pth.what[u]+of.numsmp; | 527 | d->samplenumber[u]=pth.what[u]+of.numsmp; |
520 | d->volfade = pth.volfade; | 528 | d->volfade = pth.volfade; |
521 | 529 | ||
522 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 530 | #if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C |
523 | #define XM_ProcessEnvelope(name) \ | 531 | #define XM_ProcessEnvelope(name) \ |
524 | for (u = 0; u < (XMENVCNT >> 1); u++) { \ | 532 | for (u = 0; u < (XMENVCNT >> 1); u++) { \ |
525 | d-> name##env[u].pos = pth. name##env[u << 1]; \ | 533 | d-> name##env[u].pos = pth. name##env[u << 1]; \ |
@@ -560,7 +568,7 @@ static int LoadInstruments(void) | |||
560 | \ | 568 | \ |
561 | if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \ | 569 | if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \ |
562 | d-> name/**/flg&=~EF_ON | 570 | d-> name/**/flg&=~EF_ON |
563 | #endif | 571 | #endif |
564 | 572 | ||
565 | XM_ProcessEnvelope(vol); | 573 | XM_ProcessEnvelope(vol); |
566 | XM_ProcessEnvelope(pan); | 574 | XM_ProcessEnvelope(pan); |
@@ -577,15 +585,23 @@ static int LoadInstruments(void) | |||
577 | everything over */ | 585 | everything over */ |
578 | if(mh->version>0x0103) next = 0; | 586 | if(mh->version>0x0103) next = 0; |
579 | for(u=0;u<ih.numsmp;u++,s++) { | 587 | for(u=0;u<ih.numsmp;u++,s++) { |
588 | /* XM sample header is 40 bytes: make sure we won't hit EOF */ | ||
589 | /* Note: last instrument is at the end of file in version 0x0104 */ | ||
590 | if(_mm_ftell(modreader)+40>filend) { | ||
591 | MikMod_free(nextwav);MikMod_free(wh); | ||
592 | nextwav=NULL;wh=NULL; | ||
593 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | ||
594 | return 0; | ||
595 | } | ||
580 | /* Allocate more room for sample information if necessary */ | 596 | /* Allocate more room for sample information if necessary */ |
581 | if(of.numsmp+u==wavcnt) { | 597 | if(of.numsmp+u==wavcnt) { |
582 | wavcnt+=XM_SMPINCR; | 598 | wavcnt+=XM_SMPINCR; |
583 | if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){ | 599 | if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){ |
584 | if(wh) { MikMod_free(wh);wh=NULL; } | 600 | MikMod_free(wh);wh=NULL; |
585 | _mm_errno = MMERR_OUT_OF_MEMORY; | 601 | _mm_errno = MMERR_OUT_OF_MEMORY; |
586 | return 0; | 602 | return 0; |
587 | } | 603 | } |
588 | if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) { | 604 | if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) { |
589 | MikMod_free(nextwav);nextwav=NULL; | 605 | MikMod_free(nextwav);nextwav=NULL; |
590 | _mm_errno = MMERR_OUT_OF_MEMORY; | 606 | _mm_errno = MMERR_OUT_OF_MEMORY; |
591 | return 0; | 607 | return 0; |
@@ -610,13 +626,6 @@ static int LoadInstruments(void) | |||
610 | 626 | ||
611 | nextwav[of.numsmp+u]=next; | 627 | nextwav[of.numsmp+u]=next; |
612 | next+=s->length; | 628 | next+=s->length; |
613 | |||
614 | if(_mm_eof(modreader)) { | ||
615 | MikMod_free(nextwav);MikMod_free(wh); | ||
616 | nextwav=NULL;wh=NULL; | ||
617 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | ||
618 | return 0; | ||
619 | } | ||
620 | } | 629 | } |
621 | 630 | ||
622 | if(mh->version>0x0103) { | 631 | if(mh->version>0x0103) { |
@@ -628,15 +637,15 @@ static int LoadInstruments(void) | |||
628 | } else { | 637 | } else { |
629 | /* read the remainder of the header */ | 638 | /* read the remainder of the header */ |
630 | ck = _mm_ftell(modreader); | 639 | ck = _mm_ftell(modreader); |
631 | _mm_fseek(modreader,0,SEEK_END); | 640 | if ((headend<0) || (filend<headend) || (headend<ck)) { |
632 | if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) { | ||
633 | _mm_fseek(modreader,ck,SEEK_SET); | ||
634 | break; | 641 | break; |
635 | } | 642 | } |
636 | _mm_fseek(modreader,ck,SEEK_SET); | 643 | for(u=headend-_mm_ftell(modreader);u;u--) { |
637 | for(u=headend-_mm_ftell(modreader);u;u--) (void)_mm_read_UBYTE(modreader); | 644 | _mm_skip_BYTE(modreader); |
645 | } | ||
638 | 646 | ||
639 | if(_mm_eof(modreader)) { | 647 | /* last instrument is at the end of file in version 0x0104 */ |
648 | if(_mm_eof(modreader) && (mh->version<0x0104 || t<of.numins-1)) { | ||
640 | MikMod_free(nextwav);MikMod_free(wh); | 649 | MikMod_free(nextwav);MikMod_free(wh); |
641 | nextwav=NULL;wh=NULL; | 650 | nextwav=NULL;wh=NULL; |
642 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | 651 | _mm_errno = MMERR_LOADING_SAMPLEINFO; |
@@ -648,8 +657,8 @@ static int LoadInstruments(void) | |||
648 | 657 | ||
649 | /* sanity check */ | 658 | /* sanity check */ |
650 | if(!of.numsmp) { | 659 | if(!of.numsmp) { |
651 | if(nextwav) { MikMod_free(nextwav);nextwav=NULL; } | 660 | MikMod_free(nextwav);nextwav=NULL; |
652 | if(wh) { MikMod_free(wh);wh=NULL; } | 661 | MikMod_free(wh);wh=NULL; |
653 | _mm_errno = MMERR_LOADING_SAMPLEINFO; | 662 | _mm_errno = MMERR_LOADING_SAMPLEINFO; |
654 | return 0; | 663 | return 0; |
655 | } | 664 | } |
@@ -664,17 +673,15 @@ static int XM_Load(int curious) | |||
664 | int t,u; | 673 | int t,u; |
665 | int dummypat=0; | 674 | int dummypat=0; |
666 | char tracker[21],modtype[60]; | 675 | char tracker[21],modtype[60]; |
667 | (void)curious; | 676 | (void)curious; |
668 | 677 | ||
669 | /* try to read module header */ | 678 | /* try to read module header */ |
670 | _mm_read_string(mh->id,17,modreader); | 679 | _mm_read_string(mh->id,17,modreader); |
671 | _mm_read_string(mh->songname,21,modreader); | 680 | _mm_read_string(mh->songname,21,modreader); |
672 | _mm_read_string(mh->trackername,20,modreader); | 681 | _mm_read_string(mh->trackername,20,modreader); |
673 | mh->version =_mm_read_I_UWORD(modreader); | 682 | mh->version =_mm_read_I_UWORD(modreader); |
674 | if((mh->version<0x102)||(mh->version>0x104)) { | 683 | if(mh->version < 0x102 || mh->version > 0x104) |
675 | _mm_errno=MMERR_NOT_A_MODULE; | 684 | goto bad_xm; |
676 | return 0; | ||
677 | } | ||
678 | mh->headersize =_mm_read_I_ULONG(modreader); | 685 | mh->headersize =_mm_read_I_ULONG(modreader); |
679 | mh->songlength =_mm_read_I_UWORD(modreader); | 686 | mh->songlength =_mm_read_I_UWORD(modreader); |
680 | mh->restart =_mm_read_I_UWORD(modreader); | 687 | mh->restart =_mm_read_I_UWORD(modreader); |
@@ -684,23 +691,25 @@ static int XM_Load(int curious) | |||
684 | mh->flags =_mm_read_I_UWORD(modreader); | 691 | mh->flags =_mm_read_I_UWORD(modreader); |
685 | mh->tempo =_mm_read_I_UWORD(modreader); | 692 | mh->tempo =_mm_read_I_UWORD(modreader); |
686 | mh->bpm =_mm_read_I_UWORD(modreader); | 693 | mh->bpm =_mm_read_I_UWORD(modreader); |
687 | if(!mh->bpm) { | 694 | if(mh->numchn > 64) goto bad_xm; |
688 | _mm_errno=MMERR_NOT_A_MODULE; | 695 | if(mh->tempo > 32 || mh->bpm < 32 || mh->bpm > 255) |
689 | return 0; | 696 | goto bad_xm; |
690 | } | 697 | if(mh->songlength > 256 || mh->headersize < 20 || mh->headersize > 20+256) |
691 | _mm_read_UBYTES(mh->orders,mh->headersize-20,modreader); | 698 | goto bad_xm; |
692 | 699 | if(mh->numpat > 256 || mh->numins > 255 || mh->restart > 255) | |
693 | if(_mm_eof(modreader)) { | 700 | goto bad_xm; |
694 | _mm_errno = MMERR_LOADING_HEADER; | 701 | /* _mm_read_UBYTES(mh->orders,256,modreader);*/ |
695 | return 0; | 702 | /* _mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);*/ |
696 | } | 703 | _mm_read_UBYTES(mh->orders,mh->songlength,modreader); |
704 | if(_mm_fseek(modreader, mh->headersize+60, SEEK_SET) || _mm_eof(modreader)) | ||
705 | goto bad_hdr; | ||
697 | 706 | ||
698 | /* set module variables */ | 707 | /* set module variables */ |
699 | of.initspeed = mh->tempo; | 708 | of.initspeed = mh->tempo; |
700 | of.inittempo = mh->bpm; | 709 | of.inittempo = mh->bpm; |
701 | strncpy(tracker,mh->trackername,20);tracker[20]=0; | 710 | strncpy(tracker,mh->trackername,20);tracker[20]=0; |
702 | for(t=20;(tracker[t]<=' ')&&(t>=0);t--) tracker[t]=0; | 711 | for(t=20;(t>=0)&&(tracker[t]<=' ');t--) tracker[t]=0; |
703 | 712 | ||
704 | /* some modules have the tracker name empty */ | 713 | /* some modules have the tracker name empty */ |
705 | if (!tracker[0]) | 714 | if (!tracker[0]) |
706 | strcpy(tracker,"Unknown tracker"); | 715 | strcpy(tracker,"Unknown tracker"); |
@@ -712,7 +721,7 @@ static int XM_Load(int curious) | |||
712 | sprintf(modtype,"%s (XM format %d.%02d)", | 721 | sprintf(modtype,"%s (XM format %d.%02d)", |
713 | tracker,mh->version>>8,mh->version&0xff); | 722 | tracker,mh->version>>8,mh->version&0xff); |
714 | #endif | 723 | #endif |
715 | of.modtype = StrDup(modtype); | 724 | of.modtype = MikMod_strdup(modtype); |
716 | of.numchn = mh->numchn; | 725 | of.numchn = mh->numchn; |
717 | of.numpat = mh->numpat; | 726 | of.numpat = mh->numpat; |
718 | of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */ | 727 | of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */ |
@@ -720,8 +729,7 @@ static int XM_Load(int curious) | |||
720 | of.numpos = mh->songlength; /* copy the songlength */ | 729 | of.numpos = mh->songlength; /* copy the songlength */ |
721 | of.reppos = mh->restart<mh->songlength?mh->restart:0; | 730 | of.reppos = mh->restart<mh->songlength?mh->restart:0; |
722 | of.numins = mh->numins; | 731 | of.numins = mh->numins; |
723 | of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | | 732 | of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | UF_PANNING; |
724 | UF_PANNING; | ||
725 | if(mh->flags&1) of.flags |= UF_LINEAR; | 733 | if(mh->flags&1) of.flags |= UF_LINEAR; |
726 | of.bpmlimit = 32; | 734 | of.bpmlimit = 32; |
727 | 735 | ||
@@ -802,16 +810,19 @@ static int XM_Load(int curious) | |||
802 | MikMod_free(wh);MikMod_free(nextwav); | 810 | MikMod_free(wh);MikMod_free(nextwav); |
803 | wh=NULL;nextwav=NULL; | 811 | wh=NULL;nextwav=NULL; |
804 | return 1; | 812 | return 1; |
813 | |||
814 | bad_hdr: _mm_errno = MMERR_LOADING_HEADER; return 0; | ||
815 | bad_xm: _mm_errno = MMERR_NOT_A_MODULE; return 0; | ||
805 | } | 816 | } |
806 | 817 | ||
807 | static CHAR *XM_LoadTitle(void) | 818 | static CHAR *XM_LoadTitle(void) |
808 | { | 819 | { |
809 | CHAR s[21]; | 820 | CHAR str[21]; |
810 | 821 | ||
811 | _mm_fseek(modreader,17,SEEK_SET); | 822 | _mm_fseek(modreader,17,SEEK_SET); |
812 | if(!_mm_read_UBYTES(s,21,modreader)) return NULL; | 823 | if(!_mm_read_UBYTES(str, 21, modreader)) return NULL; |
813 | 824 | ||
814 | return(DupStr(s,21,1)); | 825 | return(DupStr(str,21,1)); |
815 | } | 826 | } |
816 | 827 | ||
817 | /*========== Loader information */ | 828 | /*========== Loader information */ |
diff --git a/apps/plugins/mikmod/mdreg.c b/apps/plugins/mikmod/mdreg.c index 6cbaad2932..ff5d803000 100644 --- a/apps/plugins/mikmod/mdreg.c +++ b/apps/plugins/mikmod/mdreg.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: mdreg.c,v 1.2 2005/03/30 19:11:13 realtech Exp $ | ||
24 | |||
25 | Routine for registering all drivers in libmikmod for the current platform. | 23 | Routine for registering all drivers in libmikmod for the current platform. |
26 | 24 | ||
27 | ==============================================================================*/ | 25 | ==============================================================================*/ |
@@ -34,12 +32,13 @@ | |||
34 | 32 | ||
35 | static void _mm_registeralldrivers(void) | 33 | static void _mm_registeralldrivers(void) |
36 | { | 34 | { |
37 | #if 0 | ||
38 | |||
39 | /* Register network drivers */ | 35 | /* Register network drivers */ |
40 | #ifdef DRV_AF | 36 | #ifdef DRV_AF |
41 | _mm_registerdriver(&drv_AF); | 37 | _mm_registerdriver(&drv_AF); |
42 | #endif | 38 | #endif |
39 | #ifdef DRV_PULSEAUDIO | ||
40 | _mm_registerdriver(&drv_pulseaudio); | ||
41 | #endif | ||
43 | #ifdef DRV_ESD | 42 | #ifdef DRV_ESD |
44 | _mm_registerdriver(&drv_esd); | 43 | _mm_registerdriver(&drv_esd); |
45 | #endif | 44 | #endif |
@@ -51,8 +50,22 @@ static void _mm_registeralldrivers(void) | |||
51 | #ifdef DRV_ULTRA | 50 | #ifdef DRV_ULTRA |
52 | _mm_registerdriver(&drv_ultra); | 51 | _mm_registerdriver(&drv_ultra); |
53 | #endif | 52 | #endif |
53 | #ifdef DRV_SAM9407 | ||
54 | _mm_registerdriver(&drv_sam9407); | ||
55 | #endif | ||
54 | 56 | ||
55 | /* Register hardware drivers - software mixing */ | 57 | /* Register multi-platform drivers -- software mixing */ |
58 | #ifdef DRV_SDL | ||
59 | _mm_registerdriver(&drv_sdl); | ||
60 | #endif | ||
61 | #ifdef DRV_OPENAL | ||
62 | _mm_registerdriver(&drv_openal); | ||
63 | #endif | ||
64 | |||
65 | /* Register OS-specific hardware drivers - software mixing */ | ||
66 | #ifdef DRV_AHI | ||
67 | _mm_registerdriver(&drv_ahi); | ||
68 | #endif | ||
56 | #ifdef DRV_AIX | 69 | #ifdef DRV_AIX |
57 | _mm_registerdriver(&drv_aix); | 70 | _mm_registerdriver(&drv_aix); |
58 | #endif | 71 | #endif |
@@ -62,6 +75,9 @@ static void _mm_registeralldrivers(void) | |||
62 | #ifdef DRV_HP | 75 | #ifdef DRV_HP |
63 | _mm_registerdriver(&drv_hp); | 76 | _mm_registerdriver(&drv_hp); |
64 | #endif | 77 | #endif |
78 | #ifdef DRV_SNDIO | ||
79 | _mm_registerdriver(&drv_sndio); | ||
80 | #endif | ||
65 | #ifdef DRV_OSS | 81 | #ifdef DRV_OSS |
66 | _mm_registerdriver(&drv_oss); | 82 | _mm_registerdriver(&drv_oss); |
67 | #endif | 83 | #endif |
@@ -77,6 +93,9 @@ static void _mm_registeralldrivers(void) | |||
77 | #ifdef DRV_OS2 | 93 | #ifdef DRV_OS2 |
78 | _mm_registerdriver(&drv_os2); | 94 | _mm_registerdriver(&drv_os2); |
79 | #endif | 95 | #endif |
96 | #ifdef DRV_XAUDIO2 | ||
97 | _mm_registerdriver(&drv_xaudio2); | ||
98 | #endif | ||
80 | #ifdef DRV_DS | 99 | #ifdef DRV_DS |
81 | _mm_registerdriver(&drv_ds); | 100 | _mm_registerdriver(&drv_ds); |
82 | #endif | 101 | #endif |
@@ -89,39 +108,54 @@ static void _mm_registeralldrivers(void) | |||
89 | #ifdef DRV_OSX | 108 | #ifdef DRV_OSX |
90 | _mm_registerdriver(&drv_osx); | 109 | _mm_registerdriver(&drv_osx); |
91 | #endif | 110 | #endif |
111 | #ifdef DRV_DC | ||
112 | _mm_registerdriver(&drv_dc); | ||
113 | #endif | ||
92 | #ifdef DRV_GP32 | 114 | #ifdef DRV_GP32 |
93 | _mm_registerdriver(&drv_gp32); | 115 | _mm_registerdriver(&drv_gp32); |
94 | #endif | 116 | #endif |
95 | 117 | #ifdef DRV_PSP | |
96 | /* dos drivers */ | 118 | _mm_registerdriver(&drv_psp); |
119 | #endif | ||
120 | #ifdef DRV_OSLES | ||
121 | _mm_registerdriver(&drv_osles); | ||
122 | #endif | ||
123 | #ifdef DRV_N64 | ||
124 | _mm_registerdriver(&drv_n64); | ||
125 | #endif | ||
126 | |||
127 | /* dos drivers - wss first, since some cards emulate sb */ | ||
97 | #ifdef DRV_WSS | 128 | #ifdef DRV_WSS |
98 | /* wss first, since some cards emulate sb */ | ||
99 | _mm_registerdriver(&drv_wss); | 129 | _mm_registerdriver(&drv_wss); |
100 | #endif | 130 | #endif |
101 | #ifdef DRV_SB | 131 | #ifdef DRV_SB |
102 | _mm_registerdriver(&drv_sb); | 132 | _mm_registerdriver(&drv_sb); |
103 | #endif | 133 | #endif |
104 | 134 | ||
105 | /* Register disk writers */ | 135 | /* Register disk writers */ |
106 | _mm_registerdriver(&drv_raw); | 136 | #ifdef DRV_WAV |
107 | _mm_registerdriver(&drv_wav); | 137 | _mm_registerdriver(&drv_wav); |
138 | #endif | ||
108 | #ifdef DRV_AIFF | 139 | #ifdef DRV_AIFF |
109 | _mm_registerdriver(&drv_aiff); | 140 | _mm_registerdriver(&drv_aiff); |
110 | #endif | 141 | #endif |
111 | 142 | #ifdef DRV_RAW | |
143 | _mm_registerdriver(&drv_raw); | ||
144 | #endif | ||
145 | |||
112 | /* Register other drivers */ | 146 | /* Register other drivers */ |
113 | #ifdef DRV_PIPE | 147 | #ifdef DRV_PIPE |
114 | _mm_registerdriver(&drv_pipe); | 148 | _mm_registerdriver(&drv_pipe); |
115 | #endif | 149 | #endif |
116 | #ifndef macintosh | 150 | #if defined(DRV_STDOUT) && !defined(macintosh) |
117 | _mm_registerdriver(&drv_stdout); | 151 | _mm_registerdriver(&drv_stdout); |
118 | #endif | 152 | #endif |
119 | 153 | ||
120 | #endif | 154 | /* Register 'nosound' driver */ |
121 | _mm_registerdriver(&drv_nos); | 155 | _mm_registerdriver(&drv_nos); |
122 | } | 156 | } |
123 | 157 | ||
124 | void MikMod_RegisterAllDrivers(void) | 158 | MIKMODAPI void MikMod_RegisterAllDrivers(void) |
125 | { | 159 | { |
126 | MUTEX_LOCK(lists); | 160 | MUTEX_LOCK(lists); |
127 | _mm_registeralldrivers(); | 161 | _mm_registeralldrivers(); |
diff --git a/apps/plugins/mikmod/mdriver.c b/apps/plugins/mikmod/mdriver.c index 2e8e9b5e41..2e1f8063b9 100644 --- a/apps/plugins/mikmod/mdriver.c +++ b/apps/plugins/mikmod/mdriver.c | |||
@@ -1,17 +1,17 @@ | |||
1 | /* MikMod sound library | 1 | /* MikMod sound library |
2 | (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS | 2 | (c) 1998-2014 Miodrag Vallat and others - see file AUTHORS |
3 | for complete list. | 3 | for a complete list. |
4 | 4 | ||
5 | This library is free software; you can redistribute it and/or modify | 5 | This library is free software; you can redistribute it and/or modify |
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: mdriver.c,v 1.4 2007/12/03 20:59:05 denis111 Exp $ | ||
24 | |||
25 | These routines are used to access the available soundcard drivers. | 23 | These routines are used to access the available soundcard drivers. |
26 | 24 | ||
27 | ==============================================================================*/ | 25 | ==============================================================================*/ |
@@ -34,54 +32,59 @@ | |||
34 | #include <unistd.h> | 32 | #include <unistd.h> |
35 | #endif | 33 | #endif |
36 | 34 | ||
37 | #if 0 | ||
38 | #if defined unix || (defined __APPLE__ && defined __MACH__) | ||
39 | #include <pwd.h> | ||
40 | #include <sys/stat.h> | ||
41 | #endif | ||
42 | #endif | ||
43 | |||
44 | #include <string.h> | 35 | #include <string.h> |
45 | #ifdef HAVE_STRINGS_H | ||
46 | #include <strings.h> | ||
47 | #endif | ||
48 | 36 | ||
49 | #include "mikmod_internals.h" | 37 | #include "mikmod_internals.h" |
50 | 38 | ||
39 | #if (MIKMOD_UNIX) | ||
40 | #include <pwd.h> | ||
41 | #include <sys/stat.h> | ||
42 | #endif | ||
43 | |||
51 | #ifdef SUNOS | 44 | #ifdef SUNOS |
52 | extern int fprintf(FILE *, const char *, ...); | 45 | extern int fprintf(FILE *, const char *, ...); |
53 | #endif | 46 | #endif |
54 | 47 | ||
55 | static MDRIVER *firstdriver=NULL; | ||
56 | MIKMODAPI MDRIVER *md_driver=NULL; | ||
57 | extern MODULE *pf; /* modfile being played */ | 48 | extern MODULE *pf; /* modfile being played */ |
58 | 49 | ||
50 | /* EXPORTED GLOBALS */ | ||
51 | MIKMODAPI MDRIVER *md_driver = NULL; | ||
52 | |||
59 | /* Initial global settings */ | 53 | /* Initial global settings */ |
60 | MIKMODAPI UWORD md_device = 0; /* autodetect */ | 54 | MIKMODAPI UWORD md_device = 0; /* autodetect */ |
61 | MIKMODAPI UWORD md_mixfreq = 44100; | 55 | MIKMODAPI ULONG md_mixfreq = 44100; |
62 | MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS | | 56 | MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS | |
63 | DMODE_SURROUND |DMODE_SOFT_MUSIC | | 57 | DMODE_SURROUND | |
64 | DMODE_SOFT_SNDFX; | 58 | DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX; |
65 | MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */ | 59 | MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */ |
66 | MIKMODAPI UBYTE md_reverb = 0; /* no reverb */ | 60 | MIKMODAPI UBYTE md_reverb = 0; /* no reverb */ |
67 | MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */ | 61 | MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */ |
68 | MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */ | 62 | MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */ |
69 | MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */ | 63 | MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */ |
70 | UWORD md_bpm = 125; /* tempo */ | 64 | |
71 | 65 | /* INTERNAL GLOBALS */ | |
72 | /* Do not modify the numchn variables yourself! use MD_SetVoices() */ | 66 | UWORD md_bpm = 125; /* tempo */ |
73 | UBYTE md_numchn=0,md_sngchn=0,md_sfxchn=0; | 67 | |
74 | UBYTE md_hardchn=0,md_softchn=0; | 68 | /* Do not modify the numchn variables yourself! use MikMod_SetNumVoices() */ |
75 | 69 | UBYTE md_numchn = 0, md_sngchn = 0, md_sfxchn = 0; | |
76 | void (*md_player)(void) = Player_HandleTick; | 70 | UBYTE md_hardchn = 0, md_softchn= 0; |
77 | static volatile int isplaying=0, initialized = 0; | 71 | |
78 | static UBYTE *sfxinfo; | 72 | MikMod_player_t md_player = Player_HandleTick; |
79 | static int sfxpool; | 73 | |
80 | 74 | MikMod_callback_t vc_callback = NULL; | |
81 | static SAMPLE **md_sample = NULL; | 75 | |
76 | /* PRIVATE VARS */ | ||
77 | static MDRIVER *firstdriver = NULL; | ||
78 | |||
79 | static volatile int isplaying = 0, initialized = 0; | ||
80 | |||
81 | static UBYTE *sfxinfo; | ||
82 | static int sfxpool; | ||
83 | |||
84 | static SAMPLE **md_sample = NULL; | ||
82 | 85 | ||
83 | /* Previous driver in use */ | 86 | /* Previous driver in use */ |
84 | static SWORD olddevice = -1; | 87 | static SWORD olddevice = -1; |
85 | 88 | ||
86 | /* Limits the number of hardware voices to the specified amount. | 89 | /* Limits the number of hardware voices to the specified amount. |
87 | This function should only be used by the low-level drivers. */ | 90 | This function should only be used by the low-level drivers. */ |
@@ -183,17 +186,18 @@ MIKMODAPI CHAR* MikMod_InfoDriver(void) | |||
183 | 186 | ||
184 | MUTEX_LOCK(lists); | 187 | MUTEX_LOCK(lists); |
185 | /* compute size of buffer */ | 188 | /* compute size of buffer */ |
186 | for(l=firstdriver;l;l=l->next) | 189 | for(l = firstdriver; l; l = l->next) |
187 | len+=4+(l->next?1:0)+strlen(l->Version); | 190 | len += 4 + (l->next ? 1 : 0) + strlen(l->Version); |
188 | 191 | ||
189 | if(len) | 192 | if(len) |
190 | if((list=MikMod_malloc(len*sizeof(CHAR)))) { | 193 | if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) { |
191 | list[0]=0; | 194 | CHAR *list_end = list; |
192 | /* list all registered device drivers : */ | 195 | list[0] = 0; |
193 | for(t=1,l=firstdriver;l;l=l->next,t++) | 196 | /* list all registered device drivers : */ |
194 | sprintf(list,(l->next)?"%s%2d %s\n":"%s%2d %s", | 197 | for(t = 1, l = firstdriver; l; l = l->next, t++) { |
195 | list,t,l->Version); | 198 | list_end += sprintf(list_end, "%2d %s%s", t, l->Version, (l->next)? "\n" : ""); |
196 | } | 199 | } |
200 | } | ||
197 | MUTEX_UNLOCK(lists); | 201 | MUTEX_UNLOCK(lists); |
198 | return list; | 202 | return list; |
199 | } | 203 | } |
@@ -214,7 +218,7 @@ void _mm_registerdriver(struct MDRIVER* drv) | |||
214 | } | 218 | } |
215 | cruise->next = drv; | 219 | cruise->next = drv; |
216 | } else | 220 | } else |
217 | firstdriver = drv; | 221 | firstdriver = drv; |
218 | } | 222 | } |
219 | } | 223 | } |
220 | 224 | ||
@@ -230,7 +234,7 @@ MIKMODAPI void MikMod_RegisterDriver(struct MDRIVER* drv) | |||
230 | MUTEX_UNLOCK(lists); | 234 | MUTEX_UNLOCK(lists); |
231 | } | 235 | } |
232 | 236 | ||
233 | MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias) | 237 | MIKMODAPI int MikMod_DriverFromAlias(const CHAR *alias) |
234 | { | 238 | { |
235 | int rank=1; | 239 | int rank=1; |
236 | MDRIVER *cruise; | 240 | MDRIVER *cruise; |
@@ -252,18 +256,17 @@ MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias) | |||
252 | 256 | ||
253 | MIKMODAPI MDRIVER *MikMod_DriverByOrdinal(int ordinal) | 257 | MIKMODAPI MDRIVER *MikMod_DriverByOrdinal(int ordinal) |
254 | { | 258 | { |
255 | MDRIVER *cruise; | 259 | MDRIVER *cruise; |
256 | 260 | ||
257 | /* Allow only driver ordinals > 0 */ | 261 | /* Allow only driver ordinals > 0 */ |
258 | if (!ordinal) | 262 | if (!ordinal) return NULL; |
259 | return 0; | ||
260 | 263 | ||
261 | MUTEX_LOCK(lists); | 264 | MUTEX_LOCK(lists); |
262 | cruise = firstdriver; | 265 | cruise = firstdriver; |
263 | while (cruise && --ordinal) | 266 | while (cruise && --ordinal) |
264 | cruise = cruise->next; | 267 | cruise = cruise->next; |
265 | MUTEX_UNLOCK(lists); | 268 | MUTEX_UNLOCK(lists); |
266 | return cruise; | 269 | return cruise; |
267 | } | 270 | } |
268 | 271 | ||
269 | SWORD MD_SampleLoad(SAMPLOAD* s, int type) | 272 | SWORD MD_SampleLoad(SAMPLOAD* s, int type) |
@@ -496,14 +499,12 @@ MIKMODAPI ULONG Voice_RealVolume(SBYTE voice) | |||
496 | return result; | 499 | return result; |
497 | } | 500 | } |
498 | 501 | ||
499 | extern MikMod_callback_t vc_callback; | ||
500 | |||
501 | MIKMODAPI void VC_SetCallback(MikMod_callback_t callback) | 502 | MIKMODAPI void VC_SetCallback(MikMod_callback_t callback) |
502 | { | 503 | { |
503 | vc_callback = callback; | 504 | vc_callback = callback; |
504 | } | 505 | } |
505 | 506 | ||
506 | static int _mm_init(CHAR *cmdline) | 507 | static int _mm_init(const CHAR *cmdline) |
507 | { | 508 | { |
508 | UWORD t; | 509 | UWORD t; |
509 | 510 | ||
@@ -561,7 +562,7 @@ static int _mm_init(CHAR *cmdline) | |||
561 | return 0; | 562 | return 0; |
562 | } | 563 | } |
563 | 564 | ||
564 | MIKMODAPI int MikMod_Init(CHAR *cmdline) | 565 | MIKMODAPI int MikMod_Init(const CHAR *cmdline) |
565 | { | 566 | { |
566 | int result; | 567 | int result; |
567 | 568 | ||
@@ -581,8 +582,8 @@ void MikMod_Exit_internal(void) | |||
581 | md_numchn = md_sfxchn = md_sngchn = 0; | 582 | md_numchn = md_sfxchn = md_sngchn = 0; |
582 | md_driver = &drv_nos; | 583 | md_driver = &drv_nos; |
583 | 584 | ||
584 | if(sfxinfo) MikMod_free(sfxinfo); | 585 | MikMod_free(sfxinfo); |
585 | if(md_sample) MikMod_free(md_sample); | 586 | MikMod_free(md_sample); |
586 | md_sample = NULL; | 587 | md_sample = NULL; |
587 | sfxinfo = NULL; | 588 | sfxinfo = NULL; |
588 | 589 | ||
@@ -598,14 +599,14 @@ MIKMODAPI void MikMod_Exit(void) | |||
598 | MUTEX_UNLOCK(vars); | 599 | MUTEX_UNLOCK(vars); |
599 | } | 600 | } |
600 | 601 | ||
601 | /* Reset the driver using the new global variable settings. | 602 | /* Reset the driver using the new global variable settings. |
602 | If the driver has not been initialized, it will be now. */ | 603 | If the driver has not been initialized, it will be now. */ |
603 | static int _mm_reset(CHAR *cmdline) | 604 | static int _mm_reset(const CHAR *cmdline) |
604 | { | 605 | { |
605 | int wasplaying = 0; | 606 | int wasplaying = 0; |
606 | 607 | ||
607 | if(!initialized) return _mm_init(cmdline); | 608 | if(!initialized) return _mm_init(cmdline); |
608 | 609 | ||
609 | if (isplaying) { | 610 | if (isplaying) { |
610 | wasplaying = 1; | 611 | wasplaying = 1; |
611 | md_driver->PlayStop(); | 612 | md_driver->PlayStop(); |
@@ -629,12 +630,12 @@ static int _mm_reset(CHAR *cmdline) | |||
629 | return 1; | 630 | return 1; |
630 | } | 631 | } |
631 | } | 632 | } |
632 | 633 | ||
633 | if (wasplaying) md_driver->PlayStart(); | 634 | if (wasplaying) return md_driver->PlayStart(); |
634 | return 0; | 635 | return 0; |
635 | } | 636 | } |
636 | 637 | ||
637 | MIKMODAPI int MikMod_Reset(CHAR *cmdline) | 638 | MIKMODAPI int MikMod_Reset(const CHAR *cmdline) |
638 | { | 639 | { |
639 | int result; | 640 | int result; |
640 | 641 | ||
@@ -661,8 +662,8 @@ int MikMod_SetNumVoices_internal(int music, int sfx) | |||
661 | resume = 1; | 662 | resume = 1; |
662 | } | 663 | } |
663 | 664 | ||
664 | if(sfxinfo) MikMod_free(sfxinfo); | 665 | MikMod_free(sfxinfo); |
665 | if(md_sample) MikMod_free(md_sample); | 666 | MikMod_free(md_sample); |
666 | md_sample = NULL; | 667 | md_sample = NULL; |
667 | sfxinfo = NULL; | 668 | sfxinfo = NULL; |
668 | 669 | ||
@@ -764,7 +765,7 @@ MIKMODAPI int MikMod_Active(void) | |||
764 | allocated for use as sound effects (loops through voices, skipping all active | 765 | allocated for use as sound effects (loops through voices, skipping all active |
765 | criticals). | 766 | criticals). |
766 | 767 | ||
767 | Returns the voice that the sound is being played on. */ | 768 | Returns the voice that the sound is being played on. */ |
768 | static SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags) | 769 | static SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags) |
769 | { | 770 | { |
770 | int orig=sfxpool;/* for cases where all channels are critical */ | 771 | int orig=sfxpool;/* for cases where all channels are critical */ |
@@ -825,12 +826,15 @@ MIKMODAPI long MikMod_GetVersion(void) | |||
825 | #ifdef HAVE_PTHREAD | 826 | #ifdef HAVE_PTHREAD |
826 | #define INIT_MUTEX(name) \ | 827 | #define INIT_MUTEX(name) \ |
827 | pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER | 828 | pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER |
829 | |||
828 | #elif defined(__OS2__)||defined(__EMX__) | 830 | #elif defined(__OS2__)||defined(__EMX__) |
829 | #define INIT_MUTEX(name) \ | 831 | #define INIT_MUTEX(name) \ |
830 | HMTX _mm_mutex_##name | 832 | HMTX _mm_mutex_##name |
831 | #elif defined(WIN32) | 833 | |
834 | #elif defined(_WIN32) | ||
832 | #define INIT_MUTEX(name) \ | 835 | #define INIT_MUTEX(name) \ |
833 | HANDLE _mm_mutex_##name | 836 | HANDLE _mm_mutex_##name |
837 | |||
834 | #else | 838 | #else |
835 | #define INIT_MUTEX(name) \ | 839 | #define INIT_MUTEX(name) \ |
836 | void *_mm_mutex_##name = NULL | 840 | void *_mm_mutex_##name = NULL |
@@ -842,8 +846,8 @@ INIT_MUTEX(lists); | |||
842 | MIKMODAPI int MikMod_InitThreads(void) | 846 | MIKMODAPI int MikMod_InitThreads(void) |
843 | { | 847 | { |
844 | static int firstcall=1; | 848 | static int firstcall=1; |
845 | static int result=0; | 849 | static int result = 0; |
846 | 850 | ||
847 | if (firstcall) { | 851 | if (firstcall) { |
848 | firstcall=0; | 852 | firstcall=0; |
849 | #ifdef HAVE_PTHREAD | 853 | #ifdef HAVE_PTHREAD |
@@ -855,9 +859,9 @@ MIKMODAPI int MikMod_InitThreads(void) | |||
855 | result=0; | 859 | result=0; |
856 | } else | 860 | } else |
857 | result=1; | 861 | result=1; |
858 | #elif defined(WIN32) | 862 | #elif defined(_WIN32) |
859 | if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,"libmikmod(lists)")))|| | 863 | if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,TEXT("libmikmod(lists)"))))|| |
860 | (!(_mm_mutex_vars=CreateMutex(NULL,FALSE,"libmikmod(vars)")))) | 864 | (!(_mm_mutex_vars=CreateMutex(NULL,FALSE,TEXT("libmikmod(vars)"))))) |
861 | result=0; | 865 | result=0; |
862 | else | 866 | else |
863 | result=1; | 867 | result=1; |
@@ -880,24 +884,24 @@ MIKMODAPI void MikMod_Lock(void) | |||
880 | 884 | ||
881 | /*========== Parameter extraction helper */ | 885 | /*========== Parameter extraction helper */ |
882 | 886 | ||
883 | CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit) | 887 | CHAR *MD_GetAtom(const CHAR *atomname, const CHAR *cmdline, int implicit) |
884 | { | 888 | { |
885 | CHAR *ret=NULL; | 889 | CHAR *ret=NULL; |
886 | 890 | ||
887 | if(cmdline) { | 891 | if(cmdline) { |
888 | CHAR *buf=strstr(cmdline,atomname); | 892 | const CHAR *buf=strstr(cmdline,atomname); |
889 | 893 | ||
890 | if((buf)&&((buf==cmdline)||(*(buf-1)==','))) { | 894 | if((buf)&&((buf==cmdline)||(*(buf-1)==','))) { |
891 | CHAR *ptr=buf+strlen(atomname); | 895 | const CHAR *ptr=buf+strlen(atomname); |
892 | 896 | ||
893 | if(*ptr=='=') { | 897 | if(*ptr=='=') { |
894 | for(buf=++ptr;(*ptr)&&((*ptr)!=',');ptr++); | 898 | for(buf=++ptr;(*ptr)&&((*ptr)!=',');ptr++); |
895 | ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR)); | 899 | ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR)); |
896 | if(ret) | 900 | if(ret) |
897 | strncpy(ret,buf,ptr-buf); | 901 | strncpy(ret,buf,ptr-buf); |
898 | } else if((*ptr==',')||(!*ptr)) { | 902 | } else if((*ptr==',')||(!*ptr)) { |
899 | if(implicit) { | 903 | if(implicit) { |
900 | ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR)); | 904 | ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR)); |
901 | if(ret) | 905 | if(ret) |
902 | strncpy(ret,buf,ptr-buf); | 906 | strncpy(ret,buf,ptr-buf); |
903 | } | 907 | } |
@@ -907,8 +911,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit) | |||
907 | return ret; | 911 | return ret; |
908 | } | 912 | } |
909 | 913 | ||
910 | #if 0 | 914 | #if (MIKMOD_UNIX) |
911 | #if defined unix || (defined __APPLE__ && defined __MACH__) | ||
912 | 915 | ||
913 | /*========== Posix helper functions */ | 916 | /*========== Posix helper functions */ |
914 | 917 | ||
@@ -917,7 +920,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit) | |||
917 | reasonable. Returns 1 if it is safe to rewrite the file, 0 otherwise. | 920 | reasonable. Returns 1 if it is safe to rewrite the file, 0 otherwise. |
918 | The goal is to prevent a setuid root libmikmod application from overriding | 921 | The goal is to prevent a setuid root libmikmod application from overriding |
919 | files like /etc/passwd with digital sound... */ | 922 | files like /etc/passwd with digital sound... */ |
920 | int MD_Access(CHAR *filename) | 923 | int MD_Access(const CHAR * filename) |
921 | { | 924 | { |
922 | struct stat buf; | 925 | struct stat buf; |
923 | 926 | ||
@@ -934,7 +937,7 @@ int MD_Access(CHAR *filename) | |||
934 | } else | 937 | } else |
935 | if(!(buf.st_mode&S_IWOTH)) return 0; | 938 | if(!(buf.st_mode&S_IWOTH)) return 0; |
936 | } | 939 | } |
937 | 940 | ||
938 | return 1; | 941 | return 1; |
939 | } | 942 | } |
940 | 943 | ||
@@ -961,5 +964,5 @@ int MD_DropPrivileges(void) | |||
961 | } | 964 | } |
962 | 965 | ||
963 | #endif | 966 | #endif |
964 | #endif | 967 | |
965 | /* ex:set ts=4: */ | 968 | /* ex:set ts=8: */ |
diff --git a/apps/plugins/mikmod/mikmod.c b/apps/plugins/mikmod/mikmod.c index 688baed56c..0eba320f18 100644 --- a/apps/plugins/mikmod/mikmod.c +++ b/apps/plugins/mikmod/mikmod.c | |||
@@ -25,7 +25,7 @@ | |||
25 | /* Persistent configuration */ | 25 | /* Persistent configuration */ |
26 | #define MIKMOD_CONFIGFILE "mikmod.cfg" | 26 | #define MIKMOD_CONFIGFILE "mikmod.cfg" |
27 | #define MIKMOD_SETTINGS_MINVERSION 1 | 27 | #define MIKMOD_SETTINGS_MINVERSION 1 |
28 | #define MIKMOD_SETTINGS_VERSION 1 | 28 | #define MIKMOD_SETTINGS_VERSION 2 |
29 | 29 | ||
30 | #ifdef USETHREADS | 30 | #ifdef USETHREADS |
31 | #define EV_EXIT 9999 | 31 | #define EV_EXIT 9999 |
@@ -161,7 +161,6 @@ static bool mod_ext(const char ext[]) | |||
161 | !rb->strcasecmp(ext,".dsm") || | 161 | !rb->strcasecmp(ext,".dsm") || |
162 | !rb->strcasecmp(ext,".far") || | 162 | !rb->strcasecmp(ext,".far") || |
163 | !rb->strcasecmp(ext,".gdm") || | 163 | !rb->strcasecmp(ext,".gdm") || |
164 | !rb->strcasecmp(ext,".gt2") || | ||
165 | !rb->strcasecmp(ext,".imf") || | 164 | !rb->strcasecmp(ext,".imf") || |
166 | !rb->strcasecmp(ext,".it") || | 165 | !rb->strcasecmp(ext,".it") || |
167 | !rb->strcasecmp(ext,".m15") || | 166 | !rb->strcasecmp(ext,".m15") || |
@@ -174,6 +173,7 @@ static bool mod_ext(const char ext[]) | |||
174 | !rb->strcasecmp(ext,".stx") || | 173 | !rb->strcasecmp(ext,".stx") || |
175 | !rb->strcasecmp(ext,".ult") || | 174 | !rb->strcasecmp(ext,".ult") || |
176 | !rb->strcasecmp(ext,".uni") || | 175 | !rb->strcasecmp(ext,".uni") || |
176 | !rb->strcasecmp(ext,".umx") || | ||
177 | !rb->strcasecmp(ext,".xm") ) | 177 | !rb->strcasecmp(ext,".xm") ) |
178 | return true; | 178 | return true; |
179 | else | 179 | else |
@@ -305,7 +305,7 @@ static void showinfo(void) | |||
305 | rb->lcd_putsxy(1, 1, statustext); | 305 | rb->lcd_putsxy(1, 1, statustext); |
306 | sprintf(statustext, "Type: %s", module->modtype); | 306 | sprintf(statustext, "Type: %s", module->modtype); |
307 | rb->lcd_putsxy(1, 11, statustext); | 307 | rb->lcd_putsxy(1, 11, statustext); |
308 | 308 | ||
309 | sprintf(statustext, "Samples: %d", module->numsmp); | 309 | sprintf(statustext, "Samples: %d", module->numsmp); |
310 | rb->lcd_putsxy(1, 21, statustext); | 310 | rb->lcd_putsxy(1, 21, statustext); |
311 | 311 | ||
@@ -315,25 +315,25 @@ static void showinfo(void) | |||
315 | rb->lcd_putsxy(1, 31, statustext); | 315 | rb->lcd_putsxy(1, 31, statustext); |
316 | } | 316 | } |
317 | 317 | ||
318 | sprintf(statustext, "pat: %03d/%03d %2.2X", | 318 | sprintf(statustext, "pat: %03d/%03d %2.2X", |
319 | module->sngpos, module->numpos - 1, module->patpos); | 319 | module->sngpos, module->numpos - 1, module->patpos); |
320 | rb->lcd_putsxy(1, 51, statustext); | 320 | rb->lcd_putsxy(1, 51, statustext); |
321 | 321 | ||
322 | sprintf(statustext, "spd: %d/%d", | 322 | sprintf(statustext, "spd: %d/%d", |
323 | module->sngspd, module->bpm); | 323 | module->sngspd, module->bpm); |
324 | rb->lcd_putsxy(1, 61, statustext); | 324 | rb->lcd_putsxy(1, 61, statustext); |
325 | 325 | ||
326 | sprintf(statustext, "vol: %ddB", rb->global_settings->volume); | 326 | sprintf(statustext, "vol: %ddB", rb->global_settings->volume); |
327 | rb->lcd_putsxy(1, 71, statustext); | 327 | rb->lcd_putsxy(1, 71, statustext); |
328 | 328 | ||
329 | sprintf(statustext, "time: %d:%02d", | 329 | sprintf(statustext, "time: %d:%02d", |
330 | (playingtime / 60) % 60, playingtime % 60); | 330 | (playingtime / 60) % 60, playingtime % 60); |
331 | rb->lcd_putsxy(1, 81, statustext); | 331 | rb->lcd_putsxy(1, 81, statustext); |
332 | 332 | ||
333 | if (module->flags & UF_NNA) | 333 | if (module->flags & UF_NNA) |
334 | { | 334 | { |
335 | sprintf(statustext, "chn: %d/%d+%d->%d", | 335 | sprintf(statustext, "chn: %d/%d+%d->%d", |
336 | module->realchn, module->numchn, | 336 | module->realchn, module->numchn, |
337 | module->totalchn - module->realchn, | 337 | module->totalchn - module->realchn, |
338 | module->totalchn); | 338 | module->totalchn); |
339 | } | 339 | } |
@@ -465,32 +465,44 @@ struct mikmod_settings | |||
465 | { | 465 | { |
466 | int pansep; | 466 | int pansep; |
467 | int reverb; | 467 | int reverb; |
468 | int sample_rate; | ||
468 | bool interp; | 469 | bool interp; |
469 | bool reverse; | 470 | bool reverse; |
470 | bool surround; | 471 | bool surround; |
472 | bool hqmixer; | ||
473 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
471 | bool boost; | 474 | bool boost; |
475 | #endif | ||
472 | }; | 476 | }; |
473 | 477 | ||
474 | static struct mikmod_settings settings = | 478 | static struct mikmod_settings settings = |
475 | { | 479 | { |
476 | 128, | 480 | .pansep = 128, |
477 | 0, | 481 | .reverb = 0, |
478 | 0, | 482 | .sample_rate = -1, |
479 | 0, | 483 | .interp = 0, |
480 | 1, | 484 | .reverse = 0, |
481 | 1 | 485 | .surround = 1, |
486 | .hqmixer = 0, | ||
487 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
488 | .boost = 1, | ||
489 | #endif | ||
482 | }; | 490 | }; |
483 | 491 | ||
484 | static struct mikmod_settings old_settings; | 492 | static struct mikmod_settings old_settings; |
485 | 493 | ||
486 | static struct configdata config[] = | 494 | static const struct configdata config[] = |
487 | { | 495 | { |
488 | { TYPE_INT, 0, 128, { .int_p = &settings.pansep }, "Panning Separation", NULL}, | 496 | { TYPE_INT, 0, 128, { .int_p = &settings.pansep }, "Panning Separation", NULL}, |
489 | { TYPE_INT, 0, 15, { .int_p = &settings.reverb }, "Reverberation", NULL}, | 497 | { TYPE_INT, 0, 15, { .int_p = &settings.reverb }, "Reverberation", NULL}, |
490 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.interp }, "Interpolation", NULL}, | 498 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.interp }, "Interpolation", NULL}, |
491 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.reverse }, "Reverse Channels", NULL}, | 499 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.reverse }, "Reverse Channels", NULL}, |
492 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.surround }, "Surround", NULL}, | 500 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.surround }, "Surround", NULL}, |
501 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.hqmixer }, "HQ Mixer", NULL}, | ||
502 | { TYPE_INT, 0, HW_NUM_FREQ-1, { .int_p = &settings.sample_rate }, "Sample Rate", NULL}, | ||
503 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
493 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.boost }, "CPU Boost", NULL}, | 504 | { TYPE_BOOL, 0, 1, { .bool_p = &settings.boost }, "CPU Boost", NULL}, |
505 | #endif | ||
494 | }; | 506 | }; |
495 | 507 | ||
496 | static void applysettings(void) | 508 | static void applysettings(void) |
@@ -498,6 +510,7 @@ static void applysettings(void) | |||
498 | md_pansep = settings.pansep; | 510 | md_pansep = settings.pansep; |
499 | md_reverb = settings.reverb; | 511 | md_reverb = settings.reverb; |
500 | md_mode = DMODE_STEREO | DMODE_16BITS | DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX; | 512 | md_mode = DMODE_STEREO | DMODE_16BITS | DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX; |
513 | |||
501 | if ( settings.interp ) | 514 | if ( settings.interp ) |
502 | { | 515 | { |
503 | md_mode |= DMODE_INTERP; | 516 | md_mode |= DMODE_INTERP; |
@@ -510,6 +523,21 @@ static void applysettings(void) | |||
510 | { | 523 | { |
511 | md_mode |= DMODE_SURROUND; | 524 | md_mode |= DMODE_SURROUND; |
512 | } | 525 | } |
526 | #ifndef NO_HQMIXER | ||
527 | if ( settings.hqmixer ) | ||
528 | { | ||
529 | md_mode |= DMODE_HQMIXER; | ||
530 | } | ||
531 | #endif | ||
532 | |||
533 | if (md_mixfreq != rb->hw_freq_sampr[settings.sample_rate]) { | ||
534 | md_mixfreq = rb->hw_freq_sampr[settings.sample_rate]; | ||
535 | // MikMod_Reset(""); BROKEN! | ||
536 | rb->pcm_play_stop(); | ||
537 | rb->mixer_set_frequency(md_mixfreq); | ||
538 | rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0); | ||
539 | } | ||
540 | |||
513 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 541 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
514 | if ( Player_Active() ) | 542 | if ( Player_Active() ) |
515 | { | 543 | { |
@@ -518,6 +546,21 @@ static void applysettings(void) | |||
518 | #endif | 546 | #endif |
519 | } | 547 | } |
520 | 548 | ||
549 | static const struct opt_items sr_names[HW_NUM_FREQ] = { | ||
550 | HW_HAVE_96_([HW_FREQ_96] = { "96kHz", TALK_ID(96, UNIT_KHZ) },) | ||
551 | HW_HAVE_88_([HW_FREQ_88] = { "88.2kHz", TALK_ID(88, UNIT_KHZ) },) | ||
552 | HW_HAVE_64_([HW_FREQ_64] = { "64kHz", TALK_ID(64, UNIT_KHZ) },) | ||
553 | HW_HAVE_48_([HW_FREQ_48] = { "48kHz", TALK_ID(48, UNIT_KHZ) },) | ||
554 | HW_HAVE_44_([HW_FREQ_44] = { "44.1kHz", TALK_ID(44, UNIT_KHZ) },) | ||
555 | HW_HAVE_32_([HW_FREQ_32] = { "32kHz", TALK_ID(32, UNIT_KHZ) },) | ||
556 | HW_HAVE_24_([HW_FREQ_24] = { "24kHz", TALK_ID(24, UNIT_KHZ) },) | ||
557 | HW_HAVE_22_([HW_FREQ_22] = { "22.05kHz", TALK_ID(22, UNIT_KHZ) },) | ||
558 | HW_HAVE_16_([HW_FREQ_16] = { "16kHz", TALK_ID(16, UNIT_KHZ) },) | ||
559 | HW_HAVE_12_([HW_FREQ_12] = { "12kHz", TALK_ID(12, UNIT_KHZ) },) | ||
560 | HW_HAVE_11_([HW_FREQ_11] = { "11.025kHz", TALK_ID(11, UNIT_KHZ) },) | ||
561 | HW_HAVE_8_( [HW_FREQ_8 ] = { "8kHz", TALK_ID( 8, UNIT_KHZ) },) | ||
562 | }; | ||
563 | |||
521 | /** | 564 | /** |
522 | Shows the settings menu | 565 | Shows the settings menu |
523 | */ | 566 | */ |
@@ -531,6 +574,8 @@ static int settings_menu(void) | |||
531 | ID2P(LANG_INTERPOLATION), | 574 | ID2P(LANG_INTERPOLATION), |
532 | ID2P(LANG_SWAP_CHANNELS), | 575 | ID2P(LANG_SWAP_CHANNELS), |
533 | ID2P(LANG_MIKMOD_SURROUND), | 576 | ID2P(LANG_MIKMOD_SURROUND), |
577 | ID2P(LANG_MIKMOD_HQMIXER), | ||
578 | ID2P(LANG_MIKMOD_SAMPLERATE), | ||
534 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 579 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
535 | ID2P(LANG_CPU_BOOST) | 580 | ID2P(LANG_CPU_BOOST) |
536 | #endif | 581 | #endif |
@@ -571,9 +616,22 @@ static int settings_menu(void) | |||
571 | break; | 616 | break; |
572 | 617 | ||
573 | case 5: | 618 | case 5: |
619 | rb->set_bool(rb->str(LANG_MIKMOD_HQMIXER), &(settings.hqmixer)); | ||
620 | applysettings(); | ||
621 | break; | ||
622 | |||
623 | case 6: | ||
624 | rb->set_option(rb->str(LANG_MIKMOD_SAMPLERATE), &(settings.sample_rate), INT, sr_names, | ||
625 | HW_NUM_FREQ, NULL); | ||
626 | applysettings(); | ||
627 | break; | ||
628 | |||
629 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
630 | case 7: | ||
574 | rb->set_bool(rb->str(LANG_CPU_BOOST), &(settings.boost)); | 631 | rb->set_bool(rb->str(LANG_CPU_BOOST), &(settings.boost)); |
575 | applysettings(); | 632 | applysettings(); |
576 | break; | 633 | break; |
634 | #endif | ||
577 | 635 | ||
578 | case MENU_ATTACHED_USB: | 636 | case MENU_ATTACHED_USB: |
579 | return PLUGIN_USB_CONNECTED; | 637 | return PLUGIN_USB_CONNECTED; |
@@ -675,13 +733,12 @@ static int playfile(char* filename) | |||
675 | } | 733 | } |
676 | 734 | ||
677 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 735 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
678 | if ( settings.boost ) | 736 | rb->cpu_boost(settings.boost); |
679 | rb->cpu_boost(true); | ||
680 | #endif | 737 | #endif |
681 | #ifdef USETHREADS | 738 | #ifdef USETHREADS |
682 | rb->queue_init(&thread_q, true); | 739 | rb->queue_init(&thread_q, true); |
683 | if ((thread_id = rb->create_thread(thread, thread_stack, | 740 | if ((thread_id = rb->create_thread(thread, thread_stack, |
684 | sizeof(thread_stack), 0, "render buffering thread" | 741 | sizeof(thread_stack), 0, "render buffering thread" |
685 | IF_PRIO(, PRIORITY_PLAYBACK) | 742 | IF_PRIO(, PRIORITY_PLAYBACK) |
686 | IF_COP(, CPU))) == 0) | 743 | IF_COP(, CPU))) == 0) |
687 | { | 744 | { |
@@ -830,11 +887,11 @@ static int playfile(char* filename) | |||
830 | rb->lcd_setfont(FONT_SYSFIXED); | 887 | rb->lcd_setfont(FONT_SYSFIXED); |
831 | screenupdated = false; | 888 | screenupdated = false; |
832 | break; | 889 | break; |
833 | 890 | ||
834 | case ACTION_WPS_STOP: | 891 | case ACTION_WPS_STOP: |
835 | quit = true; | 892 | quit = true; |
836 | break; | 893 | break; |
837 | 894 | ||
838 | default: | 895 | default: |
839 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) | 896 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) |
840 | { | 897 | { |
@@ -850,20 +907,19 @@ static int playfile(char* filename) | |||
850 | rb->queue_delete(&thread_q); | 907 | rb->queue_delete(&thread_q); |
851 | #endif | 908 | #endif |
852 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 909 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
853 | if ( settings.boost ) | 910 | rb->cpu_boost(false); |
854 | rb->cpu_boost(false); | ||
855 | #endif | 911 | #endif |
856 | 912 | ||
857 | Player_Stop(); | 913 | Player_Stop(); |
858 | Player_Free(module); | 914 | Player_Free(module); |
859 | 915 | ||
860 | memset(gmbuf, '\0', sizeof(gmbuf)); | 916 | memset(gmbuf, '\0', sizeof(gmbuf)); |
861 | 917 | ||
862 | if ( retval == PLUGIN_OK && entries > 1 && !quit ) | 918 | if ( retval == PLUGIN_OK && entries > 1 && !quit ) |
863 | { | 919 | { |
864 | retval = change_filename(DIR_NEXT); | 920 | retval = change_filename(DIR_NEXT); |
865 | } | 921 | } |
866 | 922 | ||
867 | return retval; | 923 | return retval; |
868 | } | 924 | } |
869 | 925 | ||
@@ -891,10 +947,9 @@ enum plugin_status plugin_start(const void* parameter) | |||
891 | rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); | 947 | rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); |
892 | rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); | 948 | rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); |
893 | #endif | 949 | #endif |
894 | rb->mixer_set_frequency(SAMPLE_RATE); | ||
895 | 950 | ||
896 | audio_buffer = rb->plugin_get_audio_buffer((size_t *)&audio_buffer_free); | 951 | audio_buffer = rb->plugin_get_audio_buffer((size_t *)&audio_buffer_free); |
897 | 952 | ||
898 | rb->strcpy(np_file, parameter); | 953 | rb->strcpy(np_file, parameter); |
899 | get_mod_list(); | 954 | get_mod_list(); |
900 | if(!entries) { | 955 | if(!entries) { |
@@ -903,16 +958,29 @@ enum plugin_status plugin_start(const void* parameter) | |||
903 | 958 | ||
904 | //add_pool(audio_buffer, audio_buffer_free); | 959 | //add_pool(audio_buffer, audio_buffer_free); |
905 | init_memory_pool(audio_buffer_free, audio_buffer); | 960 | init_memory_pool(audio_buffer_free, audio_buffer); |
906 | 961 | ||
907 | MikMod_RegisterDriver(&drv_nos); | 962 | MikMod_RegisterDriver(&drv_nos); |
908 | MikMod_RegisterAllLoaders(); | 963 | MikMod_RegisterAllLoaders(); |
909 | MikMod_RegisterErrorHandler(mm_errorhandler); | 964 | MikMod_RegisterErrorHandler(mm_errorhandler); |
910 | 965 | ||
911 | md_mixfreq = SAMPLE_RATE; | ||
912 | |||
913 | configfile_load(MIKMOD_CONFIGFILE, config, | 966 | configfile_load(MIKMOD_CONFIGFILE, config, |
914 | ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION); | 967 | ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION); |
915 | rb->memcpy(&old_settings, &settings, sizeof (settings)); | 968 | rb->memcpy(&old_settings, &settings, sizeof (settings)); |
969 | |||
970 | /* If there's no configured rate, use the default */ | ||
971 | if (settings.sample_rate == -1) { | ||
972 | int i; | ||
973 | for (i = 0 ; i < HW_NUM_FREQ ; i++) { | ||
974 | if (rb->hw_freq_sampr[i] == SAMPLE_RATE) { | ||
975 | settings.sample_rate = i; | ||
976 | break; | ||
977 | } | ||
978 | } | ||
979 | if (settings.sample_rate == -1) { | ||
980 | settings.sample_rate = HW_NUM_FREQ -1; | ||
981 | } | ||
982 | } | ||
983 | |||
916 | applysettings(); | 984 | applysettings(); |
917 | 985 | ||
918 | if (MikMod_Init("")) | 986 | if (MikMod_Init("")) |
@@ -934,14 +1002,13 @@ enum plugin_status plugin_start(const void* parameter) | |||
934 | 1002 | ||
935 | if (retval == PLUGIN_OK) | 1003 | if (retval == PLUGIN_OK) |
936 | { | 1004 | { |
937 | rb->splash(0, "Saving Settings"); | ||
938 | if (rb->memcmp(&settings, &old_settings, sizeof (settings))) | 1005 | if (rb->memcmp(&settings, &old_settings, sizeof (settings))) |
939 | { | 1006 | { |
940 | configfile_save(MIKMOD_CONFIGFILE, config, | 1007 | configfile_save(MIKMOD_CONFIGFILE, config, |
941 | ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION); | 1008 | ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION); |
942 | } | 1009 | } |
943 | } | 1010 | } |
944 | 1011 | ||
945 | destroy_memory_pool(audio_buffer); | 1012 | destroy_memory_pool(audio_buffer); |
946 | 1013 | ||
947 | return retval; | 1014 | return retval; |
diff --git a/apps/plugins/mikmod/mikmod.h b/apps/plugins/mikmod/mikmod.h index a1c201f6d2..8256299451 100644 --- a/apps/plugins/mikmod/mikmod.h +++ b/apps/plugins/mikmod/mikmod.h | |||
@@ -1,30 +1,28 @@ | |||
1 | /* MikMod sound library | 1 | /* MikMod sound library |
2 | (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS | 2 | (c) 1998-2014 Miodrag Vallat and others - see the AUTHORS file |
3 | for complete list. | 3 | for complete list. |
4 | 4 | ||
5 | This library is free software; you can redistribute it and/or modify | 5 | This library is free software; you can redistribute it and/or modify |
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 |
18 | 02111-1307, USA. | 18 | 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /*============================================================================== | 21 | /*============================================================================== |
22 | 22 | ||
23 | $Id: mikmod.h.in,v 1.3 2005/03/30 19:09:21 realtech Exp $ | ||
24 | |||
25 | MikMod sound library include file | 23 | MikMod sound library include file |
26 | 24 | ||
27 | ==============================================================================*/ | 25 | ==============================================================================*/ |
28 | 26 | ||
29 | #ifndef _MIKMOD_H_ | 27 | #ifndef _MIKMOD_H_ |
30 | #define _MIKMOD_H_ | 28 | #define _MIKMOD_H_ |
@@ -40,163 +38,221 @@ extern "C" { | |||
40 | 38 | ||
41 | /* | 39 | /* |
42 | * ========== Compiler magic for shared libraries | 40 | * ========== Compiler magic for shared libraries |
41 | * | ||
42 | * ========== NOTE TO WINDOWS DEVELOPERS: | ||
43 | * If you are compiling for Windows and will link to the static library | ||
44 | * (libmikmod.a with MinGW, or mikmod_static.lib with MSVC or LCC, etc), | ||
45 | * you must define MIKMOD_STATIC in your project. Otherwise, dllimport | ||
46 | * will be assumed. | ||
43 | */ | 47 | */ |
44 | 48 | #if defined(_WIN32) || defined(__CYGWIN__) | |
45 | #if defined WIN32 && defined _DLL | 49 | # if defined(MIKMOD_BUILD) && defined(DLL_EXPORT) /* building libmikmod as a dll for windows */ |
46 | #ifdef DLL_EXPORTS | 50 | # define MIKMODAPI __declspec(dllexport) |
47 | #define MIKMODAPI __declspec(dllexport) | 51 | # elif defined(MIKMOD_BUILD) || defined(MIKMOD_STATIC) /* building or using static libmikmod for windows */ |
48 | #else | 52 | # define MIKMODAPI |
49 | #define MIKMODAPI __declspec(dllimport) | 53 | # else |
50 | #endif | 54 | # define MIKMODAPI __declspec(dllimport) /* using libmikmod dll for windows */ |
55 | # endif | ||
56 | #elif defined(__OS2__) && defined(__WATCOMC__) | ||
57 | # if defined(MIKMOD_BUILD) && defined(__SW_BD) /* building libmikmod as a dll for os/2 */ | ||
58 | # define MIKMODAPI __declspec(dllexport) | ||
59 | # else | ||
60 | # define MIKMODAPI /* using dll or static libmikmod for os/2 */ | ||
61 | # endif | ||
62 | /* SYM_VISIBILITY should be defined if both the compiler | ||
63 | * and the target support the visibility attributes. the | ||
64 | * configury does that automatically. for the standalone | ||
65 | * makefiles, etc, the developer should add the required | ||
66 | * flags, i.e.: -DSYM_VISIBILITY -fvisibility=hidden */ | ||
67 | #elif defined(MIKMOD_BUILD) && defined(SYM_VISIBILITY) | ||
68 | # define MIKMODAPI __attribute__((visibility("default"))) | ||
51 | #else | 69 | #else |
52 | #define MIKMODAPI | 70 | # define MIKMODAPI |
53 | #endif | 71 | #endif |
54 | 72 | ||
55 | /* | 73 | /* |
56 | * ========== Library version | 74 | * ========== Library version |
57 | */ | 75 | */ |
58 | 76 | ||
59 | #define LIBMIKMOD_VERSION_MAJOR 3L | 77 | #define LIBMIKMOD_VERSION_MAJOR 3L |
60 | #define LIBMIKMOD_VERSION_MINOR 2L | 78 | #define LIBMIKMOD_VERSION_MINOR 3L |
61 | #define LIBMIKMOD_REVISION 0L | 79 | #define LIBMIKMOD_REVISION 11L |
62 | 80 | ||
63 | #define LIBMIKMOD_VERSION \ | 81 | #define LIBMIKMOD_VERSION \ |
64 | ((LIBMIKMOD_VERSION_MAJOR<<16)| \ | 82 | ((LIBMIKMOD_VERSION_MAJOR<<16)| \ |
65 | (LIBMIKMOD_VERSION_MINOR<< 8)| \ | 83 | (LIBMIKMOD_VERSION_MINOR<< 8)| \ |
66 | (LIBMIKMOD_REVISION)) | 84 | (LIBMIKMOD_REVISION)) |
67 | 85 | ||
68 | MIKMODAPI extern long MikMod_GetVersion(void); | 86 | MIKMODAPI extern long MikMod_GetVersion(void); |
69 | 87 | ||
70 | /* | 88 | /* |
71 | * ========== Platform independent-type definitions | 89 | * ========== Dependency platform headers |
72 | */ | 90 | */ |
73 | #if 0 | 91 | |
74 | #ifdef WIN32 | 92 | #ifdef _WIN32 |
93 | #ifndef WIN32_LEAN_AND_MEAN | ||
75 | #define WIN32_LEAN_AND_MEAN | 94 | #define WIN32_LEAN_AND_MEAN |
95 | #endif | ||
76 | #include <windows.h> | 96 | #include <windows.h> |
77 | #include <io.h> | 97 | #include <io.h> |
78 | #include <mmsystem.h> | 98 | #include <mmsystem.h> |
99 | #define _MIKMOD_WIN32 | ||
100 | #endif | ||
101 | |||
102 | #if defined(__DJGPP__) || defined(MSDOS) || defined(__MSDOS__) || defined(__DOS__) | ||
103 | #define _MIKMOD_DOS | ||
79 | #endif | 104 | #endif |
80 | 105 | ||
81 | #if defined(__OS2__)||defined(__EMX__) | 106 | #if defined(__OS2__) || defined(__EMX__) |
82 | #define INCL_DOSSEMAPHORES | 107 | #define INCL_DOSSEMAPHORES |
83 | #include <os2.h> | 108 | #include <os2.h> |
84 | #else | 109 | #include <io.h> |
85 | typedef char CHAR; | 110 | #define _MIKMOD_OS2 |
111 | #endif | ||
112 | |||
113 | #if defined(__MORPHOS__) || defined(__AROS__) || defined(_AMIGA) || defined(__AMIGA__) || defined(__amigaos__) || defined(AMIGAOS) | ||
114 | #include <exec/types.h> | ||
115 | #define _MIKMOD_AMIGA | ||
86 | #endif | 116 | #endif |
117 | |||
118 | /* | ||
119 | * ========== Platform independent-type definitions | ||
120 | * (pain when it comes to cross-platform maintenance..) | ||
121 | */ | ||
122 | |||
123 | #if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32)) | ||
124 | typedef char CHAR; | ||
87 | #endif | 125 | #endif |
88 | 126 | ||
89 | typedef char CHAR; | 127 | /* int: 0=false, <>0 true -- 16 bits on Amiga, int-wide on others. */ |
128 | #if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32) || defined(_MIKMOD_AMIGA)) | ||
129 | //typedef int int; | ||
130 | #endif | ||
90 | 131 | ||
132 | /* 1 byte, signed and unsigned: */ | ||
133 | typedef signed char SBYTE; | ||
134 | #ifndef _MIKMOD_AMIGA | ||
135 | typedef unsigned char UBYTE; | ||
136 | #endif | ||
91 | 137 | ||
92 | #if defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(__powerpc64__) | 138 | /* 2 bytes, signed and unsigned: */ |
93 | /* 64 bit architectures */ | 139 | #if !(defined __LCC__ && defined _WIN32) |
140 | typedef signed short int SWORD; | ||
141 | #endif | ||
142 | #if !((defined __LCC__ && defined _WIN32) || defined(_MIKMOD_AMIGA)) | ||
143 | typedef unsigned short int UWORD; | ||
144 | #endif | ||
94 | 145 | ||
95 | typedef signed char SBYTE; /* 1 byte, signed */ | 146 | /* 4 bytes, signed and unsigned: */ |
96 | typedef unsigned char UBYTE; /* 1 byte, unsigned */ | 147 | #if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(__powerpc64__) |
97 | typedef signed short SWORD; /* 2 bytes, signed */ | 148 | /* 64 bit architectures: */ |
98 | typedef unsigned short UWORD; /* 2 bytes, unsigned */ | 149 | typedef signed int SLONG; |
99 | typedef signed int SLONG; /* 4 bytes, signed */ | 150 | #if !(defined(_WIN32) || defined(_MIKMOD_AMIGA)) |
100 | typedef unsigned int ULONG; /* 4 bytes, unsigned */ | 151 | typedef unsigned int ULONG; |
101 | //typedef int BOOL; /* 0=false, <>0 true */ | 152 | #endif |
102 | 153 | ||
103 | #else | 154 | #else /* 32 bit architectures: */ |
104 | /* 32 bit architectures */ | 155 | typedef signed long int SLONG; |
105 | 156 | #if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32) || defined(_MIKMOD_AMIGA)) | |
106 | typedef signed char SBYTE; /* 1 byte, signed */ | 157 | typedef unsigned long int ULONG; |
107 | typedef unsigned char UBYTE; /* 1 byte, unsigned */ | ||
108 | typedef signed short SWORD; /* 2 bytes, signed */ | ||
109 | typedef unsigned short UWORD; /* 2 bytes, unsigned */ | ||
110 | typedef signed long SLONG; /* 4 bytes, signed */ | ||
111 | #if !defined(__OS2__)&&!defined(__EMX__)&&!defined(WIN32) | ||
112 | typedef unsigned long ULONG; /* 4 bytes, unsigned */ | ||
113 | //typedef int BOOL; /* 0=false, <>0 true */ | ||
114 | #endif | 158 | #endif |
115 | #endif | 159 | #endif |
116 | 160 | ||
161 | /* make sure types are of correct sizes: */ | ||
162 | typedef int __mikmod_typetest [ | ||
163 | ( | ||
164 | (sizeof(SBYTE)==1) && (sizeof(UBYTE)==1) | ||
165 | && (sizeof(SWORD)==2) && (sizeof(UWORD)==2) | ||
166 | && (sizeof(SLONG)==4) && (sizeof(ULONG)==4) | ||
167 | #ifndef _MIKMOD_AMIGA | ||
168 | && (sizeof(int) == sizeof(int)) | ||
169 | #endif | ||
170 | && (sizeof(CHAR) == sizeof(char)) | ||
171 | ) * 2 - 1 ]; | ||
172 | |||
117 | /* | 173 | /* |
118 | * ========== Error codes | 174 | * ========== Error codes |
119 | */ | 175 | */ |
120 | 176 | ||
121 | enum { | 177 | enum { |
122 | MMERR_OPENING_FILE = 1, | 178 | MMERR_OPENING_FILE = 1, |
123 | MMERR_OUT_OF_MEMORY, | 179 | MMERR_OUT_OF_MEMORY, |
124 | MMERR_DYNAMIC_LINKING, | 180 | MMERR_DYNAMIC_LINKING, |
125 | 181 | ||
126 | MMERR_SAMPLE_TOO_BIG, | 182 | MMERR_SAMPLE_TOO_BIG, |
127 | MMERR_OUT_OF_HANDLES, | 183 | MMERR_OUT_OF_HANDLES, |
128 | MMERR_UNKNOWN_WAVE_TYPE, | 184 | MMERR_UNKNOWN_WAVE_TYPE, |
129 | 185 | ||
130 | MMERR_LOADING_PATTERN, | 186 | MMERR_LOADING_PATTERN, |
131 | MMERR_LOADING_TRACK, | 187 | MMERR_LOADING_TRACK, |
132 | MMERR_LOADING_HEADER, | 188 | MMERR_LOADING_HEADER, |
133 | MMERR_LOADING_SAMPLEINFO, | 189 | MMERR_LOADING_SAMPLEINFO, |
134 | MMERR_NOT_A_MODULE, | 190 | MMERR_NOT_A_MODULE, |
135 | MMERR_NOT_A_STREAM, | 191 | MMERR_NOT_A_STREAM, |
136 | MMERR_MED_SYNTHSAMPLES, | 192 | MMERR_MED_SYNTHSAMPLES, |
137 | MMERR_ITPACK_INVALID_DATA, | 193 | MMERR_ITPACK_INVALID_DATA, |
138 | 194 | ||
139 | MMERR_DETECTING_DEVICE, | 195 | MMERR_DETECTING_DEVICE, |
140 | MMERR_INVALID_DEVICE, | 196 | MMERR_INVALID_DEVICE, |
141 | MMERR_INITIALIZING_MIXER, | 197 | MMERR_INITIALIZING_MIXER, |
142 | MMERR_OPENING_AUDIO, | 198 | MMERR_OPENING_AUDIO, |
143 | MMERR_8BIT_ONLY, | 199 | MMERR_8BIT_ONLY, |
144 | MMERR_16BIT_ONLY, | 200 | MMERR_16BIT_ONLY, |
145 | MMERR_STEREO_ONLY, | 201 | MMERR_STEREO_ONLY, |
146 | MMERR_ULAW, | 202 | MMERR_ULAW, |
147 | MMERR_NON_BLOCK, | 203 | MMERR_NON_BLOCK, |
148 | 204 | ||
149 | MMERR_AF_AUDIO_PORT, | 205 | MMERR_AF_AUDIO_PORT, |
150 | 206 | ||
151 | MMERR_AIX_CONFIG_INIT, | 207 | MMERR_AIX_CONFIG_INIT, |
152 | MMERR_AIX_CONFIG_CONTROL, | 208 | MMERR_AIX_CONFIG_CONTROL, |
153 | MMERR_AIX_CONFIG_START, | 209 | MMERR_AIX_CONFIG_START, |
154 | 210 | ||
155 | MMERR_GUS_SETTINGS, | 211 | MMERR_GUS_SETTINGS, |
156 | MMERR_GUS_RESET, | 212 | MMERR_GUS_RESET, |
157 | MMERR_GUS_TIMER, | 213 | MMERR_GUS_TIMER, |
158 | 214 | ||
159 | MMERR_HP_SETSAMPLESIZE, | 215 | MMERR_HP_SETSAMPLESIZE, |
160 | MMERR_HP_SETSPEED, | 216 | MMERR_HP_SETSPEED, |
161 | MMERR_HP_CHANNELS, | 217 | MMERR_HP_CHANNELS, |
162 | MMERR_HP_AUDIO_OUTPUT, | 218 | MMERR_HP_AUDIO_OUTPUT, |
163 | MMERR_HP_AUDIO_DESC, | 219 | MMERR_HP_AUDIO_DESC, |
164 | MMERR_HP_BUFFERSIZE, | 220 | MMERR_HP_BUFFERSIZE, |
165 | 221 | ||
166 | MMERR_OSS_SETFRAGMENT, | 222 | MMERR_OSS_SETFRAGMENT, |
167 | MMERR_OSS_SETSAMPLESIZE, | 223 | MMERR_OSS_SETSAMPLESIZE, |
168 | MMERR_OSS_SETSTEREO, | 224 | MMERR_OSS_SETSTEREO, |
169 | MMERR_OSS_SETSPEED, | 225 | MMERR_OSS_SETSPEED, |
170 | 226 | ||
171 | MMERR_SGI_SPEED, | 227 | MMERR_SGI_SPEED, |
172 | MMERR_SGI_16BIT, | 228 | MMERR_SGI_16BIT, |
173 | MMERR_SGI_8BIT, | 229 | MMERR_SGI_8BIT, |
174 | MMERR_SGI_STEREO, | 230 | MMERR_SGI_STEREO, |
175 | MMERR_SGI_MONO, | 231 | MMERR_SGI_MONO, |
176 | 232 | ||
177 | MMERR_SUN_INIT, | 233 | MMERR_SUN_INIT, |
178 | 234 | ||
179 | MMERR_OS2_MIXSETUP, | 235 | MMERR_OS2_MIXSETUP, |
180 | MMERR_OS2_SEMAPHORE, | 236 | MMERR_OS2_SEMAPHORE, |
181 | MMERR_OS2_TIMER, | 237 | MMERR_OS2_TIMER, |
182 | MMERR_OS2_THREAD, | 238 | MMERR_OS2_THREAD, |
183 | 239 | ||
184 | MMERR_DS_PRIORITY, | 240 | MMERR_DS_PRIORITY, |
185 | MMERR_DS_BUFFER, | 241 | MMERR_DS_BUFFER, |
186 | MMERR_DS_FORMAT, | 242 | MMERR_DS_FORMAT, |
187 | MMERR_DS_NOTIFY, | 243 | MMERR_DS_NOTIFY, |
188 | MMERR_DS_EVENT, | 244 | MMERR_DS_EVENT, |
189 | MMERR_DS_THREAD, | 245 | MMERR_DS_THREAD, |
190 | MMERR_DS_UPDATE, | 246 | MMERR_DS_UPDATE, |
191 | 247 | ||
192 | MMERR_WINMM_HANDLE, | 248 | MMERR_WINMM_HANDLE, |
193 | MMERR_WINMM_ALLOCATED, | 249 | MMERR_WINMM_ALLOCATED, |
194 | MMERR_WINMM_DEVICEID, | 250 | MMERR_WINMM_DEVICEID, |
195 | MMERR_WINMM_FORMAT, | 251 | MMERR_WINMM_FORMAT, |
196 | MMERR_WINMM_UNKNOWN, | 252 | MMERR_WINMM_UNKNOWN, |
197 | 253 | ||
198 | MMERR_MAC_SPEED, | 254 | MMERR_MAC_SPEED, |
199 | MMERR_MAC_START, | 255 | MMERR_MAC_START, |
200 | 256 | ||
201 | MMERR_OSX_UNKNOWN_DEVICE, | 257 | MMERR_OSX_UNKNOWN_DEVICE, |
202 | MMERR_OSX_BAD_PROPERTY, | 258 | MMERR_OSX_BAD_PROPERTY, |
@@ -205,16 +261,43 @@ enum { | |||
205 | MMERR_OSX_BUFFER_ALLOC, | 261 | MMERR_OSX_BUFFER_ALLOC, |
206 | MMERR_OSX_ADD_IO_PROC, | 262 | MMERR_OSX_ADD_IO_PROC, |
207 | MMERR_OSX_DEVICE_START, | 263 | MMERR_OSX_DEVICE_START, |
208 | MMERR_OSX_PTHREAD, | 264 | MMERR_OSX_PTHREAD, |
209 | 265 | ||
210 | MMERR_DOSWSS_STARTDMA, | 266 | MMERR_DOSWSS_STARTDMA, |
211 | MMERR_DOSSB_STARTDMA, | 267 | MMERR_DOSSB_STARTDMA, |
212 | 268 | ||
213 | MMERR_MAX | 269 | MMERR_NO_FLOAT32,/* should actually be after MMERR_ULAW or something */ |
270 | |||
271 | MMERR_OPENAL_CREATECTX, | ||
272 | MMERR_OPENAL_CTXCURRENT, | ||
273 | MMERR_OPENAL_GENBUFFERS, | ||
274 | MMERR_OPENAL_GENSOURCES, | ||
275 | MMERR_OPENAL_SOURCE, | ||
276 | MMERR_OPENAL_QUEUEBUFFERS, | ||
277 | MMERR_OPENAL_UNQUEUEBUFFERS, | ||
278 | MMERR_OPENAL_BUFFERDATA, | ||
279 | MMERR_OPENAL_GETSOURCE, | ||
280 | MMERR_OPENAL_SOURCEPLAY, | ||
281 | MMERR_OPENAL_SOURCESTOP, | ||
282 | |||
283 | MMERR_ALSA_NOCONFIG, | ||
284 | MMERR_ALSA_SETPARAMS, | ||
285 | MMERR_ALSA_SETFORMAT, | ||
286 | MMERR_ALSA_SETRATE, | ||
287 | MMERR_ALSA_SETCHANNELS, | ||
288 | MMERR_ALSA_BUFFERSIZE, | ||
289 | MMERR_ALSA_PCM_START, | ||
290 | MMERR_ALSA_PCM_WRITE, | ||
291 | MMERR_ALSA_PCM_RECOVER, | ||
292 | |||
293 | MMERR_SNDIO_SETPARAMS, | ||
294 | MMERR_SNDIO_BADPARAMS, | ||
295 | |||
296 | MMERR_MAX | ||
214 | }; | 297 | }; |
215 | 298 | ||
216 | /* | 299 | /* |
217 | * ========== Error handling | 300 | * ========== Error handling |
218 | */ | 301 | */ |
219 | 302 | ||
220 | typedef void (MikMod_handler)(void); | 303 | typedef void (MikMod_handler)(void); |
@@ -222,12 +305,12 @@ typedef MikMod_handler *MikMod_handler_t; | |||
222 | 305 | ||
223 | MIKMODAPI extern int MikMod_errno; | 306 | MIKMODAPI extern int MikMod_errno; |
224 | MIKMODAPI extern int MikMod_critical; | 307 | MIKMODAPI extern int MikMod_critical; |
225 | MIKMODAPI extern char *MikMod_strerror(int); | 308 | MIKMODAPI extern const char *MikMod_strerror(int); |
226 | 309 | ||
227 | MIKMODAPI extern MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t); | 310 | MIKMODAPI extern MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t); |
228 | 311 | ||
229 | /* | 312 | /* |
230 | * ========== Library initialization and core functions | 313 | * ========== Library initialization and core functions |
231 | */ | 314 | */ |
232 | 315 | ||
233 | struct MDRIVER; | 316 | struct MDRIVER; |
@@ -236,15 +319,15 @@ MIKMODAPI extern void MikMod_RegisterAllDrivers(void); | |||
236 | 319 | ||
237 | MIKMODAPI extern CHAR* MikMod_InfoDriver(void); | 320 | MIKMODAPI extern CHAR* MikMod_InfoDriver(void); |
238 | MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*); | 321 | MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*); |
239 | MIKMODAPI extern int MikMod_DriverFromAlias(CHAR*); | 322 | MIKMODAPI extern int MikMod_DriverFromAlias(const CHAR*); |
240 | MIKMODAPI extern struct MDRIVER *MikMod_DriverByOrdinal(int); | 323 | MIKMODAPI extern struct MDRIVER *MikMod_DriverByOrdinal(int); |
241 | 324 | ||
242 | MIKMODAPI extern int MikMod_Init(CHAR*); | 325 | MIKMODAPI extern int MikMod_Init(const CHAR*); |
243 | MIKMODAPI extern void MikMod_Exit(void); | 326 | MIKMODAPI extern void MikMod_Exit(void); |
244 | MIKMODAPI extern int MikMod_Reset(CHAR*); | 327 | MIKMODAPI extern int MikMod_Reset(const CHAR*); |
245 | MIKMODAPI extern int MikMod_SetNumVoices(int,int); | 328 | MIKMODAPI extern int MikMod_SetNumVoices(int,int); |
246 | MIKMODAPI extern int MikMod_Active(void); | 329 | MIKMODAPI extern int MikMod_Active(void); |
247 | MIKMODAPI extern int MikMod_EnableOutput(void); | 330 | MIKMODAPI extern int MikMod_EnableOutput(void); |
248 | MIKMODAPI extern void MikMod_DisableOutput(void); | 331 | MIKMODAPI extern void MikMod_DisableOutput(void); |
249 | MIKMODAPI extern void MikMod_Update(void); | 332 | MIKMODAPI extern void MikMod_Update(void); |
250 | 333 | ||
@@ -253,33 +336,34 @@ MIKMODAPI extern void MikMod_Lock(void); | |||
253 | MIKMODAPI extern void MikMod_Unlock(void); | 336 | MIKMODAPI extern void MikMod_Unlock(void); |
254 | 337 | ||
255 | MIKMODAPI extern void* MikMod_malloc(size_t); | 338 | MIKMODAPI extern void* MikMod_malloc(size_t); |
256 | MIKMODAPI extern void* MikMod_realloc(void *, size_t); | ||
257 | MIKMODAPI extern void* MikMod_calloc(size_t,size_t); | 339 | MIKMODAPI extern void* MikMod_calloc(size_t,size_t); |
258 | MIKMODAPI extern void MikMod_free(void*); | 340 | MIKMODAPI extern void* MikMod_realloc(void*,size_t); |
341 | MIKMODAPI extern CHAR* MikMod_strdup(const CHAR*); | ||
342 | MIKMODAPI extern void MikMod_free(void*); /* frees if ptr != NULL */ | ||
259 | 343 | ||
260 | /* | 344 | /* |
261 | * ========== Reader, Writer | 345 | * ========== Reader, Writer |
262 | */ | 346 | */ |
263 | 347 | ||
264 | typedef struct MREADER { | 348 | typedef struct MREADER { |
265 | int (*Seek)(struct MREADER*,long,int); | 349 | int (*Seek)(struct MREADER*,long,int); |
266 | long (*Tell)(struct MREADER*); | 350 | long (*Tell)(struct MREADER*); |
267 | int (*Read)(struct MREADER*,void*,size_t); | 351 | int (*Read)(struct MREADER*,void*,size_t); |
268 | int (*Get)(struct MREADER*); | 352 | int (*Get)(struct MREADER*); |
269 | int (*Eof)(struct MREADER*); | 353 | int (*Eof)(struct MREADER*); |
270 | long iobase; | 354 | long iobase; |
271 | long prev_iobase; | 355 | long prev_iobase; |
272 | } MREADER; | 356 | } MREADER; |
273 | 357 | ||
274 | typedef struct MWRITER { | 358 | typedef struct MWRITER { |
275 | int (*Seek)(struct MWRITER*,long,int); | 359 | int (*Seek)(struct MWRITER*, long, int); |
276 | long (*Tell)(struct MWRITER*); | 360 | long (*Tell)(struct MWRITER*); |
277 | int (*Write)(struct MWRITER*,void*,size_t); | 361 | int (*Write)(struct MWRITER*, const void*, size_t); |
278 | int (*Put)(struct MWRITER*,int); | 362 | int (*Put)(struct MWRITER*, int); |
279 | } MWRITER; | 363 | } MWRITER; |
280 | 364 | ||
281 | /* | 365 | /* |
282 | * ========== Samples | 366 | * ========== Samples |
283 | */ | 367 | */ |
284 | 368 | ||
285 | /* Sample playback should not be interrupted */ | 369 | /* Sample playback should not be interrupted */ |
@@ -291,9 +375,9 @@ typedef struct MWRITER { | |||
291 | #define SF_SIGNED 0x0004 | 375 | #define SF_SIGNED 0x0004 |
292 | #define SF_BIG_ENDIAN 0x0008 | 376 | #define SF_BIG_ENDIAN 0x0008 |
293 | #define SF_DELTA 0x0010 | 377 | #define SF_DELTA 0x0010 |
294 | #define SF_ITPACKED 0x0020 | 378 | #define SF_ITPACKED 0x0020 |
295 | 379 | ||
296 | #define SF_FORMATMASK 0x003F | 380 | #define SF_FORMATMASK 0x003F |
297 | 381 | ||
298 | /* General Playback flags */ | 382 | /* General Playback flags */ |
299 | 383 | ||
@@ -302,61 +386,61 @@ typedef struct MWRITER { | |||
302 | #define SF_REVERSE 0x0400 | 386 | #define SF_REVERSE 0x0400 |
303 | #define SF_SUSTAIN 0x0800 | 387 | #define SF_SUSTAIN 0x0800 |
304 | 388 | ||
305 | #define SF_PLAYBACKMASK 0x0C00 | 389 | #define SF_PLAYBACKMASK 0x0C00 |
306 | 390 | ||
307 | /* Module-only Playback Flags */ | 391 | /* Module-only Playback Flags */ |
308 | 392 | ||
309 | #define SF_OWNPAN 0x1000 | 393 | #define SF_OWNPAN 0x1000 |
310 | #define SF_UST_LOOP 0x2000 | 394 | #define SF_UST_LOOP 0x2000 |
311 | 395 | ||
312 | #define SF_EXTRAPLAYBACKMASK 0x3000 | 396 | #define SF_EXTRAPLAYBACKMASK 0x3000 |
313 | 397 | ||
314 | /* Panning constants */ | 398 | /* Panning constants */ |
315 | #define PAN_LEFT 0 | 399 | #define PAN_LEFT 0 |
316 | #define PAN_HALFLEFT 64 | 400 | #define PAN_HALFLEFT 64 |
317 | #define PAN_CENTER 128 | 401 | #define PAN_CENTER 128 |
318 | #define PAN_HALFRIGHT 192 | 402 | #define PAN_HALFRIGHT 192 |
319 | #define PAN_RIGHT 255 | 403 | #define PAN_RIGHT 255 |
320 | #define PAN_SURROUND 512 /* panning value for Dolby Surround */ | 404 | #define PAN_SURROUND 512 /* panning value for Dolby Surround */ |
321 | 405 | ||
322 | typedef struct SAMPLE { | 406 | typedef struct SAMPLE { |
323 | SWORD panning; /* panning (0-255 or PAN_SURROUND) */ | 407 | SWORD panning; /* panning (0-255 or PAN_SURROUND) */ |
324 | ULONG speed; /* Base playing speed/frequency of note */ | 408 | ULONG speed; /* Base playing speed/frequency of note */ |
325 | UBYTE volume; /* volume 0-64 */ | 409 | UBYTE volume; /* volume 0-64 */ |
326 | UWORD inflags; /* sample format on disk */ | 410 | UWORD inflags; /* sample format on disk */ |
327 | UWORD flags; /* sample format in memory */ | 411 | UWORD flags; /* sample format in memory */ |
328 | ULONG length; /* length of sample (in samples!) */ | 412 | ULONG length; /* length of sample (in samples!) */ |
329 | ULONG loopstart; /* repeat position (relative to start, in samples) */ | 413 | ULONG loopstart; /* repeat position (relative to start, in samples) */ |
330 | ULONG loopend; /* repeat end */ | 414 | ULONG loopend; /* repeat end */ |
331 | ULONG susbegin; /* sustain loop begin (in samples) \ Not Supported */ | 415 | ULONG susbegin; /* sustain loop begin (in samples) \ Not Supported */ |
332 | ULONG susend; /* sustain loop end / Yet! */ | 416 | ULONG susend; /* sustain loop end / Yet! */ |
333 | 417 | ||
334 | /* Variables used by the module player only! (ignored for sound effects) */ | 418 | /* Variables used by the module player only! (ignored for sound effects) */ |
335 | UBYTE globvol; /* global volume */ | 419 | UBYTE globvol; /* global volume */ |
336 | UBYTE vibflags; /* autovibrato flag stuffs */ | 420 | UBYTE vibflags; /* autovibrato flag stuffs */ |
337 | UBYTE vibtype; /* Vibratos moved from INSTRUMENT to SAMPLE */ | 421 | UBYTE vibtype; /* Vibratos moved from INSTRUMENT to SAMPLE */ |
338 | UBYTE vibsweep; | 422 | UBYTE vibsweep; |
339 | UBYTE vibdepth; | 423 | UBYTE vibdepth; |
340 | UBYTE vibrate; | 424 | UBYTE vibrate; |
341 | CHAR* samplename; /* name of the sample */ | 425 | CHAR* samplename; /* name of the sample */ |
342 | 426 | ||
343 | /* Values used internally only */ | 427 | /* Values used internally only */ |
344 | UWORD avibpos; /* autovibrato pos [player use] */ | 428 | UWORD avibpos; /* autovibrato pos [player use] */ |
345 | UBYTE divfactor; /* for sample scaling, maintains proper period slides */ | 429 | UBYTE divfactor; /* for sample scaling, maintains proper period slides */ |
346 | ULONG seekpos; /* seek position in file */ | 430 | ULONG seekpos; /* seek position in file */ |
347 | SWORD handle; /* sample handle used by individual drivers */ | 431 | SWORD handle; /* sample handle used by individual drivers */ |
348 | void (*onfree)(void *ctx); /* called from Sample_Free if not NULL */ | 432 | void (*onfree)(void *ctx); /* called from Sample_Free if not NULL */ |
349 | void *ctx; /* context passed to previous function*/ | 433 | void *ctx; /* context passed to previous function*/ |
350 | } SAMPLE; | 434 | } SAMPLE; |
351 | 435 | ||
352 | /* Sample functions */ | 436 | /* Sample functions */ |
353 | 437 | ||
354 | MIKMODAPI extern SAMPLE *Sample_LoadRaw(CHAR *,ULONG rate, ULONG channel, ULONG flags); | 438 | MIKMODAPI extern SAMPLE *Sample_LoadRaw(const CHAR *,ULONG rate, ULONG channel, ULONG flags); |
355 | MIKMODAPI extern SAMPLE *Sample_LoadRawFP(int fp,ULONG rate,ULONG channel, ULONG flags); | 439 | MIKMODAPI extern SAMPLE *Sample_LoadRawFP(int fp,ULONG rate,ULONG channel, ULONG flags); |
356 | MIKMODAPI extern SAMPLE *Sample_LoadRawMem(const char *buf, int len, ULONG rate, ULONG channel, ULONG flags); | 440 | MIKMODAPI extern SAMPLE *Sample_LoadRawMem(const char *buf, int len, ULONG rate, ULONG channel, ULONG flags); |
357 | MIKMODAPI extern SAMPLE *Sample_LoadRawGeneric(MREADER*reader,ULONG rate, ULONG channel, ULONG flags); | 441 | MIKMODAPI extern SAMPLE *Sample_LoadRawGeneric(MREADER*reader,ULONG rate, ULONG channel, ULONG flags); |
358 | 442 | ||
359 | MIKMODAPI extern SAMPLE *Sample_Load(CHAR*); | 443 | MIKMODAPI extern SAMPLE *Sample_Load(const CHAR*); |
360 | MIKMODAPI extern SAMPLE *Sample_LoadFP(int); | 444 | MIKMODAPI extern SAMPLE *Sample_LoadFP(int); |
361 | MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len); | 445 | MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len); |
362 | MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*); | 446 | MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*); |
@@ -376,12 +460,12 @@ MIKMODAPI extern SLONG Voice_GetPosition(SBYTE); | |||
376 | MIKMODAPI extern ULONG Voice_RealVolume(SBYTE); | 460 | MIKMODAPI extern ULONG Voice_RealVolume(SBYTE); |
377 | 461 | ||
378 | /* | 462 | /* |
379 | * ========== Internal module representation (UniMod) | 463 | * ========== Internal module representation (UniMod) |
380 | */ | 464 | */ |
381 | 465 | ||
382 | /* | 466 | /* |
383 | Instrument definition - for information only, the only field which may be | 467 | Instrument definition - for information only, the only field which may be |
384 | of use in user programs is the name field | 468 | of use in user programs is the name field |
385 | */ | 469 | */ |
386 | 470 | ||
387 | /* Instrument note count */ | 471 | /* Instrument note count */ |
@@ -389,8 +473,8 @@ MIKMODAPI extern ULONG Voice_RealVolume(SBYTE); | |||
389 | 473 | ||
390 | /* Envelope point */ | 474 | /* Envelope point */ |
391 | typedef struct ENVPT { | 475 | typedef struct ENVPT { |
392 | SWORD pos; | 476 | SWORD pos; |
393 | SWORD val; | 477 | SWORD val; |
394 | } ENVPT; | 478 | } ENVPT; |
395 | 479 | ||
396 | /* Envelope point count */ | 480 | /* Envelope point count */ |
@@ -398,154 +482,156 @@ typedef struct ENVPT { | |||
398 | 482 | ||
399 | /* Instrument structure */ | 483 | /* Instrument structure */ |
400 | typedef struct INSTRUMENT { | 484 | typedef struct INSTRUMENT { |
401 | CHAR* insname; | 485 | CHAR* insname; |
402 | 486 | ||
403 | UBYTE flags; | 487 | UBYTE flags; |
404 | UWORD samplenumber[INSTNOTES]; | 488 | UWORD samplenumber[INSTNOTES]; |
405 | UBYTE samplenote[INSTNOTES]; | 489 | UBYTE samplenote[INSTNOTES]; |
406 | 490 | ||
407 | UBYTE nnatype; | 491 | UBYTE nnatype; |
408 | UBYTE dca; /* duplicate check action */ | 492 | UBYTE dca; /* duplicate check action */ |
409 | UBYTE dct; /* duplicate check type */ | 493 | UBYTE dct; /* duplicate check type */ |
410 | UBYTE globvol; | 494 | UBYTE globvol; |
411 | UWORD volfade; | 495 | UWORD volfade; |
412 | SWORD panning; /* instrument-based panning var */ | 496 | SWORD panning; /* instrument-based panning var */ |
413 | 497 | ||
414 | UBYTE pitpansep; /* pitch pan separation (0 to 255) */ | 498 | UBYTE pitpansep; /* pitch pan separation (0 to 255) */ |
415 | UBYTE pitpancenter; /* pitch pan center (0 to 119) */ | 499 | UBYTE pitpancenter; /* pitch pan center (0 to 119) */ |
416 | UBYTE rvolvar; /* random volume varations (0 - 100%) */ | 500 | UBYTE rvolvar; /* random volume varations (0 - 100%) */ |
417 | UBYTE rpanvar; /* random panning varations (0 - 100%) */ | 501 | UBYTE rpanvar; /* random panning varations (0 - 100%) */ |
418 | 502 | ||
419 | /* volume envelope */ | 503 | /* volume envelope */ |
420 | UBYTE volflg; /* bit 0: on 1: sustain 2: loop */ | 504 | UBYTE volflg; /* bit 0: on 1: sustain 2: loop */ |
421 | UBYTE volpts; | 505 | UBYTE volpts; |
422 | UBYTE volsusbeg; | 506 | UBYTE volsusbeg; |
423 | UBYTE volsusend; | 507 | UBYTE volsusend; |
424 | UBYTE volbeg; | 508 | UBYTE volbeg; |
425 | UBYTE volend; | 509 | UBYTE volend; |
426 | ENVPT volenv[ENVPOINTS]; | 510 | ENVPT volenv[ENVPOINTS]; |
427 | /* panning envelope */ | 511 | /* panning envelope */ |
428 | UBYTE panflg; /* bit 0: on 1: sustain 2: loop */ | 512 | UBYTE panflg; /* bit 0: on 1: sustain 2: loop */ |
429 | UBYTE panpts; | 513 | UBYTE panpts; |
430 | UBYTE pansusbeg; | 514 | UBYTE pansusbeg; |
431 | UBYTE pansusend; | 515 | UBYTE pansusend; |
432 | UBYTE panbeg; | 516 | UBYTE panbeg; |
433 | UBYTE panend; | 517 | UBYTE panend; |
434 | ENVPT panenv[ENVPOINTS]; | 518 | ENVPT panenv[ENVPOINTS]; |
435 | /* pitch envelope */ | 519 | /* pitch envelope */ |
436 | UBYTE pitflg; /* bit 0: on 1: sustain 2: loop */ | 520 | UBYTE pitflg; /* bit 0: on 1: sustain 2: loop */ |
437 | UBYTE pitpts; | 521 | UBYTE pitpts; |
438 | UBYTE pitsusbeg; | 522 | UBYTE pitsusbeg; |
439 | UBYTE pitsusend; | 523 | UBYTE pitsusend; |
440 | UBYTE pitbeg; | 524 | UBYTE pitbeg; |
441 | UBYTE pitend; | 525 | UBYTE pitend; |
442 | ENVPT pitenv[ENVPOINTS]; | 526 | ENVPT pitenv[ENVPOINTS]; |
443 | } INSTRUMENT; | 527 | } INSTRUMENT; |
444 | 528 | ||
445 | struct MP_CONTROL; | 529 | struct MP_CONTROL; |
446 | struct MP_VOICE; | 530 | struct MP_VOICE; |
447 | 531 | ||
448 | /* | 532 | /* |
449 | Module definition | 533 | Module definition |
450 | */ | 534 | */ |
451 | 535 | ||
452 | /* maximum master channels supported */ | 536 | /* maximum master channels supported */ |
453 | #define UF_MAXCHAN 64 | 537 | #define UF_MAXCHAN 64 |
454 | 538 | ||
455 | /* Module flags */ | 539 | /* Module flags */ |
456 | #define UF_XMPERIODS 0x0001 /* XM periods / finetuning */ | 540 | #define UF_XMPERIODS 0x0001 /* XM periods / finetuning */ |
457 | #define UF_LINEAR 0x0002 /* LINEAR periods (UF_XMPERIODS must be set) */ | 541 | #define UF_LINEAR 0x0002 /* LINEAR periods (UF_XMPERIODS must be set) */ |
458 | #define UF_INST 0x0004 /* Instruments are used */ | 542 | #define UF_INST 0x0004 /* Instruments are used */ |
459 | #define UF_NNA 0x0008 /* IT: NNA used, set numvoices rather | 543 | #define UF_NNA 0x0008 /* IT: NNA used, set numvoices rather |
460 | than numchn */ | 544 | than numchn */ |
461 | #define UF_S3MSLIDES 0x0010 /* uses old S3M volume slides */ | 545 | #define UF_S3MSLIDES 0x0010 /* uses old S3M volume slides */ |
462 | #define UF_BGSLIDES 0x0020 /* continue volume slides in the background */ | 546 | #define UF_BGSLIDES 0x0020 /* continue volume slides in the background */ |
463 | #define UF_HIGHBPM 0x0040 /* MED: can use >255 bpm */ | 547 | #define UF_HIGHBPM 0x0040 /* MED: can use >255 bpm */ |
464 | #define UF_NOWRAP 0x0080 /* XM-type (i.e. illogical) pattern break | 548 | #define UF_NOWRAP 0x0080 /* XM-type (i.e. illogical) pattern break |
465 | semantics */ | 549 | semantics */ |
466 | #define UF_ARPMEM 0x0100 /* IT: need arpeggio memory */ | 550 | #define UF_ARPMEM 0x0100 /* IT: need arpeggio memory */ |
467 | #define UF_FT2QUIRKS 0x0200 /* emulate some FT2 replay quirks */ | 551 | #define UF_FT2QUIRKS 0x0200 /* emulate some FT2 replay quirks */ |
468 | #define UF_PANNING 0x0400 /* module uses panning effects or have | 552 | #define UF_PANNING 0x0400 /* module uses panning effects or have |
469 | non-tracker default initial panning */ | 553 | non-tracker default initial panning */ |
470 | 554 | ||
471 | typedef struct MODULE { | 555 | typedef struct MODULE { |
472 | /* general module information */ | 556 | /* general module information */ |
473 | CHAR* songname; /* name of the song */ | 557 | CHAR* songname; /* name of the song */ |
474 | CHAR* modtype; /* string type of module loaded */ | 558 | CHAR* modtype; /* string type of module loaded */ |
475 | CHAR* comment; /* module comments */ | 559 | CHAR* comment; /* module comments */ |
476 | 560 | ||
477 | UWORD flags; /* See module flags above */ | 561 | UWORD flags; /* See module flags above */ |
478 | UBYTE numchn; /* number of module channels */ | 562 | UBYTE numchn; /* number of module channels */ |
479 | UBYTE numvoices; /* max # voices used for full NNA playback */ | 563 | UBYTE numvoices; /* max # voices used for full NNA playback */ |
480 | UWORD numpos; /* number of positions in this song */ | 564 | UWORD numpos; /* number of positions in this song */ |
481 | UWORD numpat; /* number of patterns in this song */ | 565 | UWORD numpat; /* number of patterns in this song */ |
482 | UWORD numins; /* number of instruments */ | 566 | UWORD numins; /* number of instruments */ |
483 | UWORD numsmp; /* number of samples */ | 567 | UWORD numsmp; /* number of samples */ |
484 | struct INSTRUMENT* instruments; /* all instruments */ | 568 | |
485 | struct SAMPLE* samples; /* all samples */ | 569 | struct INSTRUMENT* instruments; /* all instruments */ |
486 | UBYTE realchn; /* real number of channels used */ | 570 | struct SAMPLE* samples; /* all samples */ |
487 | UBYTE totalchn; /* total number of channels used (incl NNAs) */ | 571 | |
488 | 572 | UBYTE realchn; /* real number of channels used */ | |
489 | /* playback settings */ | 573 | UBYTE totalchn; /* total number of channels used (incl NNAs) */ |
490 | UWORD reppos; /* restart position */ | 574 | |
491 | UBYTE initspeed; /* initial song speed */ | 575 | /* playback settings */ |
492 | UWORD inittempo; /* initial song tempo */ | 576 | UWORD reppos; /* restart position */ |
493 | UBYTE initvolume; /* initial global volume (0 - 128) */ | 577 | UBYTE initspeed; /* initial song speed */ |
494 | UWORD panning[UF_MAXCHAN]; /* panning positions */ | 578 | UWORD inittempo; /* initial song tempo */ |
495 | UBYTE chanvol[UF_MAXCHAN]; /* channel positions */ | 579 | UBYTE initvolume; /* initial global volume (0 - 128) */ |
496 | UWORD bpm; /* current beats-per-minute speed */ | 580 | UWORD panning[UF_MAXCHAN]; /* panning positions */ |
497 | UWORD sngspd; /* current song speed */ | 581 | UBYTE chanvol[UF_MAXCHAN]; /* channel positions */ |
498 | SWORD volume; /* song volume (0-128) (or user volume) */ | 582 | UWORD bpm; /* current beats-per-minute speed */ |
499 | 583 | UWORD sngspd; /* current song speed */ | |
500 | int extspd; /* extended speed flag (default enabled) */ | 584 | SWORD volume; /* song volume (0-128) (or user volume) */ |
501 | int panflag; /* panning flag (default enabled) */ | 585 | |
502 | int wrap; /* wrap module ? (default disabled) */ | 586 | int extspd; /* extended speed flag (default enabled) */ |
503 | int loop; /* allow module to loop ? (default enabled) */ | 587 | int panflag; /* panning flag (default enabled) */ |
504 | int fadeout; /* volume fade out during last pattern */ | 588 | int wrap; /* wrap module ? (default disabled) */ |
505 | 589 | int loop; /* allow module to loop ? (default enabled) */ | |
506 | UWORD patpos; /* current row number */ | 590 | int fadeout; /* volume fade out during last pattern */ |
507 | SWORD sngpos; /* current song position */ | 591 | |
508 | ULONG sngtime; /* current song time in 2^-10 seconds */ | 592 | UWORD patpos; /* current row number */ |
509 | 593 | SWORD sngpos; /* current song position */ | |
510 | SWORD relspd; /* relative speed factor */ | 594 | ULONG sngtime; /* current song time in 2^-10 seconds */ |
511 | 595 | ||
512 | /* internal module representation */ | 596 | SWORD relspd; /* relative speed factor */ |
513 | UWORD numtrk; /* number of tracks */ | 597 | |
514 | UBYTE** tracks; /* array of numtrk pointers to tracks */ | 598 | /* internal module representation */ |
515 | UWORD* patterns; /* array of Patterns */ | 599 | UWORD numtrk; /* number of tracks */ |
516 | UWORD* pattrows; /* array of number of rows for each pattern */ | 600 | UBYTE** tracks; /* array of numtrk pointers to tracks */ |
517 | UWORD* positions; /* all positions */ | 601 | UWORD* patterns; /* array of Patterns */ |
518 | 602 | UWORD* pattrows; /* array of number of rows for each pattern */ | |
519 | int forbid; /* if true, no player update! */ | 603 | UWORD* positions; /* all positions */ |
520 | UWORD numrow; /* number of rows on current pattern */ | 604 | |
521 | UWORD vbtick; /* tick counter (counts from 0 to sngspd) */ | 605 | int forbid; /* if true, no player update! */ |
522 | UWORD sngremainder;/* used for song time computation */ | 606 | UWORD numrow; /* number of rows on current pattern */ |
523 | 607 | UWORD vbtick; /* tick counter (counts from 0 to sngspd) */ | |
524 | struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */ | 608 | UWORD sngremainder;/* used for song time computation */ |
525 | struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */ | 609 | |
526 | 610 | struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */ | |
527 | UBYTE globalslide; /* global volume slide rate */ | 611 | struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */ |
528 | UBYTE pat_repcrazy;/* module has just looped to position -1 */ | 612 | |
529 | UWORD patbrk; /* position where to start a new pattern */ | 613 | UBYTE globalslide; /* global volume slide rate */ |
530 | UBYTE patdly; /* patterndelay counter (command memory) */ | 614 | UBYTE pat_repcrazy;/* module has just looped to position -1 */ |
531 | UBYTE patdly2; /* patterndelay counter (real one) */ | 615 | UWORD patbrk; /* position where to start a new pattern */ |
532 | SWORD posjmp; /* flag to indicate a jump is needed... */ | 616 | UBYTE patdly; /* patterndelay counter (command memory) */ |
533 | UWORD bpmlimit; /* threshold to detect bpm or speed values */ | 617 | UBYTE patdly2; /* patterndelay counter (real one) */ |
618 | SWORD posjmp; /* flag to indicate a jump is needed... */ | ||
619 | UWORD bpmlimit; /* threshold to detect bpm or speed values */ | ||
534 | } MODULE; | 620 | } MODULE; |
535 | 621 | ||
536 | 622 | ||
537 | /* This structure is used to query current playing voices status */ | 623 | /* This structure is used to query current playing voices status */ |
538 | typedef struct VOICEINFO { | 624 | typedef struct VOICEINFO { |
539 | INSTRUMENT* i; /* Current channel instrument */ | 625 | INSTRUMENT* i; /* Current channel instrument */ |
540 | SAMPLE* s; /* Current channel sample */ | 626 | SAMPLE* s; /* Current channel sample */ |
541 | SWORD panning; /* panning position */ | 627 | SWORD panning; /* panning position */ |
542 | SBYTE volume; /* channel's "global" volume (0..64) */ | 628 | SBYTE volume; /* channel's "global" volume (0..64) */ |
543 | UWORD period; /* period to play the sample at */ | 629 | UWORD period; /* period to play the sample at */ |
544 | UBYTE kick; /* if true = sample has been restarted */ | 630 | UBYTE kick; /* if true = sample has been restarted */ |
545 | } VOICEINFO; | 631 | } VOICEINFO; |
546 | 632 | ||
547 | /* | 633 | /* |
548 | * ========== Module loaders | 634 | * ========== Module loaders |
549 | */ | 635 | */ |
550 | 636 | ||
551 | struct MLOADER; | 637 | struct MLOADER; |
@@ -572,18 +658,19 @@ MIKMODAPI extern struct MLOADER load_stm; /* ScreamTracker 2 (by Future Crew) */ | |||
572 | MIKMODAPI extern struct MLOADER load_stx; /* STMIK 0.2 (by Future Crew) */ | 658 | MIKMODAPI extern struct MLOADER load_stx; /* STMIK 0.2 (by Future Crew) */ |
573 | MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (by Future Crew) */ | 659 | MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (by Future Crew) */ |
574 | MIKMODAPI extern struct MLOADER load_ult; /* UltraTracker (by MAS) */ | 660 | MIKMODAPI extern struct MLOADER load_ult; /* UltraTracker (by MAS) */ |
661 | MIKMODAPI extern struct MLOADER load_umx; /* Unreal UMX container of Epic Games */ | ||
575 | MIKMODAPI extern struct MLOADER load_uni; /* MikMod and APlayer internal module format */ | 662 | MIKMODAPI extern struct MLOADER load_uni; /* MikMod and APlayer internal module format */ |
576 | MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */ | 663 | MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */ |
577 | 664 | ||
578 | /* | 665 | /* |
579 | * ========== Module player | 666 | * ========== Module player |
580 | */ | 667 | */ |
581 | 668 | ||
582 | MIKMODAPI extern MODULE* Player_Load(CHAR*,int,int); | 669 | MIKMODAPI extern MODULE* Player_Load(const CHAR*,int,int); |
583 | MIKMODAPI extern MODULE* Player_LoadFP(int,int,int); | 670 | MIKMODAPI extern MODULE* Player_LoadFP(int,int,int); |
584 | MIKMODAPI extern MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curious); | 671 | MIKMODAPI extern MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curious); |
585 | MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,int); | 672 | MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,int); |
586 | MIKMODAPI extern CHAR* Player_LoadTitle(CHAR*); | 673 | MIKMODAPI extern CHAR* Player_LoadTitle(const CHAR*); |
587 | MIKMODAPI extern CHAR* Player_LoadTitleFP(int); | 674 | MIKMODAPI extern CHAR* Player_LoadTitleFP(int); |
588 | MIKMODAPI extern CHAR* Player_LoadTitleMem(const char *buffer,int len); | 675 | MIKMODAPI extern CHAR* Player_LoadTitleMem(const char *buffer,int len); |
589 | MIKMODAPI extern CHAR* Player_LoadTitleGeneric(MREADER*); | 676 | MIKMODAPI extern CHAR* Player_LoadTitleGeneric(MREADER*); |
@@ -607,9 +694,9 @@ MIKMODAPI extern void Player_Mute(SLONG,...); | |||
607 | MIKMODAPI extern void Player_ToggleMute(SLONG,...); | 694 | MIKMODAPI extern void Player_ToggleMute(SLONG,...); |
608 | MIKMODAPI extern int Player_GetChannelVoice(UBYTE); | 695 | MIKMODAPI extern int Player_GetChannelVoice(UBYTE); |
609 | MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE); | 696 | MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE); |
610 | MIKMODAPI extern int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo); | 697 | MIKMODAPI extern int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo); |
611 | MIKMODAPI extern int Player_GetRow(void); | 698 | MIKMODAPI extern int Player_GetRow(void); |
612 | MIKMODAPI extern int Player_GetOrder(void); | 699 | MIKMODAPI extern int Player_GetOrder(void); |
613 | 700 | ||
614 | typedef void (*MikMod_player_t)(void); | 701 | typedef void (*MikMod_player_t)(void); |
615 | typedef void (*MikMod_callback_t)(unsigned char *data, size_t len); | 702 | typedef void (*MikMod_callback_t)(unsigned char *data, size_t len); |
@@ -620,17 +707,17 @@ MIKMODAPI extern MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t); | |||
620 | #define MUTE_INCLUSIVE 32001 | 707 | #define MUTE_INCLUSIVE 32001 |
621 | 708 | ||
622 | /* | 709 | /* |
623 | * ========== Drivers | 710 | * ========== Drivers |
624 | */ | 711 | */ |
625 | 712 | ||
626 | enum { | 713 | enum { |
627 | MD_MUSIC = 0, | 714 | MD_MUSIC = 0, |
628 | MD_SNDFX | 715 | MD_SNDFX |
629 | }; | 716 | }; |
630 | 717 | ||
631 | enum { | 718 | enum { |
632 | MD_HARDWARE = 0, | 719 | MD_HARDWARE = 0, |
633 | MD_SOFTWARE | 720 | MD_SOFTWARE |
634 | }; | 721 | }; |
635 | 722 | ||
636 | /* Mixing flags */ | 723 | /* Mixing flags */ |
@@ -646,46 +733,48 @@ enum { | |||
646 | #define DMODE_SURROUND 0x0100 /* enable surround sound */ | 733 | #define DMODE_SURROUND 0x0100 /* enable surround sound */ |
647 | #define DMODE_INTERP 0x0200 /* enable interpolation */ | 734 | #define DMODE_INTERP 0x0200 /* enable interpolation */ |
648 | #define DMODE_REVERSE 0x0400 /* reverse stereo */ | 735 | #define DMODE_REVERSE 0x0400 /* reverse stereo */ |
649 | #define DMODE_SIMDMIXER 0x0800 /* enable SIMD mixing */ | 736 | #define DMODE_SIMDMIXER 0x0800 /* enable SIMD mixing */ |
650 | #define DMODE_NOISEREDUCTION 0x1000 /* Low pass filtering */ | 737 | #define DMODE_NOISEREDUCTION 0x1000 /* Low pass filtering */ |
651 | 738 | ||
739 | |||
652 | struct SAMPLOAD; | 740 | struct SAMPLOAD; |
741 | |||
653 | typedef struct MDRIVER { | 742 | typedef struct MDRIVER { |
654 | struct MDRIVER* next; | 743 | struct MDRIVER* next; |
655 | CHAR* Name; | 744 | const CHAR* Name; |
656 | CHAR* Version; | 745 | const CHAR* Version; |
657 | 746 | ||
658 | UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */ | 747 | UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */ |
659 | UBYTE SoftVoiceLimit; /* Limit of software mixer voices */ | 748 | UBYTE SoftVoiceLimit; /* Limit of software mixer voices */ |
660 | 749 | ||
661 | CHAR *Alias; | 750 | const CHAR* Alias; |
662 | CHAR *CmdLineHelp; | 751 | const CHAR* CmdLineHelp; |
663 | 752 | ||
664 | void (*CommandLine) (CHAR*); | 753 | void (*CommandLine) (const CHAR*); |
665 | int (*IsPresent) (void); | 754 | int (*IsPresent) (void); |
666 | SWORD (*SampleLoad) (struct SAMPLOAD*,int); | 755 | SWORD (*SampleLoad) (struct SAMPLOAD*,int); |
667 | void (*SampleUnload) (SWORD); | 756 | void (*SampleUnload) (SWORD); |
668 | ULONG (*FreeSampleSpace) (int); | 757 | ULONG (*FreeSampleSpace) (int); |
669 | ULONG (*RealSampleLength) (int,struct SAMPLE*); | 758 | ULONG (*RealSampleLength) (int,struct SAMPLE*); |
670 | int (*Init) (void); | 759 | int (*Init) (void); |
671 | void (*Exit) (void); | 760 | void (*Exit) (void); |
672 | int (*Reset) (void); | 761 | int (*Reset) (void); |
673 | int (*SetNumVoices) (void); | 762 | int (*SetNumVoices) (void); |
674 | int (*PlayStart) (void); | 763 | int (*PlayStart) (void); |
675 | void (*PlayStop) (void); | 764 | void (*PlayStop) (void); |
676 | void (*Update) (void); | 765 | void (*Update) (void); |
677 | void (*Pause) (void); | 766 | void (*Pause) (void); |
678 | void (*VoiceSetVolume) (UBYTE,UWORD); | 767 | void (*VoiceSetVolume) (UBYTE,UWORD); |
679 | UWORD (*VoiceGetVolume) (UBYTE); | 768 | UWORD (*VoiceGetVolume) (UBYTE); |
680 | void (*VoiceSetFrequency)(UBYTE,ULONG); | 769 | void (*VoiceSetFrequency)(UBYTE,ULONG); |
681 | ULONG (*VoiceGetFrequency)(UBYTE); | 770 | ULONG (*VoiceGetFrequency)(UBYTE); |
682 | void (*VoiceSetPanning) (UBYTE,ULONG); | 771 | void (*VoiceSetPanning) (UBYTE,ULONG); |
683 | ULONG (*VoiceGetPanning) (UBYTE); | 772 | ULONG (*VoiceGetPanning) (UBYTE); |
684 | void (*VoicePlay) (UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); | 773 | void (*VoicePlay) (UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); |
685 | void (*VoiceStop) (UBYTE); | 774 | void (*VoiceStop) (UBYTE); |
686 | int (*VoiceStopped) (UBYTE); | 775 | int (*VoiceStopped) (UBYTE); |
687 | SLONG (*VoiceGetPosition) (UBYTE); | 776 | SLONG (*VoiceGetPosition) (UBYTE); |
688 | ULONG (*VoiceRealVolume) (UBYTE); | 777 | ULONG (*VoiceRealVolume) (UBYTE); |
689 | } MDRIVER; | 778 | } MDRIVER; |
690 | 779 | ||
691 | /* These variables can be changed at ANY time and results will be immediate */ | 780 | /* These variables can be changed at ANY time and results will be immediate */ |
@@ -700,7 +789,7 @@ MIKMODAPI extern UBYTE md_pansep; /* 0 = mono; 128 == 100% (full left/righ | |||
700 | in a skip or pop in audio (depending on the soundcard driver and the settings | 789 | in a skip or pop in audio (depending on the soundcard driver and the settings |
701 | changed). */ | 790 | changed). */ |
702 | MIKMODAPI extern UWORD md_device; /* device */ | 791 | MIKMODAPI extern UWORD md_device; /* device */ |
703 | MIKMODAPI extern UWORD md_mixfreq; /* mixing frequency */ | 792 | MIKMODAPI extern ULONG md_mixfreq; /* mixing frequency */ |
704 | MIKMODAPI extern UWORD md_mode; /* mode. See DMODE_? flags above */ | 793 | MIKMODAPI extern UWORD md_mode; /* mode. See DMODE_? flags above */ |
705 | 794 | ||
706 | /* The following variable should not be changed! */ | 795 | /* The following variable should not be changed! */ |
@@ -709,7 +798,6 @@ MIKMODAPI extern MDRIVER* md_driver; /* Current driver in use. */ | |||
709 | /* Known drivers list */ | 798 | /* Known drivers list */ |
710 | 799 | ||
711 | MIKMODAPI extern struct MDRIVER drv_nos; /* no sound */ | 800 | MIKMODAPI extern struct MDRIVER drv_nos; /* no sound */ |
712 | #if 0 | ||
713 | MIKMODAPI extern struct MDRIVER drv_pipe; /* piped output */ | 801 | MIKMODAPI extern struct MDRIVER drv_pipe; /* piped output */ |
714 | MIKMODAPI extern struct MDRIVER drv_raw; /* raw file disk writer [music.raw] */ | 802 | MIKMODAPI extern struct MDRIVER drv_raw; /* raw file disk writer [music.raw] */ |
715 | MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */ | 803 | MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */ |
@@ -717,42 +805,53 @@ MIKMODAPI extern struct MDRIVER drv_wav; /* RIFF WAVE file disk writer [music | |||
717 | MIKMODAPI extern struct MDRIVER drv_aiff; /* AIFF file disk writer [music.aiff] */ | 805 | MIKMODAPI extern struct MDRIVER drv_aiff; /* AIFF file disk writer [music.aiff] */ |
718 | 806 | ||
719 | MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */ | 807 | MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */ |
720 | MIKMODAPI extern struct MDRIVER drv_sam9407; /* Linux sam9407 driver */ | 808 | MIKMODAPI extern struct MDRIVER drv_sam9407;/* Linux sam9407 driver */ |
721 | 809 | ||
722 | MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */ | 810 | MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */ |
811 | MIKMODAPI extern struct MDRIVER drv_ahi; /* Amiga AHI */ | ||
723 | MIKMODAPI extern struct MDRIVER drv_aix; /* AIX audio device */ | 812 | MIKMODAPI extern struct MDRIVER drv_aix; /* AIX audio device */ |
724 | MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */ | 813 | MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */ |
725 | MIKMODAPI extern struct MDRIVER drv_esd; /* Enlightened sound daemon (EsounD) */ | 814 | MIKMODAPI extern struct MDRIVER drv_esd; /* Enlightened sound daemon (EsounD) */ |
815 | MIKMODAPI extern struct MDRIVER drv_pulseaudio; /* PulseAudio */ | ||
726 | MIKMODAPI extern struct MDRIVER drv_hp; /* HP-UX audio device */ | 816 | MIKMODAPI extern struct MDRIVER drv_hp; /* HP-UX audio device */ |
727 | MIKMODAPI extern struct MDRIVER drv_nas; /* Network Audio System (NAS) */ | 817 | MIKMODAPI extern struct MDRIVER drv_nas; /* Network Audio System (NAS) */ |
728 | MIKMODAPI extern struct MDRIVER drv_oss; /* OpenSound System (Linux,FreeBSD...) */ | 818 | MIKMODAPI extern struct MDRIVER drv_oss; /* OpenSound System (Linux,FreeBSD...) */ |
819 | MIKMODAPI extern struct MDRIVER drv_openal; /* OpenAL driver */ | ||
820 | MIKMODAPI extern struct MDRIVER drv_sdl; /* SDL audio driver */ | ||
729 | MIKMODAPI extern struct MDRIVER drv_sgi; /* SGI audio library */ | 821 | MIKMODAPI extern struct MDRIVER drv_sgi; /* SGI audio library */ |
822 | MIKMODAPI extern struct MDRIVER drv_sndio; /* OpenBSD sndio */ | ||
730 | MIKMODAPI extern struct MDRIVER drv_sun; /* Sun/NetBSD/OpenBSD audio device */ | 823 | MIKMODAPI extern struct MDRIVER drv_sun; /* Sun/NetBSD/OpenBSD audio device */ |
731 | 824 | ||
732 | MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */ | 825 | MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */ |
733 | MIKMODAPI extern struct MDRIVER drv_os2; /* OS/2 MMPM/2 */ | 826 | MIKMODAPI extern struct MDRIVER drv_os2; /* OS/2 MMPM/2 */ |
734 | 827 | ||
735 | MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */ | 828 | MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */ |
829 | MIKMODAPI extern struct MDRIVER drv_xaudio2;/* Win32 XAudio2 driver */ | ||
736 | MIKMODAPI extern struct MDRIVER drv_win; /* Win32 multimedia API driver */ | 830 | MIKMODAPI extern struct MDRIVER drv_win; /* Win32 multimedia API driver */ |
737 | 831 | ||
738 | MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager driver */ | 832 | MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager driver */ |
739 | MIKMODAPI extern struct MDRIVER drv_osx; /* MacOS X CoreAudio Driver */ | 833 | MIKMODAPI extern struct MDRIVER drv_osx; /* MacOS X CoreAudio Driver */ |
740 | 834 | ||
835 | MIKMODAPI extern struct MDRIVER drv_dc; /* Dreamcast driver */ | ||
741 | MIKMODAPI extern struct MDRIVER drv_gp32; /* GP32 Sound driver */ | 836 | MIKMODAPI extern struct MDRIVER drv_gp32; /* GP32 Sound driver */ |
837 | MIKMODAPI extern struct MDRIVER drv_psp; /* PlayStation Portable driver */ | ||
838 | MIKMODAPI extern struct MDRIVER drv_n64; /* Nintendo64 driver */ | ||
742 | 839 | ||
743 | MIKMODAPI extern struct MDRIVER drv_wss; /* DOS WSS driver */ | 840 | MIKMODAPI extern struct MDRIVER drv_wss; /* DOS WSS driver */ |
744 | MIKMODAPI extern struct MDRIVER drv_sb; /* DOS SB driver */ | 841 | MIKMODAPI extern struct MDRIVER drv_sb; /* DOS S/B driver */ |
745 | #endif | 842 | |
843 | MIKMODAPI extern struct MDRIVER drv_osles; /* OpenSL ES driver for android */ | ||
844 | |||
746 | /*========== Virtual channel mixer interface (for user-supplied drivers only) */ | 845 | /*========== Virtual channel mixer interface (for user-supplied drivers only) */ |
747 | 846 | ||
748 | MIKMODAPI extern int VC_Init(void); | 847 | MIKMODAPI extern int VC_Init(void); |
749 | MIKMODAPI extern void VC_Exit(void); | 848 | MIKMODAPI extern void VC_Exit(void); |
750 | MIKMODAPI extern void VC_SetCallback(MikMod_callback_t callback); | 849 | MIKMODAPI extern void VC_SetCallback(MikMod_callback_t callback); |
751 | MIKMODAPI extern int VC_SetNumVoices(void); | 850 | MIKMODAPI extern int VC_SetNumVoices(void); |
752 | MIKMODAPI extern ULONG VC_SampleSpace(int); | 851 | MIKMODAPI extern ULONG VC_SampleSpace(int); |
753 | MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*); | 852 | MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*); |
754 | 853 | ||
755 | MIKMODAPI extern int VC_PlayStart(void); | 854 | MIKMODAPI extern int VC_PlayStart(void); |
756 | MIKMODAPI extern void VC_PlayStop(void); | 855 | MIKMODAPI extern void VC_PlayStop(void); |
757 | 856 | ||
758 | MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int); | 857 | MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int); |
diff --git a/apps/plugins/mikmod/mikmod_internals.h b/apps/plugins/mikmod/mikmod_internals.h index 78d7b52045..e6ba1875c0 100644 --- a/apps/plugins/mikmod/mikmod_internals.h +++ b/apps/plugins/mikmod/mikmod_internals.h | |||
@@ -20,11 +20,9 @@ | |||
20 | 20 | ||
21 | /*============================================================================== | 21 | /*============================================================================== |
22 | 22 | ||
23 | $Id: mikmod_internals.h,v 1.7 2010/01/12 03:30:31 realtech Exp $ | ||
24 | |||
25 | MikMod sound library internal definitions | 23 | MikMod sound library internal definitions |
26 | 24 | ||
27 | ==============================================================================*/ | 25 | ==============================================================================*/ |
28 | 26 | ||
29 | #ifndef _MIKMOD_INTERNALS_H | 27 | #ifndef _MIKMOD_INTERNALS_H |
30 | #define _MIKMOD_INTERNALS_H | 28 | #define _MIKMOD_INTERNALS_H |
@@ -34,32 +32,52 @@ extern "C" { | |||
34 | #endif | 32 | #endif |
35 | 33 | ||
36 | #include <stdarg.h> | 34 | #include <stdarg.h> |
37 | #if 0 | 35 | |
38 | #if defined(__OS2__)||defined(__EMX__)||defined(WIN32) | 36 | #if defined(_MSC_VER) && !defined(__cplusplus) && !defined(HAVE_CONFIG_H) |
39 | #define strcasecmp(s,t) stricmp(s,t) | 37 | #define inline __inline |
40 | #endif | ||
41 | #endif | 38 | #endif |
42 | 39 | ||
43 | #include "mikmod.h" | 40 | #include "mikmod.h" |
44 | 41 | ||
42 | #ifndef MIKMOD_UNIX | ||
43 | #if (defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) && \ | ||
44 | !(defined(_MIKMOD_WIN32) || defined(_MIKMOD_OS2) || defined(_MIKMOD_DOS) || defined(_MIKMOD_AMIGA) || defined(macintosh)) | ||
45 | #define MIKMOD_UNIX 1 | ||
46 | #else | ||
47 | #define MIKMOD_UNIX 0 | ||
48 | #endif | ||
49 | #endif /* MIKMOD_UNIX */ | ||
50 | |||
45 | /*========== More type definitions */ | 51 | /*========== More type definitions */ |
46 | 52 | ||
47 | /* SLONGLONG: 64bit, signed */ | 53 | /* SLONGLONG: 64bit, signed */ |
48 | #if defined (__arch64__) || defined(__alpha) || defined (__x64_64) || defined (_LP64) || defined (__powerpc64__) | 54 | #if !defined(_WIN32) && \ |
49 | typedef long SLONGLONG; | 55 | (defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__)) |
56 | typedef long SLONGLONG; | ||
57 | #define NATIVE_64BIT_INT | ||
58 | #elif defined(_WIN64) /* win64 is LLP64, not LP64 */ | ||
50 | #define NATIVE_64BIT_INT | 59 | #define NATIVE_64BIT_INT |
51 | #if 0 | 60 | typedef long long SLONGLONG; |
52 | #elif defined(__WATCOMC__) | 61 | #elif defined(__WATCOMC__) |
53 | typedef __int64 SLONGLONG; | 62 | typedef __int64 SLONGLONG; |
54 | #elif defined(WIN32) && !defined(__MWERKS__) | 63 | #elif defined(_WIN32) && !defined(__MWERKS__) |
55 | typedef LONGLONG SLONGLONG; | 64 | typedef LONGLONG SLONGLONG; |
56 | #elif macintosh && !TYPE_LONGLONG | 65 | #elif defined(macintosh) && !TYPE_LONGLONG |
57 | #include <Types.h> | 66 | #include <Types.h> |
58 | typedef SInt64 SLONGLONG; | 67 | typedef SInt64 SLONGLONG; |
68 | #else | ||
69 | typedef long long SLONGLONG; | ||
59 | #endif | 70 | #endif |
71 | typedef int __s64_typetest [(sizeof(SLONGLONG)==8) * 2 - 1]; | ||
72 | |||
73 | /* pointer-sized signed int (ssize_t/intptr_t) : */ | ||
74 | #if defined(_WIN64) /* win64 is LLP64, not LP64 */ | ||
75 | typedef long long SINTPTR_T; | ||
60 | #else | 76 | #else |
61 | typedef long long SLONGLONG; | 77 | /* long should be pointer-sized for all others : */ |
78 | typedef long SINTPTR_T; | ||
62 | #endif | 79 | #endif |
80 | typedef int __iptr_typetest [(sizeof(SINTPTR_T)==sizeof(void*)) * 2 - 1]; | ||
63 | 81 | ||
64 | /*========== Error handling */ | 82 | /*========== Error handling */ |
65 | 83 | ||
@@ -72,33 +90,36 @@ extern MikMod_handler_t _mm_errorhandler; | |||
72 | #ifdef HAVE_PTHREAD | 90 | #ifdef HAVE_PTHREAD |
73 | #include <pthread.h> | 91 | #include <pthread.h> |
74 | #define DECLARE_MUTEX(name) \ | 92 | #define DECLARE_MUTEX(name) \ |
75 | extern pthread_mutex_t _mm_mutex_##name | 93 | extern pthread_mutex_t _mm_mutex_##name |
76 | #define MUTEX_LOCK(name) \ | 94 | #define MUTEX_LOCK(name) \ |
77 | pthread_mutex_lock(&_mm_mutex_##name) | 95 | pthread_mutex_lock(&_mm_mutex_##name) |
78 | #define MUTEX_UNLOCK(name) \ | 96 | #define MUTEX_UNLOCK(name) \ |
79 | pthread_mutex_unlock(&_mm_mutex_##name) | 97 | pthread_mutex_unlock(&_mm_mutex_##name) |
98 | |||
80 | #elif defined(__OS2__)||defined(__EMX__) | 99 | #elif defined(__OS2__)||defined(__EMX__) |
81 | #define DECLARE_MUTEX(name) \ | 100 | #define DECLARE_MUTEX(name) \ |
82 | extern HMTX _mm_mutex_##name | 101 | extern HMTX _mm_mutex_##name |
83 | #define MUTEX_LOCK(name) \ | 102 | #define MUTEX_LOCK(name) \ |
84 | if(_mm_mutex_##name) \ | 103 | if(_mm_mutex_##name)\ |
85 | DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT) | 104 | DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT) |
86 | #define MUTEX_UNLOCK(name) \ | 105 | #define MUTEX_UNLOCK(name) \ |
87 | if(_mm_mutex_##name) \ | 106 | if(_mm_mutex_##name)\ |
88 | DosReleaseMutexSem(_mm_mutex_##name) | 107 | DosReleaseMutexSem(_mm_mutex_##name) |
89 | #elif defined(WIN32) | 108 | |
109 | #elif defined(_WIN32) | ||
90 | #include <windows.h> | 110 | #include <windows.h> |
91 | #define DECLARE_MUTEX(name) \ | 111 | #define DECLARE_MUTEX(name) \ |
92 | extern HANDLE _mm_mutex_##name | 112 | extern HANDLE _mm_mutex_##name |
93 | #define MUTEX_LOCK(name) \ | 113 | #define MUTEX_LOCK(name) \ |
94 | if(_mm_mutex_##name) \ | 114 | if(_mm_mutex_##name)\ |
95 | WaitForSingleObject(_mm_mutex_##name,INFINITE) | 115 | WaitForSingleObject(_mm_mutex_##name,INFINITE) |
96 | #define MUTEX_UNLOCK(name) \ | 116 | #define MUTEX_UNLOCK(name) \ |
97 | if(_mm_mutex_##name) \ | 117 | if(_mm_mutex_##name)\ |
98 | ReleaseMutex(_mm_mutex_##name) | 118 | ReleaseMutex(_mm_mutex_##name) |
119 | |||
99 | #else | 120 | #else |
100 | #define DECLARE_MUTEX(name) \ | 121 | #define DECLARE_MUTEX(name) \ |
101 | extern void *_mm_mutex_##name | 122 | extern void *_mm_mutex_##name |
102 | #define MUTEX_LOCK(name) | 123 | #define MUTEX_LOCK(name) |
103 | #define MUTEX_UNLOCK(name) | 124 | #define MUTEX_UNLOCK(name) |
104 | #endif | 125 | #endif |
@@ -106,9 +127,13 @@ extern MikMod_handler_t _mm_errorhandler; | |||
106 | DECLARE_MUTEX(lists); | 127 | DECLARE_MUTEX(lists); |
107 | DECLARE_MUTEX(vars); | 128 | DECLARE_MUTEX(vars); |
108 | 129 | ||
130 | /*========== Replacement funcs */ | ||
131 | |||
132 | //extern int strcasecmp (const char *__s1, const char *__s2); | ||
133 | |||
109 | /*========== Portable file I/O */ | 134 | /*========== Portable file I/O */ |
110 | 135 | ||
111 | extern MREADER* _mm_new_mem_reader(const void *buffer, int len); | 136 | extern MREADER* _mm_new_mem_reader(const void *buffer, long len); |
112 | extern void _mm_delete_mem_reader(MREADER *reader); | 137 | extern void _mm_delete_mem_reader(MREADER *reader); |
113 | 138 | ||
114 | extern MREADER* _mm_new_file_reader(int fp); | 139 | extern MREADER* _mm_new_file_reader(int fp); |
@@ -117,33 +142,32 @@ extern void _mm_delete_file_reader(MREADER*); | |||
117 | extern MWRITER* _mm_new_file_writer(int fp); | 142 | extern MWRITER* _mm_new_file_writer(int fp); |
118 | extern void _mm_delete_file_writer(MWRITER*); | 143 | extern void _mm_delete_file_writer(MWRITER*); |
119 | 144 | ||
120 | extern int _mm_FileExists(CHAR *fname); | 145 | extern int _mm_FileExists(const CHAR *fname); |
121 | 146 | ||
122 | #define _mm_write_SBYTE(x,y) y->Put(y,(int)x) | 147 | #define _mm_write_SBYTE(x,y) y->Put(y,(int)x) |
123 | #define _mm_write_UBYTE(x,y) y->Put(y,(int)x) | 148 | #define _mm_write_UBYTE(x,y) y->Put(y,(int)x) |
124 | 149 | ||
125 | #define _mm_read_SBYTE(x) (SBYTE)x->Get(x) | 150 | #define _mm_read_SBYTE(x) (SBYTE)x->Get(x) |
126 | #define _mm_read_UBYTE(x) (UBYTE)x->Get(x) | 151 | #define _mm_read_UBYTE(x) (UBYTE)x->Get(x) |
152 | #define _mm_skip_BYTE(x) (void)x->Get(x) | ||
127 | 153 | ||
128 | #define _mm_write_SBYTES(x,y,z) z->Write(z,(void *)x,y) | 154 | #define _mm_write_SBYTES(x,y,z) z->Write(z,(const void *)x,y) |
129 | #define _mm_write_UBYTES(x,y,z) z->Write(z,(void *)x,y) | 155 | #define _mm_write_UBYTES(x,y,z) z->Write(z,(const void *)x,y) |
130 | #define _mm_read_SBYTES(x,y,z) z->Read(z,(void *)x,y) | 156 | #define _mm_read_SBYTES(x,y,z) z->Read(z,(void *)x,y) |
131 | #define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y) | 157 | #define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y) |
132 | 158 | ||
133 | #define _mm_fseek(x,y,z) x->Seek(x,y,z) | 159 | #define _mm_fseek(x,y,z) x->Seek(x,y,z) |
134 | #define _mm_ftell(x) x->Tell(x) | 160 | #define _mm_ftell(x) x->Tell(x) |
135 | #define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET) | 161 | #define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET) |
136 | 162 | ||
137 | #define _mm_eof(x) x->Eof(x) | 163 | #define _mm_eof(x) x->Eof(x) |
138 | 164 | ||
139 | extern void _mm_iobase_setcur(MREADER*); | 165 | extern void _mm_iobase_setcur(MREADER*); |
140 | extern void _mm_iobase_revert(MREADER*); | 166 | extern void _mm_iobase_revert(MREADER*); |
141 | extern int _mm_fopen(CHAR*,CHAR*); | 167 | extern int _mm_fopen(const CHAR *, const CHAR *); |
142 | extern int _mm_fclose(int); | 168 | extern int _mm_fclose(int); |
143 | #if !defined(ROCKBOX) | 169 | extern void _mm_write_string(const CHAR*,MWRITER*); |
144 | extern void _mm_write_string(CHAR*,MWRITER*); | 170 | extern int _mm_read_string (CHAR*,int,MREADER*); |
145 | #endif | ||
146 | extern int _mm_read_string (CHAR*,int,MREADER*); | ||
147 | 171 | ||
148 | extern SWORD _mm_read_M_SWORD(MREADER*); | 172 | extern SWORD _mm_read_M_SWORD(MREADER*); |
149 | extern SWORD _mm_read_I_SWORD(MREADER*); | 173 | extern SWORD _mm_read_I_SWORD(MREADER*); |
@@ -187,19 +211,21 @@ extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*); | |||
187 | 211 | ||
188 | /*========== Samples */ | 212 | /*========== Samples */ |
189 | 213 | ||
214 | #define MAX_SAMPLE_SIZE 0x10000000 /* a sane value guaranteed to not overflow an SLONG */ | ||
215 | |||
190 | /* This is a handle of sorts attached to any sample registered with | 216 | /* This is a handle of sorts attached to any sample registered with |
191 | SL_RegisterSample. Generally, this only need be used or changed by the | 217 | SL_RegisterSample. Generally, this only need be used or changed by the |
192 | loaders and drivers of mikmod. */ | 218 | loaders and drivers of mikmod. */ |
193 | typedef struct SAMPLOAD { | 219 | typedef struct SAMPLOAD { |
194 | struct SAMPLOAD *next; | 220 | struct SAMPLOAD *next; |
195 | 221 | ||
196 | ULONG length; /* length of sample (in samples!) */ | 222 | ULONG length; /* length of sample (in samples!) */ |
197 | ULONG loopstart; /* repeat position (relative to start, in samples) */ | 223 | ULONG loopstart; /* repeat position (relative to start, in samples) */ |
198 | ULONG loopend; /* repeat end */ | 224 | ULONG loopend; /* repeat end */ |
199 | UWORD infmt,outfmt; | 225 | UWORD infmt,outfmt; |
200 | int scalefactor; | 226 | int scalefactor; |
201 | SAMPLE* sample; | 227 | SAMPLE* sample; |
202 | MREADER* reader; | 228 | MREADER* reader; |
203 | } SAMPLOAD; | 229 | } SAMPLOAD; |
204 | 230 | ||
205 | /*========== Sample and waves loading interface */ | 231 | /*========== Sample and waves loading interface */ |
@@ -209,9 +235,9 @@ extern void SL_Sample8to16(SAMPLOAD*); | |||
209 | extern void SL_Sample16to8(SAMPLOAD*); | 235 | extern void SL_Sample16to8(SAMPLOAD*); |
210 | extern void SL_SampleSigned(SAMPLOAD*); | 236 | extern void SL_SampleSigned(SAMPLOAD*); |
211 | extern void SL_SampleUnsigned(SAMPLOAD*); | 237 | extern void SL_SampleUnsigned(SAMPLOAD*); |
212 | extern int SL_LoadSamples(void); | 238 | extern int SL_LoadSamples(void); |
213 | extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*); | 239 | extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*); |
214 | extern int SL_Load(void*,SAMPLOAD*,ULONG); | 240 | extern int SL_Load(void*,SAMPLOAD*,ULONG); |
215 | extern int SL_Init(SAMPLOAD*); | 241 | extern int SL_Init(SAMPLOAD*); |
216 | extern void SL_Exit(SAMPLOAD*); | 242 | extern void SL_Exit(SAMPLOAD*); |
217 | 243 | ||
@@ -233,126 +259,126 @@ extern UBYTE* UniDup(void); | |||
233 | extern int UniInit(void); | 259 | extern int UniInit(void); |
234 | extern void UniCleanup(void); | 260 | extern void UniCleanup(void); |
235 | extern void UniEffect(UWORD,UWORD); | 261 | extern void UniEffect(UWORD,UWORD); |
236 | #define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x) | 262 | #define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x) |
237 | #define UniNote(x) UniEffect(UNI_NOTE,x) | 263 | #define UniNote(x) UniEffect(UNI_NOTE,x) |
238 | extern void UniPTEffect(UBYTE,UBYTE); | 264 | extern void UniPTEffect(UBYTE,UBYTE); |
239 | extern void UniVolEffect(UWORD,UBYTE); | 265 | extern void UniVolEffect(UWORD,UBYTE); |
240 | 266 | ||
241 | /*========== Module Commands */ | 267 | /*========== Module Commands */ |
242 | 268 | ||
243 | enum { | 269 | enum { |
244 | /* Simple note */ | 270 | /* Simple note */ |
245 | UNI_NOTE = 1, | 271 | UNI_NOTE = 1, |
246 | /* Instrument change */ | 272 | /* Instrument change */ |
247 | UNI_INSTRUMENT, | 273 | UNI_INSTRUMENT, |
248 | /* Protracker effects */ | 274 | /* Protracker effects */ |
249 | UNI_PTEFFECT0, /* arpeggio */ | 275 | UNI_PTEFFECT0, /* arpeggio */ |
250 | UNI_PTEFFECT1, /* porta up */ | 276 | UNI_PTEFFECT1, /* porta up */ |
251 | UNI_PTEFFECT2, /* porta down */ | 277 | UNI_PTEFFECT2, /* porta down */ |
252 | UNI_PTEFFECT3, /* porta to note */ | 278 | UNI_PTEFFECT3, /* porta to note */ |
253 | UNI_PTEFFECT4, /* vibrato */ | 279 | UNI_PTEFFECT4, /* vibrato */ |
254 | UNI_PTEFFECT5, /* dual effect 3+A */ | 280 | UNI_PTEFFECT5, /* dual effect 3+A */ |
255 | UNI_PTEFFECT6, /* dual effect 4+A */ | 281 | UNI_PTEFFECT6, /* dual effect 4+A */ |
256 | UNI_PTEFFECT7, /* tremolo */ | 282 | UNI_PTEFFECT7, /* tremolo */ |
257 | UNI_PTEFFECT8, /* pan */ | 283 | UNI_PTEFFECT8, /* pan */ |
258 | UNI_PTEFFECT9, /* sample offset */ | 284 | UNI_PTEFFECT9, /* sample offset */ |
259 | UNI_PTEFFECTA, /* volume slide */ | 285 | UNI_PTEFFECTA, /* volume slide */ |
260 | UNI_PTEFFECTB, /* pattern jump */ | 286 | UNI_PTEFFECTB, /* pattern jump */ |
261 | UNI_PTEFFECTC, /* set volume */ | 287 | UNI_PTEFFECTC, /* set volume */ |
262 | UNI_PTEFFECTD, /* pattern break */ | 288 | UNI_PTEFFECTD, /* pattern break */ |
263 | UNI_PTEFFECTE, /* extended effects */ | 289 | UNI_PTEFFECTE, /* extended effects */ |
264 | UNI_PTEFFECTF, /* set speed */ | 290 | UNI_PTEFFECTF, /* set speed */ |
265 | /* Scream Tracker effects */ | 291 | /* Scream Tracker effects */ |
266 | UNI_S3MEFFECTA, /* set speed */ | 292 | UNI_S3MEFFECTA, /* set speed */ |
267 | UNI_S3MEFFECTD, /* volume slide */ | 293 | UNI_S3MEFFECTD, /* volume slide */ |
268 | UNI_S3MEFFECTE, /* porta down */ | 294 | UNI_S3MEFFECTE, /* porta down */ |
269 | UNI_S3MEFFECTF, /* porta up */ | 295 | UNI_S3MEFFECTF, /* porta up */ |
270 | UNI_S3MEFFECTI, /* tremor */ | 296 | UNI_S3MEFFECTI, /* tremor */ |
271 | UNI_S3MEFFECTQ, /* retrig */ | 297 | UNI_S3MEFFECTQ, /* retrig */ |
272 | UNI_S3MEFFECTR, /* tremolo */ | 298 | UNI_S3MEFFECTR, /* tremolo */ |
273 | UNI_S3MEFFECTT, /* set tempo */ | 299 | UNI_S3MEFFECTT, /* set tempo */ |
274 | UNI_S3MEFFECTU, /* fine vibrato */ | 300 | UNI_S3MEFFECTU, /* fine vibrato */ |
275 | UNI_KEYOFF, /* note off */ | 301 | UNI_KEYOFF, /* note off */ |
276 | /* Fast Tracker effects */ | 302 | /* Fast Tracker effects */ |
277 | UNI_KEYFADE, /* note fade */ | 303 | UNI_KEYFADE, /* note fade */ |
278 | UNI_VOLEFFECTS, /* volume column effects */ | 304 | UNI_VOLEFFECTS, /* volume column effects */ |
279 | UNI_XMEFFECT4, /* vibrato */ | 305 | UNI_XMEFFECT4, /* vibrato */ |
280 | UNI_XMEFFECT6, /* dual effect 4+A */ | 306 | UNI_XMEFFECT6, /* dual effect 4+A */ |
281 | UNI_XMEFFECTA, /* volume slide */ | 307 | UNI_XMEFFECTA, /* volume slide */ |
282 | UNI_XMEFFECTE1, /* fine porta up */ | 308 | UNI_XMEFFECTE1, /* fine porta up */ |
283 | UNI_XMEFFECTE2, /* fine porta down */ | 309 | UNI_XMEFFECTE2, /* fine porta down */ |
284 | UNI_XMEFFECTEA, /* fine volume slide up */ | 310 | UNI_XMEFFECTEA, /* fine volume slide up */ |
285 | UNI_XMEFFECTEB, /* fine volume slide down */ | 311 | UNI_XMEFFECTEB, /* fine volume slide down */ |
286 | UNI_XMEFFECTG, /* set global volume */ | 312 | UNI_XMEFFECTG, /* set global volume */ |
287 | UNI_XMEFFECTH, /* global volume slide */ | 313 | UNI_XMEFFECTH, /* global volume slide */ |
288 | UNI_XMEFFECTL, /* set envelope position */ | 314 | UNI_XMEFFECTL, /* set envelope position */ |
289 | UNI_XMEFFECTP, /* pan slide */ | 315 | UNI_XMEFFECTP, /* pan slide */ |
290 | UNI_XMEFFECTX1, /* extra fine porta up */ | 316 | UNI_XMEFFECTX1, /* extra fine porta up */ |
291 | UNI_XMEFFECTX2, /* extra fine porta down */ | 317 | UNI_XMEFFECTX2, /* extra fine porta down */ |
292 | /* Impulse Tracker effects */ | 318 | /* Impulse Tracker effects */ |
293 | UNI_ITEFFECTG, /* porta to note */ | 319 | UNI_ITEFFECTG, /* porta to note */ |
294 | UNI_ITEFFECTH, /* vibrato */ | 320 | UNI_ITEFFECTH, /* vibrato */ |
295 | UNI_ITEFFECTI, /* tremor (xy not incremented) */ | 321 | UNI_ITEFFECTI, /* tremor (xy not incremented) */ |
296 | UNI_ITEFFECTM, /* set channel volume */ | 322 | UNI_ITEFFECTM, /* set channel volume */ |
297 | UNI_ITEFFECTN, /* slide / fineslide channel volume */ | 323 | UNI_ITEFFECTN, /* slide / fineslide channel volume */ |
298 | UNI_ITEFFECTP, /* slide / fineslide channel panning */ | 324 | UNI_ITEFFECTP, /* slide / fineslide channel panning */ |
299 | UNI_ITEFFECTT, /* slide tempo */ | 325 | UNI_ITEFFECTT, /* slide tempo */ |
300 | UNI_ITEFFECTU, /* fine vibrato */ | 326 | UNI_ITEFFECTU, /* fine vibrato */ |
301 | UNI_ITEFFECTW, /* slide / fineslide global volume */ | 327 | UNI_ITEFFECTW, /* slide / fineslide global volume */ |
302 | UNI_ITEFFECTY, /* panbrello */ | 328 | UNI_ITEFFECTY, /* panbrello */ |
303 | UNI_ITEFFECTZ, /* resonant filters */ | 329 | UNI_ITEFFECTZ, /* resonant filters */ |
304 | UNI_ITEFFECTS0, | 330 | UNI_ITEFFECTS0, |
305 | /* UltraTracker effects */ | 331 | /* UltraTracker effects */ |
306 | UNI_ULTEFFECT9, /* Sample fine offset */ | 332 | UNI_ULTEFFECT9, /* Sample fine offset */ |
307 | /* OctaMED effects */ | 333 | /* OctaMED effects */ |
308 | UNI_MEDSPEED, | 334 | UNI_MEDSPEED, |
309 | UNI_MEDEFFECTF1, /* play note twice */ | 335 | UNI_MEDEFFECTF1,/* play note twice */ |
310 | UNI_MEDEFFECTF2, /* delay note */ | 336 | UNI_MEDEFFECTF2,/* delay note */ |
311 | UNI_MEDEFFECTF3, /* play note three times */ | 337 | UNI_MEDEFFECTF3,/* play note three times */ |
312 | /* Oktalyzer effects */ | 338 | /* Oktalyzer effects */ |
313 | UNI_OKTARP, /* arpeggio */ | 339 | UNI_OKTARP, /* arpeggio */ |
314 | 340 | ||
315 | UNI_LAST | 341 | UNI_LAST |
316 | }; | 342 | }; |
317 | 343 | ||
318 | extern UWORD unioperands[UNI_LAST]; | 344 | extern const UWORD unioperands[UNI_LAST]; |
319 | 345 | ||
320 | /* IT / S3M Extended SS effects: */ | 346 | /* IT / S3M Extended SS effects: */ |
321 | enum { | 347 | enum { |
322 | SS_GLISSANDO = 1, | 348 | SS_GLISSANDO = 1, |
323 | SS_FINETUNE, | 349 | SS_FINETUNE, |
324 | SS_VIBWAVE, | 350 | SS_VIBWAVE, |
325 | SS_TREMWAVE, | 351 | SS_TREMWAVE, |
326 | SS_PANWAVE, | 352 | SS_PANWAVE, |
327 | SS_FRAMEDELAY, | 353 | SS_FRAMEDELAY, |
328 | SS_S7EFFECTS, | 354 | SS_S7EFFECTS, |
329 | SS_PANNING, | 355 | SS_PANNING, |
330 | SS_SURROUND, | 356 | SS_SURROUND, |
331 | SS_HIOFFSET, | 357 | SS_HIOFFSET, |
332 | SS_PATLOOP, | 358 | SS_PATLOOP, |
333 | SS_NOTECUT, | 359 | SS_NOTECUT, |
334 | SS_NOTEDELAY, | 360 | SS_NOTEDELAY, |
335 | SS_PATDELAY | 361 | SS_PATDELAY |
336 | }; | 362 | }; |
337 | 363 | ||
338 | /* IT Volume column effects */ | 364 | /* IT Volume column effects */ |
339 | enum { | 365 | enum { |
340 | VOL_VOLUME = 1, | 366 | VOL_VOLUME = 1, |
341 | VOL_PANNING, | 367 | VOL_PANNING, |
342 | VOL_VOLSLIDE, | 368 | VOL_VOLSLIDE, |
343 | VOL_PITCHSLIDEDN, | 369 | VOL_PITCHSLIDEDN, |
344 | VOL_PITCHSLIDEUP, | 370 | VOL_PITCHSLIDEUP, |
345 | VOL_PORTAMENTO, | 371 | VOL_PORTAMENTO, |
346 | VOL_VIBRATO | 372 | VOL_VIBRATO |
347 | }; | 373 | }; |
348 | 374 | ||
349 | /* IT resonant filter information */ | 375 | /* IT resonant filter information */ |
350 | 376 | ||
351 | #define UF_MAXMACRO 0x10 | 377 | #define UF_MAXMACRO 0x10 |
352 | #define UF_MAXFILTER 0x100 | 378 | #define UF_MAXFILTER 0x100 |
353 | 379 | ||
354 | #define FILT_CUT 0x80 | 380 | #define FILT_CUT 0x80 |
355 | #define FILT_RESONANT 0x81 | 381 | #define FILT_RESONANT 0x81 |
356 | 382 | ||
357 | typedef struct FILTER { | 383 | typedef struct FILTER { |
358 | UBYTE filter,inf; | 384 | UBYTE filter,inf; |
@@ -401,163 +427,163 @@ typedef struct FILTER { | |||
401 | 427 | ||
402 | /*========== Playing */ | 428 | /*========== Playing */ |
403 | 429 | ||
404 | #define POS_NONE (-2) /* no loop position defined */ | 430 | #define POS_NONE (-2) /* no loop position defined */ |
405 | 431 | ||
406 | #define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */ | 432 | #define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */ |
407 | 433 | ||
408 | typedef struct ENVPR { | 434 | typedef struct ENVPR { |
409 | UBYTE flg; /* envelope flag */ | 435 | UBYTE flg; /* envelope flag */ |
410 | UBYTE pts; /* number of envelope points */ | 436 | UBYTE pts; /* number of envelope points */ |
411 | UBYTE susbeg; /* envelope sustain index begin */ | 437 | UBYTE susbeg; /* envelope sustain index begin */ |
412 | UBYTE susend; /* envelope sustain index end */ | 438 | UBYTE susend; /* envelope sustain index end */ |
413 | UBYTE beg; /* envelope loop begin */ | 439 | UBYTE beg; /* envelope loop begin */ |
414 | UBYTE end; /* envelope loop end */ | 440 | UBYTE end; /* envelope loop end */ |
415 | SWORD p; /* current envelope counter */ | 441 | SWORD p; /* current envelope counter */ |
416 | UWORD a; /* envelope index a */ | 442 | UWORD a; /* envelope index a */ |
417 | UWORD b; /* envelope index b */ | 443 | UWORD b; /* envelope index b */ |
418 | ENVPT* env; /* envelope points */ | 444 | ENVPT* env; /* envelope points */ |
419 | } ENVPR; | 445 | } ENVPR; |
420 | 446 | ||
421 | typedef struct MP_CHANNEL { | 447 | typedef struct MP_CHANNEL { |
422 | INSTRUMENT* i; | 448 | INSTRUMENT* i; |
423 | SAMPLE* s; | 449 | SAMPLE *s; |
424 | UBYTE sample; /* which sample number */ | 450 | UBYTE sample; /* which sample number */ |
425 | UBYTE note; /* the audible note as heard, direct rep of period */ | 451 | UBYTE note; /* the audible note as heard, direct rep of period */ |
426 | SWORD outvolume; /* output volume (vol + sampcol + instvol) */ | 452 | SWORD outvolume; /* output volume (vol + sampcol + instvol) */ |
427 | SBYTE chanvol; /* channel's "global" volume */ | 453 | SBYTE chanvol; /* channel's "global" volume */ |
428 | UWORD fadevol; /* fading volume rate */ | 454 | UWORD fadevol; /* fading volume rate */ |
429 | SWORD panning; /* panning position */ | 455 | SWORD panning; /* panning position */ |
430 | UBYTE kick; /* if true = sample has to be restarted */ | 456 | UBYTE kick; /* if true = sample has to be restarted */ |
431 | UBYTE kick_flag; /* kick has been true */ | 457 | UBYTE kick_flag; /* kick has been true */ |
432 | UWORD period; /* period to play the sample at */ | 458 | UWORD period; /* period to play the sample at */ |
433 | UBYTE nna; /* New note action type + master/slave flags */ | 459 | UBYTE nna; /* New note action type + master/slave flags */ |
434 | 460 | ||
435 | UBYTE volflg; /* volume envelope settings */ | 461 | UBYTE volflg; /* volume envelope settings */ |
436 | UBYTE panflg; /* panning envelope settings */ | 462 | UBYTE panflg; /* panning envelope settings */ |
437 | UBYTE pitflg; /* pitch envelope settings */ | 463 | UBYTE pitflg; /* pitch envelope settings */ |
438 | 464 | ||
439 | UBYTE keyoff; /* if true = fade out and stuff */ | 465 | UBYTE keyoff; /* if true = fade out and stuff */ |
440 | SWORD handle; /* which sample-handle */ | 466 | SWORD handle; /* which sample-handle */ |
441 | UBYTE notedelay; /* (used for note delay) */ | 467 | UBYTE notedelay; /* (used for note delay) */ |
442 | SLONG start; /* The starting byte index in the sample */ | 468 | SLONG start; /* The starting byte index in the sample */ |
443 | } MP_CHANNEL; | 469 | } MP_CHANNEL; |
444 | 470 | ||
445 | typedef struct MP_CONTROL { | 471 | typedef struct MP_CONTROL { |
446 | struct MP_CHANNEL main; | 472 | struct MP_CHANNEL main; |
447 | 473 | ||
448 | struct MP_VOICE *slave; /* Audio Slave of current effects control channel */ | 474 | struct MP_VOICE* slave; /* Audio Slave of current effects control channel */ |
449 | 475 | ||
450 | UBYTE slavechn; /* Audio Slave of current effects control channel */ | 476 | UBYTE slavechn; /* Audio Slave of current effects control channel */ |
451 | UBYTE muted; /* if set, channel not played */ | 477 | UBYTE muted; /* if set, channel not played */ |
452 | UWORD ultoffset; /* fine sample offset memory */ | 478 | UWORD ultoffset; /* fine sample offset memory */ |
453 | UBYTE anote; /* the note that indexes the audible */ | 479 | UBYTE anote; /* the note that indexes the audible */ |
454 | UBYTE oldnote; | 480 | UBYTE oldnote; |
455 | SWORD ownper; | 481 | SWORD ownper; |
456 | SWORD ownvol; | 482 | SWORD ownvol; |
457 | UBYTE dca; /* duplicate check action */ | 483 | UBYTE dca; /* duplicate check action */ |
458 | UBYTE dct; /* duplicate check type */ | 484 | UBYTE dct; /* duplicate check type */ |
459 | UBYTE* row; /* row currently playing on this channel */ | 485 | UBYTE* row; /* row currently playing on this channel */ |
460 | SBYTE retrig; /* retrig value (0 means don't retrig) */ | 486 | SBYTE retrig; /* retrig value (0 means don't retrig) */ |
461 | ULONG speed; /* what finetune to use */ | 487 | ULONG speed; /* what finetune to use */ |
462 | SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */ | 488 | SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */ |
463 | 489 | ||
464 | SWORD tmpvolume; /* tmp volume */ | 490 | SWORD tmpvolume; /* tmp volume */ |
465 | UWORD tmpperiod; /* tmp period */ | 491 | UWORD tmpperiod; /* tmp period */ |
466 | UWORD wantedperiod; /* period to slide to (with effect 3 or 5) */ | 492 | UWORD wantedperiod;/* period to slide to (with effect 3 or 5) */ |
467 | 493 | ||
468 | UBYTE arpmem; /* arpeggio command memory */ | 494 | UBYTE arpmem; /* arpeggio command memory */ |
469 | UBYTE pansspd; /* panslide speed */ | 495 | UBYTE pansspd; /* panslide speed */ |
470 | UWORD slidespeed; | 496 | UWORD slidespeed; |
471 | UWORD portspeed; /* noteslide speed (toneportamento) */ | 497 | UWORD portspeed; /* noteslide speed (toneportamento) */ |
472 | 498 | ||
473 | UBYTE s3mtremor; /* s3m tremor (effect I) counter */ | 499 | UBYTE s3mtremor; /* s3m tremor (effect I) counter */ |
474 | UBYTE s3mtronof; /* s3m tremor ontime/offtime */ | 500 | UBYTE s3mtronof; /* s3m tremor ontime/offtime */ |
475 | UBYTE s3mvolslide; /* last used volslide */ | 501 | UBYTE s3mvolslide;/* last used volslide */ |
476 | SBYTE sliding; | 502 | SBYTE sliding; |
477 | UBYTE s3mrtgspeed; /* last used retrig speed */ | 503 | UBYTE s3mrtgspeed;/* last used retrig speed */ |
478 | UBYTE s3mrtgslide; /* last used retrig slide */ | 504 | UBYTE s3mrtgslide;/* last used retrig slide */ |
479 | 505 | ||
480 | UBYTE glissando; /* glissando (0 means off) */ | 506 | UBYTE glissando; /* glissando (0 means off) */ |
481 | UBYTE wavecontrol; | 507 | UBYTE wavecontrol; |
482 | 508 | ||
483 | SBYTE vibpos; /* current vibrato position */ | 509 | SBYTE vibpos; /* current vibrato position */ |
484 | UBYTE vibspd; /* "" speed */ | 510 | UBYTE vibspd; /* "" speed */ |
485 | UBYTE vibdepth; /* "" depth */ | 511 | UBYTE vibdepth; /* "" depth */ |
486 | 512 | ||
487 | SBYTE trmpos; /* current tremolo position */ | 513 | SBYTE trmpos; /* current tremolo position */ |
488 | UBYTE trmspd; /* "" speed */ | 514 | UBYTE trmspd; /* "" speed */ |
489 | UBYTE trmdepth; /* "" depth */ | 515 | UBYTE trmdepth; /* "" depth */ |
490 | 516 | ||
491 | UBYTE fslideupspd; | 517 | UBYTE fslideupspd; |
492 | UBYTE fslidednspd; | 518 | UBYTE fslidednspd; |
493 | UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */ | 519 | UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */ |
494 | UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */ | 520 | UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */ |
495 | UBYTE ffportupspd; /* fx X1 (extra fine portamento up) data */ | 521 | UBYTE ffportupspd;/* fx X1 (extra fine portamento up) data */ |
496 | UBYTE ffportdnspd; /* fx X2 (extra fine portamento dn) data */ | 522 | UBYTE ffportdnspd;/* fx X2 (extra fine portamento dn) data */ |
497 | 523 | ||
498 | ULONG hioffset; /* last used high order of sample offset */ | 524 | ULONG hioffset; /* last used high order of sample offset */ |
499 | UWORD soffset; /* last used low order of sample-offset (effect 9) */ | 525 | UWORD soffset; /* last used low order of sample-offset (effect 9) */ |
500 | 526 | ||
501 | UBYTE sseffect; /* last used Sxx effect */ | 527 | UBYTE sseffect; /* last used Sxx effect */ |
502 | UBYTE ssdata; /* last used Sxx data info */ | 528 | UBYTE ssdata; /* last used Sxx data info */ |
503 | UBYTE chanvolslide; /* last used channel volume slide */ | 529 | UBYTE chanvolslide;/* last used channel volume slide */ |
504 | 530 | ||
505 | UBYTE panbwave; /* current panbrello waveform */ | 531 | UBYTE panbwave; /* current panbrello waveform */ |
506 | UBYTE panbpos; /* current panbrello position */ | 532 | UBYTE panbpos; /* current panbrello position */ |
507 | SBYTE panbspd; /* "" speed */ | 533 | SBYTE panbspd; /* "" speed */ |
508 | UBYTE panbdepth; /* "" depth */ | 534 | UBYTE panbdepth; /* "" depth */ |
509 | 535 | ||
510 | UWORD newsamp; /* set to 1 upon a sample / inst change */ | 536 | UWORD newsamp; /* set to 1 upon a sample / inst change */ |
511 | UBYTE voleffect; /* Volume Column Effect Memory as used by IT */ | 537 | UBYTE voleffect; /* Volume Column Effect Memory as used by IT */ |
512 | UBYTE voldata; /* Volume Column Data Memory */ | 538 | UBYTE voldata; /* Volume Column Data Memory */ |
513 | 539 | ||
514 | SWORD pat_reppos; /* patternloop position */ | 540 | SWORD pat_reppos; /* patternloop position */ |
515 | UWORD pat_repcnt; /* times to loop */ | 541 | UWORD pat_repcnt; /* times to loop */ |
516 | } MP_CONTROL; | 542 | } MP_CONTROL; |
517 | 543 | ||
518 | /* Used by NNA only player (audio control. AUDTMP is used for full effects | 544 | /* Used by NNA only player (audio control. AUDTMP is used for full effects |
519 | control). */ | 545 | control). */ |
520 | typedef struct MP_VOICE { | 546 | typedef struct MP_VOICE { |
521 | struct MP_CHANNEL main; | 547 | struct MP_CHANNEL main; |
522 | 548 | ||
523 | ENVPR venv; | 549 | ENVPR venv; |
524 | ENVPR penv; | 550 | ENVPR penv; |
525 | ENVPR cenv; | 551 | ENVPR cenv; |
526 | 552 | ||
527 | UWORD avibpos; /* autovibrato pos */ | 553 | UWORD avibpos; /* autovibrato pos */ |
528 | UWORD aswppos; /* autovibrato sweep pos */ | 554 | UWORD aswppos; /* autovibrato sweep pos */ |
529 | 555 | ||
530 | ULONG totalvol; /* total volume of channel (before global mixings) */ | 556 | ULONG totalvol; /* total volume of channel (before global mixings) */ |
531 | 557 | ||
532 | int mflag; | 558 | int mflag; |
533 | SWORD masterchn; | 559 | SWORD masterchn; |
534 | UWORD masterperiod; | 560 | UWORD masterperiod; |
535 | 561 | ||
536 | MP_CONTROL* master; /* index of "master" effects channel */ | 562 | MP_CONTROL* master; /* index of "master" effects channel */ |
537 | } MP_VOICE; | 563 | } MP_VOICE; |
538 | 564 | ||
539 | /*========== Loaders */ | 565 | /*========== Loaders */ |
540 | 566 | ||
541 | typedef struct MLOADER { | 567 | typedef struct MLOADER { |
542 | struct MLOADER* next; | 568 | struct MLOADER* next; |
543 | CHAR* type; | 569 | const CHAR* type; |
544 | CHAR* version; | 570 | const CHAR* version; |
545 | int (*Init)(void); | 571 | int (*Init)(void); |
546 | int (*Test)(void); | 572 | int (*Test)(void); |
547 | int (*Load)(int); | 573 | int (*Load)(int); |
548 | void (*Cleanup)(void); | 574 | void (*Cleanup)(void); |
549 | CHAR* (*LoadTitle)(void); | 575 | CHAR* (*LoadTitle)(void); |
550 | } MLOADER; | 576 | } MLOADER; |
551 | 577 | ||
552 | /* internal loader variables */ | 578 | /* internal loader variables */ |
553 | extern MREADER* modreader; | 579 | extern MREADER* modreader; |
554 | extern UWORD finetune[16]; | ||
555 | extern MODULE of; /* static unimod loading space */ | 580 | extern MODULE of; /* static unimod loading space */ |
556 | extern UWORD npertab[7*OCTAVE]; /* used by the original MOD loaders */ | 581 | extern const UWORD finetune[16]; |
582 | extern const UWORD npertab[7*OCTAVE];/* used by the original MOD loaders */ | ||
557 | 583 | ||
558 | extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ | 584 | extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ |
559 | extern UBYTE* poslookup; /* lookup table for pattern jumps after | 585 | extern UBYTE* poslookup; /* lookup table for pattern jumps after |
560 | blank pattern removal */ | 586 | blank pattern removal */ |
561 | extern UWORD poslookupcnt; | 587 | extern UWORD poslookupcnt; |
562 | extern UWORD* origpositions; | 588 | extern UWORD* origpositions; |
563 | 589 | ||
@@ -577,8 +603,7 @@ extern int AllocPatterns(void); | |||
577 | extern int AllocTracks(void); | 603 | extern int AllocTracks(void); |
578 | extern int AllocInstruments(void); | 604 | extern int AllocInstruments(void); |
579 | extern int AllocSamples(void); | 605 | extern int AllocSamples(void); |
580 | extern CHAR* DupStr(CHAR*,UWORD,int); | 606 | extern CHAR* DupStr(const CHAR*, UWORD, int); |
581 | extern CHAR* StrDup(CHAR *s); | ||
582 | 607 | ||
583 | /* loader utility functions */ | 608 | /* loader utility functions */ |
584 | extern int* AllocLinear(void); | 609 | extern int* AllocLinear(void); |
@@ -588,28 +613,38 @@ extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int); | |||
588 | extern void S3MIT_CreateOrders(int); | 613 | extern void S3MIT_CreateOrders(int); |
589 | 614 | ||
590 | /* flags for S3MIT_ProcessCmd */ | 615 | /* flags for S3MIT_ProcessCmd */ |
591 | #define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */ | 616 | #define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */ |
592 | #define S3MIT_IT 2 /* behave as impulse tracker */ | 617 | #define S3MIT_IT 2 /* behave as impulse tracker */ |
593 | #define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */ | 618 | #define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */ |
594 | 619 | ||
595 | /* used to convert c4spd to linear XM periods (IT and IMF loaders). */ | 620 | /* used to convert c4spd to linear XM periods (IT and IMF loaders). */ |
596 | extern UWORD getlinearperiod(UWORD,ULONG); | 621 | extern UWORD getlinearperiod(UWORD,ULONG); |
597 | extern ULONG getfrequency(UWORD,ULONG); | 622 | extern ULONG getfrequency(UWORD,ULONG); |
598 | 623 | ||
599 | /* loader shared data */ | 624 | /* loader shared data */ |
600 | #define STM_NTRACKERS 3 | 625 | #define STM_NTRACKERS 3 |
601 | extern CHAR *STM_Signatures[STM_NTRACKERS]; | 626 | extern const CHAR *STM_Signatures[STM_NTRACKERS]; |
602 | 627 | ||
603 | /*========== Player interface */ | 628 | /*========== Player interface */ |
604 | 629 | ||
605 | extern int Player_Init(MODULE*); | 630 | extern int Player_Init(MODULE*); |
606 | extern void Player_Exit(MODULE*); | 631 | extern void Player_Exit(MODULE*); |
607 | extern void Player_HandleTick(void); | 632 | extern void Player_HandleTick(void); |
608 | 633 | ||
634 | /*========== UnPackers */ | ||
635 | |||
636 | typedef int (*MUNPACKER) (struct MREADER*, | ||
637 | void** /* unpacked data out */ , | ||
638 | long* /* unpacked data size */ ); | ||
639 | extern int PP20_Unpack(MREADER*, void**, long*); | ||
640 | extern int MMCMP_Unpack(MREADER*, void**, long*); | ||
641 | extern int XPK_Unpack(MREADER*, void**, long*); | ||
642 | extern int S404_Unpack(MREADER*, void**, long*); | ||
643 | |||
609 | /*========== Drivers */ | 644 | /*========== Drivers */ |
610 | 645 | ||
611 | /* max. number of handles a driver has to provide. (not strict) */ | 646 | /* max. number of handles a driver has to provide. (not strict) */ |
612 | #define MAXSAMPLEHANDLES 384 | 647 | #define MAXSAMPLEHANDLES 384 |
613 | 648 | ||
614 | /* These variables can be changed at ANY time and results will be immediate */ | 649 | /* These variables can be changed at ANY time and results will be immediate */ |
615 | extern UWORD md_bpm; /* current song / hardware BPM rate */ | 650 | extern UWORD md_bpm; /* current song / hardware BPM rate */ |
@@ -625,7 +660,7 @@ extern UBYTE md_softchn; /* number of software mixed voices */ | |||
625 | 660 | ||
626 | /* This is for use by the hardware drivers only. It points to the registered | 661 | /* This is for use by the hardware drivers only. It points to the registered |
627 | tickhandler function. */ | 662 | tickhandler function. */ |
628 | extern void (*md_player)(void); | 663 | extern MikMod_player_t md_player; |
629 | 664 | ||
630 | extern SWORD MD_SampleLoad(SAMPLOAD*,int); | 665 | extern SWORD MD_SampleLoad(SAMPLOAD*,int); |
631 | extern void MD_SampleUnload(SWORD); | 666 | extern void MD_SampleUnload(SWORD); |
@@ -636,17 +671,17 @@ extern ULONG MD_SampleLength(int,SAMPLE*); | |||
636 | extern void unsignedtoulaw(char *,int); | 671 | extern void unsignedtoulaw(char *,int); |
637 | 672 | ||
638 | /* Parameter extraction helper */ | 673 | /* Parameter extraction helper */ |
639 | extern CHAR *MD_GetAtom(CHAR*,CHAR*,int); | 674 | extern CHAR *MD_GetAtom(const CHAR*, const CHAR*, int); |
640 | 675 | ||
641 | /* Internal software mixer stuff */ | 676 | /* Internal software mixer stuff */ |
642 | extern void VC_SetupPointers(void); | 677 | extern void VC_SetupPointers(void); |
643 | extern int VC1_Init(void); | 678 | extern int VC1_Init(void); |
644 | extern int VC2_Init(void); | 679 | extern int VC2_Init(void); |
645 | 680 | ||
646 | #if defined(unix) || defined(__APPLE__) && defined(__MACH__) | 681 | #if (MIKMOD_UNIX) |
647 | /* POSIX helper functions */ | 682 | /* POSIX helper functions */ |
648 | extern int MD_Access(CHAR *); | 683 | extern int MD_Access(const CHAR *); |
649 | extern int MD_DropPrivileges(void); | 684 | extern int MD_DropPrivileges(void); |
650 | #endif | 685 | #endif |
651 | 686 | ||
652 | /* Macro to define a missing driver, yet allowing binaries to dynamically link | 687 | /* Macro to define a missing driver, yet allowing binaries to dynamically link |
@@ -659,9 +694,9 @@ extern void _mm_registerdriver(struct MDRIVER*); | |||
659 | extern void _mm_registerloader(struct MLOADER*); | 694 | extern void _mm_registerloader(struct MLOADER*); |
660 | extern int MikMod_Active_internal(void); | 695 | extern int MikMod_Active_internal(void); |
661 | extern void MikMod_DisableOutput_internal(void); | 696 | extern void MikMod_DisableOutput_internal(void); |
662 | extern int MikMod_EnableOutput_internal(void); | 697 | extern int MikMod_EnableOutput_internal(void); |
663 | extern void MikMod_Exit_internal(void); | 698 | extern void MikMod_Exit_internal(void); |
664 | extern int MikMod_SetNumVoices_internal(int,int); | 699 | extern int MikMod_SetNumVoices_internal(int,int); |
665 | extern void Player_Exit_internal(MODULE*); | 700 | extern void Player_Exit_internal(MODULE*); |
666 | extern void Player_Stop_internal(void); | 701 | extern void Player_Stop_internal(void); |
667 | extern int Player_Paused_internal(void); | 702 | extern int Player_Paused_internal(void); |
@@ -673,6 +708,15 @@ extern void Voice_SetVolume_internal(SBYTE,UWORD); | |||
673 | extern void Voice_Stop_internal(SBYTE); | 708 | extern void Voice_Stop_internal(SBYTE); |
674 | extern int Voice_Stopped_internal(SBYTE); | 709 | extern int Voice_Stopped_internal(SBYTE); |
675 | 710 | ||
711 | extern int VC1_PlayStart(void); | ||
712 | extern int VC2_PlayStart(void); | ||
713 | extern void VC1_PlayStop(void); | ||
714 | extern void VC2_PlayStop(void); | ||
715 | extern int VC1_SetNumVoices(void); | ||
716 | extern int VC2_SetNumVoices(void); | ||
717 | |||
718 | extern MikMod_callback_t vc_callback; | ||
719 | |||
676 | #ifdef __cplusplus | 720 | #ifdef __cplusplus |
677 | } | 721 | } |
678 | #endif | 722 | #endif |
@@ -680,30 +724,36 @@ extern int Voice_Stopped_internal(SBYTE); | |||
680 | /*========== SIMD mixing routines */ | 724 | /*========== SIMD mixing routines */ |
681 | #undef HAVE_ALTIVEC | 725 | #undef HAVE_ALTIVEC |
682 | #undef HAVE_SSE2 | 726 | #undef HAVE_SSE2 |
727 | #if defined(MIKMOD_SIMD) | ||
683 | 728 | ||
684 | #if defined(__APPLE__) && !defined (__i386__) | 729 | #if (defined(__ppc__) || defined(__ppc64__)) && defined(__VEC__) && !(defined(__GNUC__) && (__GNUC__ < 3)) |
685 | |||
686 | #if defined __VEC__ && !(defined(__GNUC__) && (__GNUC__ < 3)) | ||
687 | #define HAVE_ALTIVEC | 730 | #define HAVE_ALTIVEC |
688 | #endif // __VEC__ | ||
689 | 731 | ||
690 | #elif defined WIN32 || defined __WIN64 || (defined __APPLE__ && defined (__i386__) && defined __VEC__) | 732 | #elif defined(__GNUC__) && defined(__SSE2__) /* x86 / x86_64 */ |
691 | |||
692 | // FIXME: emmintrin.h requires VC6 processor pack or VC2003+ | ||
693 | #define HAVE_SSE2 | 733 | #define HAVE_SSE2 |
694 | 734 | ||
695 | /* Fixes couples warnings */ | 735 | #elif defined(_MSC_VER) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64)) |
696 | #ifdef _MSC_VER | 736 | /* FIXME: emmintrin.h requires VC6 processor pack or VC2003+ */ |
737 | #define HAVE_SSE2 | ||
738 | /* avoid some warnings */ | ||
697 | #pragma warning(disable:4761) | 739 | #pragma warning(disable:4761) |
698 | #pragma warning(disable:4391) | 740 | #pragma warning(disable:4391) |
699 | #pragma warning(disable:4244) | 741 | #pragma warning(disable:4244) |
700 | #endif | 742 | |
701 | #endif | 743 | #endif /* AltiVec/SSE2 */ |
702 | // TODO: Test for GCC Linux | 744 | #endif /* MIKMOD_SIMD */ |
703 | 745 | ||
704 | /*========== SIMD mixing helper functions =============*/ | 746 | /*========== SIMD mixing helper functions =============*/ |
705 | 747 | ||
706 | #define IS_ALIGNED_16(ptr) (!(((intptr_t)(ptr)) & 15)) | 748 | #if defined(_WIN64) |
749 | # if defined(_MSC_VER) | ||
750 | # define IS_ALIGNED_16(ptr) (!((__int64)(ptr) & 15i64)) | ||
751 | # else /* GCC, LCC, .. */ | ||
752 | # define IS_ALIGNED_16(ptr) (!((long long)(ptr) & 15LL)) | ||
753 | # endif | ||
754 | #else /* long cast should be OK for all else */ | ||
755 | #define IS_ALIGNED_16(ptr) (!((long)(ptr) & 15L)) | ||
756 | #endif | ||
707 | 757 | ||
708 | /* Altivec helper function */ | 758 | /* Altivec helper function */ |
709 | #if defined HAVE_ALTIVEC | 759 | #if defined HAVE_ALTIVEC |
@@ -715,33 +765,29 @@ extern int Voice_Stopped_internal(SBYTE); | |||
715 | #include <ppc_intrinsics.h> | 765 | #include <ppc_intrinsics.h> |
716 | #endif | 766 | #endif |
717 | 767 | ||
718 | // Helper functions | 768 | /* Helper functions */ |
719 | 769 | ||
720 | // Set single float across the four values | 770 | /* Set single float across the four values */ |
721 | static inline vector float vec_mul( const vector float a, const vector float b) | 771 | static inline vector float vec_mul(const vector float a, const vector float b) { |
722 | { | ||
723 | return vec_madd(a, b, (const vector float)(0.f)); | 772 | return vec_madd(a, b, (const vector float)(0.f)); |
724 | } | 773 | } |
725 | 774 | ||
726 | // Set single float across the four values | 775 | /* Set single float across the four values */ |
727 | static inline vector float vec_load_ps1(const float *pF ) | 776 | static inline vector float vec_load_ps1(const float *pF) { |
728 | { | ||
729 | vector float data = vec_lde(0, pF); | 777 | vector float data = vec_lde(0, pF); |
730 | return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0); | 778 | return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0); |
731 | } | 779 | } |
732 | 780 | ||
733 | // Set vector to 0 | 781 | /* Set vector to 0 */ |
734 | static inline const vector float vec_setzero() | 782 | static inline vector float vec_setzero() { |
735 | { | 783 | return (vector float) (0.); |
736 | return (const vector float) (0.); | ||
737 | } | 784 | } |
738 | 785 | ||
739 | static inline vector signed char vec_set1_8(unsigned char splatchar) | 786 | static inline vector signed char vec_set1_8(unsigned char splatchar) { |
740 | { | 787 | vector unsigned char splatmap = vec_lvsl(0, &splatchar); |
741 | vector unsigned char splatmap = vec_lvsl(0, &splatchar); | 788 | vector unsigned char result = vec_lde(0, &splatchar); |
742 | vector unsigned char result = vec_lde(0, &splatchar); | 789 | splatmap = vec_splat(splatmap, 0); |
743 | splatmap = vec_splat(splatmap, 0); | 790 | return (vector signed char)vec_perm(result, result, splatmap); |
744 | return (vector signed char)vec_perm(result, result, splatmap); | ||
745 | } | 791 | } |
746 | 792 | ||
747 | #define PERM_A0 0x00,0x01,0x02,0x03 | 793 | #define PERM_A0 0x00,0x01,0x02,0x03 |
@@ -753,48 +799,45 @@ static inline vector signed char vec_set1_8(unsigned char splatchar) | |||
753 | #define PERM_B2 0x18,0x19,0x1A,0x1B | 799 | #define PERM_B2 0x18,0x19,0x1A,0x1B |
754 | #define PERM_B3 0x1C,0x1D,0x1E,0x1F | 800 | #define PERM_B3 0x1C,0x1D,0x1E,0x1F |
755 | 801 | ||
756 | // Equivalent to _mm_unpacklo_epi32 | 802 | /* Equivalent to _mm_unpacklo_epi32 */ |
757 | static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) | 803 | static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) { |
758 | { | ||
759 | return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1)); | 804 | return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1)); |
760 | } | 805 | } |
761 | 806 | ||
762 | // Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part). | 807 | /* Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part). */ |
763 | static inline vector signed int vec_hiqq(vector signed int a) | 808 | static inline vector signed int vec_hiqq(vector signed int a) { |
764 | { | ||
765 | vector signed int b = vec_splat_s32(0); | 809 | vector signed int b = vec_splat_s32(0); |
766 | return vec_perm(a, b, (vector unsigned char)(PERM_A2,PERM_A3,PERM_B2,PERM_B3)); | 810 | return vec_perm(a, b, (vector unsigned char)(PERM_A2,PERM_A3,PERM_B2,PERM_B3)); |
767 | } | 811 | } |
768 | 812 | ||
769 | // vec_sra is max +15. We have to do in two times ... | 813 | /* vec_sra is max +15. We have to do in two times ... */ |
770 | #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = vec_mul(vec_ctf(vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(BITSHIFT-size)),0), mul); | 814 | #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = vec_mul(vec_ctf(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT-size)),0), mul); |
771 | #define EXTRACT_SAMPLE_SIMD_0(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-0)); | 815 | #define EXTRACT_SAMPLE_SIMD_0(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-0)); |
772 | #define EXTRACT_SAMPLE_SIMD_8(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-8)); | 816 | #define EXTRACT_SAMPLE_SIMD_8(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-8)); |
773 | #define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int*)(srce)), vec_splat_u32(BITSHIFT+16-16)); | 817 | #define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT+16-16)); |
774 | #define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste); | 818 | #define PUT_SAMPLE_SIMD_W(dste, v1, v2) vec_st(vec_packs(v1, v2), 0, dste); |
775 | #define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) vec_st(vec_add(vec_packs((vector signed short)vec_packs(v1, v2), (vector signed short)vec_packs(v3, v4)), vec_set1_8(128)), 0, dste); | 819 | #define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) vec_st(vec_add(vec_packs((vector signed short)vec_packs(v1, v2), (vector signed short)vec_packs(v3, v4)), vec_set1_8(128)), 0, dste); |
776 | #define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste); | 820 | #define PUT_SAMPLE_SIMD_F(dste, v1) vec_st(v1, 0, dste); |
777 | #define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr) | 821 | #define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr) |
778 | 822 | ||
779 | #elif defined HAVE_SSE2 | 823 | #elif defined HAVE_SSE2 |
780 | 824 | ||
781 | /* SSE2 helper function */ | ||
782 | |||
783 | #include <emmintrin.h> | 825 | #include <emmintrin.h> |
784 | 826 | ||
785 | static __inline __m128i mm_hiqq(const __m128i a) | 827 | /* SSE2 helper function */ |
786 | { | 828 | |
787 | return _mm_srli_si128(a, 8); // get the 64bit upper part. new 64bit upper is undefined (zeroed is fine). | 829 | static __inline __m128i mm_hiqq(const __m128i a) { |
830 | return _mm_srli_si128(a, 8); /* get the 64bit upper part. new 64bit upper is undefined (zeroed is fine). */ | ||
788 | } | 831 | } |
789 | 832 | ||
790 | /* 128-bit mixing macros */ | 833 | /* 128-bit mixing macros */ |
791 | #define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i*)(srce)), BITSHIFT+16-size); | 834 | #define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT+16-size); |
792 | #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128((__m128i*)(srce)), BITSHIFT-size)), mul); | 835 | #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT-size)), mul); |
793 | #define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0) | 836 | #define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0) |
794 | #define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8) | 837 | #define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8) |
795 | #define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16) | 838 | #define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16) |
796 | #define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2)); | 839 | #define PUT_SAMPLE_SIMD_W(dste, v1, v2) _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2)); |
797 | #define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) _mm_store_si128((__m128i*)(dste), _mm_add_epi8(_mm_packs_epi16(_mm_packs_epi32(v1, v2), _mm_packs_epi32(v3, v4)), _mm_set1_epi8(128))); | 840 | #define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4) _mm_store_si128((__m128i*)(dste), _mm_add_epi8(_mm_packs_epi16(_mm_packs_epi32(v1, v2), _mm_packs_epi32(v3, v4)), _mm_set1_epi8(128))); |
798 | #define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1); | 841 | #define PUT_SAMPLE_SIMD_F(dste, v1) _mm_store_ps((float*)(dste), v1); |
799 | #define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr) | 842 | #define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr) |
800 | #define simd_m128i __m128i | 843 | #define simd_m128i __m128i |
@@ -802,7 +845,25 @@ static __inline __m128i mm_hiqq(const __m128i a) | |||
802 | 845 | ||
803 | #endif | 846 | #endif |
804 | 847 | ||
848 | #if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC) | ||
849 | /* MikMod_amalloc() returns a 16 byte aligned zero-filled | ||
850 | memory in SIMD-enabled builds. | ||
851 | - the returned memory can be freed with MikMod_afree() | ||
852 | - the returned memory CAN NOT be realloc()'ed safely. */ | ||
853 | #ifdef __cplusplus | ||
854 | extern "C" { | ||
855 | #endif | ||
856 | void* MikMod_amalloc(size_t); | ||
857 | void MikMod_afree(void *); /* frees if ptr != NULL */ | ||
858 | #ifdef __cplusplus | ||
859 | } | ||
860 | #endif | ||
805 | 861 | ||
862 | #else /* NO SIMD */ | ||
863 | #define MikMod_amalloc MikMod_malloc | ||
864 | #define MikMod_afree MikMod_free | ||
806 | #endif | 865 | #endif |
807 | 866 | ||
867 | #endif /* _MIKMOD_INTERNALS_H */ | ||
868 | |||
808 | /* ex:set ts=4: */ | 869 | /* ex:set ts=4: */ |
diff --git a/apps/plugins/mikmod/mikmod_supp.h b/apps/plugins/mikmod/mikmod_supp.h index c1a8681720..fdd9d8f24f 100644 --- a/apps/plugins/mikmod/mikmod_supp.h +++ b/apps/plugins/mikmod/mikmod_supp.h | |||
@@ -8,6 +8,9 @@ | |||
8 | 8 | ||
9 | #undef WIN32 | 9 | #undef WIN32 |
10 | 10 | ||
11 | #define NO_DEPACKERS // We don't support these | ||
12 | //#define NO_HQMIXER // We don't have the oomph | ||
13 | |||
11 | #ifndef NO_MMSUPP_DEFINES | 14 | #ifndef NO_MMSUPP_DEFINES |
12 | #define snprintf(...) rb->snprintf(__VA_ARGS__) | 15 | #define snprintf(...) rb->snprintf(__VA_ARGS__) |
13 | #define fdprintf(...) rb->fdprintf(__VA_ARGS__) | 16 | #define fdprintf(...) rb->fdprintf(__VA_ARGS__) |
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 | } |
diff --git a/apps/plugins/mikmod/mlreg.c b/apps/plugins/mikmod/mlreg.c index c8850fb62f..10095d8157 100644 --- a/apps/plugins/mikmod/mlreg.c +++ b/apps/plugins/mikmod/mlreg.c | |||
@@ -40,7 +40,7 @@ static void MikMod_RegisterAllLoaders_internal(void) | |||
40 | _mm_registerloader(&load_dsm); | 40 | _mm_registerloader(&load_dsm); |
41 | _mm_registerloader(&load_far); | 41 | _mm_registerloader(&load_far); |
42 | _mm_registerloader(&load_gdm); | 42 | _mm_registerloader(&load_gdm); |
43 | _mm_registerloader(&load_gt2); | 43 | /* _mm_registerloader(&load_gt2);*/ /* load_gt2 isn't complete */ |
44 | _mm_registerloader(&load_it); | 44 | _mm_registerloader(&load_it); |
45 | _mm_registerloader(&load_imf); | 45 | _mm_registerloader(&load_imf); |
46 | _mm_registerloader(&load_mod); | 46 | _mm_registerloader(&load_mod); |
@@ -51,13 +51,14 @@ static void MikMod_RegisterAllLoaders_internal(void) | |||
51 | _mm_registerloader(&load_stm); | 51 | _mm_registerloader(&load_stm); |
52 | _mm_registerloader(&load_stx); | 52 | _mm_registerloader(&load_stx); |
53 | _mm_registerloader(&load_ult); | 53 | _mm_registerloader(&load_ult); |
54 | _mm_registerloader(&load_umx); | ||
54 | _mm_registerloader(&load_uni); | 55 | _mm_registerloader(&load_uni); |
55 | _mm_registerloader(&load_xm); | 56 | _mm_registerloader(&load_xm); |
56 | 57 | ||
57 | _mm_registerloader(&load_m15); | 58 | _mm_registerloader(&load_m15); |
58 | } | 59 | } |
59 | 60 | ||
60 | void MikMod_RegisterAllLoaders(void) | 61 | MIKMODAPI void MikMod_RegisterAllLoaders(void) |
61 | { | 62 | { |
62 | MUTEX_LOCK(lists); | 63 | MUTEX_LOCK(lists); |
63 | MikMod_RegisterAllLoaders_internal(); | 64 | MikMod_RegisterAllLoaders_internal(); |
diff --git a/apps/plugins/mikmod/mlutil.c b/apps/plugins/mikmod/mlutil.c index ddaddc7871..328b1d4089 100644 --- a/apps/plugins/mikmod/mlutil.c +++ b/apps/plugins/mikmod/mlutil.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: mlutil.c,v 1.3 2007/12/06 17:43:10 denis111 Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Utility functions for the module loader | 25 | Utility functions for the module loader |
26 | 26 | ||
@@ -43,13 +43,13 @@ extern int fprintf(FILE *, const char *, ...); | |||
43 | 43 | ||
44 | /*========== Shared tracker identifiers */ | 44 | /*========== Shared tracker identifiers */ |
45 | 45 | ||
46 | CHAR *STM_Signatures[STM_NTRACKERS] = { | 46 | const CHAR *STM_Signatures[STM_NTRACKERS] = { |
47 | "!Scream!", | 47 | "!Scream!", |
48 | "BMOD2STM", | 48 | "BMOD2STM", |
49 | "WUZAMOD!" | 49 | "WUZAMOD!" |
50 | }; | 50 | }; |
51 | 51 | ||
52 | CHAR *STM_Version[STM_NTRACKERS] = { | 52 | const CHAR *STM_Version[STM_NTRACKERS] = { |
53 | "Screamtracker 2", | 53 | "Screamtracker 2", |
54 | "Converted by MOD2STM (STM format)", | 54 | "Converted by MOD2STM (STM format)", |
55 | "Wuzamod (STM format)" | 55 | "Wuzamod (STM format)" |
@@ -71,29 +71,27 @@ FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */ | |||
71 | /*========== Linear periods stuff */ | 71 | /*========== Linear periods stuff */ |
72 | 72 | ||
73 | int* noteindex=NULL; /* remap value for linear period modules */ | 73 | int* noteindex=NULL; /* remap value for linear period modules */ |
74 | static int noteindexcount=0; | 74 | static unsigned noteindexcount=0; |
75 | 75 | ||
76 | int *AllocLinear(void) | 76 | int *AllocLinear(void) |
77 | { | 77 | { |
78 | if(of.numsmp>noteindexcount) { | 78 | if(of.numsmp>noteindexcount) { |
79 | noteindexcount=of.numsmp; | 79 | noteindexcount=of.numsmp; |
80 | noteindex=MikMod_realloc(noteindex,noteindexcount*sizeof(int)); | 80 | noteindex=(int*)MikMod_realloc(noteindex,noteindexcount*sizeof(int)); |
81 | } | 81 | } |
82 | return noteindex; | 82 | return noteindex; |
83 | } | 83 | } |
84 | 84 | ||
85 | void FreeLinear(void) | 85 | void FreeLinear(void) |
86 | { | 86 | { |
87 | if(noteindex) { | 87 | MikMod_free(noteindex); |
88 | MikMod_free(noteindex); | 88 | noteindex=NULL; |
89 | noteindex=NULL; | ||
90 | } | ||
91 | noteindexcount=0; | 89 | noteindexcount=0; |
92 | } | 90 | } |
93 | 91 | ||
94 | int speed_to_finetune(ULONG speed,int sample) | 92 | int speed_to_finetune(ULONG speed,int sample) |
95 | { | 93 | { |
96 | ULONG ctmp=0,tmp,note=1,finetune=0; | 94 | ULONG ctmp=0,tmp,note=1,ft=0; |
97 | 95 | ||
98 | speed>>=1; | 96 | speed>>=1; |
99 | while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) { | 97 | while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) { |
@@ -104,16 +102,16 @@ int speed_to_finetune(ULONG speed,int sample) | |||
104 | if(tmp!=speed) { | 102 | if(tmp!=speed) { |
105 | if((tmp-speed)<(speed-ctmp)) | 103 | if((tmp-speed)<(speed-ctmp)) |
106 | while(tmp>speed) | 104 | while(tmp>speed) |
107 | tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune)); | 105 | tmp=getfrequency(of.flags,getlinearperiod(note<<1,--ft)); |
108 | else { | 106 | else { |
109 | note--; | 107 | note--; |
110 | while(ctmp<speed) | 108 | while(ctmp<speed) |
111 | ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++finetune)); | 109 | ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++ft)); |
112 | } | 110 | } |
113 | } | 111 | } |
114 | 112 | ||
115 | noteindex[sample]=note-4*OCTAVE; | 113 | noteindex[sample]=note-4*OCTAVE; |
116 | return finetune; | 114 | return ft; |
117 | } | 115 | } |
118 | 116 | ||
119 | /*========== Order stuff */ | 117 | /*========== Order stuff */ |
@@ -141,13 +139,9 @@ void S3MIT_CreateOrders(int curious) | |||
141 | /*========== Effect stuff */ | 139 | /*========== Effect stuff */ |
142 | 140 | ||
143 | /* handles S3M and IT effects */ | 141 | /* handles S3M and IT effects */ |
144 | void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags) | 142 | void S3MIT_ProcessCmd(UBYTE cmd, UBYTE inf, unsigned int flags) |
145 | { | 143 | { |
146 | UBYTE /* hi,*/ lo; | 144 | UBYTE lo = inf&0xF; |
147 | |||
148 | lo=inf&0xf; | ||
149 | /* hi=inf>>4; */ | ||
150 | |||
151 | /* process S3M / IT specific command structure */ | 145 | /* process S3M / IT specific command structure */ |
152 | 146 | ||
153 | if(cmd!=255) { | 147 | if(cmd!=255) { |
@@ -196,7 +190,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags) | |||
196 | case 9: /* Ixy tremor, ontime x, offtime y */ | 190 | case 9: /* Ixy tremor, ontime x, offtime y */ |
197 | if (flags & S3MIT_OLDSTYLE) | 191 | if (flags & S3MIT_OLDSTYLE) |
198 | UniEffect(UNI_S3MEFFECTI,inf); | 192 | UniEffect(UNI_S3MEFFECTI,inf); |
199 | else | 193 | else |
200 | UniEffect(UNI_ITEFFECTI,inf); | 194 | UniEffect(UNI_ITEFFECTI,inf); |
201 | break; | 195 | break; |
202 | case 0xa: /* Jxy arpeggio */ | 196 | case 0xa: /* Jxy arpeggio */ |
@@ -204,7 +198,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags) | |||
204 | break; | 198 | break; |
205 | case 0xb: /* Kxy Dual command H00 & Dxy */ | 199 | case 0xb: /* Kxy Dual command H00 & Dxy */ |
206 | if (flags & S3MIT_OLDSTYLE) | 200 | if (flags & S3MIT_OLDSTYLE) |
207 | UniPTEffect(0x4,0); | 201 | UniPTEffect(0x4,0); |
208 | else | 202 | else |
209 | UniEffect(UNI_ITEFFECTH,0); | 203 | UniEffect(UNI_ITEFFECTH,0); |
210 | UniEffect(UNI_S3MEFFECTD,inf); | 204 | UniEffect(UNI_S3MEFFECTD,inf); |
@@ -218,7 +212,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags) | |||
218 | break; | 212 | break; |
219 | case 0xd: /* Mxx Set Channel Volume */ | 213 | case 0xd: /* Mxx Set Channel Volume */ |
220 | UniEffect(UNI_ITEFFECTM,inf); | 214 | UniEffect(UNI_ITEFFECTM,inf); |
221 | break; | 215 | break; |
222 | case 0xe: /* Nxy Slide Channel Volume */ | 216 | case 0xe: /* Nxy Slide Channel Volume */ |
223 | UniEffect(UNI_ITEFFECTN,inf); | 217 | UniEffect(UNI_ITEFFECTN,inf); |
224 | break; | 218 | break; |
@@ -233,7 +227,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags) | |||
233 | if(inf && !lo && !(flags & S3MIT_OLDSTYLE)) | 227 | if(inf && !lo && !(flags & S3MIT_OLDSTYLE)) |
234 | UniWriteByte(1); | 228 | UniWriteByte(1); |
235 | else | 229 | else |
236 | UniWriteByte(inf); | 230 | UniWriteByte(inf); |
237 | break; | 231 | break; |
238 | case 0x12: /* Rxy tremolo speed x, depth y */ | 232 | case 0x12: /* Rxy tremolo speed x, depth y */ |
239 | UniEffect(UNI_S3MEFFECTR,inf); | 233 | UniEffect(UNI_S3MEFFECTR,inf); |
diff --git a/apps/plugins/mikmod/mmalloc.c b/apps/plugins/mikmod/mmalloc.c index 2797def57d..ed5fd4684c 100644 --- a/apps/plugins/mikmod/mmalloc.c +++ b/apps/plugins/mikmod/mmalloc.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: mmalloc.c,v 1.3 2007/12/03 20:42:58 denis111 Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Dynamic memory routines | 25 | Dynamic memory routines |
26 | 26 | ||
@@ -30,150 +30,113 @@ | |||
30 | #include "config.h" | 30 | #include "config.h" |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | #include "mikmod_internals.h" | 33 | #ifdef HAVE_POSIX_MEMALIGN |
34 | 34 | #define _XOPEN_SOURCE 600 /* for posix_memalign */ | |
35 | #define ALIGN_STRIDE 16 | 35 | #endif |
36 | /* not used | ||
37 | static void * align_pointer(char *ptr, size_t stride) | ||
38 | { | ||
39 | char *pptr = ptr + sizeof(void*); | ||
40 | char *fptr; | ||
41 | size_t err = ((size_t)pptr)&(stride-1); | ||
42 | if (err) | ||
43 | fptr = pptr + (stride - err); | ||
44 | else | ||
45 | fptr = pptr; | ||
46 | *(size_t*)(fptr - sizeof(void*)) = (size_t)ptr; | ||
47 | return fptr; | ||
48 | } | ||
49 | 36 | ||
50 | static void *get_pointer(void *data) | 37 | #include "string.h" |
51 | { | 38 | #include "mikmod_internals.h" |
52 | unsigned char *_pptr = (unsigned char*)data - sizeof(void*); | ||
53 | size_t _ptr = *(size_t*)_pptr; | ||
54 | return (void*)_ptr; | ||
55 | } | ||
56 | */ | ||
57 | 39 | ||
58 | void* MikMod_realloc(void *data, size_t size) | 40 | #if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC) |
59 | { | 41 | #undef WIN32_ALIGNED_MALLOC |
60 | return realloc(data, size); | 42 | #if defined(_WIN32) && !defined(_WIN32_WCE) |
61 | 43 | # if defined(_WIN64) /* OK with MSVC and MinGW */ | |
62 | #if 0 | 44 | # define WIN32_ALIGNED_MALLOC |
63 | if (data) | 45 | # elif defined(_MSC_VER) && (_MSC_VER >= 1300) |
64 | { | 46 | # define WIN32_ALIGNED_MALLOC |
65 | #if defined __MACH__ | 47 | # elif defined(__MINGW32__) |
66 | void *d = realloc(data, size); | 48 | /* no guarantees that msvcrt.dll will have it */ |
67 | if (d) | 49 | # endif |
68 | { | ||
69 | return d; | ||
70 | } | ||
71 | return 0; | ||
72 | #elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE) | ||
73 | return _aligned_realloc(data, size, ALIGN_STRIDE); | ||
74 | #else | ||
75 | unsigned char *newPtr = (unsigned char *)realloc(get_pointer(data), size + ALIGN_STRIDE + sizeof(void*)); | ||
76 | return align_pointer(newPtr, ALIGN_STRIDE); | ||
77 | #endif | 50 | #endif |
78 | } | ||
79 | return MikMod_malloc(size); | ||
80 | #endif | ||
81 | } | ||
82 | 51 | ||
52 | #define PTRSIZE (sizeof(void*)) | ||
83 | 53 | ||
84 | /* Same as malloc, but sets error variable _mm_error when fails. Returns a 16-byte aligned pointer */ | 54 | /* return a 16 byte aligned address */ |
85 | void* MikMod_malloc(size_t size) | 55 | void* MikMod_amalloc(size_t size) |
86 | { | 56 | { |
87 | void *d; | 57 | void *d; |
88 | if(!(d=calloc(1,size))) { | 58 | #if defined(HAVE_POSIX_MEMALIGN) |
89 | _mm_errno = MMERR_OUT_OF_MEMORY; | 59 | if (!posix_memalign(&d, 16, size)) { |
90 | if(_mm_errorhandler) _mm_errorhandler(); | 60 | memset(d, 0, size); |
91 | } | ||
92 | return d; | ||
93 | |||
94 | #if 0 | ||
95 | #if defined __MACH__ | ||
96 | void *d = calloc(1, size); | ||
97 | if (d) | ||
98 | { | ||
99 | return d; | 61 | return d; |
100 | } | 62 | } |
101 | return 0; | 63 | #elif defined(WIN32_ALIGNED_MALLOC) |
102 | #elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE) | 64 | d = _aligned_malloc(size, 16); |
103 | void * d = _aligned_malloc(size, ALIGN_STRIDE); | 65 | if (d) { |
104 | if (d) | ||
105 | { | ||
106 | ZeroMemory(d, size); | 66 | ZeroMemory(d, size); |
107 | return d; | 67 | return d; |
108 | } | 68 | } |
109 | return 0; | ||
110 | #else | 69 | #else |
111 | void *d = calloc(1, size + ALIGN_STRIDE + sizeof(void*)); | 70 | size_t s = (size)? ((size + (PTRSIZE-1)) & ~(PTRSIZE-1)) : PTRSIZE; |
112 | 71 | s += PTRSIZE + 16; | |
113 | if(!d) { | 72 | d = calloc(1, s); |
114 | _mm_errno = MMERR_OUT_OF_MEMORY; | 73 | if (d) { |
115 | if(_mm_errorhandler) _mm_errorhandler(); | 74 | char *pptr = (char *)d + PTRSIZE; |
75 | size_t err = ((size_t)pptr) & 15; | ||
76 | char *fptr = pptr + (16 - err); | ||
77 | *(size_t*)(fptr - PTRSIZE) = (size_t)d; | ||
78 | return fptr; | ||
116 | } | 79 | } |
117 | return align_pointer(d, ALIGN_STRIDE); | ||
118 | #endif | 80 | #endif |
81 | |||
82 | _mm_errno = MMERR_OUT_OF_MEMORY; | ||
83 | if(_mm_errorhandler) _mm_errorhandler(); | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | void MikMod_afree(void *data) | ||
88 | { | ||
89 | if (!data) return; | ||
90 | #if defined(HAVE_POSIX_MEMALIGN) | ||
91 | free(data); | ||
92 | #elif defined(WIN32_ALIGNED_MALLOC) | ||
93 | _aligned_free(data); | ||
94 | #else | ||
95 | free((void *) *(size_t*)((unsigned char *)data - PTRSIZE)); | ||
119 | #endif | 96 | #endif |
120 | } | 97 | } |
98 | #endif /* (HAVE_SSE2) || (HAVE_ALTIVEC) */ | ||
99 | |||
100 | void* MikMod_realloc(void *data, size_t size) | ||
101 | { | ||
102 | if (data) return realloc(data, size); | ||
103 | return calloc(1, size); | ||
104 | } | ||
105 | |||
106 | /* Same as malloc, but sets error variable _mm_error when fails */ | ||
107 | void* MikMod_malloc(size_t size) | ||
108 | { | ||
109 | return MikMod_calloc(1, size); | ||
110 | } | ||
121 | 111 | ||
122 | /* Same as calloc, but sets error variable _mm_error when fails */ | 112 | /* Same as calloc, but sets error variable _mm_error when fails */ |
123 | void* MikMod_calloc(size_t nitems,size_t size) | 113 | void* MikMod_calloc(size_t nitems, size_t size) |
124 | { | 114 | { |
125 | void *d; | ||
126 | |||
127 | if(!(d=calloc(nitems,size))) { | ||
128 | _mm_errno = MMERR_OUT_OF_MEMORY; | ||
129 | if(_mm_errorhandler) _mm_errorhandler(); | ||
130 | } | ||
131 | return d; | ||
132 | |||
133 | #if 0 | ||
134 | #if defined __MACH__ | ||
135 | void *d = calloc(nitems, size); | 115 | void *d = calloc(nitems, size); |
136 | if (d) | 116 | if (d) return d; |
137 | { | 117 | |
138 | return d; | 118 | _mm_errno = MMERR_OUT_OF_MEMORY; |
139 | } | 119 | if(_mm_errorhandler) _mm_errorhandler(); |
140 | return 0; | 120 | return NULL; |
141 | #elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE) | ||
142 | void * d = _aligned_malloc(size * nitems, ALIGN_STRIDE); | ||
143 | if (d) | ||
144 | { | ||
145 | ZeroMemory(d, size * nitems); | ||
146 | return d; | ||
147 | } | ||
148 | return 0; | ||
149 | #else | ||
150 | void *d = calloc(nitems, size + ALIGN_STRIDE + sizeof(void*)); | ||
151 | |||
152 | if(!d) { | ||
153 | _mm_errno = MMERR_OUT_OF_MEMORY; | ||
154 | if(_mm_errorhandler) _mm_errorhandler(); | ||
155 | } | ||
156 | return align_pointer(d, ALIGN_STRIDE); | ||
157 | #endif | ||
158 | #endif | ||
159 | } | 121 | } |
160 | 122 | ||
161 | void MikMod_free(void *data) | 123 | void MikMod_free(void *data) |
162 | { | 124 | { |
163 | free(data); | 125 | if (data) free(data); |
164 | 126 | } | |
165 | #if 0 | 127 | |
166 | if (data) | 128 | /* like strdup(), but the result must be freed using MikMod_free() */ |
167 | { | 129 | CHAR *MikMod_strdup(const CHAR *s) |
168 | #if defined __MACH__ | 130 | { |
169 | free(data); | 131 | size_t l; |
170 | #elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE) | 132 | CHAR *d; |
171 | _aligned_free(data); | 133 | |
172 | #else | 134 | if (!s) return NULL; |
173 | free(get_pointer(data)); | 135 | |
174 | #endif | 136 | l = strlen(s) + 1; |
175 | } | 137 | d = (CHAR *) MikMod_calloc(1, l * sizeof(CHAR)); |
176 | #endif | 138 | if (d) strcpy(d, s); |
139 | return d; | ||
177 | } | 140 | } |
178 | 141 | ||
179 | /* ex:set ts=4: */ | 142 | /* ex:set ts=4: */ |
diff --git a/apps/plugins/mikmod/mmerror.c b/apps/plugins/mikmod/mmerror.c index ed7c66a10f..4d7949890e 100644 --- a/apps/plugins/mikmod/mmerror.c +++ b/apps/plugins/mikmod/mmerror.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: mmerror.c,v 1.2 2005/03/30 19:10:41 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Error handling functions. | 25 | Error handling functions. |
26 | Register an error handler with _mm_RegisterErrorHandler() and you're all set. | 26 | Register an error handler with _mm_RegisterErrorHandler() and you're all set. |
@@ -40,7 +40,9 @@ | |||
40 | 40 | ||
41 | #include "mikmod_internals.h" | 41 | #include "mikmod_internals.h" |
42 | 42 | ||
43 | CHAR *_mm_errmsg[MMERR_MAX+1] = | 43 | #define _mmerr_invalid "Invalid error code" |
44 | |||
45 | static const char *_mm_errmsg[MMERR_MAX+1] = | ||
44 | { | 46 | { |
45 | /* No error */ | 47 | /* No error */ |
46 | 48 | ||
@@ -82,62 +84,89 @@ CHAR *_mm_errmsg[MMERR_MAX+1] = | |||
82 | "Unable to set non-blocking mode for audio device", | 84 | "Unable to set non-blocking mode for audio device", |
83 | 85 | ||
84 | /* AudioFile driver errors */ | 86 | /* AudioFile driver errors */ |
85 | 87 | #ifdef DRV_AF | |
86 | "Cannot find suitable AudioFile audio port", | 88 | "Cannot find suitable AudioFile audio port", |
89 | #else | ||
90 | _mmerr_invalid, | ||
91 | #endif | ||
87 | 92 | ||
88 | /* AIX driver errors */ | 93 | /* AIX driver errors */ |
89 | 94 | #ifdef DRV_AIX | |
90 | "Configuration (init step) of audio device failed", | 95 | "Configuration (init step) of audio device failed", |
91 | "Configuration (control step) of audio device failed", | 96 | "Configuration (control step) of audio device failed", |
92 | "Configuration (start step) of audio device failed", | 97 | "Configuration (start step) of audio device failed", |
93 | 98 | #else | |
94 | /* ALSA driver errors */ | 99 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, |
95 | 100 | #endif | |
96 | /* EsounD driver errors */ | ||
97 | 101 | ||
98 | /* Ultrasound driver errors */ | 102 | /* Ultrasound driver errors */ |
99 | 103 | #ifdef DRV_ULTRA | |
100 | "Ultrasound driver only works in 16 bit stereo 44 KHz", | 104 | "Ultrasound driver only works in 16 bit stereo 44 KHz", |
101 | "Ultrasound card could not be reset", | 105 | "Ultrasound card could not be reset", |
102 | "Could not start Ultrasound timer", | 106 | "Could not start Ultrasound timer", |
107 | #else | ||
108 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
109 | #endif | ||
103 | 110 | ||
104 | /* HP driver errors */ | 111 | /* HP driver errors */ |
105 | 112 | #ifdef DRV_HP | |
106 | "Unable to select 16bit-linear sample format", | 113 | "Unable to select 16bit-linear sample format", |
107 | "Could not select requested sample-rate", | 114 | "Could not select requested sample-rate", |
108 | "Could not select requested number of channels", | 115 | "Could not select requested number of channels", |
109 | "Unable to select audio output", | 116 | "Unable to select audio output", |
110 | "Unable to get audio description", | 117 | "Unable to get audio description", |
111 | "Could not set transmission buffer size", | 118 | "Could not set transmission buffer size", |
119 | #else | ||
120 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
121 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
122 | #endif | ||
112 | 123 | ||
113 | /* Open Sound System driver errors */ | 124 | /* Open Sound System driver errors */ |
114 | 125 | #ifdef DRV_OSS | |
115 | "Could not set fragment size", | 126 | "Could not set fragment size", |
116 | "Could not set sample size", | 127 | "Could not set sample size", |
117 | "Could not set mono/stereo setting", | 128 | "Could not set mono/stereo setting", |
118 | "Could not set sample rate", | 129 | "Could not set sample rate", |
130 | #else | ||
131 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
132 | _mmerr_invalid, | ||
133 | #endif | ||
119 | 134 | ||
120 | /* SGI driver errors */ | 135 | /* SGI driver errors */ |
121 | 136 | #ifdef DRV_SGI | |
122 | "Unsupported sample rate", | 137 | "Unsupported sample rate", |
123 | "Hardware does not support 16 bit sound", | 138 | "Hardware does not support 16 bit sound", |
124 | "Hardware does not support 8 bit sound", | 139 | "Hardware does not support 8 bit sound", |
125 | "Hardware does not support stereo sound", | 140 | "Hardware does not support stereo sound", |
126 | "Hardware does not support mono sound", | 141 | "Hardware does not support mono sound", |
142 | #else | ||
143 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
144 | _mmerr_invalid, _mmerr_invalid, | ||
145 | #endif | ||
127 | 146 | ||
128 | /* Sun driver errors */ | 147 | /* Sun driver errors */ |
129 | 148 | #ifdef DRV_SUN | |
130 | "Sound device initialization failed", | 149 | "Sound device initialization failed", |
150 | #else | ||
151 | _mmerr_invalid, | ||
152 | #endif | ||
131 | 153 | ||
132 | /* OS/2 drivers errors */ | 154 | /* OS/2 drivers errors */ |
133 | 155 | #if defined(DRV_OS2) || defined(DRV_DART) | |
134 | "Could not set mixing parameters", | 156 | "Could not set mixing parameters", |
157 | #else | ||
158 | _mmerr_invalid, | ||
159 | #endif | ||
160 | #ifdef DRV_OS2 | ||
135 | "Could not create playback semaphores", | 161 | "Could not create playback semaphores", |
136 | "Could not create playback timer", | 162 | "Could not create playback timer", |
137 | "Could not create playback thread", | 163 | "Could not create playback thread", |
164 | #else | ||
165 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
166 | #endif | ||
138 | 167 | ||
139 | /* DirectSound driver errors */ | 168 | /* DirectSound driver errors */ |
140 | 169 | #ifdef DRV_DS | |
141 | "Could not set playback priority", | 170 | "Could not set playback priority", |
142 | "Could not create playback buffers", | 171 | "Could not create playback buffers", |
143 | "Could not set playback format", | 172 | "Could not set playback format", |
@@ -145,22 +174,34 @@ CHAR *_mm_errmsg[MMERR_MAX+1] = | |||
145 | "Could not register event", | 174 | "Could not register event", |
146 | "Could not create playback thread", | 175 | "Could not create playback thread", |
147 | "Could not initialize playback thread", | 176 | "Could not initialize playback thread", |
177 | #else | ||
178 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
179 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
180 | _mmerr_invalid, | ||
181 | #endif | ||
148 | 182 | ||
149 | /* Windows Multimedia API driver errors */ | 183 | /* Windows Multimedia API driver errors */ |
150 | 184 | #ifdef DRV_WIN | |
151 | "Invalid device handle", | 185 | "Invalid device handle", |
152 | "The resource is already allocated", | 186 | "The resource is already allocated", |
153 | "Invalid device identifier", | 187 | "Invalid device identifier", |
154 | "Unsupported output format", | 188 | "Unsupported output format", |
155 | "Unknown error", | 189 | "Unknown error", |
190 | #else | ||
191 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
192 | _mmerr_invalid, _mmerr_invalid, | ||
193 | #endif | ||
156 | 194 | ||
157 | /* Macintosh driver errors */ | 195 | /* Macintosh driver errors */ |
158 | 196 | #ifdef DRV_MAC | |
159 | "Unsupported sample rate", | 197 | "Unsupported sample rate", |
160 | "Could not start playback", | 198 | "Could not start playback", |
199 | #else | ||
200 | _mmerr_invalid, _mmerr_invalid, | ||
201 | #endif | ||
161 | 202 | ||
162 | /* MacOS X/Darwin driver errors */ | 203 | /* MacOS X/Darwin driver errors */ |
163 | 204 | #ifdef DRV_OSX | |
164 | "Unknown device", | 205 | "Unknown device", |
165 | "Bad property", | 206 | "Bad property", |
166 | "Could not set playback format", | 207 | "Could not set playback format", |
@@ -169,20 +210,81 @@ CHAR *_mm_errmsg[MMERR_MAX+1] = | |||
169 | "Could not create playback thread", | 210 | "Could not create playback thread", |
170 | "Could not start audio device", | 211 | "Could not start audio device", |
171 | "Could not create buffer thread", | 212 | "Could not create buffer thread", |
213 | #else | ||
214 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
215 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
216 | _mmerr_invalid, _mmerr_invalid, | ||
217 | #endif | ||
172 | 218 | ||
173 | /* DOS driver errors */ | 219 | /* DOS driver errors */ |
174 | 220 | #ifdef DRV_WSS | |
175 | "WSS_STARTDMA", | 221 | "WSS_STARTDMA", |
222 | #else | ||
223 | _mmerr_invalid, | ||
224 | #endif | ||
225 | #ifdef DRV_SB | ||
176 | "SB_STARTDMA", | 226 | "SB_STARTDMA", |
227 | #else | ||
228 | _mmerr_invalid, | ||
229 | #endif | ||
230 | |||
231 | /* float32 output */ | ||
232 | |||
233 | "This driver doesn't support 32 bit float output", | ||
234 | |||
235 | /* OpenAL driver errors */ | ||
236 | #ifdef DRV_OPENAL | ||
237 | "Could not create context", | ||
238 | "Could not make context current", | ||
239 | "Could not create buffers", | ||
240 | "Could not create sources", | ||
241 | "Could not change source parameters", | ||
242 | "Could not queue buffers", | ||
243 | "Could not unqueue buffers", | ||
244 | "Could not copy buffer data", | ||
245 | "Could not get source parameters", | ||
246 | "Could not play source", | ||
247 | "Could not stop source", | ||
248 | #else | ||
249 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
250 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
251 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
252 | _mmerr_invalid, _mmerr_invalid, | ||
253 | #endif | ||
254 | |||
255 | /* ALSA driver errors */ | ||
256 | #ifdef DRV_ALSA | ||
257 | "No ALSA configurations available", | ||
258 | "Could not set ALSA output params", | ||
259 | "Could not set playback format", | ||
260 | "Could not set sample rate", | ||
261 | "Could not set mono/stereo setting", | ||
262 | "Could not get buffer size from ALSA", | ||
263 | "ALSA PCM start error", | ||
264 | "ALSA PCM write error", | ||
265 | "ALSA PCM recovery failure", | ||
266 | #else | ||
267 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
268 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
269 | _mmerr_invalid, _mmerr_invalid, _mmerr_invalid, | ||
270 | #endif | ||
271 | |||
272 | /* Sndio errors */ | ||
273 | #ifdef DRV_SNDIO | ||
274 | "Could not set SNDIO output params", | ||
275 | "Unsupported SNDIO output params", | ||
276 | #else | ||
277 | _mmerr_invalid, _mmerr_invalid, | ||
278 | #endif | ||
177 | 279 | ||
178 | /* Invalid error */ | 280 | /* Invalid error */ |
179 | 281 | ||
180 | "Invalid error code" | 282 | _mmerr_invalid |
181 | }; | 283 | }; |
182 | 284 | ||
183 | MIKMODAPI char *MikMod_strerror(int code) | 285 | MIKMODAPI const char *MikMod_strerror(int code) |
184 | { | 286 | { |
185 | if ((code<0)||(code>MMERR_MAX)) code=MMERR_MAX+1; | 287 | if ((code<0)||(code>MMERR_MAX)) code=MMERR_MAX; |
186 | return _mm_errmsg[code]; | 288 | return _mm_errmsg[code]; |
187 | } | 289 | } |
188 | 290 | ||
diff --git a/apps/plugins/mikmod/mmio.c b/apps/plugins/mikmod/mmio.c index 0ffecffd2f..023c56baef 100644 --- a/apps/plugins/mikmod/mmio.c +++ b/apps/plugins/mikmod/mmio.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: mmio.c,v 1.3 2005/03/30 19:10:58 realtech Exp $ | ||
24 | |||
25 | Portable file I/O routines | 23 | Portable file I/O routines |
26 | 24 | ||
27 | ==============================================================================*/ | 25 | ==============================================================================*/ |
@@ -51,10 +49,14 @@ | |||
51 | #include <unistd.h> | 49 | #include <unistd.h> |
52 | #endif | 50 | #endif |
53 | 51 | ||
52 | #ifdef HAVE_LIMITS_H | ||
53 | #include <limits.h> | ||
54 | #endif | ||
55 | |||
54 | #include <stdio.h> | 56 | #include <stdio.h> |
55 | #include <string.h> | 57 | #include <string.h> |
58 | #include <limits.h> | ||
56 | 59 | ||
57 | #include "mikmod.h" | ||
58 | #include "mikmod_internals.h" | 60 | #include "mikmod_internals.h" |
59 | 61 | ||
60 | #ifdef SUNOS | 62 | #ifdef SUNOS |
@@ -66,8 +68,6 @@ extern int fseek(FILE *, long, int); | |||
66 | extern size_t fwrite(const void *, size_t, size_t, FILE *); | 68 | extern size_t fwrite(const void *, size_t, size_t, FILE *); |
67 | #endif | 69 | #endif |
68 | 70 | ||
69 | #define COPY_BUFSIZE 1024 | ||
70 | |||
71 | /* some prototypes */ | 71 | /* some prototypes */ |
72 | static int _mm_MemReader_Eof(MREADER* reader); | 72 | static int _mm_MemReader_Eof(MREADER* reader); |
73 | static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size); | 73 | static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size); |
@@ -75,16 +75,13 @@ static int _mm_MemReader_Get(MREADER* reader); | |||
75 | static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence); | 75 | static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence); |
76 | static long _mm_MemReader_Tell(MREADER* reader); | 76 | static long _mm_MemReader_Tell(MREADER* reader); |
77 | 77 | ||
78 | //static long _mm_iobase=0,temp_iobase=0; | 78 | int _mm_fopen(const CHAR* fname, const CHAR* attrib) |
79 | |||
80 | int _mm_fopen(CHAR* fname,CHAR* attrib) | ||
81 | { | 79 | { |
82 | int fp; | 80 | int fp; |
83 | (void)attrib; | 81 | (void)attrib; |
84 | |||
85 | //if(!(fp=fopen(fname,attrib))) { | 82 | //if(!(fp=fopen(fname,attrib))) { |
86 | // _mm_errno = MMERR_OPENING_FILE; | 83 | // _mm_errno = MMERR_OPENING_FILE; |
87 | // if(_mm_errorhandler) _mm_errorhandler(); | 84 | // if(_mm_errorhandler) _mm_errorhandler(); |
88 | //} | 85 | //} |
89 | fp = open(fname, O_RDONLY); | 86 | fp = open(fname, O_RDONLY); |
90 | if( fp < 0 ) { | 87 | if( fp < 0 ) { |
@@ -94,7 +91,7 @@ int _mm_fopen(CHAR* fname,CHAR* attrib) | |||
94 | return fp; | 91 | return fp; |
95 | } | 92 | } |
96 | 93 | ||
97 | int _mm_FileExists(CHAR* fname) | 94 | int _mm_FileExists(const CHAR* fname) |
98 | { | 95 | { |
99 | int fp; | 96 | int fp; |
100 | 97 | ||
@@ -103,7 +100,7 @@ int _mm_FileExists(CHAR* fname) | |||
103 | fp = open(fname, O_RDONLY); | 100 | fp = open(fname, O_RDONLY); |
104 | if ( fp < 0 ) return 0; | 101 | if ( fp < 0 ) return 0; |
105 | close(fp); | 102 | close(fp); |
106 | 103 | ||
107 | return 1; | 104 | return 1; |
108 | } | 105 | } |
109 | 106 | ||
@@ -130,12 +127,12 @@ void _mm_iobase_revert(MREADER* reader) | |||
130 | 127 | ||
131 | typedef struct MFILEREADER { | 128 | typedef struct MFILEREADER { |
132 | MREADER core; | 129 | MREADER core; |
133 | int file; | 130 | int file; |
134 | } MFILEREADER; | 131 | } MFILEREADER; |
135 | 132 | ||
136 | static int _mm_FileReader_Eof(MREADER* reader) | 133 | static int _mm_FileReader_Eof(MREADER* reader) |
137 | { | 134 | { |
138 | //return feof(((MFILEREADER*)reader)->file); | 135 | //return feof(((MFILEREADER*)reader)->file); |
139 | int size = filesize(((MFILEREADER*)reader)->file); | 136 | int size = filesize(((MFILEREADER*)reader)->file); |
140 | int offset = lseek(((MFILEREADER*)reader)->file, 0, SEEK_CUR); | 137 | int offset = lseek(((MFILEREADER*)reader)->file, 0, SEEK_CUR); |
141 | return (size <= 0 || offset < 0 || offset >= size) ? 1 : 0; | 138 | return (size <= 0 || offset < 0 || offset >= size) ? 1 : 0; |
@@ -143,8 +140,8 @@ static int _mm_FileReader_Eof(MREADER* reader) | |||
143 | 140 | ||
144 | static int _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size) | 141 | static int _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size) |
145 | { | 142 | { |
146 | //return !!fread(ptr,size,1,((MFILEREADER*)reader)->file); | ||
147 | return read(((MFILEREADER*)reader)->file, ptr, size); | 143 | return read(((MFILEREADER*)reader)->file, ptr, size); |
144 | //return !!fread(ptr,size,1,((MFILEREADER*)reader)->file); | ||
148 | } | 145 | } |
149 | 146 | ||
150 | static int _mm_FileReader_Get(MREADER* reader) | 147 | static int _mm_FileReader_Get(MREADER* reader) |
@@ -160,7 +157,7 @@ static int _mm_FileReader_Get(MREADER* reader) | |||
160 | static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence) | 157 | static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence) |
161 | { | 158 | { |
162 | //return fseek(((MFILEREADER*)reader)->file, | 159 | //return fseek(((MFILEREADER*)reader)->file, |
163 | // (whence==SEEK_SET)?offset+reader->iobase:offset,whence); | 160 | // (whence==SEEK_SET)?offset+reader->iobase:offset,whence); |
164 | return lseek(((MFILEREADER*)reader)->file, | 161 | return lseek(((MFILEREADER*)reader)->file, |
165 | (whence==SEEK_SET)?offset+reader->iobase:offset,whence); | 162 | (whence==SEEK_SET)?offset+reader->iobase:offset,whence); |
166 | } | 163 | } |
@@ -173,7 +170,7 @@ static long _mm_FileReader_Tell(MREADER* reader) | |||
173 | 170 | ||
174 | MREADER *_mm_new_file_reader(int fp) | 171 | MREADER *_mm_new_file_reader(int fp) |
175 | { | 172 | { |
176 | MFILEREADER* reader=(MFILEREADER*)MikMod_malloc(sizeof(MFILEREADER)); | 173 | MFILEREADER* reader=(MFILEREADER*)MikMod_calloc(1,sizeof(MFILEREADER)); |
177 | if (reader) { | 174 | if (reader) { |
178 | reader->core.Eof =&_mm_FileReader_Eof; | 175 | reader->core.Eof =&_mm_FileReader_Eof; |
179 | reader->core.Read=&_mm_FileReader_Read; | 176 | reader->core.Read=&_mm_FileReader_Read; |
@@ -187,14 +184,14 @@ MREADER *_mm_new_file_reader(int fp) | |||
187 | 184 | ||
188 | void _mm_delete_file_reader (MREADER* reader) | 185 | void _mm_delete_file_reader (MREADER* reader) |
189 | { | 186 | { |
190 | if(reader) MikMod_free(reader); | 187 | MikMod_free(reader); |
191 | } | 188 | } |
192 | 189 | ||
193 | /*========== File Writer */ | 190 | /*========== File Writer */ |
194 | 191 | ||
195 | typedef struct MFILEWRITER { | 192 | typedef struct MFILEWRITER { |
196 | MWRITER core; | 193 | MWRITER core; |
197 | int file; | 194 | int file; |
198 | } MFILEWRITER; | 195 | } MFILEWRITER; |
199 | 196 | ||
200 | static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence) | 197 | static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence) |
@@ -209,27 +206,26 @@ static long _mm_FileWriter_Tell(MWRITER* writer) | |||
209 | return lseek(((MFILEWRITER*)writer)->file, 0, SEEK_CUR); | 206 | return lseek(((MFILEWRITER*)writer)->file, 0, SEEK_CUR); |
210 | } | 207 | } |
211 | 208 | ||
212 | static int _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size) | 209 | static int _mm_FileWriter_Write(MWRITER* writer, const void* ptr, size_t size) |
213 | { | 210 | { |
214 | //return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size); | 211 | //return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size); |
215 | //return (write(ptr,size,((MFILEWRITER*)writer)->file)==(int)size); | 212 | (void)writer; |
216 | (void)writer; | 213 | (void)ptr; |
217 | (void)ptr; | 214 | (void)size; |
218 | (void)size; | 215 | return 0; |
219 | return 0; | ||
220 | } | 216 | } |
221 | 217 | ||
222 | static int _mm_FileWriter_Put(MWRITER* writer,int value) | 218 | static int _mm_FileWriter_Put(MWRITER* writer,int value) |
223 | { | 219 | { |
224 | (void)writer; | 220 | (void)writer; |
225 | (void)value; | 221 | (void)value; |
226 | //return fputc(value,((MFILEWRITER*)writer)->file); | 222 | //return fputc(value,((MFILEWRITER*)writer)->file); |
227 | return 1; // TODO | 223 | return 1; // TODO |
228 | } | 224 | } |
229 | 225 | ||
230 | MWRITER *_mm_new_file_writer(int fp) | 226 | MWRITER *_mm_new_file_writer(int fp) |
231 | { | 227 | { |
232 | MFILEWRITER* writer=(MFILEWRITER*)MikMod_malloc(sizeof(MFILEWRITER)); | 228 | MFILEWRITER* writer=(MFILEWRITER*)MikMod_calloc(1,sizeof(MFILEWRITER)); |
233 | if (writer) { | 229 | if (writer) { |
234 | writer->core.Seek =&_mm_FileWriter_Seek; | 230 | writer->core.Seek =&_mm_FileWriter_Seek; |
235 | writer->core.Tell =&_mm_FileWriter_Tell; | 231 | writer->core.Tell =&_mm_FileWriter_Tell; |
@@ -242,12 +238,11 @@ MWRITER *_mm_new_file_writer(int fp) | |||
242 | 238 | ||
243 | void _mm_delete_file_writer (MWRITER* writer) | 239 | void _mm_delete_file_writer (MWRITER* writer) |
244 | { | 240 | { |
245 | if(writer) MikMod_free (writer); | 241 | MikMod_free (writer); |
246 | } | 242 | } |
247 | 243 | ||
248 | /*========== Memory Reader */ | 244 | /*========== Memory Reader */ |
249 | 245 | ||
250 | |||
251 | typedef struct MMEMREADER { | 246 | typedef struct MMEMREADER { |
252 | MREADER core; | 247 | MREADER core; |
253 | const void *buffer; | 248 | const void *buffer; |
@@ -257,12 +252,12 @@ typedef struct MMEMREADER { | |||
257 | 252 | ||
258 | void _mm_delete_mem_reader(MREADER* reader) | 253 | void _mm_delete_mem_reader(MREADER* reader) |
259 | { | 254 | { |
260 | if (reader) { MikMod_free(reader); } | 255 | MikMod_free(reader); |
261 | } | 256 | } |
262 | 257 | ||
263 | MREADER *_mm_new_mem_reader(const void *buffer, int len) | 258 | MREADER *_mm_new_mem_reader(const void *buffer, long len) |
264 | { | 259 | { |
265 | MMEMREADER* reader=(MMEMREADER*)MikMod_malloc(sizeof(MMEMREADER)); | 260 | MMEMREADER* reader=(MMEMREADER*)MikMod_calloc(1,sizeof(MMEMREADER)); |
266 | if (reader) | 261 | if (reader) |
267 | { | 262 | { |
268 | reader->core.Eof =&_mm_MemReader_Eof; | 263 | reader->core.Eof =&_mm_MemReader_Eof; |
@@ -279,74 +274,86 @@ MREADER *_mm_new_mem_reader(const void *buffer, int len) | |||
279 | 274 | ||
280 | static int _mm_MemReader_Eof(MREADER* reader) | 275 | static int _mm_MemReader_Eof(MREADER* reader) |
281 | { | 276 | { |
282 | if (!reader) { return 1; } | 277 | MMEMREADER* mr = (MMEMREADER*) reader; |
283 | if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) { | 278 | if (!mr) return 1; |
284 | return 1; | 279 | if (mr->pos >= mr->len) return 1; |
285 | } | ||
286 | return 0; | 280 | return 0; |
287 | } | 281 | } |
288 | 282 | ||
289 | static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size) | 283 | static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size) |
290 | { | 284 | { |
291 | unsigned char *d=ptr; | 285 | unsigned char *d; |
292 | const unsigned char *s; | 286 | const unsigned char *s; |
293 | 287 | MMEMREADER* mr; | |
294 | if (!reader) { return 0; } | 288 | long siz; |
295 | 289 | int ret; | |
296 | if (reader->Eof(reader)) { return 0; } | 290 | |
297 | 291 | if (!reader || !size || (size > (size_t) LONG_MAX)) | |
298 | s = ((MMEMREADER*)reader)->buffer; | 292 | return 0; |
299 | s += ((MMEMREADER*)reader)->pos; | 293 | |
300 | 294 | mr = (MMEMREADER*) reader; | |
301 | if ( ((MMEMREADER*)reader)->pos + (long)size > ((MMEMREADER*)reader)->len) | 295 | siz = (long) size; |
302 | { | 296 | if (mr->pos >= mr->len) return 0; /* @ eof */ |
303 | ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len; | 297 | if (mr->pos + siz > mr->len) { |
304 | return 0; /* not enough remaining bytes */ | 298 | siz = mr->len - mr->pos; |
299 | ret = 0; /* not enough remaining bytes */ | ||
300 | } | ||
301 | else { | ||
302 | ret = 1; | ||
305 | } | 303 | } |
306 | 304 | ||
307 | ((MMEMREADER*)reader)->pos += (long)size; | 305 | s = (const unsigned char *) mr->buffer; |
306 | s += mr->pos; | ||
307 | mr->pos += siz; | ||
308 | d = (unsigned char *) ptr; | ||
308 | 309 | ||
309 | while (size--) | 310 | while (siz) { |
310 | { | 311 | *d++ = *s++; |
311 | *d = *s; | 312 | siz--; |
312 | s++; | ||
313 | d++; | ||
314 | } | 313 | } |
315 | 314 | ||
316 | return 1; | 315 | return ret; |
317 | } | 316 | } |
318 | 317 | ||
319 | static int _mm_MemReader_Get(MREADER* reader) | 318 | static int _mm_MemReader_Get(MREADER* reader) |
320 | { | 319 | { |
321 | int pos; | 320 | MMEMREADER* mr; |
321 | int c; | ||
322 | 322 | ||
323 | if (reader->Eof(reader)) { return 0; } | 323 | mr = (MMEMREADER*) reader; |
324 | 324 | if (mr->pos >= mr->len) return EOF; | |
325 | pos = ((MMEMREADER*)reader)->pos; | 325 | c = ((const unsigned char*) mr->buffer)[mr->pos]; |
326 | ((MMEMREADER*)reader)->pos++; | 326 | mr->pos++; |
327 | 327 | ||
328 | return ((unsigned char*)(((MMEMREADER*)reader)->buffer))[pos]; | 328 | return c; |
329 | } | 329 | } |
330 | 330 | ||
331 | static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence) | 331 | static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence) |
332 | { | 332 | { |
333 | if (!reader) { return -1; } | 333 | MMEMREADER* mr; |
334 | 334 | ||
335 | if (!reader) return -1; | ||
336 | mr = (MMEMREADER*) reader; | ||
335 | switch(whence) | 337 | switch(whence) |
336 | { | 338 | { |
337 | case SEEK_CUR: | 339 | case SEEK_CUR: |
338 | ((MMEMREADER*)reader)->pos += offset; | 340 | mr->pos += offset; |
339 | break; | 341 | break; |
340 | case SEEK_SET: | 342 | case SEEK_SET: |
341 | ((MMEMREADER*)reader)->pos = offset; | 343 | mr->pos = reader->iobase + offset; |
342 | break; | 344 | break; |
343 | case SEEK_END: | 345 | case SEEK_END: |
344 | ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len - offset - 1; | 346 | mr->pos = mr->len + offset; |
345 | break; | 347 | break; |
348 | default: /* invalid */ | ||
349 | return -1; | ||
346 | } | 350 | } |
347 | if ( ((MMEMREADER*)reader)->pos < 0) { ((MMEMREADER*)reader)->pos = 0; } | 351 | if (mr->pos < reader->iobase) { |
348 | if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) { | 352 | mr->pos = mr->core.iobase; |
349 | ((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len; | 353 | return -1; |
354 | } | ||
355 | if (mr->pos > mr->len) { | ||
356 | mr->pos = mr->len; | ||
350 | } | 357 | } |
351 | return 0; | 358 | return 0; |
352 | } | 359 | } |
@@ -354,13 +361,14 @@ static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence) | |||
354 | static long _mm_MemReader_Tell(MREADER* reader) | 361 | static long _mm_MemReader_Tell(MREADER* reader) |
355 | { | 362 | { |
356 | if (reader) { | 363 | if (reader) { |
357 | return ((MMEMREADER*)reader)->pos; | 364 | return ((MMEMREADER*)reader)->pos - reader->iobase; |
358 | } | 365 | } |
359 | return 0; | 366 | return 0; |
360 | } | 367 | } |
361 | 368 | ||
362 | /*========== Write functions */ | 369 | /*========== Write functions */ |
363 | void _mm_write_string(CHAR* data,MWRITER* writer) | 370 | |
371 | void _mm_write_string(const CHAR* data,MWRITER* writer) | ||
364 | { | 372 | { |
365 | if(data) | 373 | if(data) |
366 | _mm_write_UBYTES(data,strlen(data),writer); | 374 | _mm_write_UBYTES(data,strlen(data),writer); |
@@ -410,37 +418,51 @@ void _mm_write_I_SLONG(SLONG data,MWRITER* writer) | |||
410 | _mm_write_I_ULONG((ULONG)data,writer); | 418 | _mm_write_I_ULONG((ULONG)data,writer); |
411 | } | 419 | } |
412 | 420 | ||
413 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 421 | void _mm_write_M_SWORDS(SWORD *buffer,int cnt,MWRITER* writer) |
414 | #define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ | 422 | { |
415 | void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \ | 423 | while(cnt-- > 0) _mm_write_M_SWORD(*(buffer++),writer); |
416 | { \ | ||
417 | while(number-->0) \ | ||
418 | _mm_write_##type_name(*(buffer++),writer); \ | ||
419 | } | 424 | } |
420 | #else | 425 | |
421 | #define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ | 426 | void _mm_write_M_UWORDS(UWORD *buffer,int cnt,MWRITER* writer) |
422 | void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \ | 427 | { |
423 | { \ | 428 | while(cnt-- > 0) _mm_write_M_UWORD(*(buffer++),writer); |
424 | while(number-->0) \ | ||
425 | _mm_write_/**/type_name(*(buffer++),writer); \ | ||
426 | } | 429 | } |
427 | #endif | ||
428 | 430 | ||
429 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD) | 431 | void _mm_write_I_SWORDS(SWORD *buffer,int cnt,MWRITER* writer) |
430 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD) | 432 | { |
431 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD) | 433 | while(cnt-- > 0) _mm_write_I_SWORD(*(buffer++),writer); |
432 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD) | 434 | } |
433 | 435 | ||
434 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG) | 436 | void _mm_write_I_UWORDS(UWORD *buffer,int cnt,MWRITER* writer) |
435 | DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG) | 437 | { |
436 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG) | 438 | while(cnt-- > 0) _mm_write_I_UWORD(*(buffer++),writer); |
437 | DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG) | 439 | } |
440 | |||
441 | void _mm_write_M_SLONGS(SLONG *buffer,int cnt,MWRITER* writer) | ||
442 | { | ||
443 | while(cnt-- > 0) _mm_write_M_SLONG(*(buffer++),writer); | ||
444 | } | ||
445 | |||
446 | void _mm_write_M_ULONGS(ULONG *buffer,int cnt,MWRITER* writer) | ||
447 | { | ||
448 | while(cnt-- > 0) _mm_write_M_ULONG(*(buffer++),writer); | ||
449 | } | ||
450 | |||
451 | void _mm_write_I_SLONGS(SLONG *buffer,int cnt,MWRITER* writer) | ||
452 | { | ||
453 | while(cnt-- > 0) _mm_write_I_SLONG(*(buffer++),writer); | ||
454 | } | ||
455 | |||
456 | void _mm_write_I_ULONGS(ULONG *buffer,int cnt,MWRITER* writer) | ||
457 | { | ||
458 | while(cnt-- > 0) _mm_write_I_ULONG(*(buffer++),writer); | ||
459 | } | ||
438 | 460 | ||
439 | /*========== Read functions */ | 461 | /*========== Read functions */ |
440 | 462 | ||
441 | int _mm_read_string(CHAR* buffer,int number,MREADER* reader) | 463 | int _mm_read_string(CHAR* buffer,int cnt,MREADER* reader) |
442 | { | 464 | { |
443 | return reader->Read(reader,buffer,number); | 465 | return reader->Read(reader,buffer,cnt); |
444 | } | 466 | } |
445 | 467 | ||
446 | UWORD _mm_read_M_UWORD(MREADER* reader) | 468 | UWORD _mm_read_M_UWORD(MREADER* reader) |
@@ -491,32 +513,52 @@ SLONG _mm_read_I_SLONG(MREADER* reader) | |||
491 | return((SLONG)_mm_read_I_ULONG(reader)); | 513 | return((SLONG)_mm_read_I_ULONG(reader)); |
492 | } | 514 | } |
493 | 515 | ||
494 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 516 | int _mm_read_M_SWORDS(SWORD *buffer,int cnt,MREADER* reader) |
495 | #define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ | 517 | { |
496 | int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \ | 518 | while(cnt-- > 0) *(buffer++)=_mm_read_M_SWORD(reader); |
497 | { \ | 519 | return !reader->Eof(reader); |
498 | while(number-->0) \ | ||
499 | *(buffer++)=_mm_read_##type_name(reader); \ | ||
500 | return !reader->Eof(reader); \ | ||
501 | } | 520 | } |
502 | #else | 521 | |
503 | #define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ | 522 | int _mm_read_M_UWORDS(UWORD *buffer,int cnt,MREADER* reader) |
504 | int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \ | 523 | { |
505 | { \ | 524 | while(cnt-- > 0) *(buffer++)=_mm_read_M_UWORD(reader); |
506 | while(number-->0) \ | 525 | return !reader->Eof(reader); |
507 | *(buffer++)=_mm_read_/**/type_name(reader); \ | ||
508 | return !reader->Eof(reader); \ | ||
509 | } | 526 | } |
510 | #endif | ||
511 | 527 | ||
512 | DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD) | 528 | int _mm_read_I_SWORDS(SWORD *buffer,int cnt,MREADER* reader) |
513 | DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD) | 529 | { |
514 | DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD) | 530 | while(cnt-- > 0) *(buffer++)=_mm_read_I_SWORD(reader); |
515 | DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD) | 531 | return !reader->Eof(reader); |
532 | } | ||
533 | |||
534 | int _mm_read_I_UWORDS(UWORD *buffer,int cnt,MREADER* reader) | ||
535 | { | ||
536 | while(cnt-- > 0) *(buffer++)=_mm_read_I_UWORD(reader); | ||
537 | return !reader->Eof(reader); | ||
538 | } | ||
539 | |||
540 | int _mm_read_M_SLONGS(SLONG *buffer,int cnt,MREADER* reader) | ||
541 | { | ||
542 | while(cnt-- > 0) *(buffer++)=_mm_read_M_SLONG(reader); | ||
543 | return !reader->Eof(reader); | ||
544 | } | ||
516 | 545 | ||
517 | DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG) | 546 | int _mm_read_M_ULONGS(ULONG *buffer,int cnt,MREADER* reader) |
518 | DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG) | 547 | { |
519 | DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG) | 548 | while(cnt-- > 0) *(buffer++)=_mm_read_M_ULONG(reader); |
520 | DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG) | 549 | return !reader->Eof(reader); |
550 | } | ||
551 | |||
552 | int _mm_read_I_SLONGS(SLONG *buffer,int cnt,MREADER* reader) | ||
553 | { | ||
554 | while(cnt-- > 0) *(buffer++)=_mm_read_I_SLONG(reader); | ||
555 | return !reader->Eof(reader); | ||
556 | } | ||
557 | |||
558 | int _mm_read_I_ULONGS(ULONG *buffer,int cnt,MREADER* reader) | ||
559 | { | ||
560 | while(cnt-- > 0) *(buffer++)=_mm_read_I_ULONG(reader); | ||
561 | return !reader->Eof(reader); | ||
562 | } | ||
521 | 563 | ||
522 | /* ex:set ts=4: */ | 564 | /* ex:set ts=4: */ |
diff --git a/apps/plugins/mikmod/mplayer.c b/apps/plugins/mikmod/mplayer.c index 88d6a81af4..ee5c2d187e 100644 --- a/apps/plugins/mikmod/mplayer.c +++ b/apps/plugins/mikmod/mplayer.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: mplayer.c,v 1.4 2006/08/08 00:06:31 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | The Protracker Player Driver | 25 | The Protracker Player Driver |
26 | 26 | ||
@@ -40,31 +40,35 @@ | |||
40 | #include <stdlib.h> | 40 | #include <stdlib.h> |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #include <limits.h> | ||
44 | |||
43 | #include "mikmod_internals.h" | 45 | #include "mikmod_internals.h" |
44 | 46 | ||
45 | #ifdef SUNOS | 47 | #ifdef SUNOS |
46 | extern int fprintf(FILE *, const char *, ...); | 48 | extern int fprintf(int, const char *, ...); |
47 | extern long int random(void); | 49 | extern long int random(void); |
48 | #endif | 50 | #endif |
49 | 51 | ||
50 | /* The currently playing module */ | 52 | /* The currently playing module */ |
51 | MODULE *pf = NULL; | 53 | MODULE *pf = NULL; |
52 | 54 | ||
55 | #define NUMVOICES(mod) (md_sngchn < (mod)->numvoices ? md_sngchn : (mod)->numvoices) | ||
56 | |||
53 | #define HIGH_OCTAVE 2 /* number of above-range octaves */ | 57 | #define HIGH_OCTAVE 2 /* number of above-range octaves */ |
54 | 58 | ||
55 | static UWORD oldperiods[OCTAVE*2]={ | 59 | static const UWORD oldperiods[OCTAVE*2]={ |
56 | 0x6b00, 0x6800, 0x6500, 0x6220, 0x5f50, 0x5c80, | 60 | 0x6b00, 0x6800, 0x6500, 0x6220, 0x5f50, 0x5c80, |
57 | 0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0, | 61 | 0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0, |
58 | 0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160, | 62 | 0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160, |
59 | 0x3f90, 0x3dc0, 0x3c10, 0x3a40, 0x38b0, 0x3700 | 63 | 0x3f90, 0x3dc0, 0x3c10, 0x3a40, 0x38b0, 0x3700 |
60 | }; | 64 | }; |
61 | 65 | ||
62 | static UBYTE VibratoTable[32]={ | 66 | static const UBYTE VibratoTable[32]={ |
63 | 0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253, | 67 | 0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253, |
64 | 255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24 | 68 | 255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24 |
65 | }; | 69 | }; |
66 | 70 | ||
67 | static UBYTE avibtab[128]={ | 71 | static const UBYTE avibtab[128]={ |
68 | 0, 1, 3, 4, 6, 7, 9,10,12,14,15,17,18,20,21,23, | 72 | 0, 1, 3, 4, 6, 7, 9,10,12,14,15,17,18,20,21,23, |
69 | 24,25,27,28,30,31,32,34,35,36,38,39,40,41,42,44, | 73 | 24,25,27,28,30,31,32,34,35,36,38,39,40,41,42,44, |
70 | 45,46,47,48,49,50,51,52,53,54,54,55,56,57,57,58, | 74 | 45,46,47,48,49,50,51,52,53,54,54,55,56,57,57,58, |
@@ -76,7 +80,7 @@ static UBYTE avibtab[128]={ | |||
76 | }; | 80 | }; |
77 | 81 | ||
78 | /* Triton's linear periods to frequency translation table (for XM modules) */ | 82 | /* Triton's linear periods to frequency translation table (for XM modules) */ |
79 | static ULONG lintab[768]={ | 83 | static const ULONG lintab[768]={ |
80 | 535232,534749,534266,533784,533303,532822,532341,531861, | 84 | 535232,534749,534266,533784,533303,532822,532341,531861, |
81 | 531381,530902,530423,529944,529466,528988,528511,528034, | 85 | 531381,530902,530423,529944,529466,528988,528511,528034, |
82 | 527558,527082,526607,526131,525657,525183,524709,524236, | 86 | 527558,527082,526607,526131,525657,525183,524709,524236, |
@@ -176,7 +180,7 @@ static ULONG lintab[768]={ | |||
176 | }; | 180 | }; |
177 | 181 | ||
178 | #define LOGFAC 2*16 | 182 | #define LOGFAC 2*16 |
179 | static UWORD logtab[104]={ | 183 | static const UWORD logtab[104]={ |
180 | LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887, | 184 | LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887, |
181 | LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862, | 185 | LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862, |
182 | LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838, | 186 | LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838, |
@@ -205,7 +209,7 @@ static UWORD logtab[104]={ | |||
205 | LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431 | 209 | LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431 |
206 | }; | 210 | }; |
207 | 211 | ||
208 | static SBYTE PanbrelloTable[256]={ | 212 | static const SBYTE PanbrelloTable[256]={ |
209 | 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, | 213 | 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, |
210 | 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, | 214 | 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, |
211 | 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, | 215 | 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, |
@@ -225,12 +229,12 @@ static SBYTE PanbrelloTable[256]={ | |||
225 | }; | 229 | }; |
226 | 230 | ||
227 | /* returns a random value between 0 and ceil-1, ceil must be a power of two */ | 231 | /* returns a random value between 0 and ceil-1, ceil must be a power of two */ |
228 | static int getrandom(int ceil) | 232 | static int getrandom(int ceilval) |
229 | { | 233 | { |
230 | #ifdef HAVE_SRANDOM | 234 | #if defined(HAVE_SRANDOM) && !defined(_MIKMOD_AMIGA) |
231 | return random()&(ceil-1); | 235 | return random()&(ceilval-1); |
232 | #else | 236 | #else |
233 | return (rand()*ceil)/(RAND_MAX+1.0); | 237 | return (rand()*ceilval)/(RAND_MAX+1.0); |
234 | #endif | 238 | #endif |
235 | } | 239 | } |
236 | 240 | ||
@@ -246,14 +250,14 @@ static int MP_FindEmptyChannel(MODULE *mod) | |||
246 | MP_VOICE *a; | 250 | MP_VOICE *a; |
247 | ULONG t,k,tvol,pp; | 251 | ULONG t,k,tvol,pp; |
248 | 252 | ||
249 | for (t=0;t<md_sngchn;t++) | 253 | for (t=0;t<NUMVOICES(mod);t++) |
250 | if (((mod->voice[t].main.kick==KICK_ABSENT)|| | 254 | if (((mod->voice[t].main.kick==KICK_ABSENT)|| |
251 | (mod->voice[t].main.kick==KICK_ENV))&& | 255 | (mod->voice[t].main.kick==KICK_ENV))&& |
252 | Voice_Stopped_internal(t)) | 256 | Voice_Stopped_internal(t)) |
253 | return t; | 257 | return t; |
254 | 258 | ||
255 | tvol=0xffffffUL;t=-1;a=mod->voice; | 259 | tvol=0xffffffUL;t=-1;a=mod->voice; |
256 | for (k=0;k<md_sngchn;k++,a++) { | 260 | for (k=0;k<NUMVOICES(mod);k++,a++) { |
257 | /* allow us to take over a nonexisting sample */ | 261 | /* allow us to take over a nonexisting sample */ |
258 | if (!a->main.s) | 262 | if (!a->main.s) |
259 | return k; | 263 | return k; |
@@ -325,9 +329,9 @@ static UWORD GetPeriod(UWORD flags, UWORD note, ULONG speed) | |||
325 | { | 329 | { |
326 | if (flags & UF_XMPERIODS) { | 330 | if (flags & UF_XMPERIODS) { |
327 | if (flags & UF_LINEAR) | 331 | if (flags & UF_LINEAR) |
328 | return getlinearperiod(note, speed); | 332 | return getlinearperiod(note, speed); |
329 | else | 333 | else |
330 | return getlogperiod(note, speed); | 334 | return getlogperiod(note, speed); |
331 | } else | 335 | } else |
332 | return getoldperiod(note, speed); | 336 | return getoldperiod(note, speed); |
333 | } | 337 | } |
@@ -359,9 +363,15 @@ static SWORD StartEnvelope(ENVPR *t,UBYTE flg,UBYTE pts,UBYTE susbeg,UBYTE susen | |||
359 | t->a=0; | 363 | t->a=0; |
360 | t->b=((t->flg&EF_SUSTAIN)&&(!(keyoff&KEY_OFF)))?0:1; | 364 | t->b=((t->flg&EF_SUSTAIN)&&(!(keyoff&KEY_OFF)))?0:1; |
361 | 365 | ||
366 | if (!t->pts) { /* FIXME: bad/crafted file. better/more general solution? */ | ||
367 | t->b=0; | ||
368 | return t->env[0].val; | ||
369 | } | ||
370 | |||
362 | /* Imago Orpheus sometimes stores an extra initial point in the envelope */ | 371 | /* Imago Orpheus sometimes stores an extra initial point in the envelope */ |
363 | if ((t->pts>=2)&&(t->env[0].pos==t->env[1].pos)) { | 372 | if ((t->pts>=2)&&(t->env[0].pos==t->env[1].pos)) { |
364 | t->a++;t->b++; | 373 | t->a++; |
374 | t->b++; | ||
365 | } | 375 | } |
366 | 376 | ||
367 | /* Fit in the envelope, still */ | 377 | /* Fit in the envelope, still */ |
@@ -615,10 +625,10 @@ static void DoToneSlide(UWORD tick, MP_CONTROL *a) | |||
615 | /* ...make tmpperiod equal tperiod */ | 625 | /* ...make tmpperiod equal tperiod */ |
616 | a->tmpperiod=a->main.period=a->wantedperiod; | 626 | a->tmpperiod=a->main.period=a->wantedperiod; |
617 | else if (dist>0) { | 627 | else if (dist>0) { |
618 | a->tmpperiod-=a->portspeed; | 628 | a->tmpperiod-=a->portspeed; |
619 | a->main.period-=a->portspeed; /* dist>0, slide up */ | 629 | a->main.period-=a->portspeed; /* dist>0, slide up */ |
620 | } else { | 630 | } else { |
621 | a->tmpperiod+=a->portspeed; | 631 | a->tmpperiod+=a->portspeed; |
622 | a->main.period+=a->portspeed; /* dist<0, slide down */ | 632 | a->main.period+=a->portspeed; /* dist<0, slide down */ |
623 | } | 633 | } |
624 | } else | 634 | } else |
@@ -786,8 +796,8 @@ static int DoPTEffect7(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
786 | static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 796 | static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
787 | { | 797 | { |
788 | UBYTE dat; | 798 | UBYTE dat; |
789 | (void)tick; | 799 | (void)tick; |
790 | (void)flags; | 800 | (void)flags; |
791 | 801 | ||
792 | dat = UniGetByte(); | 802 | dat = UniGetByte(); |
793 | if (mod->panflag) | 803 | if (mod->panflag) |
@@ -799,16 +809,16 @@ static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
799 | static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 809 | static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
800 | { | 810 | { |
801 | UBYTE dat; | 811 | UBYTE dat; |
802 | (void)flags; | 812 | (void)flags; |
803 | (void)mod; | 813 | (void)mod; |
804 | (void)channel; | 814 | (void)channel; |
805 | 815 | ||
806 | dat=UniGetByte(); | 816 | dat=UniGetByte(); |
807 | if (!tick) { | 817 | if (!tick) { |
808 | if (dat) a->soffset=(UWORD)dat<<8; | 818 | if (dat) a->soffset=(UWORD)dat<<8; |
809 | a->main.start=a->hioffset|a->soffset; | 819 | a->main.start=a->hioffset|a->soffset; |
810 | 820 | ||
811 | if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length)) | 821 | if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length)) |
812 | a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? | 822 | a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? |
813 | a->main.s->loopstart:a->main.s->length; | 823 | a->main.s->loopstart:a->main.s->length; |
814 | } | 824 | } |
@@ -819,9 +829,9 @@ static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
819 | static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 829 | static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
820 | { | 830 | { |
821 | UBYTE dat; | 831 | UBYTE dat; |
822 | (void)flags; | 832 | (void)flags; |
823 | (void)mod; | 833 | (void)mod; |
824 | (void)channel; | 834 | (void)channel; |
825 | 835 | ||
826 | dat=UniGetByte(); | 836 | dat=UniGetByte(); |
827 | if (tick) | 837 | if (tick) |
@@ -842,14 +852,19 @@ static int DoPTEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
842 | static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 852 | static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
843 | { | 853 | { |
844 | UBYTE dat; | 854 | UBYTE dat; |
845 | (void)a; | 855 | (void)a; |
846 | (void)channel; | 856 | (void)channel; |
847 | 857 | ||
848 | dat=UniGetByte(); | 858 | dat=UniGetByte(); |
849 | 859 | ||
850 | if (tick || mod->patdly2) | 860 | if (tick || mod->patdly2) |
851 | return 0; | 861 | return 0; |
852 | 862 | ||
863 | if (dat >= mod->numpos) { /* crafted file? */ | ||
864 | /* fprintf(stderr,"DoPTEffectB: numpos=%d, dat=%d -> %d\n",mod->numpos,dat,mod->numpos-1);*/ | ||
865 | dat=mod->numpos-1; | ||
866 | } | ||
867 | |||
853 | /* Vincent Voois uses a nasty trick in "Universal Bolero" */ | 868 | /* Vincent Voois uses a nasty trick in "Universal Bolero" */ |
854 | if (dat == mod->sngpos && mod->patbrk == mod->patpos) | 869 | if (dat == mod->sngpos && mod->patbrk == mod->patpos) |
855 | return 0; | 870 | return 0; |
@@ -857,8 +872,8 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
857 | if (!mod->loop && !mod->patbrk && | 872 | if (!mod->loop && !mod->patbrk && |
858 | (dat < mod->sngpos || | 873 | (dat < mod->sngpos || |
859 | (mod->sngpos == (mod->numpos - 1) && !mod->patbrk) || | 874 | (mod->sngpos == (mod->numpos - 1) && !mod->patbrk) || |
860 | (dat == mod->sngpos && (flags & UF_NOWRAP)) | 875 | (dat == mod->sngpos && (flags & UF_NOWRAP)) ) ) |
861 | )) { | 876 | { |
862 | /* if we don't loop, better not to skip the end of the | 877 | /* if we don't loop, better not to skip the end of the |
863 | pattern, after all... so: | 878 | pattern, after all... so: |
864 | mod->patbrk=0; */ | 879 | mod->patbrk=0; */ |
@@ -870,6 +885,9 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
870 | mod->sngpos=dat; | 885 | mod->sngpos=dat; |
871 | mod->posjmp=2; | 886 | mod->posjmp=2; |
872 | mod->patpos=0; | 887 | mod->patpos=0; |
888 | /* cancel the FT2 pattern loop (E60) bug. | ||
889 | * also see DoEEffects() below for it. */ | ||
890 | if (flags & UF_FT2QUIRKS) mod->patbrk=0; | ||
873 | } | 891 | } |
874 | 892 | ||
875 | return 0; | 893 | return 0; |
@@ -878,15 +896,15 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
878 | static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 896 | static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
879 | { | 897 | { |
880 | UBYTE dat; | 898 | UBYTE dat; |
881 | (void)flags; | 899 | (void)flags; |
882 | (void)mod; | 900 | (void)mod; |
883 | (void)channel; | 901 | (void)channel; |
884 | 902 | ||
885 | dat=UniGetByte(); | 903 | dat=UniGetByte(); |
886 | if (tick) return 0; | 904 | if (tick) return 0; |
887 | if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */ | 905 | if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */ |
888 | else if (dat>64) dat=64; | 906 | else if (dat>64) dat=64; |
889 | a->tmpvolume=dat; | 907 | a->tmpvolume=dat; |
890 | 908 | ||
891 | return 0; | 909 | return 0; |
892 | } | 910 | } |
@@ -894,29 +912,33 @@ static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
894 | static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 912 | static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
895 | { | 913 | { |
896 | UBYTE dat; | 914 | UBYTE dat; |
897 | (void)a; | 915 | (void)a; |
898 | (void)channel; | 916 | (void)channel; |
899 | 917 | ||
900 | dat=UniGetByte(); | 918 | dat=UniGetByte(); |
901 | if ((tick)||(mod->patdly2)) return 0; | 919 | if ((tick)||(mod->patdly2)) return 0; |
902 | if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&& | 920 | if (dat && dat >= mod->numrow) { /* crafted file? */ |
903 | (dat>mod->pattrows[mod->positions[mod->sngpos]])) | 921 | /* fprintf(stderr,"DoPTEffectD: numrow=%d, dat=%d -> 0\n",mod->numrow,dat);*/ |
904 | dat=mod->pattrows[mod->positions[mod->sngpos]]; | 922 | dat=0; |
905 | mod->patbrk=dat; | 923 | } |
906 | if (!mod->posjmp) { | 924 | if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&& |
907 | /* don't ask me to explain this code - it makes | 925 | (dat>mod->pattrows[mod->positions[mod->sngpos]])) { |
908 | backwards.s3m and children.xm (heretic's version) play | 926 | dat=mod->pattrows[mod->positions[mod->sngpos]]; |
909 | correctly, among others. Take that for granted, or write | 927 | } |
910 | the page of comments yourself... you might need some | 928 | mod->patbrk=dat; |
911 | aspirin - Miod */ | 929 | if (!mod->posjmp) { |
912 | if ((mod->sngpos==mod->numpos-1)&&(dat)&&((mod->loop)|| | 930 | /* don't ask me to explain this code - it makes |
913 | (mod->positions[mod->sngpos]==(mod->numpat-1) | 931 | backwards.s3m and children.xm (heretic's version) play |
914 | && !(flags&UF_NOWRAP)))) { | 932 | correctly, among others. Take that for granted, or write |
915 | mod->sngpos=0; | 933 | the page of comments yourself... you might need some |
916 | mod->posjmp=2; | 934 | aspirin - Miod */ |
917 | } else | 935 | if ((mod->sngpos==mod->numpos-1)&&(dat)&& |
918 | mod->posjmp=3; | 936 | ((mod->loop) || (mod->positions[mod->sngpos]==(mod->numpat-1) && !(flags&UF_NOWRAP)))) { |
919 | } | 937 | mod->sngpos=0; |
938 | mod->posjmp=2; | ||
939 | } else | ||
940 | mod->posjmp=3; | ||
941 | } | ||
920 | 942 | ||
921 | return 0; | 943 | return 0; |
922 | } | 944 | } |
@@ -982,8 +1004,13 @@ static void DoEEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, | |||
982 | } else | 1004 | } else |
983 | mod->patpos=a->pat_reppos; | 1005 | mod->patpos=a->pat_reppos; |
984 | } else a->pat_reppos=POS_NONE; | 1006 | } else a->pat_reppos=POS_NONE; |
985 | } else | 1007 | } else { |
986 | a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */ | 1008 | a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */ |
1009 | /* emulate the FT2 pattern loop (E60) bug: | ||
1010 | * http://milkytracker.org/docs/MilkyTracker.html#fxE6x | ||
1011 | * roadblas.xm plays correctly with this. */ | ||
1012 | if (flags & UF_FT2QUIRKS) mod->patbrk=mod->patpos; | ||
1013 | } | ||
987 | break; | 1014 | break; |
988 | case 0x7: /* set tremolo waveform */ | 1015 | case 0x7: /* set tremolo waveform */ |
989 | a->wavecontrol&=0x0f; | 1016 | a->wavecontrol&=0x0f; |
@@ -1065,7 +1092,7 @@ static int DoPTEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
1065 | if (tick||mod->patdly2) return 0; | 1092 | if (tick||mod->patdly2) return 0; |
1066 | if (mod->extspd&&(dat>=mod->bpmlimit)) | 1093 | if (mod->extspd&&(dat>=mod->bpmlimit)) |
1067 | mod->bpm=dat; | 1094 | mod->bpm=dat; |
1068 | else | 1095 | else |
1069 | if (dat) { | 1096 | if (dat) { |
1070 | mod->sngspd=(dat>=mod->bpmlimit)?mod->bpmlimit-1:dat; | 1097 | mod->sngspd=(dat>=mod->bpmlimit)?mod->bpmlimit-1:dat; |
1071 | mod->vbtick=0; | 1098 | mod->vbtick=0; |
@@ -1465,7 +1492,7 @@ static int DoXMEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
1465 | a->s3mvolslide = inf; | 1492 | a->s3mvolslide = inf; |
1466 | else | 1493 | else |
1467 | inf = a->s3mvolslide; | 1494 | inf = a->s3mvolslide; |
1468 | 1495 | ||
1469 | if (tick) { | 1496 | if (tick) { |
1470 | lo=inf&0xf; | 1497 | lo=inf&0xf; |
1471 | hi=inf>>4; | 1498 | hi=inf>>4; |
@@ -1608,7 +1635,7 @@ static int DoXMEffectL(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
1608 | INSTRUMENT *i=a->main.i; | 1635 | INSTRUMENT *i=a->main.i; |
1609 | MP_VOICE *aout; | 1636 | MP_VOICE *aout; |
1610 | 1637 | ||
1611 | if ((aout=a->slave)) { | 1638 | if ((aout=a->slave) != NULL) { |
1612 | if (aout->venv.env) { | 1639 | if (aout->venv.env) { |
1613 | points=i->volenv[i->volpts-1].pos; | 1640 | points=i->volenv[i->volpts-1].pos; |
1614 | aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos; | 1641 | aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos; |
@@ -1710,7 +1737,7 @@ static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat) | |||
1710 | /* if we don't come from another note, ignore the slide and play the note | 1737 | /* if we don't come from another note, ignore the slide and play the note |
1711 | as is */ | 1738 | as is */ |
1712 | if (!a->oldnote || !a->main.period) | 1739 | if (!a->oldnote || !a->main.period) |
1713 | return; | 1740 | return; |
1714 | 1741 | ||
1715 | if ((!tick)&&(a->newsamp)){ | 1742 | if ((!tick)&&(a->newsamp)){ |
1716 | a->main.kick=KICK_NOTE; | 1743 | a->main.kick=KICK_NOTE; |
@@ -1725,15 +1752,15 @@ static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat) | |||
1725 | difference between those two values */ | 1752 | difference between those two values */ |
1726 | dist=a->main.period-a->wantedperiod; | 1753 | dist=a->main.period-a->wantedperiod; |
1727 | 1754 | ||
1728 | /* if they are equal or if portamentospeed is too big... */ | 1755 | /* if they are equal or if portamentospeed is too big... */ |
1729 | if ((!dist)||((a->portspeed<<2)>abs(dist))) | 1756 | if ((!dist)||((a->portspeed<<2)>abs(dist))) |
1730 | /* ... make tmpperiod equal tperiod */ | 1757 | /* ... make tmpperiod equal tperiod */ |
1731 | a->tmpperiod=a->main.period=a->wantedperiod; | 1758 | a->tmpperiod=a->main.period=a->wantedperiod; |
1732 | else | 1759 | else |
1733 | if (dist>0) { | 1760 | if (dist>0) { |
1734 | a->tmpperiod-=a->portspeed<<2; | 1761 | a->tmpperiod-=a->portspeed<<2; |
1735 | a->main.period-=a->portspeed<<2; /* dist>0 slide up */ | 1762 | a->main.period-=a->portspeed<<2; /* dist>0 slide up */ |
1736 | } else { | 1763 | } else { |
1737 | a->tmpperiod+=a->portspeed<<2; | 1764 | a->tmpperiod+=a->portspeed<<2; |
1738 | a->main.period+=a->portspeed<<2; /* dist<0 slide down */ | 1765 | a->main.period+=a->portspeed<<2; /* dist<0 slide down */ |
1739 | } | 1766 | } |
@@ -1762,7 +1789,7 @@ static void DoITVibrato(UWORD tick, MP_CONTROL *a, UBYTE dat) | |||
1762 | if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; | 1789 | if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; |
1763 | } | 1790 | } |
1764 | if (!a->main.period) | 1791 | if (!a->main.period) |
1765 | return; | 1792 | return; |
1766 | 1793 | ||
1767 | q=(a->vibpos>>2)&0x1f; | 1794 | q=(a->vibpos>>2)&0x1f; |
1768 | 1795 | ||
@@ -1867,7 +1894,7 @@ static int DoITEffectN(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR | |||
1867 | lo=inf&0xf; | 1894 | lo=inf&0xf; |
1868 | hi=inf>>4; | 1895 | hi=inf>>4; |
1869 | 1896 | ||
1870 | if (!hi) | 1897 | if (!hi) |
1871 | a->main.chanvol-=lo; | 1898 | a->main.chanvol-=lo; |
1872 | else | 1899 | else |
1873 | if (!lo) { | 1900 | if (!lo) { |
@@ -2105,13 +2132,13 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO | |||
2105 | switch (c) { | 2132 | switch (c) { |
2106 | case SS_GLISSANDO: /* S1x set glissando voice */ | 2133 | case SS_GLISSANDO: /* S1x set glissando voice */ |
2107 | DoEEffects(tick, flags, a, mod, channel, 0x30|inf); | 2134 | DoEEffects(tick, flags, a, mod, channel, 0x30|inf); |
2108 | break; | 2135 | break; |
2109 | case SS_FINETUNE: /* S2x set finetune */ | 2136 | case SS_FINETUNE: /* S2x set finetune */ |
2110 | DoEEffects(tick, flags, a, mod, channel, 0x50|inf); | 2137 | DoEEffects(tick, flags, a, mod, channel, 0x50|inf); |
2111 | break; | 2138 | break; |
2112 | case SS_VIBWAVE: /* S3x set vibrato waveform */ | 2139 | case SS_VIBWAVE: /* S3x set vibrato waveform */ |
2113 | DoEEffects(tick, flags, a, mod, channel, 0x40|inf); | 2140 | DoEEffects(tick, flags, a, mod, channel, 0x40|inf); |
2114 | break; | 2141 | break; |
2115 | case SS_TREMWAVE: /* S4x set tremolo waveform */ | 2142 | case SS_TREMWAVE: /* S4x set tremolo waveform */ |
2116 | DoEEffects(tick, flags, a, mod, channel, 0x70|inf); | 2143 | DoEEffects(tick, flags, a, mod, channel, 0x70|inf); |
2117 | break; | 2144 | break; |
@@ -2130,13 +2157,13 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO | |||
2130 | case SS_SURROUND: /* S9x set surround sound */ | 2157 | case SS_SURROUND: /* S9x set surround sound */ |
2131 | if (mod->panflag) | 2158 | if (mod->panflag) |
2132 | a->main.panning = mod->panning[channel] = PAN_SURROUND; | 2159 | a->main.panning = mod->panning[channel] = PAN_SURROUND; |
2133 | break; | 2160 | break; |
2134 | case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */ | 2161 | case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */ |
2135 | if (!tick) { | 2162 | if (!tick) { |
2136 | a->hioffset=inf<<16; | 2163 | a->hioffset=inf<<16; |
2137 | a->main.start=a->hioffset|a->soffset; | 2164 | a->main.start=a->hioffset|a->soffset; |
2138 | 2165 | ||
2139 | if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length)) | 2166 | if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length)) |
2140 | a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? | 2167 | a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? |
2141 | a->main.s->loopstart:a->main.s->length; | 2168 | a->main.s->loopstart:a->main.s->length; |
2142 | } | 2169 | } |
@@ -2168,10 +2195,10 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO | |||
2168 | static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 2195 | static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
2169 | { | 2196 | { |
2170 | UBYTE c, inf; | 2197 | UBYTE c, inf; |
2171 | (void)channel; | 2198 | (void)channel; |
2172 | 2199 | ||
2173 | c = UniGetByte(); | 2200 | c = UniGetByte(); |
2174 | inf = UniGetByte(); | 2201 | inf = UniGetByte(); |
2175 | 2202 | ||
2176 | if ((!c)&&(!inf)) { | 2203 | if ((!c)&&(!inf)) { |
2177 | c=a->voleffect; | 2204 | c=a->voleffect; |
@@ -2219,16 +2246,16 @@ static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO | |||
2219 | static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) | 2246 | static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) |
2220 | { | 2247 | { |
2221 | UWORD offset=UniGetWord(); | 2248 | UWORD offset=UniGetWord(); |
2222 | (void)tick; | 2249 | (void)tick; |
2223 | (void)flags; | 2250 | (void)flags; |
2224 | (void)mod; | 2251 | (void)mod; |
2225 | (void)channel; | 2252 | (void)channel; |
2226 | 2253 | ||
2227 | if (offset) | 2254 | if (offset) |
2228 | a->ultoffset=offset; | 2255 | a->ultoffset=offset; |
2229 | 2256 | ||
2230 | a->main.start=a->ultoffset<<2; | 2257 | a->main.start=a->ultoffset<<2; |
2231 | if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length)) | 2258 | if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length)) |
2232 | a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? | 2259 | a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? |
2233 | a->main.s->loopstart:a->main.s->length; | 2260 | a->main.s->loopstart:a->main.s->length; |
2234 | 2261 | ||
@@ -2310,68 +2337,68 @@ static int DoNothing(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD | |||
2310 | typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD); | 2337 | typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD); |
2311 | 2338 | ||
2312 | static effect_func effects[UNI_LAST] = { | 2339 | static effect_func effects[UNI_LAST] = { |
2313 | DoNothing, /* 0 */ | 2340 | DoNothing, /* 0 */ |
2314 | DoNothing, /* UNI_NOTE */ | 2341 | DoNothing, /* UNI_NOTE */ |
2315 | DoNothing, /* UNI_INSTRUMENT */ | 2342 | DoNothing, /* UNI_INSTRUMENT */ |
2316 | DoPTEffect0, /* UNI_PTEFFECT0 */ | 2343 | DoPTEffect0, /* UNI_PTEFFECT0 */ |
2317 | DoPTEffect1, /* UNI_PTEFFECT1 */ | 2344 | DoPTEffect1, /* UNI_PTEFFECT1 */ |
2318 | DoPTEffect2, /* UNI_PTEFFECT2 */ | 2345 | DoPTEffect2, /* UNI_PTEFFECT2 */ |
2319 | DoPTEffect3, /* UNI_PTEFFECT3 */ | 2346 | DoPTEffect3, /* UNI_PTEFFECT3 */ |
2320 | DoPTEffect4, /* UNI_PTEFFECT4 */ | 2347 | DoPTEffect4, /* UNI_PTEFFECT4 */ |
2321 | DoPTEffect5, /* UNI_PTEFFECT5 */ | 2348 | DoPTEffect5, /* UNI_PTEFFECT5 */ |
2322 | DoPTEffect6, /* UNI_PTEFFECT6 */ | 2349 | DoPTEffect6, /* UNI_PTEFFECT6 */ |
2323 | DoPTEffect7, /* UNI_PTEFFECT7 */ | 2350 | DoPTEffect7, /* UNI_PTEFFECT7 */ |
2324 | DoPTEffect8, /* UNI_PTEFFECT8 */ | 2351 | DoPTEffect8, /* UNI_PTEFFECT8 */ |
2325 | DoPTEffect9, /* UNI_PTEFFECT9 */ | 2352 | DoPTEffect9, /* UNI_PTEFFECT9 */ |
2326 | DoPTEffectA, /* UNI_PTEFFECTA */ | 2353 | DoPTEffectA, /* UNI_PTEFFECTA */ |
2327 | DoPTEffectB, /* UNI_PTEFFECTB */ | 2354 | DoPTEffectB, /* UNI_PTEFFECTB */ |
2328 | DoPTEffectC, /* UNI_PTEFFECTC */ | 2355 | DoPTEffectC, /* UNI_PTEFFECTC */ |
2329 | DoPTEffectD, /* UNI_PTEFFECTD */ | 2356 | DoPTEffectD, /* UNI_PTEFFECTD */ |
2330 | DoPTEffectE, /* UNI_PTEFFECTE */ | 2357 | DoPTEffectE, /* UNI_PTEFFECTE */ |
2331 | DoPTEffectF, /* UNI_PTEFFECTF */ | 2358 | DoPTEffectF, /* UNI_PTEFFECTF */ |
2332 | DoS3MEffectA, /* UNI_S3MEFFECTA */ | 2359 | DoS3MEffectA, /* UNI_S3MEFFECTA */ |
2333 | DoS3MEffectD, /* UNI_S3MEFFECTD */ | 2360 | DoS3MEffectD, /* UNI_S3MEFFECTD */ |
2334 | DoS3MEffectE, /* UNI_S3MEFFECTE */ | 2361 | DoS3MEffectE, /* UNI_S3MEFFECTE */ |
2335 | DoS3MEffectF, /* UNI_S3MEFFECTF */ | 2362 | DoS3MEffectF, /* UNI_S3MEFFECTF */ |
2336 | DoS3MEffectI, /* UNI_S3MEFFECTI */ | 2363 | DoS3MEffectI, /* UNI_S3MEFFECTI */ |
2337 | DoS3MEffectQ, /* UNI_S3MEFFECTQ */ | 2364 | DoS3MEffectQ, /* UNI_S3MEFFECTQ */ |
2338 | DoS3MEffectR, /* UNI_S3MEFFECTR */ | 2365 | DoS3MEffectR, /* UNI_S3MEFFECTR */ |
2339 | DoS3MEffectT, /* UNI_S3MEFFECTT */ | 2366 | DoS3MEffectT, /* UNI_S3MEFFECTT */ |
2340 | DoS3MEffectU, /* UNI_S3MEFFECTU */ | 2367 | DoS3MEffectU, /* UNI_S3MEFFECTU */ |
2341 | DoKeyOff, /* UNI_KEYOFF */ | 2368 | DoKeyOff, /* UNI_KEYOFF */ |
2342 | DoKeyFade, /* UNI_KEYFADE */ | 2369 | DoKeyFade, /* UNI_KEYFADE */ |
2343 | DoVolEffects, /* UNI_VOLEFFECTS */ | 2370 | DoVolEffects, /* UNI_VOLEFFECTS */ |
2344 | DoPTEffect4, /* UNI_XMEFFECT4 */ | 2371 | DoPTEffect4, /* UNI_XMEFFECT4 */ |
2345 | DoXMEffect6, /* UNI_XMEFFECT6 */ | 2372 | DoXMEffect6, /* UNI_XMEFFECT6 */ |
2346 | DoXMEffectA, /* UNI_XMEFFECTA */ | 2373 | DoXMEffectA, /* UNI_XMEFFECTA */ |
2347 | DoXMEffectE1, /* UNI_XMEFFECTE1 */ | 2374 | DoXMEffectE1, /* UNI_XMEFFECTE1 */ |
2348 | DoXMEffectE2, /* UNI_XMEFFECTE2 */ | 2375 | DoXMEffectE2, /* UNI_XMEFFECTE2 */ |
2349 | DoXMEffectEA, /* UNI_XMEFFECTEA */ | 2376 | DoXMEffectEA, /* UNI_XMEFFECTEA */ |
2350 | DoXMEffectEB, /* UNI_XMEFFECTEB */ | 2377 | DoXMEffectEB, /* UNI_XMEFFECTEB */ |
2351 | DoXMEffectG, /* UNI_XMEFFECTG */ | 2378 | DoXMEffectG, /* UNI_XMEFFECTG */ |
2352 | DoXMEffectH, /* UNI_XMEFFECTH */ | 2379 | DoXMEffectH, /* UNI_XMEFFECTH */ |
2353 | DoXMEffectL, /* UNI_XMEFFECTL */ | 2380 | DoXMEffectL, /* UNI_XMEFFECTL */ |
2354 | DoXMEffectP, /* UNI_XMEFFECTP */ | 2381 | DoXMEffectP, /* UNI_XMEFFECTP */ |
2355 | DoXMEffectX1, /* UNI_XMEFFECTX1 */ | 2382 | DoXMEffectX1, /* UNI_XMEFFECTX1 */ |
2356 | DoXMEffectX2, /* UNI_XMEFFECTX2 */ | 2383 | DoXMEffectX2, /* UNI_XMEFFECTX2 */ |
2357 | DoITEffectG, /* UNI_ITEFFECTG */ | 2384 | DoITEffectG, /* UNI_ITEFFECTG */ |
2358 | DoITEffectH, /* UNI_ITEFFECTH */ | 2385 | DoITEffectH, /* UNI_ITEFFECTH */ |
2359 | DoITEffectI, /* UNI_ITEFFECTI */ | 2386 | DoITEffectI, /* UNI_ITEFFECTI */ |
2360 | DoITEffectM, /* UNI_ITEFFECTM */ | 2387 | DoITEffectM, /* UNI_ITEFFECTM */ |
2361 | DoITEffectN, /* UNI_ITEFFECTN */ | 2388 | DoITEffectN, /* UNI_ITEFFECTN */ |
2362 | DoITEffectP, /* UNI_ITEFFECTP */ | 2389 | DoITEffectP, /* UNI_ITEFFECTP */ |
2363 | DoITEffectT, /* UNI_ITEFFECTT */ | 2390 | DoITEffectT, /* UNI_ITEFFECTT */ |
2364 | DoITEffectU, /* UNI_ITEFFECTU */ | 2391 | DoITEffectU, /* UNI_ITEFFECTU */ |
2365 | DoITEffectW, /* UNI_ITEFFECTW */ | 2392 | DoITEffectW, /* UNI_ITEFFECTW */ |
2366 | DoITEffectY, /* UNI_ITEFFECTY */ | 2393 | DoITEffectY, /* UNI_ITEFFECTY */ |
2367 | DoNothing, /* UNI_ITEFFECTZ */ | 2394 | DoNothing, /* UNI_ITEFFECTZ */ |
2368 | DoITEffectS0, /* UNI_ITEFFECTS0 */ | 2395 | DoITEffectS0, /* UNI_ITEFFECTS0 */ |
2369 | DoULTEffect9, /* UNI_ULTEFFECT9 */ | 2396 | DoULTEffect9, /* UNI_ULTEFFECT9 */ |
2370 | DoMEDSpeed, /* UNI_MEDSPEED */ | 2397 | DoMEDSpeed, /* UNI_MEDSPEED */ |
2371 | DoMEDEffectF1, /* UNI_MEDEFFECTF1 */ | 2398 | DoMEDEffectF1, /* UNI_MEDEFFECTF1 */ |
2372 | DoMEDEffectF2, /* UNI_MEDEFFECTF2 */ | 2399 | DoMEDEffectF2, /* UNI_MEDEFFECTF2 */ |
2373 | DoMEDEffectF3, /* UNI_MEDEFFECTF3 */ | 2400 | DoMEDEffectF3, /* UNI_MEDEFFECTF3 */ |
2374 | DoOktArp, /* UNI_OKTARP */ | 2401 | DoOktArp, /* UNI_OKTARP */ |
2375 | }; | 2402 | }; |
2376 | 2403 | ||
2377 | static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a) | 2404 | static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a) |
@@ -2382,10 +2409,14 @@ static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a) | |||
2382 | int explicitslides = 0; | 2409 | int explicitslides = 0; |
2383 | effect_func f; | 2410 | effect_func f; |
2384 | 2411 | ||
2385 | while((c=UniGetByte())) { | 2412 | while((c=UniGetByte()) != 0) { |
2413 | #if 0 /* this doesn't normally happen unless things go fubar elsewhere */ | ||
2414 | if (c >= UNI_LAST) | ||
2415 | fprintf(stderr,"fubar'ed opcode %u\n",c); | ||
2416 | #endif | ||
2386 | f = effects[c]; | 2417 | f = effects[c]; |
2387 | if (f != DoNothing) | 2418 | if (f != DoNothing) |
2388 | a->sliding = 0; | 2419 | a->sliding = 0; |
2389 | explicitslides |= f(tick, flags, a, mod, channel); | 2420 | explicitslides |= f(tick, flags, a, mod, channel); |
2390 | } | 2421 | } |
2391 | return explicitslides; | 2422 | return explicitslides; |
@@ -2396,17 +2427,17 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat) | |||
2396 | int t; | 2427 | int t; |
2397 | MP_VOICE *aout; | 2428 | MP_VOICE *aout; |
2398 | 2429 | ||
2399 | dat&=0xf; | 2430 | dat&=0xf; |
2400 | aout=(a->slave)?a->slave:NULL; | 2431 | aout=(a->slave)?a->slave:NULL; |
2401 | 2432 | ||
2402 | switch (dat) { | 2433 | switch (dat) { |
2403 | case 0x0: /* past note cut */ | 2434 | case 0x0: /* past note cut */ |
2404 | for (t=0;t<md_sngchn;t++) | 2435 | for (t=0;t<NUMVOICES(mod);t++) |
2405 | if (mod->voice[t].master==a) | 2436 | if (mod->voice[t].master==a) |
2406 | mod->voice[t].main.fadevol=0; | 2437 | mod->voice[t].main.fadevol=0; |
2407 | break; | 2438 | break; |
2408 | case 0x1: /* past note off */ | 2439 | case 0x1: /* past note off */ |
2409 | for (t=0;t<md_sngchn;t++) | 2440 | for (t=0;t<NUMVOICES(mod);t++) |
2410 | if (mod->voice[t].master==a) { | 2441 | if (mod->voice[t].master==a) { |
2411 | mod->voice[t].main.keyoff|=KEY_OFF; | 2442 | mod->voice[t].main.keyoff|=KEY_OFF; |
2412 | if ((!(mod->voice[t].venv.flg & EF_ON))|| | 2443 | if ((!(mod->voice[t].venv.flg & EF_ON))|| |
@@ -2415,7 +2446,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat) | |||
2415 | } | 2446 | } |
2416 | break; | 2447 | break; |
2417 | case 0x2: /* past note fade */ | 2448 | case 0x2: /* past note fade */ |
2418 | for (t=0;t<md_sngchn;t++) | 2449 | for (t=0;t<NUMVOICES(mod);t++) |
2419 | if (mod->voice[t].master==a) | 2450 | if (mod->voice[t].master==a) |
2420 | mod->voice[t].main.keyoff|=KEY_FADE; | 2451 | mod->voice[t].main.keyoff|=KEY_FADE; |
2421 | break; | 2452 | break; |
@@ -2427,7 +2458,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat) | |||
2427 | break; | 2458 | break; |
2428 | case 0x5: /* set NNA note off */ | 2459 | case 0x5: /* set NNA note off */ |
2429 | a->main.nna=(a->main.nna&~NNA_MASK)|NNA_OFF; | 2460 | a->main.nna=(a->main.nna&~NNA_MASK)|NNA_OFF; |
2430 | break; | 2461 | break; |
2431 | case 0x6: /* set NNA note fade */ | 2462 | case 0x6: /* set NNA note fade */ |
2432 | a->main.nna=(a->main.nna&~NNA_MASK)|NNA_FADE; | 2463 | a->main.nna=(a->main.nna&~NNA_MASK)|NNA_FADE; |
2433 | break; | 2464 | break; |
@@ -2442,7 +2473,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat) | |||
2442 | case 0x9: /* disable panning envelope */ | 2473 | case 0x9: /* disable panning envelope */ |
2443 | if (aout) | 2474 | if (aout) |
2444 | aout->main.panflg&=~EF_ON; | 2475 | aout->main.panflg&=~EF_ON; |
2445 | break; | 2476 | break; |
2446 | case 0xa: /* enable panning envelope */ | 2477 | case 0xa: /* enable panning envelope */ |
2447 | if (aout) | 2478 | if (aout) |
2448 | aout->main.panflg|=EF_ON; | 2479 | aout->main.panflg|=EF_ON; |
@@ -2470,7 +2501,7 @@ static void pt_UpdateVoices(MODULE *mod, int max_volume) | |||
2470 | SAMPLE *s; | 2501 | SAMPLE *s; |
2471 | 2502 | ||
2472 | mod->totalchn=mod->realchn=0; | 2503 | mod->totalchn=mod->realchn=0; |
2473 | for (channel=0;channel<md_sngchn;channel++) { | 2504 | for (channel=0;channel<NUMVOICES(mod);channel++) { |
2474 | aout=&mod->voice[channel]; | 2505 | aout=&mod->voice[channel]; |
2475 | i=aout->main.i; | 2506 | i=aout->main.i; |
2476 | s=aout->main.s; | 2507 | s=aout->main.s; |
@@ -2484,7 +2515,7 @@ static void pt_UpdateVoices(MODULE *mod, int max_volume) | |||
2484 | 2515 | ||
2485 | if ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_KEYOFF)) { | 2516 | if ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_KEYOFF)) { |
2486 | Voice_Play_internal(channel,s,(aout->main.start==-1)? | 2517 | Voice_Play_internal(channel,s,(aout->main.start==-1)? |
2487 | ((s->flags&SF_UST_LOOP) ? (SLONG)s->loopstart : 0) : aout->main.start); | 2518 | ((s->flags&SF_UST_LOOP)?(SLONG)s->loopstart:0):aout->main.start); |
2488 | aout->main.fadevol=32768; | 2519 | aout->main.fadevol=32768; |
2489 | aout->aswppos=0; | 2520 | aout->aswppos=0; |
2490 | } | 2521 | } |
@@ -2687,7 +2718,7 @@ static void pt_Notes(MODULE *mod) | |||
2687 | UniSetRow(a->row); | 2718 | UniSetRow(a->row); |
2688 | funky=0; | 2719 | funky=0; |
2689 | 2720 | ||
2690 | while((c=UniGetByte())) | 2721 | while((c=UniGetByte()) != 0) |
2691 | switch (c) { | 2722 | switch (c) { |
2692 | case UNI_NOTE: | 2723 | case UNI_NOTE: |
2693 | funky|=1; | 2724 | funky|=1; |
@@ -2720,7 +2751,7 @@ static void pt_Notes(MODULE *mod) | |||
2720 | INSTRUMENT *i; | 2751 | INSTRUMENT *i; |
2721 | SAMPLE *s; | 2752 | SAMPLE *s; |
2722 | 2753 | ||
2723 | if ((i=a->main.i)) { | 2754 | if ((i=a->main.i) != NULL) { |
2724 | if (i->samplenumber[a->anote] >= mod->numsmp) continue; | 2755 | if (i->samplenumber[a->anote] >= mod->numsmp) continue; |
2725 | s=&mod->samples[i->samplenumber[a->anote]]; | 2756 | s=&mod->samples[i->samplenumber[a->anote]]; |
2726 | a->main.note=i->samplenote[a->anote]; | 2757 | a->main.note=i->samplenote[a->anote]; |
@@ -2809,7 +2840,7 @@ static void pt_EffectsPass1(MODULE *mod) | |||
2809 | for (channel=0;channel<mod->numchn;channel++) { | 2840 | for (channel=0;channel<mod->numchn;channel++) { |
2810 | a=&mod->control[channel]; | 2841 | a=&mod->control[channel]; |
2811 | 2842 | ||
2812 | if ((aout=a->slave)) { | 2843 | if ((aout=a->slave) != NULL) { |
2813 | a->main.fadevol=aout->main.fadevol; | 2844 | a->main.fadevol=aout->main.fadevol; |
2814 | a->main.period=aout->main.period; | 2845 | a->main.period=aout->main.period; |
2815 | if (a->main.kick==KICK_KEYOFF) | 2846 | if (a->main.kick==KICK_KEYOFF) |
@@ -2891,7 +2922,7 @@ static void pt_NNA(MODULE *mod) | |||
2891 | if (a->dct!=DCT_OFF) { | 2922 | if (a->dct!=DCT_OFF) { |
2892 | int t; | 2923 | int t; |
2893 | 2924 | ||
2894 | for (t=0;t<md_sngchn;t++) | 2925 | for (t=0;t<NUMVOICES(mod);t++) |
2895 | if ((!Voice_Stopped_internal(t))&& | 2926 | if ((!Voice_Stopped_internal(t))&& |
2896 | (mod->voice[t].masterchn==channel)&& | 2927 | (mod->voice[t].masterchn==channel)&& |
2897 | (a->main.sample==mod->voice[t].main.sample)) { | 2928 | (a->main.sample==mod->voice[t].main.sample)) { |
@@ -2951,11 +2982,11 @@ static void pt_SetupVoices(MODULE *mod) | |||
2951 | if ((newchn=MP_FindEmptyChannel(mod))!=-1) | 2982 | if ((newchn=MP_FindEmptyChannel(mod))!=-1) |
2952 | a->slave=&mod->voice[a->slavechn=newchn]; | 2983 | a->slave=&mod->voice[a->slavechn=newchn]; |
2953 | } | 2984 | } |
2954 | } else | 2985 | } else |
2955 | a->slave=&mod->voice[a->slavechn=channel]; | 2986 | a->slave=&mod->voice[a->slavechn=channel]; |
2956 | 2987 | ||
2957 | /* assign parts of MP_VOICE only done for a KICK_NOTE */ | 2988 | /* assign parts of MP_VOICE only done for a KICK_NOTE */ |
2958 | if ((aout=a->slave)) { | 2989 | if ((aout=a->slave) != NULL) { |
2959 | if (aout->mflag && aout->master) aout->master->slave=NULL; | 2990 | if (aout->mflag && aout->master) aout->master->slave=NULL; |
2960 | aout->master=a; | 2991 | aout->master=a; |
2961 | a->slave=aout; | 2992 | a->slave=aout; |
@@ -2984,7 +3015,7 @@ static void pt_EffectsPass2(MODULE *mod) | |||
2984 | if (!a->row) continue; | 3015 | if (!a->row) continue; |
2985 | UniSetRow(a->row); | 3016 | UniSetRow(a->row); |
2986 | 3017 | ||
2987 | while((c=UniGetByte())) | 3018 | while((c=UniGetByte()) != 0) |
2988 | if (c==UNI_ITEFFECTS0) { | 3019 | if (c==UNI_ITEFFECTS0) { |
2989 | c=UniGetByte(); | 3020 | c=UniGetByte(); |
2990 | if ((c>>4)==SS_S7EFFECTS) | 3021 | if ((c>>4)==SS_S7EFFECTS) |
@@ -3016,7 +3047,7 @@ void Player_HandleTick(void) | |||
3016 | pf->sngremainder%=pf->bpm; | 3047 | pf->sngremainder%=pf->bpm; |
3017 | 3048 | ||
3018 | if (++pf->vbtick>=pf->sngspd) { | 3049 | if (++pf->vbtick>=pf->sngspd) { |
3019 | if (pf->pat_repcrazy) | 3050 | if (pf->pat_repcrazy) |
3020 | pf->pat_repcrazy=0; /* play 2 times row 0 */ | 3051 | pf->pat_repcrazy=0; /* play 2 times row 0 */ |
3021 | else | 3052 | else |
3022 | pf->patpos++; | 3053 | pf->patpos++; |
@@ -3046,6 +3077,9 @@ void Player_HandleTick(void) | |||
3046 | pf->control[channel].pat_reppos=-1; | 3077 | pf->control[channel].pat_reppos=-1; |
3047 | 3078 | ||
3048 | pf->patbrk=pf->posjmp=0; | 3079 | pf->patbrk=pf->posjmp=0; |
3080 | |||
3081 | if (pf->sngpos<0) pf->sngpos=(SWORD)(pf->numpos-1); | ||
3082 | |||
3049 | /* handle the "---" (end of song) pattern since it can occur | 3083 | /* handle the "---" (end of song) pattern since it can occur |
3050 | *inside* the module in some formats */ | 3084 | *inside* the module in some formats */ |
3051 | if ((pf->sngpos>=pf->numpos)|| | 3085 | if ((pf->sngpos>=pf->numpos)|| |
@@ -3060,7 +3094,6 @@ void Player_HandleTick(void) | |||
3060 | pf->bpm=pf->inittempo<32?32:pf->inittempo; | 3094 | pf->bpm=pf->inittempo<32?32:pf->inittempo; |
3061 | } | 3095 | } |
3062 | } | 3096 | } |
3063 | if (pf->sngpos<0) pf->sngpos=pf->numpos-1; | ||
3064 | } | 3097 | } |
3065 | 3098 | ||
3066 | if (!pf->patdly2) | 3099 | if (!pf->patdly2) |
@@ -3093,7 +3126,7 @@ static void Player_Init_internal(MODULE* mod) | |||
3093 | mod->control[t].main.chanvol=mod->chanvol[t]; | 3126 | mod->control[t].main.chanvol=mod->chanvol[t]; |
3094 | mod->control[t].main.panning=mod->panning[t]; | 3127 | mod->control[t].main.panning=mod->panning[t]; |
3095 | } | 3128 | } |
3096 | 3129 | ||
3097 | mod->sngtime=0; | 3130 | mod->sngtime=0; |
3098 | mod->sngremainder=0; | 3131 | mod->sngremainder=0; |
3099 | 3132 | ||
@@ -3133,6 +3166,11 @@ int Player_Init(MODULE* mod) | |||
3133 | if (!(mod->voice=(MP_VOICE*)MikMod_calloc(md_sngchn,sizeof(MP_VOICE)))) | 3166 | if (!(mod->voice=(MP_VOICE*)MikMod_calloc(md_sngchn,sizeof(MP_VOICE)))) |
3134 | return 1; | 3167 | return 1; |
3135 | 3168 | ||
3169 | /* mod->numvoices was used during loading to clamp md_sngchn. | ||
3170 | After loading it's used to remember how big mod->voice is. | ||
3171 | */ | ||
3172 | mod->numvoices = md_sngchn; | ||
3173 | |||
3136 | Player_Init_internal(mod); | 3174 | Player_Init_internal(mod); |
3137 | return 0; | 3175 | return 0; |
3138 | } | 3176 | } |
@@ -3148,10 +3186,8 @@ void Player_Exit_internal(MODULE* mod) | |||
3148 | pf=NULL; | 3186 | pf=NULL; |
3149 | } | 3187 | } |
3150 | 3188 | ||
3151 | if (mod->control) | 3189 | MikMod_free(mod->control); |
3152 | MikMod_free(mod->control); | 3190 | MikMod_free(mod->voice); |
3153 | if (mod->voice) | ||
3154 | MikMod_free(mod->voice); | ||
3155 | mod->control=NULL; | 3191 | mod->control=NULL; |
3156 | mod->voice=NULL; | 3192 | mod->voice=NULL; |
3157 | } | 3193 | } |
@@ -3166,8 +3202,10 @@ void Player_Exit(MODULE* mod) | |||
3166 | MIKMODAPI void Player_SetVolume(SWORD volume) | 3202 | MIKMODAPI void Player_SetVolume(SWORD volume) |
3167 | { | 3203 | { |
3168 | MUTEX_LOCK(vars); | 3204 | MUTEX_LOCK(vars); |
3169 | if (pf) | 3205 | if (pf) { |
3170 | pf->volume=(volume<0)?0:(volume>128)?128:volume; | 3206 | pf->volume=(volume<0)?0:(volume>128)?128:volume; |
3207 | pf->initvolume=pf->volume; | ||
3208 | } | ||
3171 | MUTEX_UNLOCK(vars); | 3209 | MUTEX_UNLOCK(vars); |
3172 | } | 3210 | } |
3173 | 3211 | ||
@@ -3241,7 +3279,7 @@ MIKMODAPI void Player_NextPosition(void) | |||
3241 | pf->patbrk=0; | 3279 | pf->patbrk=0; |
3242 | pf->vbtick=pf->sngspd; | 3280 | pf->vbtick=pf->sngspd; |
3243 | 3281 | ||
3244 | for (t=0;t<md_sngchn;t++) { | 3282 | for (t=0;t<NUMVOICES(pf);t++) { |
3245 | Voice_Stop_internal(t); | 3283 | Voice_Stop_internal(t); |
3246 | pf->voice[t].main.i=NULL; | 3284 | pf->voice[t].main.i=NULL; |
3247 | pf->voice[t].main.s=NULL; | 3285 | pf->voice[t].main.s=NULL; |
@@ -3266,7 +3304,7 @@ MIKMODAPI void Player_PrevPosition(void) | |||
3266 | pf->patbrk=0; | 3304 | pf->patbrk=0; |
3267 | pf->vbtick=pf->sngspd; | 3305 | pf->vbtick=pf->sngspd; |
3268 | 3306 | ||
3269 | for (t=0;t<md_sngchn;t++) { | 3307 | for (t=0;t<NUMVOICES(pf);t++) { |
3270 | Voice_Stop_internal(t); | 3308 | Voice_Stop_internal(t); |
3271 | pf->voice[t].main.i=NULL; | 3309 | pf->voice[t].main.i=NULL; |
3272 | pf->voice[t].main.s=NULL; | 3310 | pf->voice[t].main.s=NULL; |
@@ -3293,7 +3331,7 @@ MIKMODAPI void Player_SetPosition(UWORD pos) | |||
3293 | pf->sngpos=pos; | 3331 | pf->sngpos=pos; |
3294 | pf->vbtick=pf->sngspd; | 3332 | pf->vbtick=pf->sngspd; |
3295 | 3333 | ||
3296 | for (t=0;t<md_sngchn;t++) { | 3334 | for (t=0;t<NUMVOICES(pf);t++) { |
3297 | Voice_Stop_internal(t); | 3335 | Voice_Stop_internal(t); |
3298 | pf->voice[t].main.i=NULL; | 3336 | pf->voice[t].main.i=NULL; |
3299 | pf->voice[t].main.s=NULL; | 3337 | pf->voice[t].main.s=NULL; |
@@ -3303,12 +3341,12 @@ MIKMODAPI void Player_SetPosition(UWORD pos) | |||
3303 | pf->control[t].main.s=NULL; | 3341 | pf->control[t].main.s=NULL; |
3304 | } | 3342 | } |
3305 | pf->forbid=0; | 3343 | pf->forbid=0; |
3306 | 3344 | ||
3307 | if (!pos) | 3345 | if (!pos) |
3308 | Player_Init_internal(pf); | 3346 | Player_Init_internal(pf); |
3309 | } | 3347 | } |
3310 | MUTEX_UNLOCK(vars); | 3348 | MUTEX_UNLOCK(vars); |
3311 | } | 3349 | } |
3312 | 3350 | ||
3313 | static void Player_Unmute_internal(SLONG arg1,va_list ap) | 3351 | static void Player_Unmute_internal(SLONG arg1,va_list ap) |
3314 | { | 3352 | { |
@@ -3418,7 +3456,7 @@ static void Player_ToggleMute_internal(SLONG arg1,va_list ap) | |||
3418 | } | 3456 | } |
3419 | break; | 3457 | break; |
3420 | default: | 3458 | default: |
3421 | if (arg1<pf->numchn) | 3459 | if (arg1<pf->numchn) |
3422 | pf->control[arg1].muted=1-pf->control[arg1].muted; | 3460 | pf->control[arg1].muted=1-pf->control[arg1].muted; |
3423 | break; | 3461 | break; |
3424 | } | 3462 | } |
@@ -3465,7 +3503,7 @@ MIKMODAPI UWORD Player_GetChannelPeriod(UBYTE chan) | |||
3465 | UWORD result=0; | 3503 | UWORD result=0; |
3466 | 3504 | ||
3467 | MUTEX_LOCK(vars); | 3505 | MUTEX_LOCK(vars); |
3468 | if (pf) | 3506 | if (pf) |
3469 | result=(chan<pf->numchn)?pf->control[chan].main.period:0; | 3507 | result=(chan<pf->numchn)?pf->control[chan].main.period:0; |
3470 | MUTEX_UNLOCK(vars); | 3508 | MUTEX_UNLOCK(vars); |
3471 | 3509 | ||
@@ -3499,7 +3537,7 @@ MIKMODAPI void Player_TogglePause(void) | |||
3499 | MIKMODAPI void Player_SetSpeed(UWORD speed) | 3537 | MIKMODAPI void Player_SetSpeed(UWORD speed) |
3500 | { | 3538 | { |
3501 | MUTEX_LOCK(vars); | 3539 | MUTEX_LOCK(vars); |
3502 | if (pf) | 3540 | if (pf) |
3503 | pf->sngspd=speed?(speed<32?speed:32):1; | 3541 | pf->sngspd=speed?(speed<32?speed:32):1; |
3504 | MUTEX_UNLOCK(vars); | 3542 | MUTEX_UNLOCK(vars); |
3505 | } | 3543 | } |
@@ -3538,18 +3576,17 @@ MIKMODAPI int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo) | |||
3538 | return numvoices; | 3576 | return numvoices; |
3539 | } | 3577 | } |
3540 | 3578 | ||
3541 | 3579 | /* Get current module order */ | |
3542 | // Get current module order | ||
3543 | MIKMODAPI int Player_GetOrder(void) | 3580 | MIKMODAPI int Player_GetOrder(void) |
3544 | { | 3581 | { |
3545 | int ret; | 3582 | int ret; |
3546 | MUTEX_LOCK(vars); | 3583 | MUTEX_LOCK(vars); |
3547 | ret = pf ? pf->sngpos :0; // pf->positions[pf->sngpos ? pf->sngpos-1 : 0]: 0; | 3584 | ret = pf ? pf->sngpos :0; /* pf->positions[pf->sngpos ? pf->sngpos-1 : 0]: 0; */ |
3548 | MUTEX_UNLOCK(vars); | 3585 | MUTEX_UNLOCK(vars); |
3549 | return ret; | 3586 | return ret; |
3550 | } | 3587 | } |
3551 | 3588 | ||
3552 | // Get current module row | 3589 | /* Get current module row */ |
3553 | MIKMODAPI int Player_GetRow(void) | 3590 | MIKMODAPI int Player_GetRow(void) |
3554 | { | 3591 | { |
3555 | int ret; | 3592 | int ret; |
@@ -3559,5 +3596,4 @@ MIKMODAPI int Player_GetRow(void) | |||
3559 | return ret; | 3596 | return ret; |
3560 | } | 3597 | } |
3561 | 3598 | ||
3562 | |||
3563 | /* ex:set ts=4: */ | 3599 | /* ex:set ts=4: */ |
diff --git a/apps/plugins/mikmod/munitrk.c b/apps/plugins/mikmod/munitrk.c index f0a8f58af7..72e7de4e7e 100644 --- a/apps/plugins/mikmod/munitrk.c +++ b/apps/plugins/mikmod/munitrk.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: munitrk.c,v 1.2 2005/03/30 19:11:46 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | All routines dealing with the manipulation of UNITRK streams | 25 | All routines dealing with the manipulation of UNITRK streams |
26 | 26 | ||
@@ -37,7 +37,7 @@ | |||
37 | /* Unibuffer chunk size */ | 37 | /* Unibuffer chunk size */ |
38 | #define BUFPAGE 128 | 38 | #define BUFPAGE 128 |
39 | 39 | ||
40 | UWORD unioperands[UNI_LAST]={ | 40 | const UWORD unioperands[UNI_LAST] = { |
41 | 0, /* not used */ | 41 | 0, /* not used */ |
42 | 1, /* UNI_NOTE */ | 42 | 1, /* UNI_NOTE */ |
43 | 1, /* UNI_INSTRUMENT */ | 43 | 1, /* UNI_INSTRUMENT */ |
@@ -214,7 +214,7 @@ static int UniExpand(int wanted) | |||
214 | unibuf = newbuf; | 214 | unibuf = newbuf; |
215 | unimax+=BUFPAGE; | 215 | unimax+=BUFPAGE; |
216 | return 1; | 216 | return 1; |
217 | } else | 217 | } else |
218 | return 0; | 218 | return 0; |
219 | } | 219 | } |
220 | return 1; | 220 | return 1; |
@@ -236,7 +236,7 @@ void UniWriteWord(UWORD data) | |||
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | static int MyCmp(UBYTE* a,UBYTE* b,UWORD l) | 239 | static int MyCmp(const UBYTE* a,const UBYTE* b,UWORD l) |
240 | { | 240 | { |
241 | UWORD t; | 241 | UWORD t; |
242 | 242 | ||
@@ -275,15 +275,15 @@ void UniNewline(void) | |||
275 | stream. */ | 275 | stream. */ |
276 | UBYTE* UniDup(void) | 276 | UBYTE* UniDup(void) |
277 | { | 277 | { |
278 | UBYTE *d; | 278 | void *d; |
279 | 279 | ||
280 | if (!UniExpand(unitt-unipc)) return NULL; | 280 | if (!UniExpand(unipc-unitt)) return NULL; |
281 | unibuf[unitt] = 0; | 281 | unibuf[unitt] = 0; |
282 | 282 | ||
283 | if(!(d=(UBYTE *)MikMod_malloc(unipc))) return NULL; | 283 | if(!(d=MikMod_malloc(unipc))) return NULL; |
284 | memcpy(d,unibuf,unipc); | 284 | memcpy(d,unibuf,unipc); |
285 | 285 | ||
286 | return d; | 286 | return (UBYTE *)d; |
287 | } | 287 | } |
288 | 288 | ||
289 | int UniInit(void) | 289 | int UniInit(void) |
@@ -296,7 +296,7 @@ int UniInit(void) | |||
296 | 296 | ||
297 | void UniCleanup(void) | 297 | void UniCleanup(void) |
298 | { | 298 | { |
299 | if(unibuf) MikMod_free(unibuf); | 299 | MikMod_free(unibuf); |
300 | unibuf = NULL; | 300 | unibuf = NULL; |
301 | } | 301 | } |
302 | 302 | ||
diff --git a/apps/plugins/mikmod/npertab.c b/apps/plugins/mikmod/npertab.c index 4aa5ef9a17..b106b2adf8 100644 --- a/apps/plugins/mikmod/npertab.c +++ b/apps/plugins/mikmod/npertab.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: npertab.c,v 1.2 2005/03/30 19:11:47 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | MOD format period table. Used by both the MOD and M15 (15-inst mod) Loaders. | 25 | MOD format period table. Used by both the MOD and M15 (15-inst mod) Loaders. |
26 | 26 | ||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include "mikmod_internals.h" | 33 | #include "mikmod_internals.h" |
34 | 34 | ||
35 | UWORD npertab[7 * OCTAVE] = { | 35 | const UWORD npertab[7 * OCTAVE] = { |
36 | /* Octaves 6 -> 0 */ | 36 | /* Octaves 6 -> 0 */ |
37 | /* C C# D D# E F F# G G# A A# B */ | 37 | /* C C# D D# E F F# G G# A A# B */ |
38 | 0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a, | 38 | 0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a, |
diff --git a/apps/plugins/mikmod/sloader.c b/apps/plugins/mikmod/sloader.c index 8c1070cba1..af7f623799 100644 --- a/apps/plugins/mikmod/sloader.c +++ b/apps/plugins/mikmod/sloader.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: sloader.c,v 1.3 2007/12/06 17:46:08 denis111 Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Routines for loading samples. The sample loader utilizes the routines | 25 | Routines for loading samples. The sample loader utilizes the routines |
26 | provided by the "registered" sample loader. | 26 | provided by the "registered" sample loader. |
@@ -56,7 +56,7 @@ typedef struct ITPACK { | |||
56 | int SL_Init(SAMPLOAD* s) | 56 | int SL_Init(SAMPLOAD* s) |
57 | { | 57 | { |
58 | if(!sl_buffer) | 58 | if(!sl_buffer) |
59 | if(!(sl_buffer=MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0; | 59 | if(!(sl_buffer=(SWORD*)MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0; |
60 | 60 | ||
61 | sl_rlength = s->length; | 61 | sl_rlength = s->length; |
62 | if(s->infmt & SF_16BITS) sl_rlength>>=1; | 62 | if(s->infmt & SF_16BITS) sl_rlength>>=1; |
@@ -68,16 +68,15 @@ int SL_Init(SAMPLOAD* s) | |||
68 | void SL_Exit(SAMPLOAD *s) | 68 | void SL_Exit(SAMPLOAD *s) |
69 | { | 69 | { |
70 | if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR); | 70 | if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR); |
71 | if(sl_buffer) { | 71 | |
72 | MikMod_free(sl_buffer); | 72 | MikMod_free(sl_buffer); |
73 | sl_buffer=NULL; | 73 | sl_buffer=NULL; |
74 | } | ||
75 | } | 74 | } |
76 | 75 | ||
77 | /* unpack a 8bit IT packed sample */ | 76 | /* unpack a 8bit IT packed sample */ |
78 | static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt) | 77 | static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *out,UWORD count,UWORD* incnt) |
79 | { | 78 | { |
80 | SWORD *dest=sl_buffer,*end=sl_buffer+count; | 79 | SWORD *dest=out,*end=out+count; |
81 | UWORD x,y,needbits,havebits,new_count=0; | 80 | UWORD x,y,needbits,havebits,new_count=0; |
82 | UWORD bits = status->bits; | 81 | UWORD bits = status->bits; |
83 | UWORD bufbits = status->bufbits; | 82 | UWORD bufbits = status->bufbits; |
@@ -145,13 +144,13 @@ static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD c | |||
145 | status->bufbits = bufbits; | 144 | status->bufbits = bufbits; |
146 | status->last = last; | 145 | status->last = last; |
147 | status->buf = buf; | 146 | status->buf = buf; |
148 | return (dest-sl_buffer); | 147 | return (dest-out); |
149 | } | 148 | } |
150 | 149 | ||
151 | /* unpack a 16bit IT packed sample */ | 150 | /* unpack a 16bit IT packed sample */ |
152 | static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt) | 151 | static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *out,UWORD count,UWORD* incnt) |
153 | { | 152 | { |
154 | SWORD *dest=sl_buffer,*end=sl_buffer+count; | 153 | SWORD *dest=out,*end=out+count; |
155 | SLONG x,y,needbits,havebits,new_count=0; | 154 | SLONG x,y,needbits,havebits,new_count=0; |
156 | UWORD bits = status->bits; | 155 | UWORD bits = status->bits; |
157 | UWORD bufbits = status->bufbits; | 156 | UWORD bufbits = status->bufbits; |
@@ -219,7 +218,7 @@ static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD | |||
219 | status->bufbits = bufbits; | 218 | status->bufbits = bufbits; |
220 | status->last = last; | 219 | status->last = last; |
221 | status->buf = buf; | 220 | status->buf = buf; |
222 | return (dest-sl_buffer); | 221 | return (dest-out); |
223 | } | 222 | } |
224 | 223 | ||
225 | static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,int dither) | 224 | static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,int dither) |
@@ -231,9 +230,11 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor | |||
231 | int result,c_block=0; /* compression bytes until next block */ | 230 | int result,c_block=0; /* compression bytes until next block */ |
232 | ITPACK status; | 231 | ITPACK status; |
233 | UWORD incnt = 0; | 232 | UWORD incnt = 0; |
234 | 233 | ||
235 | memset(&status, 0, sizeof(status)); /* initialize status */ | 234 | status.buf = 0; |
236 | 235 | status.last = 0; | |
236 | status.bufbits = 0; | ||
237 | status.bits = 0; | ||
237 | 238 | ||
238 | while(length) { | 239 | while(length) { |
239 | stodo=(length<SLBUFSIZE)?length:SLBUFSIZE; | 240 | stodo=(length<SLBUFSIZE)?length:SLBUFSIZE; |
@@ -261,6 +262,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor | |||
261 | c_block -= stodo; | 262 | c_block -= stodo; |
262 | } else { | 263 | } else { |
263 | if(infmt&SF_16BITS) { | 264 | if(infmt&SF_16BITS) { |
265 | if(_mm_eof(reader)) { | ||
266 | _mm_errno=MMERR_NOT_A_STREAM;/* better error? */ | ||
267 | return 1; | ||
268 | } | ||
264 | if(infmt&SF_BIG_ENDIAN) | 269 | if(infmt&SF_BIG_ENDIAN) |
265 | _mm_read_M_SWORDS(sl_buffer,stodo,reader); | 270 | _mm_read_M_SWORDS(sl_buffer,stodo,reader); |
266 | else | 271 | else |
@@ -269,6 +274,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor | |||
269 | SBYTE *src; | 274 | SBYTE *src; |
270 | SWORD *dest; | 275 | SWORD *dest; |
271 | 276 | ||
277 | if(_mm_eof(reader)) { | ||
278 | _mm_errno=MMERR_NOT_A_STREAM;/* better error? */ | ||
279 | return 1; | ||
280 | } | ||
272 | reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo); | 281 | reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo); |
273 | src = (SBYTE*)sl_buffer; | 282 | src = (SBYTE*)sl_buffer; |
274 | dest = sl_buffer; | 283 | dest = sl_buffer; |
@@ -288,7 +297,7 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor | |||
288 | sl_old = sl_buffer[t]; | 297 | sl_old = sl_buffer[t]; |
289 | } | 298 | } |
290 | 299 | ||
291 | if((infmt^outfmt) & SF_SIGNED) | 300 | if((infmt^outfmt) & SF_SIGNED) |
292 | for(t=0;t<stodo;t++) | 301 | for(t=0;t<stodo;t++) |
293 | sl_buffer[t]^= 0x8000; | 302 | sl_buffer[t]^= 0x8000; |
294 | 303 | ||
@@ -340,7 +349,7 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor | |||
340 | int SL_Load(void* buffer,SAMPLOAD *smp,ULONG length) | 349 | int SL_Load(void* buffer,SAMPLOAD *smp,ULONG length) |
341 | { | 350 | { |
342 | return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor, | 351 | return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor, |
343 | length,smp->reader,0); | 352 | length,smp->reader,0); |
344 | } | 353 | } |
345 | 354 | ||
346 | /* Registers a sample for loading when SL_LoadSamples() is called. */ | 355 | /* Registers a sample for loading when SL_LoadSamples() is called. */ |
@@ -357,7 +366,7 @@ SAMPLOAD* SL_RegisterSample(SAMPLE* s,int type,MREADER* reader) | |||
357 | cruise = sndfxlist; | 366 | cruise = sndfxlist; |
358 | } else | 367 | } else |
359 | return NULL; | 368 | return NULL; |
360 | 369 | ||
361 | /* Allocate and add structure to the END of the list */ | 370 | /* Allocate and add structure to the END of the list */ |
362 | if(!(news=(SAMPLOAD*)MikMod_malloc(sizeof(SAMPLOAD)))) return NULL; | 371 | if(!(news=(SAMPLOAD*)MikMod_malloc(sizeof(SAMPLOAD)))) return NULL; |
363 | 372 | ||
@@ -407,7 +416,7 @@ static ULONG SampleTotal(SAMPLOAD* samplist,int type) | |||
407 | static ULONG RealSpeed(SAMPLOAD *s) | 416 | static ULONG RealSpeed(SAMPLOAD *s) |
408 | { | 417 | { |
409 | return(s->sample->speed/(s->scalefactor?s->scalefactor:1)); | 418 | return(s->sample->speed/(s->scalefactor?s->scalefactor:1)); |
410 | } | 419 | } |
411 | 420 | ||
412 | static int DitherSamples(SAMPLOAD* samplist,int type) | 421 | static int DitherSamples(SAMPLOAD* samplist,int type) |
413 | { | 422 | { |
@@ -417,7 +426,7 @@ static int DitherSamples(SAMPLOAD* samplist,int type) | |||
417 | 426 | ||
418 | if(!samplist) return 0; | 427 | if(!samplist) return 0; |
419 | 428 | ||
420 | if((maxsize=MD_SampleSpace(type)*1024)) | 429 | if((maxsize=MD_SampleSpace(type)*1024) != 0) |
421 | while(SampleTotal(samplist,type)>maxsize) { | 430 | while(SampleTotal(samplist,type)>maxsize) { |
422 | /* First Pass - check for any 16 bit samples */ | 431 | /* First Pass - check for any 16 bit samples */ |
423 | s = samplist; | 432 | s = samplist; |
@@ -473,15 +482,15 @@ static int DitherSamples(SAMPLOAD* samplist,int type) | |||
473 | 482 | ||
474 | int SL_LoadSamples(void) | 483 | int SL_LoadSamples(void) |
475 | { | 484 | { |
476 | int ok; | 485 | int rc; |
477 | 486 | ||
478 | _mm_critical = 0; | 487 | _mm_critical = 0; |
479 | 488 | ||
480 | if((!musiclist)&&(!sndfxlist)) return 0; | 489 | if((!musiclist)&&(!sndfxlist)) return 0; |
481 | ok=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX); | 490 | rc=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX); |
482 | musiclist=sndfxlist=NULL; | 491 | musiclist=sndfxlist=NULL; |
483 | 492 | ||
484 | return ok; | 493 | return rc; |
485 | } | 494 | } |
486 | 495 | ||
487 | void SL_Sample16to8(SAMPLOAD* s) | 496 | void SL_Sample16to8(SAMPLOAD* s) |
@@ -518,5 +527,4 @@ void SL_HalveSample(SAMPLOAD* s,int factor) | |||
518 | s->sample->loopend = s->loopend / s->scalefactor; | 527 | s->sample->loopend = s->loopend / s->scalefactor; |
519 | } | 528 | } |
520 | 529 | ||
521 | |||
522 | /* ex:set ts=4: */ | 530 | /* ex:set ts=4: */ |
diff --git a/apps/plugins/mikmod/virtch.c b/apps/plugins/mikmod/virtch.c index 6e8174016c..f2fd528b00 100644 --- a/apps/plugins/mikmod/virtch.c +++ b/apps/plugins/mikmod/virtch.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: virtch.c,v 1.4 2005/05/18 13:42:23 raphassenat Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Sample mixing routines, using a 32 bits mixing buffer. | 25 | Sample mixing routines, using a 32 bits mixing buffer. |
26 | 26 | ||
@@ -33,28 +33,23 @@ | |||
33 | (b) Interpolation of sample data during mixing | 33 | (b) Interpolation of sample data during mixing |
34 | (c) Dolby Surround Sound | 34 | (c) Dolby Surround Sound |
35 | */ | 35 | */ |
36 | #if 0 | ||
37 | #include <assert.h> | ||
38 | #endif | ||
39 | 36 | ||
40 | #ifdef HAVE_CONFIG_H | 37 | #ifdef HAVE_CONFIG_H |
41 | #include "config.h" | 38 | #include "config.h" |
42 | #endif | 39 | #endif |
43 | 40 | ||
44 | #include <stddef.h> | ||
45 | #ifdef HAVE_MEMORY_H | 41 | #ifdef HAVE_MEMORY_H |
46 | #include <memory.h> | 42 | #include <memory.h> |
47 | #endif | 43 | #endif |
48 | #include <string.h> | 44 | #include <string.h> |
49 | 45 | ||
50 | #include "mikmod_internals.h" | 46 | #include "mikmod_internals.h" |
51 | #include "mikmod.h" | ||
52 | 47 | ||
53 | /* | 48 | /* |
54 | Constant definitions | 49 | Constant definitions |
55 | ==================== | 50 | ==================== |
56 | 51 | ||
57 | BITSHIFT | 52 | BITSHIFT |
58 | Controls the maximum volume of the sound output. All data is shifted | 53 | Controls the maximum volume of the sound output. All data is shifted |
59 | right by BITSHIFT after being mixed. Higher values result in quieter | 54 | right by BITSHIFT after being mixed. Higher values result in quieter |
60 | sound and less chance of distortion. | 55 | sound and less chance of distortion. |
@@ -130,164 +125,176 @@ static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL, | |||
130 | #else | 125 | #else |
131 | #define NATIVE SLONG | 126 | #define NATIVE SLONG |
132 | #endif | 127 | #endif |
128 | |||
133 | #if defined HAVE_SSE2 || defined HAVE_ALTIVEC | 129 | #if defined HAVE_SSE2 || defined HAVE_ALTIVEC |
134 | 130 | ||
135 | static size_t MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,size_t index, size_t increment,size_t todo) | 131 | # if !defined(NATIVE_64BIT_INT) |
132 | static SINTPTR_T MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo) | ||
136 | { | 133 | { |
137 | // TODO: | 134 | /* TODO: */ |
138 | SWORD sample; | 135 | SWORD sample; |
139 | SLONG lvolsel = vnf->lvolsel; | 136 | SLONG lvolsel = vnf->lvolsel; |
140 | 137 | ||
141 | while(todo--) { | 138 | while(todo--) { |
142 | sample = srce[index >> FRACBITS]; | 139 | sample = srce[idx >> FRACBITS]; |
143 | index += increment; | 140 | idx += increment; |
144 | 141 | ||
145 | *dest++ += lvolsel * sample; | 142 | *dest++ += lvolsel * sample; |
146 | } | 143 | } |
147 | return index; | 144 | return idx; |
148 | } | 145 | } |
146 | # endif /* !NATIVE_64BIT_INT */ | ||
149 | 147 | ||
150 | static size_t MixSIMDStereoNormal(const SWORD* srce, SLONG* dest, size_t index, size_t increment,size_t todo) | 148 | static SINTPTR_T MixSIMDStereoNormal(const SWORD* srce,SLONG* dest,SINTPTR_T idx,SINTPTR_T increment,SINTPTR_T todo) |
151 | { | 149 | { |
152 | SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel}; | 150 | SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel}; |
153 | SWORD sample; | 151 | SWORD sample; |
154 | SLONG remain = todo; | 152 | SLONG remain = todo; |
155 | 153 | ||
156 | // Dest can be misaligned ... | 154 | /* Dest can be misaligned */ |
157 | while(!IS_ALIGNED_16(dest)) { | 155 | while(!IS_ALIGNED_16(dest)) { |
158 | sample=srce[(index += increment) >> FRACBITS]; | 156 | sample=srce[idx >> FRACBITS]; |
157 | idx += increment; | ||
159 | *dest++ += vol[0] * sample; | 158 | *dest++ += vol[0] * sample; |
160 | *dest++ += vol[1] * sample; | 159 | *dest++ += vol[1] * sample; |
161 | todo--; | 160 | todo--; |
161 | if(!todo) return idx; | ||
162 | } | 162 | } |
163 | 163 | ||
164 | // Srce is always aligned ... | 164 | /* Srce is always aligned */ |
165 | 165 | ||
166 | #if defined HAVE_SSE2 | 166 | #if defined HAVE_SSE2 |
167 | remain = todo&3; | 167 | remain = todo&3; |
168 | { | 168 | { |
169 | __m128i v0 = _mm_set_epi16(0, vol[1], | 169 | __m128i v0 = _mm_set_epi16(0, vol[1], |
170 | 0, vol[0], | 170 | 0, vol[0], |
171 | 0, vol[1], | 171 | 0, vol[1], |
172 | 0, vol[0]); | 172 | 0, vol[0]); |
173 | for(todo>>=2;todo; todo--) | 173 | for(todo>>=2;todo; todo--) |
174 | { | 174 | { |
175 | SWORD s0 = srce[(index += increment) >> FRACBITS]; | 175 | SWORD s0 = srce[idx >> FRACBITS]; |
176 | SWORD s1 = srce[(index += increment) >> FRACBITS]; | 176 | SWORD s1 = srce[(idx += increment) >> FRACBITS]; |
177 | SWORD s2 = srce[(index += increment) >> FRACBITS]; | 177 | SWORD s2 = srce[(idx += increment) >> FRACBITS]; |
178 | SWORD s3 = srce[(index += increment) >> FRACBITS]; | 178 | SWORD s3 = srce[(idx += increment) >> FRACBITS]; |
179 | __m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0); | 179 | __m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0); |
180 | __m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2); | 180 | __m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2); |
181 | __m128i v3 = _mm_load_si128((__m128i*)(dest+0)); | 181 | __m128i v3 = _mm_load_si128((__m128i*)(dest+0)); |
182 | __m128i v4 = _mm_load_si128((__m128i*)(dest+4)); | 182 | __m128i v4 = _mm_load_si128((__m128i*)(dest+4)); |
183 | _mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1))); | 183 | _mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1))); |
184 | _mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2))); | 184 | _mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2))); |
185 | dest+=8; | 185 | dest+=8; |
186 | idx += increment; | ||
186 | } | 187 | } |
187 | } | 188 | } |
188 | 189 | ||
189 | #elif defined HAVE_ALTIVEC | 190 | #elif defined HAVE_ALTIVEC |
190 | remain = todo&3; | 191 | remain = todo&3; |
191 | { | 192 | { |
192 | vector signed short r0 = vec_ld(0, vol); | ||
193 | vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, // l | ||
194 | 0, 1, // l | ||
195 | 2, 3, // r | ||
196 | 2, 1, // r | ||
197 | 0, 1, // l | ||
198 | 0, 1, // l | ||
199 | 2, 3, // r | ||
200 | 2, 3 // r | ||
201 | )); | ||
202 | SWORD s[8]; | 193 | SWORD s[8]; |
203 | 194 | vector signed short r0 = vec_ld(0, vol); | |
195 | vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, /* l */ | ||
196 | 0, 1, /* l */ | ||
197 | 2, 3, /* r */ | ||
198 | 2, 1, /* r */ | ||
199 | 0, 1, /* l */ | ||
200 | 0, 1, /* l */ | ||
201 | 2, 3, /* r */ | ||
202 | 2, 3 /* r */ | ||
203 | )); | ||
204 | |||
204 | for(todo>>=2;todo; todo--) | 205 | for(todo>>=2;todo; todo--) |
205 | { | 206 | { |
206 | // Load constants | 207 | vector short int r1; |
207 | s[0] = srce[(index += increment) >> FRACBITS]; | 208 | vector signed short v1, v2; |
208 | s[1] = srce[(index += increment) >> FRACBITS]; | 209 | vector signed int v3, v4, v5, v6; |
209 | s[2] = srce[(index += increment) >> FRACBITS]; | 210 | |
210 | s[3] = srce[(index += increment) >> FRACBITS]; | 211 | /* Load constants */ |
212 | s[0] = srce[idx >> FRACBITS]; | ||
213 | s[1] = srce[(idx += increment) >> FRACBITS]; | ||
214 | s[2] = srce[(idx += increment) >> FRACBITS]; | ||
215 | s[3] = srce[(idx += increment) >> FRACBITS]; | ||
211 | s[4] = 0; | 216 | s[4] = 0; |
212 | 217 | ||
213 | vector short int r1 = vec_ld(0, s); | 218 | r1 = vec_ld(0, s); |
214 | vector signed short v1 = vec_perm(r1, r1, (vector unsigned char)(0*2, 0*2+1, // s0 | 219 | v1 = vec_perm(r1, r1, (vector unsigned char) |
215 | 4*2, 4*2+1, // 0 | 220 | (0*2, 0*2+1, /* s0 */ |
216 | 0*2, 0*2+1, // s0 | 221 | 4*2, 4*2+1, /* 0 */ |
217 | 4*2, 4*2+1, // 0 | 222 | 0*2, 0*2+1, /* s0 */ |
218 | 1*2, 1*2+1, // s1 | 223 | 4*2, 4*2+1, /* 0 */ |
219 | 4*2, 4*2+1, // 0 | 224 | 1*2, 1*2+1, /* s1 */ |
220 | 1*2, 1*2+1, // s1 | 225 | 4*2, 4*2+1, /* 0 */ |
221 | 4*2, 4*2+1 // 0 | 226 | 1*2, 1*2+1, /* s1 */ |
222 | )); | 227 | 4*2, 4*2+1 /* 0 */ |
223 | 228 | ) ); | |
224 | vector signed short v2 = vec_perm(r1, r1, (vector unsigned char)(2*2, 2*2+1, // s2 | 229 | v2 = vec_perm(r1, r1, (vector unsigned char) |
225 | 4*2, 4*2+1, // 0 | 230 | (2*2, 2*2+1, /* s2 */ |
226 | 2*2, 2*2+1, // s2 | 231 | 4*2, 4*2+1, /* 0 */ |
227 | 4*2, 4*2+1, // 0 | 232 | 2*2, 2*2+1, /* s2 */ |
228 | 3*2, 3*2+1, // s3 | 233 | 4*2, 4*2+1, /* 0 */ |
229 | 4*2, 4*2+1, // 0 | 234 | 3*2, 3*2+1, /* s3 */ |
230 | 3*2, 3*2+1, // s3 | 235 | 4*2, 4*2+1, /* 0 */ |
231 | 4*2, 4*2+1 // 0 | 236 | 3*2, 3*2+1, /* s3 */ |
232 | )); | 237 | 4*2, 4*2+1 /* 0 */ |
233 | vector signed int v3 = vec_ld(0, dest); | 238 | ) ); |
234 | vector signed int v4 = vec_ld(0, dest + 4); | 239 | |
235 | vector signed int v5 = vec_mule(v0, v1); | 240 | v3 = vec_ld(0, dest); |
236 | vector signed int v6 = vec_mule(v0, v2); | 241 | v4 = vec_ld(0, dest + 4); |
237 | 242 | v5 = vec_mule(v0, v1); | |
238 | vec_st(vec_add(v3, v5), 0, dest); | 243 | v6 = vec_mule(v0, v2); |
244 | |||
245 | vec_st(vec_add(v3, v5), 0, dest); | ||
239 | vec_st(vec_add(v4, v6), 0x10, dest); | 246 | vec_st(vec_add(v4, v6), 0x10, dest); |
240 | 247 | ||
241 | dest+=8; | 248 | dest+=8; |
249 | idx += increment; | ||
242 | } | 250 | } |
243 | } | 251 | } |
244 | #endif // HAVE_ALTIVEC | 252 | #endif /* HAVE_ALTIVEC */ |
245 | 253 | ||
246 | // Remaining bits ... | 254 | /* Remaining bits */ |
247 | while(remain--) { | 255 | while(remain--) { |
248 | sample=srce[(index += increment) >> FRACBITS]; | 256 | sample=srce[idx >> FRACBITS]; |
257 | idx += increment; | ||
249 | 258 | ||
250 | *dest++ += vol[0] * sample; | 259 | *dest++ += vol[0] * sample; |
251 | *dest++ += vol[1] * sample; | 260 | *dest++ += vol[1] * sample; |
252 | } | 261 | } |
253 | return index; | 262 | return idx; |
254 | } | 263 | } |
255 | #endif | 264 | #endif |
256 | 265 | ||
257 | /*========== 32 bit sample mixers - only for 32 bit platforms */ | 266 | /*========== 32 bit sample mixers - only for 32 bit platforms */ |
258 | #ifndef NATIVE_64BIT_INT | 267 | #ifndef NATIVE_64BIT_INT |
259 | 268 | ||
260 | static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) | 269 | static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) |
261 | { | 270 | { |
262 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 | 271 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 |
263 | if (md_mode & DMODE_SIMDMIXER) | 272 | if (md_mode & DMODE_SIMDMIXER) { |
264 | { | 273 | return MixSIMDMonoNormal(srce, dest, idx, increment, todo); |
265 | return MixSIMDMonoNormal(srce, dest, index, increment, todo); | ||
266 | } | 274 | } |
267 | else | 275 | else |
268 | #endif | 276 | #endif |
269 | { | 277 | { |
270 | SWORD sample; | 278 | SWORD sample; |
271 | SLONG lvolsel = vnf->lvolsel; | 279 | SLONG lvolsel = vnf->lvolsel; |
272 | 280 | ||
273 | while(todo--) { | 281 | while(todo--) { |
274 | sample = srce[index >> FRACBITS]; | 282 | sample = srce[idx >> FRACBITS]; |
275 | index += increment; | 283 | idx += increment; |
276 | 284 | ||
277 | *dest++ += lvolsel * sample; | 285 | *dest++ += lvolsel * sample; |
278 | } | 286 | } |
279 | } | 287 | } |
280 | return index; | 288 | return idx; |
281 | } | 289 | } |
282 | 290 | ||
283 | // FIXME: This mixer should works also on 64-bit platform | 291 | /* FIXME: This mixer should works also on 64-bit platform */ |
284 | // Hint : changes SLONG / SLONGLONG mess with size_t | 292 | /* Hint : changes SLONG / SLONGLONG mess with intptr */ |
285 | static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) | 293 | static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) |
286 | { | 294 | { |
287 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 | 295 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 |
288 | if (md_mode & DMODE_SIMDMIXER) | 296 | if (md_mode & DMODE_SIMDMIXER) { |
289 | { | 297 | return MixSIMDStereoNormal(srce, dest, idx, increment, todo); |
290 | return MixSIMDStereoNormal(srce, dest, index, increment, todo); | ||
291 | } | 298 | } |
292 | else | 299 | else |
293 | #endif | 300 | #endif |
@@ -297,17 +304,17 @@ static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG i | |||
297 | SLONG rvolsel = vnf->rvolsel; | 304 | SLONG rvolsel = vnf->rvolsel; |
298 | 305 | ||
299 | while(todo--) { | 306 | while(todo--) { |
300 | sample=srce[(index += increment) >> FRACBITS]; | 307 | sample=srce[idx >> FRACBITS]; |
308 | idx += increment; | ||
301 | 309 | ||
302 | *dest++ += lvolsel * sample; | 310 | *dest++ += lvolsel * sample; |
303 | *dest++ += rvolsel * sample; | 311 | *dest++ += rvolsel * sample; |
304 | } | 312 | } |
305 | } | 313 | } |
306 | return index; | 314 | return idx; |
307 | } | 315 | } |
308 | 316 | ||
309 | 317 | static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) | |
310 | static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) | ||
311 | { | 318 | { |
312 | SWORD sample; | 319 | SWORD sample; |
313 | SLONG lvolsel = vnf->lvolsel; | 320 | SLONG lvolsel = vnf->lvolsel; |
@@ -315,25 +322,26 @@ static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG | |||
315 | 322 | ||
316 | if (lvolsel>=rvolsel) { | 323 | if (lvolsel>=rvolsel) { |
317 | while(todo--) { | 324 | while(todo--) { |
318 | sample = srce[index >> FRACBITS]; | 325 | sample = srce[idx >> FRACBITS]; |
319 | index += increment; | 326 | idx += increment; |
320 | 327 | ||
321 | *dest++ += lvolsel*sample; | 328 | *dest++ += lvolsel*sample; |
322 | *dest++ -= lvolsel*sample; | 329 | *dest++ -= lvolsel*sample; |
323 | } | 330 | } |
324 | } else { | 331 | } |
332 | else { | ||
325 | while(todo--) { | 333 | while(todo--) { |
326 | sample = srce[index >> FRACBITS]; | 334 | sample = srce[idx >> FRACBITS]; |
327 | index += increment; | 335 | idx += increment; |
328 | 336 | ||
329 | *dest++ -= rvolsel*sample; | 337 | *dest++ -= rvolsel*sample; |
330 | *dest++ += rvolsel*sample; | 338 | *dest++ += rvolsel*sample; |
331 | } | 339 | } |
332 | } | 340 | } |
333 | return index; | 341 | return idx; |
334 | } | 342 | } |
335 | 343 | ||
336 | static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) | 344 | static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) |
337 | { | 345 | { |
338 | SLONG sample; | 346 | SLONG sample; |
339 | SLONG lvolsel = vnf->lvolsel; | 347 | SLONG lvolsel = vnf->lvolsel; |
@@ -342,33 +350,33 @@ static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG inc | |||
342 | if (rampvol) { | 350 | if (rampvol) { |
343 | SLONG oldlvol = vnf->oldlvol - lvolsel; | 351 | SLONG oldlvol = vnf->oldlvol - lvolsel; |
344 | while(todo--) { | 352 | while(todo--) { |
345 | sample=(SLONG)srce[index>>FRACBITS]+ | 353 | sample=(SLONG)srce[idx>>FRACBITS]+ |
346 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 354 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
347 | *(index&FRACMASK)>>FRACBITS); | 355 | *(idx&FRACMASK)>>FRACBITS); |
348 | index += increment; | 356 | idx += increment; |
349 | 357 | ||
350 | *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) | 358 | *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) |
351 | * sample >> CLICK_SHIFT; | 359 | * sample >> CLICK_SHIFT; |
352 | if (!--rampvol) | 360 | if (!--rampvol) |
353 | break; | 361 | break; |
354 | } | 362 | } |
355 | vnf->rampvol = rampvol; | 363 | vnf->rampvol = rampvol; |
356 | if (todo < 0) | 364 | if (todo < 0) |
357 | return index; | 365 | return idx; |
358 | } | 366 | } |
359 | 367 | ||
360 | while(todo--) { | 368 | while(todo--) { |
361 | sample=(SLONG)srce[index>>FRACBITS]+ | 369 | sample=(SLONG)srce[idx>>FRACBITS]+ |
362 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 370 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
363 | *(index&FRACMASK)>>FRACBITS); | 371 | *(idx&FRACMASK)>>FRACBITS); |
364 | index += increment; | 372 | idx += increment; |
365 | 373 | ||
366 | *dest++ += lvolsel * sample; | 374 | *dest++ += lvolsel * sample; |
367 | } | 375 | } |
368 | return index; | 376 | return idx; |
369 | } | 377 | } |
370 | 378 | ||
371 | static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) | 379 | static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) |
372 | { | 380 | { |
373 | SLONG sample; | 381 | SLONG sample; |
374 | SLONG lvolsel = vnf->lvolsel; | 382 | SLONG lvolsel = vnf->lvolsel; |
@@ -379,13 +387,13 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i | |||
379 | SLONG oldlvol = vnf->oldlvol - lvolsel; | 387 | SLONG oldlvol = vnf->oldlvol - lvolsel; |
380 | SLONG oldrvol = vnf->oldrvol - rvolsel; | 388 | SLONG oldrvol = vnf->oldrvol - rvolsel; |
381 | while(todo--) { | 389 | while(todo--) { |
382 | sample=(SLONG)srce[index>>FRACBITS]+ | 390 | sample=(SLONG)srce[idx>>FRACBITS]+ |
383 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 391 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
384 | *(index&FRACMASK)>>FRACBITS); | 392 | *(idx&FRACMASK)>>FRACBITS); |
385 | index += increment; | 393 | idx += increment; |
386 | 394 | ||
387 | *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) | 395 | *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) |
388 | * sample >> CLICK_SHIFT; | 396 | * sample >> CLICK_SHIFT; |
389 | *dest++ += ((rvolsel << CLICK_SHIFT) + oldrvol * rampvol) | 397 | *dest++ += ((rvolsel << CLICK_SHIFT) + oldrvol * rampvol) |
390 | * sample >> CLICK_SHIFT; | 398 | * sample >> CLICK_SHIFT; |
391 | if (!--rampvol) | 399 | if (!--rampvol) |
@@ -393,22 +401,22 @@ static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG i | |||
393 | } | 401 | } |
394 | vnf->rampvol = rampvol; | 402 | vnf->rampvol = rampvol; |
395 | if (todo < 0) | 403 | if (todo < 0) |
396 | return index; | 404 | return idx; |
397 | } | 405 | } |
398 | 406 | ||
399 | while(todo--) { | 407 | while(todo--) { |
400 | sample=(SLONG)srce[index>>FRACBITS]+ | 408 | sample=(SLONG)srce[idx>>FRACBITS]+ |
401 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 409 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
402 | *(index&FRACMASK)>>FRACBITS); | 410 | *(idx&FRACMASK)>>FRACBITS); |
403 | index += increment; | 411 | idx += increment; |
404 | 412 | ||
405 | *dest++ += lvolsel * sample; | 413 | *dest++ += lvolsel * sample; |
406 | *dest++ += rvolsel * sample; | 414 | *dest++ += rvolsel * sample; |
407 | } | 415 | } |
408 | return index; | 416 | return idx; |
409 | } | 417 | } |
410 | 418 | ||
411 | static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) | 419 | static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) |
412 | { | 420 | { |
413 | SLONG sample; | 421 | SLONG sample; |
414 | SLONG lvolsel = vnf->lvolsel; | 422 | SLONG lvolsel = vnf->lvolsel; |
@@ -427,13 +435,13 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG | |||
427 | if (rampvol) { | 435 | if (rampvol) { |
428 | oldvol -= vol; | 436 | oldvol -= vol; |
429 | while(todo--) { | 437 | while(todo--) { |
430 | sample=(SLONG)srce[index>>FRACBITS]+ | 438 | sample=(SLONG)srce[idx>>FRACBITS]+ |
431 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 439 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
432 | *(index&FRACMASK)>>FRACBITS); | 440 | *(idx&FRACMASK)>>FRACBITS); |
433 | index += increment; | 441 | idx += increment; |
434 | 442 | ||
435 | sample=((vol << CLICK_SHIFT) + oldvol * rampvol) | 443 | sample=((vol << CLICK_SHIFT) + oldvol * rampvol) |
436 | * sample >> CLICK_SHIFT; | 444 | * sample >> CLICK_SHIFT; |
437 | *dest++ += sample; | 445 | *dest++ += sample; |
438 | *dest++ -= sample; | 446 | *dest++ -= sample; |
439 | 447 | ||
@@ -442,55 +450,55 @@ static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG | |||
442 | } | 450 | } |
443 | vnf->rampvol = rampvol; | 451 | vnf->rampvol = rampvol; |
444 | if (todo < 0) | 452 | if (todo < 0) |
445 | return index; | 453 | return idx; |
446 | } | 454 | } |
447 | 455 | ||
448 | while(todo--) { | 456 | while(todo--) { |
449 | sample=(SLONG)srce[index>>FRACBITS]+ | 457 | sample=(SLONG)srce[idx>>FRACBITS]+ |
450 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 458 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
451 | *(index&FRACMASK)>>FRACBITS); | 459 | *(idx&FRACMASK)>>FRACBITS); |
452 | index += increment; | 460 | idx += increment; |
453 | 461 | ||
454 | *dest++ += vol*sample; | 462 | *dest++ += vol*sample; |
455 | *dest++ -= vol*sample; | 463 | *dest++ -= vol*sample; |
456 | } | 464 | } |
457 | return index; | 465 | return idx; |
458 | } | 466 | } |
459 | #endif | 467 | #endif |
460 | 468 | ||
461 | /*========== 64 bit sample mixers - all platforms */ | 469 | /*========== 64 bit sample mixers - all platforms */ |
462 | 470 | ||
463 | static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) | 471 | static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) |
464 | { | 472 | { |
465 | SWORD sample; | 473 | SWORD sample; |
466 | SLONG lvolsel = vnf->lvolsel; | 474 | SLONG lvolsel = vnf->lvolsel; |
467 | 475 | ||
468 | while(todo--) { | 476 | while(todo--) { |
469 | sample = srce[index >> FRACBITS]; | 477 | sample = srce[idx >> FRACBITS]; |
470 | index += increment; | 478 | idx += increment; |
471 | 479 | ||
472 | *dest++ += lvolsel * sample; | 480 | *dest++ += lvolsel * sample; |
473 | } | 481 | } |
474 | return index; | 482 | return idx; |
475 | } | 483 | } |
476 | 484 | ||
477 | static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) | 485 | static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) |
478 | { | 486 | { |
479 | SWORD sample; | 487 | SWORD sample; |
480 | SLONG lvolsel = vnf->lvolsel; | 488 | SLONG lvolsel = vnf->lvolsel; |
481 | SLONG rvolsel = vnf->rvolsel; | 489 | SLONG rvolsel = vnf->rvolsel; |
482 | 490 | ||
483 | while(todo--) { | 491 | while(todo--) { |
484 | sample=srce[index >> FRACBITS]; | 492 | sample=srce[idx >> FRACBITS]; |
485 | index += increment; | 493 | idx += increment; |
486 | 494 | ||
487 | *dest++ += lvolsel * sample; | 495 | *dest++ += lvolsel * sample; |
488 | *dest++ += rvolsel * sample; | 496 | *dest++ += rvolsel * sample; |
489 | } | 497 | } |
490 | return index; | 498 | return idx; |
491 | } | 499 | } |
492 | 500 | ||
493 | static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) | 501 | static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) |
494 | { | 502 | { |
495 | SWORD sample; | 503 | SWORD sample; |
496 | SLONG lvolsel = vnf->lvolsel; | 504 | SLONG lvolsel = vnf->lvolsel; |
@@ -498,25 +506,26 @@ static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index | |||
498 | 506 | ||
499 | if(vnf->lvolsel>=vnf->rvolsel) { | 507 | if(vnf->lvolsel>=vnf->rvolsel) { |
500 | while(todo--) { | 508 | while(todo--) { |
501 | sample = srce[index >> FRACBITS]; | 509 | sample = srce[idx >> FRACBITS]; |
502 | index += increment; | 510 | idx += increment; |
503 | 511 | ||
504 | *dest++ += lvolsel*sample; | 512 | *dest++ += lvolsel*sample; |
505 | *dest++ -= lvolsel*sample; | 513 | *dest++ -= lvolsel*sample; |
506 | } | 514 | } |
507 | } else { | 515 | } |
516 | else { | ||
508 | while(todo--) { | 517 | while(todo--) { |
509 | sample = srce[index >> FRACBITS]; | 518 | sample = srce[idx >> FRACBITS]; |
510 | index += increment; | 519 | idx += increment; |
511 | 520 | ||
512 | *dest++ -= rvolsel*sample; | 521 | *dest++ -= rvolsel*sample; |
513 | *dest++ += rvolsel*sample; | 522 | *dest++ += rvolsel*sample; |
514 | } | 523 | } |
515 | } | 524 | } |
516 | return index; | 525 | return idx; |
517 | } | 526 | } |
518 | 527 | ||
519 | static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) | 528 | static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) |
520 | { | 529 | { |
521 | SLONG sample; | 530 | SLONG sample; |
522 | SLONG lvolsel = vnf->lvolsel; | 531 | SLONG lvolsel = vnf->lvolsel; |
@@ -525,10 +534,10 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO | |||
525 | if (rampvol) { | 534 | if (rampvol) { |
526 | SLONG oldlvol = vnf->oldlvol - lvolsel; | 535 | SLONG oldlvol = vnf->oldlvol - lvolsel; |
527 | while(todo--) { | 536 | while(todo--) { |
528 | sample=(SLONG)srce[index>>FRACBITS]+ | 537 | sample=(SLONG)srce[idx>>FRACBITS]+ |
529 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 538 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
530 | *(index&FRACMASK)>>FRACBITS); | 539 | *(idx&FRACMASK)>>FRACBITS); |
531 | index += increment; | 540 | idx += increment; |
532 | 541 | ||
533 | *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) | 542 | *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) |
534 | * sample >> CLICK_SHIFT; | 543 | * sample >> CLICK_SHIFT; |
@@ -537,21 +546,21 @@ static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLO | |||
537 | } | 546 | } |
538 | vnf->rampvol = rampvol; | 547 | vnf->rampvol = rampvol; |
539 | if (todo < 0) | 548 | if (todo < 0) |
540 | return index; | 549 | return idx; |
541 | } | 550 | } |
542 | 551 | ||
543 | while(todo--) { | 552 | while(todo--) { |
544 | sample=(SLONG)srce[index>>FRACBITS]+ | 553 | sample=(SLONG)srce[idx>>FRACBITS]+ |
545 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 554 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
546 | *(index&FRACMASK)>>FRACBITS); | 555 | *(idx&FRACMASK)>>FRACBITS); |
547 | index += increment; | 556 | idx += increment; |
548 | 557 | ||
549 | *dest++ += lvolsel * sample; | 558 | *dest++ += lvolsel * sample; |
550 | } | 559 | } |
551 | return index; | 560 | return idx; |
552 | } | 561 | } |
553 | 562 | ||
554 | static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) | 563 | static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) |
555 | { | 564 | { |
556 | SLONG sample; | 565 | SLONG sample; |
557 | SLONG lvolsel = vnf->lvolsel; | 566 | SLONG lvolsel = vnf->lvolsel; |
@@ -562,10 +571,10 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S | |||
562 | SLONG oldlvol = vnf->oldlvol - lvolsel; | 571 | SLONG oldlvol = vnf->oldlvol - lvolsel; |
563 | SLONG oldrvol = vnf->oldrvol - rvolsel; | 572 | SLONG oldrvol = vnf->oldrvol - rvolsel; |
564 | while(todo--) { | 573 | while(todo--) { |
565 | sample=(SLONG)srce[index>>FRACBITS]+ | 574 | sample=(SLONG)srce[idx>>FRACBITS]+ |
566 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 575 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
567 | *(index&FRACMASK)>>FRACBITS); | 576 | *(idx&FRACMASK)>>FRACBITS); |
568 | index += increment; | 577 | idx += increment; |
569 | 578 | ||
570 | *dest++ +=((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) | 579 | *dest++ +=((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) |
571 | * sample >> CLICK_SHIFT; | 580 | * sample >> CLICK_SHIFT; |
@@ -576,22 +585,22 @@ static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,S | |||
576 | } | 585 | } |
577 | vnf->rampvol = rampvol; | 586 | vnf->rampvol = rampvol; |
578 | if (todo < 0) | 587 | if (todo < 0) |
579 | return index; | 588 | return idx; |
580 | } | 589 | } |
581 | 590 | ||
582 | while(todo--) { | 591 | while(todo--) { |
583 | sample=(SLONG)srce[index>>FRACBITS]+ | 592 | sample=(SLONG)srce[idx>>FRACBITS]+ |
584 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 593 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
585 | *(index&FRACMASK)>>FRACBITS); | 594 | *(idx&FRACMASK)>>FRACBITS); |
586 | index += increment; | 595 | idx += increment; |
587 | 596 | ||
588 | *dest++ += lvolsel * sample; | 597 | *dest++ += lvolsel * sample; |
589 | *dest++ += rvolsel * sample; | 598 | *dest++ += rvolsel * sample; |
590 | } | 599 | } |
591 | return index; | 600 | return idx; |
592 | } | 601 | } |
593 | 602 | ||
594 | static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) | 603 | static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) |
595 | { | 604 | { |
596 | SLONG sample; | 605 | SLONG sample; |
597 | SLONG lvolsel = vnf->lvolsel; | 606 | SLONG lvolsel = vnf->lvolsel; |
@@ -610,13 +619,13 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index | |||
610 | if (rampvol) { | 619 | if (rampvol) { |
611 | oldvol -= vol; | 620 | oldvol -= vol; |
612 | while(todo--) { | 621 | while(todo--) { |
613 | sample=(SLONG)srce[index>>FRACBITS]+ | 622 | sample=(SLONG)srce[idx>>FRACBITS]+ |
614 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 623 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
615 | *(index&FRACMASK)>>FRACBITS); | 624 | *(idx&FRACMASK)>>FRACBITS); |
616 | index += increment; | 625 | idx += increment; |
617 | 626 | ||
618 | sample=((vol << CLICK_SHIFT) + oldvol * rampvol) | 627 | sample=((vol << CLICK_SHIFT) + oldvol * rampvol) |
619 | * sample >> CLICK_SHIFT; | 628 | * sample >> CLICK_SHIFT; |
620 | *dest++ += sample; | 629 | *dest++ += sample; |
621 | *dest++ -= sample; | 630 | *dest++ -= sample; |
622 | if (!--rampvol) | 631 | if (!--rampvol) |
@@ -624,19 +633,19 @@ static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index | |||
624 | } | 633 | } |
625 | vnf->rampvol = rampvol; | 634 | vnf->rampvol = rampvol; |
626 | if (todo < 0) | 635 | if (todo < 0) |
627 | return index; | 636 | return idx; |
628 | } | 637 | } |
629 | 638 | ||
630 | while(todo--) { | 639 | while(todo--) { |
631 | sample=(SLONG)srce[index>>FRACBITS]+ | 640 | sample=(SLONG)srce[idx>>FRACBITS]+ |
632 | ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) | 641 | ((SLONG)(srce[(idx>>FRACBITS)+1]-srce[idx>>FRACBITS]) |
633 | *(index&FRACMASK)>>FRACBITS); | 642 | *(idx&FRACMASK)>>FRACBITS); |
634 | index += increment; | 643 | idx += increment; |
635 | 644 | ||
636 | *dest++ += vol*sample; | 645 | *dest++ += vol*sample; |
637 | *dest++ -= vol*sample; | 646 | *dest++ -= vol*sample; |
638 | } | 647 | } |
639 | return index; | 648 | return idx; |
640 | } | 649 | } |
641 | 650 | ||
642 | static void (*MixReverb)(SLONG* srce,NATIVE count); | 651 | static void (*MixReverb)(SLONG* srce,NATIVE count); |
@@ -673,7 +682,7 @@ static void MixReverb_Normal(SLONG* srce,NATIVE count) | |||
673 | 682 | ||
674 | /* left channel */ | 683 | /* left channel */ |
675 | *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ | 684 | *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ |
676 | RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; | 685 | RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; |
677 | } | 686 | } |
678 | } | 687 | } |
679 | 688 | ||
@@ -710,10 +719,10 @@ static void MixReverb_Stereo(SLONG* srce,NATIVE count) | |||
710 | 719 | ||
711 | /* left channel then right channel */ | 720 | /* left channel then right channel */ |
712 | *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ | 721 | *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ |
713 | RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; | 722 | RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; |
714 | 723 | ||
715 | *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+ | 724 | *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+ |
716 | RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; | 725 | RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; |
717 | } | 726 | } |
718 | } | 727 | } |
719 | 728 | ||
@@ -839,58 +848,56 @@ static void Mix32To8(SBYTE* dste,const SLONG *srce,NATIVE count) | |||
839 | 848 | ||
840 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 | 849 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 |
841 | 850 | ||
842 | // Mix 32bit input to floating point. 32 samples per iteration | 851 | /* Mix 32bit input to floating point. 32 samples per iteration */ |
843 | // PC: ?, Mac OK | 852 | /* PC: ?, Mac OK */ |
844 | static void Mix32ToFP_SIMD(float* dste,SLONG* srce,NATIVE count) | 853 | static void Mix32ToFP_SIMD(float* dste,const SLONG* srce,NATIVE count) |
845 | { | 854 | { |
846 | int remain=count; | 855 | const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT)); |
856 | int remain=count; | ||
857 | simd_m128 x1, x2, xk; | ||
847 | 858 | ||
848 | while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) | 859 | while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) |
849 | { | 860 | { |
850 | float x1; | 861 | float xf; |
851 | EXTRACT_SAMPLE_FP(x1,FP_SHIFT); | 862 | EXTRACT_SAMPLE_FP(xf,FP_SHIFT); |
852 | CHECK_SAMPLE_FP(x1,1.0f); | 863 | CHECK_SAMPLE_FP(xf,1.0f); |
853 | PUT_SAMPLE_FP(x1); | 864 | PUT_SAMPLE_FP(xf); |
854 | count--; | 865 | count--; |
855 | if (!count) | 866 | if (!count) return; |
856 | { | ||
857 | return; | ||
858 | } | ||
859 | } | 867 | } |
860 | 868 | ||
861 | remain = count&7; | 869 | remain = count&7; |
862 | 870 | ||
863 | const float k = ((1.0f / 32768.0f) / (1 << FP_SHIFT)); | 871 | xk = LOAD_PS1_SIMD(&k); /* Scale factor */ |
864 | simd_m128 x1, x2; | ||
865 | simd_m128 xk = LOAD_PS1_SIMD(&k); // Scale factor | ||
866 | 872 | ||
867 | for(count>>=3;count;count--) { | 873 | for(count>>=3;count;count--) { |
868 | EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples | 874 | EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */ |
869 | EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); // Load 4 samples | 875 | EXTRACT_SAMPLE_SIMD_F(srce+4, x2, FP_SHIFT, xk); /* Load 4 samples */ |
870 | PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples | 876 | PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */ |
871 | PUT_SAMPLE_SIMD_F(dste+4, x2); // Store 4 samples | 877 | PUT_SAMPLE_SIMD_F(dste+4, x2); /* Store 4 samples */ |
872 | srce+=8; | 878 | srce+=8; |
873 | dste+=8; | 879 | dste+=8; |
874 | } | 880 | } |
875 | 881 | ||
876 | if (remain&4) { | 882 | if (remain&4) { |
877 | EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); // Load 4 samples | 883 | EXTRACT_SAMPLE_SIMD_F(srce, x1, FP_SHIFT, xk); /* Load 4 samples */ |
878 | PUT_SAMPLE_SIMD_F(dste, x1); // Store 4 samples | 884 | PUT_SAMPLE_SIMD_F(dste, x1); /* Store 4 samples */ |
879 | srce+=4; | 885 | srce+=4; |
880 | dste+=4; | 886 | dste+=4; |
881 | remain &= 3; | 887 | remain &= 3; |
882 | } | 888 | } |
883 | 889 | ||
884 | while(remain--) { | 890 | while(remain--) { |
885 | float x1; | 891 | float xf; |
886 | EXTRACT_SAMPLE_FP(x1,FP_SHIFT); | 892 | EXTRACT_SAMPLE_FP(xf,FP_SHIFT); |
887 | CHECK_SAMPLE_FP(x1,1.0f); | 893 | CHECK_SAMPLE_FP(xf,1.0f); |
888 | PUT_SAMPLE_FP(x1); | 894 | PUT_SAMPLE_FP(xf); |
889 | } | 895 | } |
890 | } | 896 | } |
891 | // PC: Ok, Mac Ok | 897 | |
892 | static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count) | 898 | /* PC: Ok, Mac Ok */ |
893 | { | 899 | static void Mix32To16_SIMD(SWORD* dste,const SLONG* srce,NATIVE count) |
900 | { | ||
894 | int remain = count; | 901 | int remain = count; |
895 | 902 | ||
896 | while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) | 903 | while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) |
@@ -900,34 +907,31 @@ static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count) | |||
900 | CHECK_SAMPLE(x1,32768); | 907 | CHECK_SAMPLE(x1,32768); |
901 | PUT_SAMPLE(x1); | 908 | PUT_SAMPLE(x1); |
902 | count--; | 909 | count--; |
903 | if (!count) | 910 | if (!count) return; |
904 | { | ||
905 | return; | ||
906 | } | ||
907 | } | 911 | } |
908 | 912 | ||
909 | remain = count&7; | 913 | remain = count&7; |
910 | 914 | ||
911 | for(count>>=3;count;count--) | 915 | for(count>>=3;count;count--) |
912 | { | 916 | { |
913 | simd_m128i x1,x2; | 917 | simd_m128i x1,x2; |
914 | EXTRACT_SAMPLE_SIMD_16(srce, x1); // Load 4 samples | 918 | EXTRACT_SAMPLE_SIMD_16(srce, x1); /* Load 4 samples */ |
915 | EXTRACT_SAMPLE_SIMD_16(srce+4, x2); // Load 4 samples | 919 | EXTRACT_SAMPLE_SIMD_16(srce+4, x2); /* Load 4 samples */ |
916 | PUT_SAMPLE_SIMD_W(dste, x1, x2); // Store 8 samples | 920 | PUT_SAMPLE_SIMD_W(dste, x1, x2); /* Store 8 samples */ |
917 | srce+=8; | 921 | srce+=8; |
918 | dste+=8; | 922 | dste+=8; |
919 | } | 923 | } |
920 | 924 | ||
921 | if (remain) | 925 | if (remain) |
922 | Mix32To16(dste, srce, remain); | 926 | Mix32To16(dste, srce, remain); |
923 | } | 927 | } |
924 | 928 | ||
925 | // Mix 32bit input to 8bit. 128 samples per iteration | 929 | /* Mix 32bit input to 8bit. 128 samples per iteration */ |
926 | // PC:OK, Mac: Ok | 930 | /* PC:OK, Mac: Ok */ |
927 | static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count) | 931 | static void Mix32To8_SIMD(SBYTE* dste,const SLONG* srce,NATIVE count) |
928 | { | 932 | { |
929 | int remain=count; | 933 | int remain=count; |
930 | 934 | ||
931 | while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) | 935 | while(!IS_ALIGNED_16(dste) || !IS_ALIGNED_16(srce)) |
932 | { | 936 | { |
933 | SWORD x1; | 937 | SWORD x1; |
@@ -935,32 +939,29 @@ static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count) | |||
935 | CHECK_SAMPLE(x1,128); | 939 | CHECK_SAMPLE(x1,128); |
936 | PUT_SAMPLE(x1+128); | 940 | PUT_SAMPLE(x1+128); |
937 | count--; | 941 | count--; |
938 | if (!count) | 942 | if (!count) return; |
939 | { | ||
940 | return; | ||
941 | } | ||
942 | } | 943 | } |
943 | 944 | ||
944 | remain = count&15; | 945 | remain = count&15; |
945 | 946 | ||
946 | for(count>>=4;count;count--) { | 947 | for(count>>=4;count;count--) { |
947 | simd_m128i x1,x2,x3,x4; | 948 | simd_m128i x1,x2,x3,x4; |
948 | EXTRACT_SAMPLE_SIMD_8(srce, x1); // Load 4 samples | 949 | EXTRACT_SAMPLE_SIMD_8(srce, x1); /* Load 4 samples */ |
949 | EXTRACT_SAMPLE_SIMD_8(srce+4, x2); // Load 4 samples | 950 | EXTRACT_SAMPLE_SIMD_8(srce+4, x2); /* Load 4 samples */ |
950 | EXTRACT_SAMPLE_SIMD_8(srce+8, x3); // Load 4 samples | 951 | EXTRACT_SAMPLE_SIMD_8(srce+8, x3); /* Load 4 samples */ |
951 | EXTRACT_SAMPLE_SIMD_8(srce+12, x4); // Load 4 samples | 952 | EXTRACT_SAMPLE_SIMD_8(srce+12, x4); /* Load 4 samples */ |
952 | PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); // Store 16 samples | 953 | PUT_SAMPLE_SIMD_B(dste, x1, x2, x3, x4); /* Store 16 samples */ |
953 | srce+=16; | 954 | srce+=16; |
954 | dste+=16; | 955 | dste+=16; |
955 | } | 956 | } |
957 | |||
956 | if (remain) | 958 | if (remain) |
957 | Mix32To8(dste, srce, remain); | 959 | Mix32To8(dste, srce, remain); |
958 | } | 960 | } |
959 | 961 | ||
960 | #endif | 962 | #endif |
961 | 963 | ||
962 | 964 | ||
963 | |||
964 | static void AddChannel(SLONG* ptr,NATIVE todo) | 965 | static void AddChannel(SLONG* ptr,NATIVE todo) |
965 | { | 966 | { |
966 | SLONGLONG end,done; | 967 | SLONGLONG end,done; |
@@ -1050,65 +1051,64 @@ static void AddChannel(SLONG* ptr,NATIVE todo) | |||
1050 | if(vc_mode & DMODE_STEREO) { | 1051 | if(vc_mode & DMODE_STEREO) { |
1051 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) | 1052 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) |
1052 | vnf->current=Mix32SurroundInterp | 1053 | vnf->current=Mix32SurroundInterp |
1053 | (s,ptr,vnf->current,vnf->increment,done); | 1054 | (s,ptr,vnf->current,vnf->increment,done); |
1054 | else | 1055 | else |
1055 | vnf->current=Mix32StereoInterp | 1056 | vnf->current=Mix32StereoInterp |
1056 | (s,ptr,vnf->current,vnf->increment,done); | 1057 | (s,ptr,vnf->current,vnf->increment,done); |
1057 | } else | 1058 | } else |
1058 | vnf->current=Mix32MonoInterp | 1059 | vnf->current=Mix32MonoInterp |
1059 | (s,ptr,vnf->current,vnf->increment,done); | 1060 | (s,ptr,vnf->current,vnf->increment,done); |
1060 | } else if(vc_mode & DMODE_STEREO) { | 1061 | } else if(vc_mode & DMODE_STEREO) { |
1061 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) | 1062 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) |
1062 | vnf->current=Mix32SurroundNormal | 1063 | vnf->current=Mix32SurroundNormal |
1063 | (s,ptr,vnf->current,vnf->increment,done); | 1064 | (s,ptr,vnf->current,vnf->increment,done); |
1064 | else | 1065 | else |
1065 | { | 1066 | { |
1066 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 | 1067 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 |
1067 | if (md_mode & DMODE_SIMDMIXER) | 1068 | if (md_mode & DMODE_SIMDMIXER) |
1068 | vnf->current=MixSIMDStereoNormal | 1069 | vnf->current=MixSIMDStereoNormal |
1069 | (s,ptr,vnf->current,vnf->increment,done); | 1070 | (s,ptr,vnf->current,vnf->increment,done); |
1070 | 1071 | else | |
1071 | else | ||
1072 | #endif | 1072 | #endif |
1073 | vnf->current=Mix32StereoNormal | 1073 | vnf->current=Mix32StereoNormal |
1074 | (s,ptr,vnf->current,vnf->increment,done); | 1074 | (s,ptr,vnf->current,vnf->increment,done); |
1075 | } | 1075 | } |
1076 | } else | 1076 | } else |
1077 | vnf->current=Mix32MonoNormal | 1077 | vnf->current=Mix32MonoNormal |
1078 | (s,ptr,vnf->current,vnf->increment,done); | 1078 | (s,ptr,vnf->current,vnf->increment,done); |
1079 | } else | 1079 | } |
1080 | else | ||
1080 | #endif | 1081 | #endif |
1081 | { | 1082 | { |
1082 | if((md_mode & DMODE_INTERP)) { | 1083 | if((md_mode & DMODE_INTERP)) { |
1083 | if(vc_mode & DMODE_STEREO) { | 1084 | if(vc_mode & DMODE_STEREO) { |
1084 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) | 1085 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) |
1085 | vnf->current=MixSurroundInterp | 1086 | vnf->current=MixSurroundInterp |
1086 | (s,ptr,vnf->current,vnf->increment,done); | 1087 | (s,ptr,vnf->current,vnf->increment,done); |
1087 | else | 1088 | else |
1088 | vnf->current=MixStereoInterp | 1089 | vnf->current=MixStereoInterp |
1089 | (s,ptr,vnf->current,vnf->increment,done); | 1090 | (s,ptr,vnf->current,vnf->increment,done); |
1090 | } else | 1091 | } else |
1091 | vnf->current=MixMonoInterp | 1092 | vnf->current=MixMonoInterp |
1092 | (s,ptr,vnf->current,vnf->increment,done); | 1093 | (s,ptr,vnf->current,vnf->increment,done); |
1093 | } else if(vc_mode & DMODE_STEREO) { | 1094 | } else if(vc_mode & DMODE_STEREO) { |
1094 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) | 1095 | if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) |
1095 | vnf->current=MixSurroundNormal | 1096 | vnf->current=MixSurroundNormal |
1096 | (s,ptr,vnf->current,vnf->increment,done); | 1097 | (s,ptr,vnf->current,vnf->increment,done); |
1097 | else | 1098 | else |
1098 | { | 1099 | { |
1099 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 | 1100 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 |
1100 | if (md_mode & DMODE_SIMDMIXER) | 1101 | if (md_mode & DMODE_SIMDMIXER) |
1101 | vnf->current=MixSIMDStereoNormal | 1102 | vnf->current=MixSIMDStereoNormal |
1102 | (s,ptr,vnf->current,vnf->increment,done); | 1103 | (s,ptr,vnf->current,vnf->increment,done); |
1103 | 1104 | else | |
1104 | else | ||
1105 | #endif | 1105 | #endif |
1106 | vnf->current=MixStereoNormal | 1106 | vnf->current=MixStereoNormal |
1107 | (s,ptr,vnf->current,vnf->increment,done); | 1107 | (s,ptr,vnf->current,vnf->increment,done); |
1108 | } | 1108 | } |
1109 | } else | 1109 | } else |
1110 | vnf->current=MixMonoNormal | 1110 | vnf->current=MixMonoNormal |
1111 | (s,ptr,vnf->current,vnf->increment,done); | 1111 | (s,ptr,vnf->current,vnf->increment,done); |
1112 | } | 1112 | } |
1113 | } else | 1113 | } else |
1114 | /* update sample position */ | 1114 | /* update sample position */ |
@@ -1119,6 +1119,33 @@ static void AddChannel(SLONG* ptr,NATIVE todo) | |||
1119 | } | 1119 | } |
1120 | } | 1120 | } |
1121 | 1121 | ||
1122 | #ifdef NO_HQMIXER | ||
1123 | #define VC_SetupPointers() do{}while(0) | ||
1124 | #define VC1_Init VC_Init | ||
1125 | #define VC1_Exit VC_Exit | ||
1126 | #define VC1_PlayStart VC_PlayStart | ||
1127 | #define VC1_PlayStop VC_PlayStop | ||
1128 | #define VC1_SampleLength VC_SampleLength | ||
1129 | #define VC1_SampleSpace VC_SampleSpace | ||
1130 | #define VC1_SampleLoad VC_SampleLoad | ||
1131 | #define VC1_SampleUnload VC_SampleUnload | ||
1132 | #define VC1_SetNumVoices VC_SetNumVoices | ||
1133 | #define VC1_SilenceBytes VC_SilenceBytes | ||
1134 | #define VC1_VoicePlay VC_VoicePlay | ||
1135 | #define VC1_VoiceStop VC_VoiceStop | ||
1136 | #define VC1_VoiceGetFrequency VC_VoiceGetFrequency | ||
1137 | #define VC1_VoiceGetPanning VC_VoiceGetPanning | ||
1138 | #define VC1_VoiceGetPosition VC_VoiceGetPosition | ||
1139 | #define VC1_VoiceGetVolume VC_VoiceGetVolume | ||
1140 | #define VC1_VoiceRealVolume VC_VoiceRealVolume | ||
1141 | #define VC1_VoiceSetFrequency VC_VoiceSetFrequency | ||
1142 | #define VC1_VoiceSetPanning VC_VoiceSetPanning | ||
1143 | #define VC1_VoiceSetVolume VC_VoiceSetVolume | ||
1144 | #define VC1_VoiceStopped VC_VoiceStopped | ||
1145 | #define VC1_WriteBytes VC_WriteBytes | ||
1146 | #define VC1_WriteSamples VC_WriteSamples | ||
1147 | #endif | ||
1148 | |||
1122 | #define _IN_VIRTCH_ | 1149 | #define _IN_VIRTCH_ |
1123 | #include "virtch_common.c" | 1150 | #include "virtch_common.c" |
1124 | #undef _IN_VIRTCH_ | 1151 | #undef _IN_VIRTCH_ |
@@ -1190,7 +1217,6 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo) | |||
1190 | vc_callback((unsigned char*)vc_tickbuf, portion); | 1217 | vc_callback((unsigned char*)vc_tickbuf, portion); |
1191 | } | 1218 | } |
1192 | 1219 | ||
1193 | |||
1194 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 | 1220 | #if defined HAVE_ALTIVEC || defined HAVE_SSE2 |
1195 | if (md_mode & DMODE_SIMDMIXER) | 1221 | if (md_mode & DMODE_SIMDMIXER) |
1196 | { | 1222 | { |
@@ -1219,20 +1245,23 @@ void VC1_WriteSamples(SBYTE* buf,ULONG todo) | |||
1219 | 1245 | ||
1220 | int VC1_Init(void) | 1246 | int VC1_Init(void) |
1221 | { | 1247 | { |
1248 | #ifndef NO_HQMIXER | ||
1222 | VC_SetupPointers(); | 1249 | VC_SetupPointers(); |
1223 | |||
1224 | //if (md_mode&DMODE_HQMIXER) | ||
1225 | // return VC2_Init(); | ||
1226 | 1250 | ||
1227 | if(!(Samples=(SWORD**)MikMod_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) { | 1251 | if (md_mode&DMODE_HQMIXER) |
1252 | return VC2_Init(); | ||
1253 | #endif | ||
1254 | |||
1255 | if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) { | ||
1228 | _mm_errno = MMERR_INITIALIZING_MIXER; | 1256 | _mm_errno = MMERR_INITIALIZING_MIXER; |
1229 | return 1; | 1257 | return 1; |
1230 | } | 1258 | } |
1231 | if(!vc_tickbuf) | 1259 | if(!vc_tickbuf) { |
1232 | if(!(vc_tickbuf=(SLONG*)MikMod_malloc((TICKLSIZE+32)*sizeof(SLONG)))) { | 1260 | if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) { |
1233 | _mm_errno = MMERR_INITIALIZING_MIXER; | 1261 | _mm_errno = MMERR_INITIALIZING_MIXER; |
1234 | return 1; | 1262 | return 1; |
1235 | } | 1263 | } |
1264 | } | ||
1236 | 1265 | ||
1237 | MixReverb=(md_mode&DMODE_STEREO)?MixReverb_Stereo:MixReverb_Normal; | 1266 | MixReverb=(md_mode&DMODE_STEREO)?MixReverb_Stereo:MixReverb_Normal; |
1238 | MixLowPass=(md_mode&DMODE_STEREO)?MixLowPass_Stereo:MixLowPass_Normal; | 1267 | MixLowPass=(md_mode&DMODE_STEREO)?MixLowPass_Stereo:MixLowPass_Normal; |
@@ -1264,14 +1293,17 @@ int VC1_PlayStart(void) | |||
1264 | if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; | 1293 | if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; |
1265 | if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; | 1294 | if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; |
1266 | 1295 | ||
1267 | if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1; | 1296 | /* allocate reverb buffers for the right channel if in stereo mode only. */ |
1268 | if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; | 1297 | if (vc_mode & DMODE_STEREO) { |
1269 | if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; | 1298 | if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1; |
1270 | if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1; | 1299 | if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; |
1271 | if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1; | 1300 | if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; |
1272 | if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; | 1301 | if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1; |
1273 | if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; | 1302 | if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1; |
1274 | if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; | 1303 | if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; |
1304 | if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; | ||
1305 | if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; | ||
1306 | } | ||
1275 | 1307 | ||
1276 | RVRindex = 0; | 1308 | RVRindex = 0; |
1277 | return 0; | 1309 | return 0; |
@@ -1279,23 +1311,23 @@ int VC1_PlayStart(void) | |||
1279 | 1311 | ||
1280 | void VC1_PlayStop(void) | 1312 | void VC1_PlayStop(void) |
1281 | { | 1313 | { |
1282 | if(RVbufL1) MikMod_free(RVbufL1); | 1314 | MikMod_free(RVbufL1); |
1283 | if(RVbufL2) MikMod_free(RVbufL2); | 1315 | MikMod_free(RVbufL2); |
1284 | if(RVbufL3) MikMod_free(RVbufL3); | 1316 | MikMod_free(RVbufL3); |
1285 | if(RVbufL4) MikMod_free(RVbufL4); | 1317 | MikMod_free(RVbufL4); |
1286 | if(RVbufL5) MikMod_free(RVbufL5); | 1318 | MikMod_free(RVbufL5); |
1287 | if(RVbufL6) MikMod_free(RVbufL6); | 1319 | MikMod_free(RVbufL6); |
1288 | if(RVbufL7) MikMod_free(RVbufL7); | 1320 | MikMod_free(RVbufL7); |
1289 | if(RVbufL8) MikMod_free(RVbufL8); | 1321 | MikMod_free(RVbufL8); |
1290 | RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; | 1322 | RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; |
1291 | if(RVbufR1) MikMod_free(RVbufR1); | 1323 | MikMod_free(RVbufR1); |
1292 | if(RVbufR2) MikMod_free(RVbufR2); | 1324 | MikMod_free(RVbufR2); |
1293 | if(RVbufR3) MikMod_free(RVbufR3); | 1325 | MikMod_free(RVbufR3); |
1294 | if(RVbufR4) MikMod_free(RVbufR4); | 1326 | MikMod_free(RVbufR4); |
1295 | if(RVbufR5) MikMod_free(RVbufR5); | 1327 | MikMod_free(RVbufR5); |
1296 | if(RVbufR6) MikMod_free(RVbufR6); | 1328 | MikMod_free(RVbufR6); |
1297 | if(RVbufR7) MikMod_free(RVbufR7); | 1329 | MikMod_free(RVbufR7); |
1298 | if(RVbufR8) MikMod_free(RVbufR8); | 1330 | MikMod_free(RVbufR8); |
1299 | RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; | 1331 | RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; |
1300 | } | 1332 | } |
1301 | 1333 | ||
@@ -1305,8 +1337,8 @@ int VC1_SetNumVoices(void) | |||
1305 | 1337 | ||
1306 | if(!(vc_softchn=md_softchn)) return 0; | 1338 | if(!(vc_softchn=md_softchn)) return 0; |
1307 | 1339 | ||
1308 | if(vinf) MikMod_free(vinf); | 1340 | MikMod_free(vinf); |
1309 | if(!(vinf= MikMod_calloc(sizeof(VINFO),vc_softchn))) return 1; | 1341 | if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1; |
1310 | 1342 | ||
1311 | for(t=0;t<vc_softchn;t++) { | 1343 | for(t=0;t<vc_softchn;t++) { |
1312 | vinf[t].frq=10000; | 1344 | vinf[t].frq=10000; |
diff --git a/apps/plugins/mikmod/virtch2.c b/apps/plugins/mikmod/virtch2.c new file mode 100644 index 0000000000..d512833bbe --- /dev/null +++ b/apps/plugins/mikmod/virtch2.c | |||
@@ -0,0 +1,1370 @@ | |||
1 | /* MikMod sound library | ||
2 | (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for | ||
3 | complete list. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU Library General Public License as | ||
7 | published by the Free Software Foundation; either version 2 of | ||
8 | the License, or (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU Library General Public License for more details. | ||
14 | |||
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 | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
18 | 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /*============================================================================== | ||
22 | |||
23 | $Id$ | ||
24 | |||
25 | High-quality sample mixing routines, using a 32 bits mixing buffer, | ||
26 | interpolation, and sample smoothing to improve sound quality and remove | ||
27 | clicks. | ||
28 | |||
29 | ==============================================================================*/ | ||
30 | |||
31 | /* | ||
32 | |||
33 | Future Additions: | ||
34 | Low-Pass filter to remove annoying staticy buzz. | ||
35 | |||
36 | */ | ||
37 | |||
38 | #ifdef HAVE_CONFIG_H | ||
39 | #include "config.h" | ||
40 | #endif | ||
41 | |||
42 | #include "mikmod.h" | ||
43 | |||
44 | #ifndef NO_HQMIXER | ||
45 | |||
46 | #ifdef HAVE_MEMORY_H | ||
47 | #include <memory.h> | ||
48 | #endif | ||
49 | #include <string.h> | ||
50 | |||
51 | #include "mikmod_internals.h" | ||
52 | |||
53 | /* | ||
54 | Constant Definitions | ||
55 | ==================== | ||
56 | |||
57 | MAXVOL_FACTOR (was BITSHIFT in virtch.c) | ||
58 | Controls the maximum volume of the output data. All mixed data is | ||
59 | divided by this number after mixing, so larger numbers result in | ||
60 | quieter mixing. Smaller numbers will increase the likeliness of | ||
61 | distortion on loud modules. | ||
62 | |||
63 | REVERBERATION | ||
64 | Larger numbers result in shorter reverb duration. Longer reverb | ||
65 | durations can cause unwanted static and make the reverb sound more | ||
66 | like a crappy echo. | ||
67 | |||
68 | SAMPLING_SHIFT | ||
69 | Specified the shift multiplier which controls by how much the mixing | ||
70 | rate is multiplied while mixing. Higher values can improve quality by | ||
71 | smoothing the sound and reducing pops and clicks. Note, this is a shift | ||
72 | value, so a value of 2 becomes a mixing-rate multiplier of 4, and a | ||
73 | value of 3 = 8, etc. | ||
74 | |||
75 | FRACBITS | ||
76 | The number of bits per integer devoted to the fractional part of the | ||
77 | number. Generally, this number should not be changed for any reason. | ||
78 | |||
79 | !!! IMPORTANT !!! All values below MUST ALWAYS be greater than 0 | ||
80 | |||
81 | */ | ||
82 | |||
83 | #define BITSHIFT 9 | ||
84 | #define MAXVOL_FACTOR (1<<BITSHIFT) | ||
85 | #define REVERBERATION 11000L | ||
86 | |||
87 | #define SAMPLING_SHIFT 2 | ||
88 | #define SAMPLING_FACTOR (1UL<<SAMPLING_SHIFT) | ||
89 | |||
90 | #define FRACBITS 28 | ||
91 | #define FRACMASK ((1UL<<FRACBITS)-1UL) | ||
92 | |||
93 | #define TICKLSIZE 8192 | ||
94 | #define TICKWSIZE (TICKLSIZE * 2) | ||
95 | #define TICKBSIZE (TICKWSIZE * 2) | ||
96 | |||
97 | #define CLICK_SHIFT_BASE 6 | ||
98 | #define CLICK_SHIFT (CLICK_SHIFT_BASE + SAMPLING_SHIFT) | ||
99 | #define CLICK_BUFFER (1L << CLICK_SHIFT) | ||
100 | |||
101 | #ifndef MIN | ||
102 | #define MIN(a,b) (((a)<(b)) ? (a) : (b)) | ||
103 | #endif | ||
104 | |||
105 | typedef struct VINFO { | ||
106 | UBYTE kick; /* =1 -> sample has to be restarted */ | ||
107 | UBYTE active; /* =1 -> sample is playing */ | ||
108 | UWORD flags; /* 16/8 bits looping/one-shot */ | ||
109 | SWORD handle; /* identifies the sample */ | ||
110 | ULONG start; /* start index */ | ||
111 | ULONG size; /* samplesize */ | ||
112 | ULONG reppos; /* loop start */ | ||
113 | ULONG repend; /* loop end */ | ||
114 | ULONG frq; /* current frequency */ | ||
115 | int vol; /* current volume */ | ||
116 | int pan; /* current panning position */ | ||
117 | |||
118 | int click; | ||
119 | int rampvol; | ||
120 | SLONG lastvalL,lastvalR; | ||
121 | int lvolsel,rvolsel; /* Volume factor in range 0-255 */ | ||
122 | int oldlvol,oldrvol; | ||
123 | |||
124 | SLONGLONG current; /* current index in the sample */ | ||
125 | SLONGLONG increment; /* increment value */ | ||
126 | } VINFO; | ||
127 | |||
128 | static SWORD **Samples; | ||
129 | static VINFO *vinf=NULL,*vnf; | ||
130 | static long tickleft,samplesthatfit,vc_memory=0; | ||
131 | static int vc_softchn; | ||
132 | static SLONGLONG idxsize,idxlpos,idxlend; | ||
133 | static SLONG *vc_tickbuf=NULL; | ||
134 | static UWORD vc_mode; | ||
135 | |||
136 | #ifdef _MSC_VER | ||
137 | /* Weird bug in compiler */ /* FIXME is this still needed? */ | ||
138 | typedef void (*MikMod_callback_t)(unsigned char *data, size_t len); | ||
139 | #endif | ||
140 | |||
141 | /* Reverb control variables */ | ||
142 | |||
143 | static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8; | ||
144 | static ULONG RVRindex; | ||
145 | |||
146 | /* For Mono or Left Channel */ | ||
147 | static SLONG *RVbufL1=NULL,*RVbufL2=NULL,*RVbufL3=NULL,*RVbufL4=NULL, | ||
148 | *RVbufL5=NULL,*RVbufL6=NULL,*RVbufL7=NULL,*RVbufL8=NULL; | ||
149 | |||
150 | /* For Stereo only (Right Channel) */ | ||
151 | static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL, | ||
152 | *RVbufR5=NULL,*RVbufR6=NULL,*RVbufR7=NULL,*RVbufR8=NULL; | ||
153 | |||
154 | #ifdef NATIVE_64BIT_INT | ||
155 | #define NATIVE SLONGLONG | ||
156 | #else | ||
157 | #define NATIVE SLONG | ||
158 | #endif | ||
159 | |||
160 | /*========== 32 bit sample mixers - only for 32 bit platforms */ | ||
161 | #ifndef NATIVE_64BIT_INT | ||
162 | |||
163 | static SLONG Mix32MonoNormal(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo) | ||
164 | { | ||
165 | SWORD sample=0; | ||
166 | SLONG i,f; | ||
167 | |||
168 | while(todo--) { | ||
169 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
170 | sample=(SWORD)( (((SLONG)(srce[i]*(FRACMASK+1L-f)) + | ||
171 | ((SLONG)srce[i+1]*f)) >> FRACBITS)); | ||
172 | idx+=increment; | ||
173 | |||
174 | if(vnf->rampvol) { | ||
175 | *dest++ += (long)( | ||
176 | ( ( (SLONG)(vnf->oldlvol*vnf->rampvol) + | ||
177 | (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * | ||
178 | (SLONG)sample ) >> CLICK_SHIFT ); | ||
179 | vnf->rampvol--; | ||
180 | } else | ||
181 | if(vnf->click) { | ||
182 | *dest++ += (long)( | ||
183 | ( ( ((SLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * | ||
184 | (SLONG)sample ) + | ||
185 | (vnf->lastvalL*vnf->click) ) >> CLICK_SHIFT ); | ||
186 | vnf->click--; | ||
187 | } else | ||
188 | *dest++ +=vnf->lvolsel*sample; | ||
189 | } | ||
190 | vnf->lastvalL=vnf->lvolsel * sample; | ||
191 | |||
192 | return idx; | ||
193 | } | ||
194 | |||
195 | static SLONG Mix32StereoNormal(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,ULONG todo) | ||
196 | { | ||
197 | SWORD sample=0; | ||
198 | SLONG i,f; | ||
199 | |||
200 | while(todo--) { | ||
201 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
202 | sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) + | ||
203 | ((SLONG)srce[i+1] * f)) >> FRACBITS)); | ||
204 | idx += increment; | ||
205 | |||
206 | if(vnf->rampvol) { | ||
207 | *dest++ += (long)( | ||
208 | ( ( ((SLONG)vnf->oldlvol*vnf->rampvol) + | ||
209 | (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) | ||
210 | ) * (SLONG)sample ) >> CLICK_SHIFT ); | ||
211 | *dest++ += (long)( | ||
212 | ( ( ((SLONG)vnf->oldrvol*vnf->rampvol) + | ||
213 | (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol)) | ||
214 | ) * (SLONG)sample ) >> CLICK_SHIFT ); | ||
215 | vnf->rampvol--; | ||
216 | } else | ||
217 | if(vnf->click) { | ||
218 | *dest++ += (long)( | ||
219 | ( ( (SLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * | ||
220 | (SLONG)sample ) + (vnf->lastvalL * vnf->click) ) | ||
221 | >> CLICK_SHIFT ); | ||
222 | *dest++ += (long)( | ||
223 | ( ( ((SLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) * | ||
224 | (SLONG)sample ) + (vnf->lastvalR * vnf->click) ) | ||
225 | >> CLICK_SHIFT ); | ||
226 | vnf->click--; | ||
227 | } else { | ||
228 | *dest++ +=vnf->lvolsel*sample; | ||
229 | *dest++ +=vnf->rvolsel*sample; | ||
230 | } | ||
231 | } | ||
232 | vnf->lastvalL=vnf->lvolsel*sample; | ||
233 | vnf->lastvalR=vnf->rvolsel*sample; | ||
234 | |||
235 | return idx; | ||
236 | } | ||
237 | |||
238 | static SLONG Mix32StereoSurround(const SWORD* const srce,SLONG* dest,SLONG idx,SLONG increment,ULONG todo) | ||
239 | { | ||
240 | SWORD sample=0; | ||
241 | long whoop; | ||
242 | SLONG i, f; | ||
243 | |||
244 | while(todo--) { | ||
245 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
246 | sample=(SWORD)(((((SLONG)srce[i]*(FRACMASK+1L-f)) + | ||
247 | ((SLONG)srce[i+1]*f)) >> FRACBITS)); | ||
248 | idx+=increment; | ||
249 | |||
250 | if(vnf->rampvol) { | ||
251 | whoop=(long)( | ||
252 | ( ( (SLONG)(vnf->oldlvol*vnf->rampvol) + | ||
253 | (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * | ||
254 | (SLONG)sample) >> CLICK_SHIFT ); | ||
255 | *dest++ +=whoop; | ||
256 | *dest++ -=whoop; | ||
257 | vnf->rampvol--; | ||
258 | } else | ||
259 | if(vnf->click) { | ||
260 | whoop = (long)( | ||
261 | ( ( ((SLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * | ||
262 | (SLONG)sample) + | ||
263 | (vnf->lastvalL * vnf->click) ) >> CLICK_SHIFT ); | ||
264 | *dest++ +=whoop; | ||
265 | *dest++ -=whoop; | ||
266 | vnf->click--; | ||
267 | } else { | ||
268 | *dest++ +=vnf->lvolsel*sample; | ||
269 | *dest++ -=vnf->lvolsel*sample; | ||
270 | } | ||
271 | } | ||
272 | vnf->lastvalL=vnf->lvolsel*sample; | ||
273 | vnf->lastvalR=vnf->lvolsel*sample; | ||
274 | |||
275 | return idx; | ||
276 | } | ||
277 | #endif | ||
278 | |||
279 | /*========== 64 bit mixers */ | ||
280 | |||
281 | static SLONGLONG MixMonoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,SLONG todo) | ||
282 | { | ||
283 | SWORD sample=0; | ||
284 | SLONGLONG i,f; | ||
285 | |||
286 | while(todo--) { | ||
287 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
288 | sample=(SWORD)((((SLONGLONG)(srce[i]*(FRACMASK+1L-f)) + | ||
289 | ((SLONGLONG)srce[i+1]*f)) >> FRACBITS)); | ||
290 | idx+=increment; | ||
291 | |||
292 | if(vnf->rampvol) { | ||
293 | *dest++ += (long)( | ||
294 | ( ( (SLONGLONG)(vnf->oldlvol*vnf->rampvol) + | ||
295 | (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * | ||
296 | (SLONGLONG)sample ) >> CLICK_SHIFT ); | ||
297 | vnf->rampvol--; | ||
298 | } else | ||
299 | if(vnf->click) { | ||
300 | *dest++ += (long)( | ||
301 | ( ( ((SLONGLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * | ||
302 | (SLONGLONG)sample ) + | ||
303 | (vnf->lastvalL*vnf->click) ) >> CLICK_SHIFT ); | ||
304 | vnf->click--; | ||
305 | } else | ||
306 | *dest++ +=vnf->lvolsel*sample; | ||
307 | } | ||
308 | vnf->lastvalL=vnf->lvolsel * sample; | ||
309 | |||
310 | return idx; | ||
311 | } | ||
312 | |||
313 | /* Slowest part... */ | ||
314 | |||
315 | #if defined HAVE_SSE2 || defined HAVE_ALTIVEC | ||
316 | |||
317 | static __inline SWORD GetSample(const SWORD* const srce, SLONGLONG idx) | ||
318 | { | ||
319 | SLONGLONG i=idx>>FRACBITS; | ||
320 | SLONGLONG f=idx&FRACMASK; | ||
321 | return (SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + | ||
322 | ((SLONGLONG)srce[i+1] * f)) >> FRACBITS)); | ||
323 | } | ||
324 | |||
325 | static SLONGLONG MixSIMDStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo) | ||
326 | { | ||
327 | SWORD vol[8] = {vnf->lvolsel, vnf->rvolsel}; | ||
328 | SWORD sample=0; | ||
329 | SLONG remain = todo; | ||
330 | |||
331 | /* Dest can be misaligned */ | ||
332 | while(!IS_ALIGNED_16(dest)) { | ||
333 | sample=srce[idx >> FRACBITS]; | ||
334 | idx += increment; | ||
335 | *dest++ += vol[0] * sample; | ||
336 | *dest++ += vol[1] * sample; | ||
337 | todo--; | ||
338 | if(!todo) goto end; | ||
339 | } | ||
340 | |||
341 | /* Srce is always aligned */ | ||
342 | |||
343 | #if defined HAVE_SSE2 | ||
344 | remain = todo&3; | ||
345 | { | ||
346 | __m128i v0 = _mm_set_epi16(0, vol[1], | ||
347 | 0, vol[0], | ||
348 | 0, vol[1], | ||
349 | 0, vol[0]); | ||
350 | for(todo>>=2;todo; todo--) | ||
351 | { | ||
352 | SWORD s0 = GetSample(srce, idx); | ||
353 | SWORD s1 = GetSample(srce, idx += increment); | ||
354 | SWORD s2 = GetSample(srce, idx += increment); | ||
355 | SWORD s3 = GetSample(srce, idx += increment); | ||
356 | __m128i v1 = _mm_set_epi16(0, s1, 0, s1, 0, s0, 0, s0); | ||
357 | __m128i v2 = _mm_set_epi16(0, s3, 0, s3, 0, s2, 0, s2); | ||
358 | __m128i v3 = _mm_load_si128((__m128i*)(dest+0)); | ||
359 | __m128i v4 = _mm_load_si128((__m128i*)(dest+4)); | ||
360 | _mm_store_si128((__m128i*)(dest+0), _mm_add_epi32(v3, _mm_madd_epi16(v0, v1))); | ||
361 | _mm_store_si128((__m128i*)(dest+4), _mm_add_epi32(v4, _mm_madd_epi16(v0, v2))); | ||
362 | dest+=8; | ||
363 | idx += increment; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | #elif defined HAVE_ALTIVEC | ||
368 | remain = todo&3; | ||
369 | { | ||
370 | SWORD s[8]; | ||
371 | vector signed short r0 = vec_ld(0, vol); | ||
372 | vector signed short v0 = vec_perm(r0, r0, (vector unsigned char)(0, 1, /* l */ | ||
373 | 0, 1, /* l */ | ||
374 | 2, 3, /* r */ | ||
375 | 2, 1, /* r */ | ||
376 | 0, 1, /* l */ | ||
377 | 0, 1, /* l */ | ||
378 | 2, 3, /* r */ | ||
379 | 2, 3 /* r */ | ||
380 | )); | ||
381 | |||
382 | for(todo>>=2;todo; todo--) | ||
383 | { | ||
384 | vector short int r1; | ||
385 | vector signed short v1, v2; | ||
386 | vector signed int v3, v4, v5, v6; | ||
387 | |||
388 | /* Load constants */ | ||
389 | s[0] = GetSample(srce, idx); | ||
390 | s[1] = GetSample(srce, idx += increment); | ||
391 | s[2] = GetSample(srce, idx += increment); | ||
392 | s[3] = GetSample(srce, idx += increment); | ||
393 | s[4] = 0; | ||
394 | |||
395 | r1 = vec_ld(0, s); | ||
396 | v1 = vec_perm(r1, r1, (vector unsigned char) | ||
397 | (0*2, 0*2+1, /* s0 */ | ||
398 | 4*2, 4*2+1, /* 0 */ | ||
399 | 0*2, 0*2+1, /* s0 */ | ||
400 | 4*2, 4*2+1, /* 0 */ | ||
401 | 1*2, 1*2+1, /* s1 */ | ||
402 | 4*2, 4*2+1, /* 0 */ | ||
403 | 1*2, 1*2+1, /* s1 */ | ||
404 | 4*2, 4*2+1 /* 0 */ | ||
405 | ) ); | ||
406 | v2 = vec_perm(r1, r1, (vector unsigned char) | ||
407 | (2*2, 2*2+1, /* s2 */ | ||
408 | 4*2, 4*2+1, /* 0 */ | ||
409 | 2*2, 2*2+1, /* s2 */ | ||
410 | 4*2, 4*2+1, /* 0 */ | ||
411 | 3*2, 3*2+1, /* s3 */ | ||
412 | 4*2, 4*2+1, /* 0 */ | ||
413 | 3*2, 3*2+1, /* s3 */ | ||
414 | 4*2, 4*2+1 /* 0 */ | ||
415 | ) ); | ||
416 | |||
417 | v3 = vec_ld(0, dest); | ||
418 | v4 = vec_ld(0x10, dest); | ||
419 | v5 = vec_mule(v0, v1); | ||
420 | v6 = vec_mule(v0, v2); | ||
421 | |||
422 | vec_st(vec_add(v3, v5), 0, dest); | ||
423 | vec_st(vec_add(v4, v6), 0x10, dest); | ||
424 | |||
425 | dest+=8; | ||
426 | idx += increment; | ||
427 | } | ||
428 | } | ||
429 | #endif /* HAVE_ALTIVEC */ | ||
430 | |||
431 | /* Remaining bits */ | ||
432 | while(remain--) { | ||
433 | sample=GetSample(srce, idx); | ||
434 | idx+= increment; | ||
435 | *dest++ += vol[0] * sample; | ||
436 | *dest++ += vol[1] * sample; | ||
437 | } | ||
438 | end: | ||
439 | vnf->lastvalL=vnf->lvolsel*sample; | ||
440 | vnf->lastvalR=vnf->rvolsel*sample; | ||
441 | return idx; | ||
442 | } | ||
443 | |||
444 | static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo) | ||
445 | { | ||
446 | SWORD sample=0; | ||
447 | SLONGLONG i,f; | ||
448 | |||
449 | if (vnf->rampvol) | ||
450 | while(todo) { | ||
451 | todo--; | ||
452 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
453 | sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + | ||
454 | ((SLONGLONG)srce[i+1] * f)) >> FRACBITS)); | ||
455 | idx += increment; | ||
456 | |||
457 | *dest++ += (long)( | ||
458 | ( ( ((SLONGLONG)vnf->oldlvol*vnf->rampvol) + | ||
459 | (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) | ||
460 | ) * (SLONGLONG)sample ) >> CLICK_SHIFT ); | ||
461 | *dest++ += (long)( | ||
462 | ( ( ((SLONGLONG)vnf->oldrvol*vnf->rampvol) + | ||
463 | (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol)) | ||
464 | ) * (SLONGLONG)sample ) >> CLICK_SHIFT ); | ||
465 | vnf->rampvol--; | ||
466 | |||
467 | if (!vnf->rampvol) | ||
468 | break; | ||
469 | } | ||
470 | |||
471 | if (vnf->click) | ||
472 | while(todo) { | ||
473 | todo--; | ||
474 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
475 | sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + | ||
476 | ((SLONGLONG)srce[i+1] * f)) >> FRACBITS)); | ||
477 | idx += increment; | ||
478 | |||
479 | *dest++ += (long)( | ||
480 | ( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * | ||
481 | (SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) ) | ||
482 | >> CLICK_SHIFT ); | ||
483 | |||
484 | *dest++ += (long)( | ||
485 | ( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) * | ||
486 | (SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) ) | ||
487 | >> CLICK_SHIFT ); | ||
488 | vnf->click--; | ||
489 | |||
490 | if (!vnf->click) | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | if (todo) | ||
495 | { | ||
496 | if (md_mode & DMODE_SIMDMIXER) { | ||
497 | return MixSIMDStereoNormal(srce, dest, idx, increment, todo); | ||
498 | } | ||
499 | while(todo) | ||
500 | { | ||
501 | i=idx>>FRACBITS, | ||
502 | f=idx&FRACMASK; | ||
503 | sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + | ||
504 | ((SLONGLONG)srce[i+1] * f)) >> FRACBITS)); | ||
505 | idx += increment; | ||
506 | |||
507 | *dest++ +=vnf->lvolsel*sample; | ||
508 | *dest++ +=vnf->rvolsel*sample; | ||
509 | todo--; | ||
510 | } | ||
511 | } | ||
512 | vnf->lastvalL=vnf->lvolsel*sample; | ||
513 | vnf->lastvalR=vnf->rvolsel*sample; | ||
514 | |||
515 | return idx; | ||
516 | } | ||
517 | |||
518 | #else /* HAVE_SSE2 || HAVE_ALTIVEC */ | ||
519 | static SLONGLONG MixStereoNormal(const SWORD* const srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo) | ||
520 | { | ||
521 | SWORD sample=0; | ||
522 | SLONGLONG i,f; | ||
523 | |||
524 | while(todo--) { | ||
525 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
526 | sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + | ||
527 | ((SLONGLONG)srce[i+1] * f)) >> FRACBITS)); | ||
528 | idx += increment; | ||
529 | |||
530 | if(vnf->rampvol) { | ||
531 | *dest++ += (long)( | ||
532 | ( ( ((SLONGLONG)vnf->oldlvol*vnf->rampvol) + | ||
533 | (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) | ||
534 | ) * (SLONGLONG)sample ) >> CLICK_SHIFT ); | ||
535 | *dest++ += (long)( | ||
536 | ( ( ((SLONGLONG)vnf->oldrvol*vnf->rampvol) + | ||
537 | (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol)) | ||
538 | ) * (SLONGLONG)sample ) >> CLICK_SHIFT ); | ||
539 | vnf->rampvol--; | ||
540 | } else | ||
541 | if(vnf->click) { | ||
542 | *dest++ += (long)( | ||
543 | ( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * | ||
544 | (SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) ) | ||
545 | >> CLICK_SHIFT ); | ||
546 | *dest++ += (long)( | ||
547 | ( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) * | ||
548 | (SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) ) | ||
549 | >> CLICK_SHIFT ); | ||
550 | vnf->click--; | ||
551 | } else { | ||
552 | *dest++ +=vnf->lvolsel*sample; | ||
553 | *dest++ +=vnf->rvolsel*sample; | ||
554 | } | ||
555 | } | ||
556 | vnf->lastvalL=vnf->lvolsel*sample; | ||
557 | vnf->lastvalR=vnf->rvolsel*sample; | ||
558 | |||
559 | return idx; | ||
560 | } | ||
561 | #endif /* HAVE_SSE2 || HAVE_ALTIVEC */ | ||
562 | |||
563 | |||
564 | static SLONGLONG MixStereoSurround(const SWORD* srce,SLONG* dest,SLONGLONG idx,SLONGLONG increment,ULONG todo) | ||
565 | { | ||
566 | SWORD sample=0; | ||
567 | long whoop; | ||
568 | SLONGLONG i, f; | ||
569 | |||
570 | while(todo--) { | ||
571 | i=idx>>FRACBITS,f=idx&FRACMASK; | ||
572 | sample=(SWORD)(((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + | ||
573 | ((SLONGLONG)srce[i+1]*f)) >> FRACBITS)); | ||
574 | idx+=increment; | ||
575 | |||
576 | if(vnf->rampvol) { | ||
577 | whoop=(long)( | ||
578 | ( ( (SLONGLONG)(vnf->oldlvol*vnf->rampvol) + | ||
579 | (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * | ||
580 | (SLONGLONG)sample) >> CLICK_SHIFT ); | ||
581 | *dest++ +=whoop; | ||
582 | *dest++ -=whoop; | ||
583 | vnf->rampvol--; | ||
584 | } else | ||
585 | if(vnf->click) { | ||
586 | whoop = (long)( | ||
587 | ( ( ((SLONGLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * | ||
588 | (SLONGLONG)sample) + | ||
589 | (vnf->lastvalL * vnf->click) ) >> CLICK_SHIFT ); | ||
590 | *dest++ +=whoop; | ||
591 | *dest++ -=whoop; | ||
592 | vnf->click--; | ||
593 | } else { | ||
594 | *dest++ +=vnf->lvolsel*sample; | ||
595 | *dest++ -=vnf->lvolsel*sample; | ||
596 | } | ||
597 | } | ||
598 | vnf->lastvalL=vnf->lvolsel*sample; | ||
599 | vnf->lastvalR=vnf->lvolsel*sample; | ||
600 | |||
601 | return idx; | ||
602 | } | ||
603 | |||
604 | static void(*Mix32toFP)(float* dste,const SLONG *srce,NATIVE count); | ||
605 | static void(*Mix32to16)(SWORD* dste,const SLONG *srce,NATIVE count); | ||
606 | static void(*Mix32to8)(SBYTE* dste,const SLONG *srce,NATIVE count); | ||
607 | static void(*MixReverb)(SLONG *srce,NATIVE count); | ||
608 | |||
609 | /* Reverb macros */ | ||
610 | #define COMPUTE_LOC(n) loc##n = RVRindex % RVc##n | ||
611 | #define COMPUTE_LECHO(n) RVbufL##n [loc##n ]=speedup+((ReverbPct*RVbufL##n [loc##n ])>>7) | ||
612 | #define COMPUTE_RECHO(n) RVbufR##n [loc##n ]=speedup+((ReverbPct*RVbufR##n [loc##n ])>>7) | ||
613 | |||
614 | static void MixReverb_Normal(SLONG *srce,NATIVE count) | ||
615 | { | ||
616 | NATIVE speedup; | ||
617 | int ReverbPct; | ||
618 | unsigned int loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8; | ||
619 | |||
620 | ReverbPct=58+(md_reverb*4); | ||
621 | |||
622 | COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); | ||
623 | COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); | ||
624 | |||
625 | while(count--) { | ||
626 | /* Compute the left channel echo buffers */ | ||
627 | speedup = *srce >> 3; | ||
628 | |||
629 | COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4); | ||
630 | COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8); | ||
631 | |||
632 | /* Prepare to compute actual finalized data */ | ||
633 | RVRindex++; | ||
634 | |||
635 | COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); | ||
636 | COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); | ||
637 | |||
638 | /* left channel */ | ||
639 | *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ | ||
640 | RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | static void MixReverb_Stereo(SLONG *srce,NATIVE count) | ||
645 | { | ||
646 | NATIVE speedup; | ||
647 | int ReverbPct; | ||
648 | unsigned int loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8; | ||
649 | |||
650 | ReverbPct=58+(md_reverb*4); | ||
651 | |||
652 | COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); | ||
653 | COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); | ||
654 | |||
655 | while(count--) { | ||
656 | /* Compute the left channel echo buffers */ | ||
657 | speedup = *srce >> 3; | ||
658 | |||
659 | COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4); | ||
660 | COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8); | ||
661 | |||
662 | /* Compute the right channel echo buffers */ | ||
663 | speedup = srce[1] >> 3; | ||
664 | |||
665 | COMPUTE_RECHO(1); COMPUTE_RECHO(2); COMPUTE_RECHO(3); COMPUTE_RECHO(4); | ||
666 | COMPUTE_RECHO(5); COMPUTE_RECHO(6); COMPUTE_RECHO(7); COMPUTE_RECHO(8); | ||
667 | |||
668 | /* Prepare to compute actual finalized data */ | ||
669 | RVRindex++; | ||
670 | |||
671 | COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); | ||
672 | COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); | ||
673 | |||
674 | /* left channel */ | ||
675 | *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ | ||
676 | RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; | ||
677 | |||
678 | /* right channel */ | ||
679 | *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+ | ||
680 | RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; | ||
681 | } | ||
682 | } | ||
683 | |||
684 | static void (*MixLowPass)(SLONG* srce,NATIVE count); | ||
685 | |||
686 | static int nLeftNR, nRightNR; | ||
687 | |||
688 | static void MixLowPass_Stereo(SLONG* srce,NATIVE count) | ||
689 | { | ||
690 | int n1 = nLeftNR, n2 = nRightNR; | ||
691 | SLONG *pnr = srce; | ||
692 | int nr=count; | ||
693 | for (; nr; nr--) | ||
694 | { | ||
695 | int vnr = pnr[0] >> 1; | ||
696 | pnr[0] = vnr + n1; | ||
697 | n1 = vnr; | ||
698 | vnr = pnr[1] >> 1; | ||
699 | pnr[1] = vnr + n2; | ||
700 | n2 = vnr; | ||
701 | pnr += 2; | ||
702 | } | ||
703 | nLeftNR = n1; | ||
704 | nRightNR = n2; | ||
705 | } | ||
706 | |||
707 | static void MixLowPass_Normal(SLONG* srce,NATIVE count) | ||
708 | { | ||
709 | int n1 = nLeftNR; | ||
710 | SLONG *pnr = srce; | ||
711 | int nr=count; | ||
712 | for (; nr; nr--) | ||
713 | { | ||
714 | int vnr = pnr[0] >> 1; | ||
715 | pnr[0] = vnr + n1; | ||
716 | n1 = vnr; | ||
717 | pnr ++; | ||
718 | } | ||
719 | nLeftNR = n1; | ||
720 | } | ||
721 | |||
722 | /* Mixing macros */ | ||
723 | #define EXTRACT_SAMPLE_FP(var,attenuation) var=*srce++*((1.0f / 32768.0f) / (MAXVOL_FACTOR*attenuation)) | ||
724 | #define CHECK_SAMPLE_FP(var,bound) var=(var>bound)?bound:(var<-bound)?-bound:var | ||
725 | |||
726 | static void Mix32ToFP_Normal(float* dste,const SLONG *srce,NATIVE count) | ||
727 | { | ||
728 | float x1,x2,tmpx; | ||
729 | int i; | ||
730 | |||
731 | for(count/=SAMPLING_FACTOR;count;count--) { | ||
732 | tmpx=0.0f; | ||
733 | |||
734 | for(i=SAMPLING_FACTOR/2;i;i--) { | ||
735 | EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f); | ||
736 | |||
737 | CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f); | ||
738 | |||
739 | tmpx+=x1+x2; | ||
740 | } | ||
741 | *dste++ =tmpx*(1.0f/SAMPLING_FACTOR); | ||
742 | } | ||
743 | } | ||
744 | |||
745 | static void Mix32ToFP_Stereo(float* dste,const SLONG *srce,NATIVE count) | ||
746 | { | ||
747 | float x1,x2,x3,x4,tmpx,tmpy; | ||
748 | int i; | ||
749 | |||
750 | for(count/=SAMPLING_FACTOR;count;count--) { | ||
751 | tmpx=tmpy=0.0f; | ||
752 | |||
753 | for(i=SAMPLING_FACTOR/2;i;i--) { | ||
754 | EXTRACT_SAMPLE_FP(x1,1.0f); EXTRACT_SAMPLE_FP(x2,1.0f); | ||
755 | EXTRACT_SAMPLE_FP(x3,1.0f); EXTRACT_SAMPLE_FP(x4,1.0f); | ||
756 | |||
757 | CHECK_SAMPLE_FP(x1,1.0f); CHECK_SAMPLE_FP(x2,1.0f); | ||
758 | CHECK_SAMPLE_FP(x3,1.0f); CHECK_SAMPLE_FP(x4,1.0f); | ||
759 | |||
760 | tmpx+=x1+x3; | ||
761 | tmpy+=x2+x4; | ||
762 | } | ||
763 | *dste++ =tmpx*(1.0f/SAMPLING_FACTOR); | ||
764 | *dste++ =tmpy*(1.0f/SAMPLING_FACTOR); | ||
765 | } | ||
766 | } | ||
767 | |||
768 | /* Mixing macros */ | ||
769 | #define EXTRACT_SAMPLE(var,attenuation) var=*srce++/(MAXVOL_FACTOR*attenuation) | ||
770 | #define CHECK_SAMPLE(var,bound) var=(var>=bound)?bound-1:(var<-bound)?-bound:var | ||
771 | |||
772 | static void Mix32To16_Normal(SWORD* dste,const SLONG *srce,NATIVE count) | ||
773 | { | ||
774 | NATIVE x1,x2,tmpx; | ||
775 | int i; | ||
776 | |||
777 | for(count/=SAMPLING_FACTOR;count;count--) { | ||
778 | tmpx=0; | ||
779 | |||
780 | for(i=SAMPLING_FACTOR/2;i;i--) { | ||
781 | EXTRACT_SAMPLE(x1,1); EXTRACT_SAMPLE(x2,1); | ||
782 | |||
783 | CHECK_SAMPLE(x1,32768); CHECK_SAMPLE(x2,32768); | ||
784 | |||
785 | tmpx+=x1+x2; | ||
786 | } | ||
787 | *dste++ =(SWORD)(tmpx/SAMPLING_FACTOR); | ||
788 | } | ||
789 | } | ||
790 | |||
791 | |||
792 | static void Mix32To16_Stereo(SWORD* dste,const SLONG *srce,NATIVE count) | ||
793 | { | ||
794 | NATIVE x1,x2,x3,x4,tmpx,tmpy; | ||
795 | int i; | ||
796 | |||
797 | for(count/=SAMPLING_FACTOR;count;count--) { | ||
798 | tmpx=tmpy=0; | ||
799 | |||
800 | for(i=SAMPLING_FACTOR/2;i;i--) { | ||
801 | EXTRACT_SAMPLE(x1,1); EXTRACT_SAMPLE(x2,1); | ||
802 | EXTRACT_SAMPLE(x3,1); EXTRACT_SAMPLE(x4,1); | ||
803 | |||
804 | CHECK_SAMPLE(x1,32768); CHECK_SAMPLE(x2,32768); | ||
805 | CHECK_SAMPLE(x3,32768); CHECK_SAMPLE(x4,32768); | ||
806 | |||
807 | tmpx+=x1+x3; | ||
808 | tmpy+=x2+x4; | ||
809 | } | ||
810 | *dste++ =(SWORD)(tmpx/SAMPLING_FACTOR); | ||
811 | *dste++ =(SWORD)(tmpy/SAMPLING_FACTOR); | ||
812 | } | ||
813 | } | ||
814 | |||
815 | static void Mix32To8_Normal(SBYTE* dste,const SLONG *srce,NATIVE count) | ||
816 | { | ||
817 | NATIVE x1,x2,tmpx; | ||
818 | int i; | ||
819 | |||
820 | for(count/=SAMPLING_FACTOR;count;count--) { | ||
821 | tmpx = 0; | ||
822 | |||
823 | for(i=SAMPLING_FACTOR/2;i;i--) { | ||
824 | EXTRACT_SAMPLE(x1,256); EXTRACT_SAMPLE(x2,256); | ||
825 | |||
826 | CHECK_SAMPLE(x1,128); CHECK_SAMPLE(x2,128); | ||
827 | |||
828 | tmpx+=x1+x2; | ||
829 | } | ||
830 | *dste++ = (SBYTE)((tmpx/SAMPLING_FACTOR)+128); | ||
831 | } | ||
832 | } | ||
833 | |||
834 | static void Mix32To8_Stereo(SBYTE* dste,const SLONG *srce,NATIVE count) | ||
835 | { | ||
836 | NATIVE x1,x2,x3,x4,tmpx,tmpy; | ||
837 | int i; | ||
838 | |||
839 | for(count/=SAMPLING_FACTOR;count;count--) { | ||
840 | tmpx=tmpy=0; | ||
841 | |||
842 | for(i=SAMPLING_FACTOR/2;i;i--) { | ||
843 | EXTRACT_SAMPLE(x1,256); EXTRACT_SAMPLE(x2,256); | ||
844 | EXTRACT_SAMPLE(x3,256); EXTRACT_SAMPLE(x4,256); | ||
845 | |||
846 | CHECK_SAMPLE(x1,128); CHECK_SAMPLE(x2,128); | ||
847 | CHECK_SAMPLE(x3,128); CHECK_SAMPLE(x4,128); | ||
848 | |||
849 | tmpx+=x1+x3; | ||
850 | tmpy+=x2+x4; | ||
851 | } | ||
852 | *dste++ =(SBYTE)((tmpx/SAMPLING_FACTOR)+128); | ||
853 | *dste++ =(SBYTE)((tmpy/SAMPLING_FACTOR)+128); | ||
854 | } | ||
855 | } | ||
856 | |||
857 | #if defined HAVE_SSE2 | ||
858 | #define SHIFT_MIX_TO_16 (BITSHIFT + 16 - 16) | ||
859 | /* TEST: Ok */ | ||
860 | static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count) | ||
861 | { | ||
862 | int remain = count; | ||
863 | |||
864 | /* Check unaligned dste buffer. srce is always aligned. */ | ||
865 | while(!IS_ALIGNED_16(dste)) | ||
866 | { | ||
867 | Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR); | ||
868 | dste+=2; | ||
869 | srce+=8; | ||
870 | count--; | ||
871 | if(!count) return; | ||
872 | } | ||
873 | |||
874 | /* dste and srce aligned. srce is always aligned. */ | ||
875 | remain = count & 15; | ||
876 | /* count / 2 for 1 sample */ | ||
877 | |||
878 | for(count>>=4;count;count--) | ||
879 | { | ||
880 | /* Load 32bit sample. 1st average */ | ||
881 | __m128i v0 = _mm_add_epi32( | ||
882 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+0)), SHIFT_MIX_TO_16), | ||
883 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+4)), SHIFT_MIX_TO_16) | ||
884 | ); /* v0: s0.l+s2.l | s0.r+s2.r | s1.l+s3.l | s1.r+s3.r */ | ||
885 | |||
886 | /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */ | ||
887 | __m128i v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2); | ||
888 | /* v1: s0.l+s2.l / 4 | s0.r+s2.r / 4 | s1.l+s3.l+s0.l+s2.l / 4 | s1.r+s3.r+s0.r+s2.r / 4 */ | ||
889 | |||
890 | __m128i v2 = _mm_add_epi32( | ||
891 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+8)), SHIFT_MIX_TO_16), | ||
892 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+12)), SHIFT_MIX_TO_16) | ||
893 | ); /* v2: s4.l+s6.l | s4.r+s6.r | s5.l+s7.l | s5.r+s7.r */ | ||
894 | |||
895 | __m128i v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */ | ||
896 | /* v3: s4.l+s6.l /4 | s4.r+s6.r / 4| s5.l+s7.l+s4.l+s6.l / 4 | s5.r+s7.r+s4.r+s6.l / 4 */ | ||
897 | |||
898 | /* pack two stereo samples in one */ | ||
899 | __m128i v4 = _mm_unpacklo_epi64(v1, v3); /* v4 = avg(s0,s1,s2,s3) | avg(s4,s5,s6,s7) */ | ||
900 | |||
901 | __m128i v6; | ||
902 | |||
903 | /* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */ | ||
904 | v0 = _mm_add_epi32( | ||
905 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+16)), SHIFT_MIX_TO_16), | ||
906 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+20)), SHIFT_MIX_TO_16) | ||
907 | ); /* 128bit = 2 stereo samples */ | ||
908 | |||
909 | /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */ | ||
910 | v1 = _mm_srai_epi32(_mm_add_epi32(v0, mm_hiqq(v0)), 2); | ||
911 | |||
912 | v2 = _mm_add_epi32( | ||
913 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+24)), SHIFT_MIX_TO_16), | ||
914 | _mm_srai_epi32(_mm_loadu_si128((__m128i const *)(srce+28)), SHIFT_MIX_TO_16) | ||
915 | ); | ||
916 | |||
917 | v3 = _mm_srai_epi32(_mm_add_epi32(v2, mm_hiqq(v2)), 2); /* Upper 64bit is unused */ | ||
918 | |||
919 | /* pack two stereo samples in one */ | ||
920 | v6 = _mm_unpacklo_epi64(v1, v3); /* v6 = avg(s8,s9,s10,s11) | avg(s12,s13,s14,s15) */ | ||
921 | |||
922 | _mm_store_si128((__m128i*)dste, _mm_packs_epi32(v4, v6)); /* 4 interpolated stereo sample 32bit to 4 */ | ||
923 | |||
924 | dste+=8; | ||
925 | srce+=32; /* 32 = 4 * 8 */ | ||
926 | } | ||
927 | |||
928 | /* FIXME: THIS PART WRITES PAST DST !! */ | ||
929 | if (remain) | ||
930 | { | ||
931 | Mix32To16_Stereo(dste, srce, remain); | ||
932 | } | ||
933 | } | ||
934 | |||
935 | #elif defined HAVE_ALTIVEC | ||
936 | #define SHIFT_MIX_TO_16 vec_splat_u32(BITSHIFT + 16 - 16) | ||
937 | /* TEST: Ok */ | ||
938 | static void Mix32To16_Stereo_SIMD_4Tap(SWORD* dste, const SLONG* srce, NATIVE count) | ||
939 | { | ||
940 | int remain = count; | ||
941 | |||
942 | /* Check unaligned dste buffer. srce is always aligned. */ | ||
943 | while(!IS_ALIGNED_16(dste)) | ||
944 | { | ||
945 | Mix32To16_Stereo(dste, srce, SAMPLING_FACTOR); | ||
946 | dste+=2; | ||
947 | srce+=8; | ||
948 | count--; | ||
949 | if(!count) return; | ||
950 | } | ||
951 | |||
952 | /* dste and srce aligned. srce is always aligned. */ | ||
953 | remain = count & 15; | ||
954 | for(count>>=4;count;count--) | ||
955 | { | ||
956 | /* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */ | ||
957 | vector signed int v0 = vec_add( | ||
958 | vec_sra(vec_ld(0, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */ | ||
959 | vec_sra(vec_ld(0x10, srce), SHIFT_MIX_TO_16) | ||
960 | ); /* 128bit = 2 stereo samples */ | ||
961 | |||
962 | /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */ | ||
963 | vector signed int v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2)); | ||
964 | |||
965 | vector signed int v2 = vec_add( | ||
966 | vec_sra(vec_ld(0x20, srce), SHIFT_MIX_TO_16), | ||
967 | vec_sra(vec_ld(0x30, srce), SHIFT_MIX_TO_16) | ||
968 | ); | ||
969 | |||
970 | vector signed int v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */ | ||
971 | |||
972 | /* pack two stereo samples in one */ | ||
973 | vector signed int v6, v4 = vec_unpacklo(v1, v3); /* v4 = lo64(v1) | lo64(v3) */ | ||
974 | |||
975 | /* Load 32bit sample. 1st average (s0.l+s2.l, s0.r+s2.r, s1.l+s3.l, s1.r+s3.r) */ | ||
976 | v0 = vec_add( | ||
977 | vec_sra(vec_ld(0x40, srce), SHIFT_MIX_TO_16), /* 128bit = 2 stereo samples */ | ||
978 | vec_sra(vec_ld(0x50, srce), SHIFT_MIX_TO_16) | ||
979 | ); /* 128bit = 2 stereo samples */ | ||
980 | |||
981 | /* 2nd average (s0.l+s2.l+s1.l+s3.l / 4, s0.r+s2.r+s1.r+s3.r / 4). Upper 64bit is unused (1 stereo sample) */ | ||
982 | v1 = vec_sra(vec_add(v0, vec_hiqq(v0)), vec_splat_u32(2)); | ||
983 | |||
984 | v2 = vec_add( | ||
985 | vec_sra(vec_ld(0x60, srce), SHIFT_MIX_TO_16), | ||
986 | vec_sra(vec_ld(0x70, srce), SHIFT_MIX_TO_16) | ||
987 | ); | ||
988 | |||
989 | v3 = vec_sra(vec_add(v2, vec_hiqq(v2)), vec_splat_u32(2)); /* Upper 64bit is unused */ | ||
990 | |||
991 | /* pack two stereo samples in one */ | ||
992 | v6 = vec_unpacklo(v1, v3); | ||
993 | |||
994 | vec_st(vec_packs(v4, v6), 0, dste); /* 4 interpolated stereo sample 32bit to 4 interpolated stereo sample 16bit + saturation */ | ||
995 | |||
996 | dste+=8; | ||
997 | srce+=32; /* 32 = 4 * 8 */ | ||
998 | } | ||
999 | |||
1000 | if (remain) | ||
1001 | { | ||
1002 | Mix32To16_Stereo(dste, srce, remain); | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | #endif | ||
1007 | |||
1008 | |||
1009 | static void AddChannel(SLONG* ptr,NATIVE todo) | ||
1010 | { | ||
1011 | SLONGLONG end,done; | ||
1012 | SWORD *s; | ||
1013 | |||
1014 | if(!(s=Samples[vnf->handle])) { | ||
1015 | vnf->current = vnf->active = 0; | ||
1016 | vnf->lastvalL = vnf->lastvalR = 0; | ||
1017 | return; | ||
1018 | } | ||
1019 | |||
1020 | /* update the 'current' index so the sample loops, or stops playing if it | ||
1021 | reached the end of the sample */ | ||
1022 | while(todo>0) { | ||
1023 | SLONGLONG endpos; | ||
1024 | |||
1025 | if(vnf->flags & SF_REVERSE) { | ||
1026 | /* The sample is playing in reverse */ | ||
1027 | if((vnf->flags&SF_LOOP)&&(vnf->current<idxlpos)) { | ||
1028 | /* the sample is looping and has reached the loopstart index */ | ||
1029 | if(vnf->flags & SF_BIDI) { | ||
1030 | /* sample is doing bidirectional loops, so 'bounce' the | ||
1031 | current index against the idxlpos */ | ||
1032 | vnf->current = idxlpos+(idxlpos-vnf->current); | ||
1033 | vnf->flags &= ~SF_REVERSE; | ||
1034 | vnf->increment = -vnf->increment; | ||
1035 | } else | ||
1036 | /* normal backwards looping, so set the current position to | ||
1037 | loopend index */ | ||
1038 | vnf->current=idxlend-(idxlpos-vnf->current); | ||
1039 | } else { | ||
1040 | /* the sample is not looping, so check if it reached index 0 */ | ||
1041 | if(vnf->current < 0) { | ||
1042 | /* playing index reached 0, so stop playing this sample */ | ||
1043 | vnf->current = vnf->active = 0; | ||
1044 | break; | ||
1045 | } | ||
1046 | } | ||
1047 | } else { | ||
1048 | /* The sample is playing forward */ | ||
1049 | if((vnf->flags & SF_LOOP) && | ||
1050 | (vnf->current >= idxlend)) { | ||
1051 | /* the sample is looping, check the loopend index */ | ||
1052 | if(vnf->flags & SF_BIDI) { | ||
1053 | /* sample is doing bidirectional loops, so 'bounce' the | ||
1054 | current index against the idxlend */ | ||
1055 | vnf->flags |= SF_REVERSE; | ||
1056 | vnf->increment = -vnf->increment; | ||
1057 | vnf->current = idxlend-(vnf->current-idxlend); | ||
1058 | } else | ||
1059 | /* normal backwards looping, so set the current position | ||
1060 | to loopend index */ | ||
1061 | vnf->current=idxlpos+(vnf->current-idxlend); | ||
1062 | } else { | ||
1063 | /* sample is not looping, so check if it reached the last | ||
1064 | position */ | ||
1065 | if(vnf->current >= idxsize) { | ||
1066 | /* yes, so stop playing this sample */ | ||
1067 | vnf->current = vnf->active = 0; | ||
1068 | break; | ||
1069 | } | ||
1070 | } | ||
1071 | } | ||
1072 | |||
1073 | end=(vnf->flags&SF_REVERSE)?(vnf->flags&SF_LOOP)?idxlpos:0: | ||
1074 | (vnf->flags&SF_LOOP)?idxlend:idxsize; | ||
1075 | |||
1076 | /* if the sample is not blocked... */ | ||
1077 | if((end==vnf->current)||(!vnf->increment)) | ||
1078 | done=0; | ||
1079 | else { | ||
1080 | done=MIN((end-vnf->current)/vnf->increment+1,todo); | ||
1081 | if(done<0) done=0; | ||
1082 | } | ||
1083 | |||
1084 | if(!done) { | ||
1085 | vnf->active = 0; | ||
1086 | break; | ||
1087 | } | ||
1088 | |||
1089 | endpos=vnf->current+done*vnf->increment; | ||
1090 | |||
1091 | if(vnf->vol || vnf->rampvol) { | ||
1092 | #ifndef NATIVE_64BIT_INT | ||
1093 | /* use the 32 bit mixers as often as we can (they're much faster) */ | ||
1094 | if((vnf->current<0x7fffffff)&&(endpos<0x7fffffff)) { | ||
1095 | if(vc_mode & DMODE_STEREO) { | ||
1096 | if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND)) | ||
1097 | vnf->current=(SLONGLONG)Mix32StereoSurround | ||
1098 | (s,ptr,vnf->current,vnf->increment,done); | ||
1099 | else | ||
1100 | vnf->current=Mix32StereoNormal | ||
1101 | (s,ptr,vnf->current,vnf->increment,done); | ||
1102 | } else | ||
1103 | vnf->current=Mix32MonoNormal | ||
1104 | (s,ptr,vnf->current,vnf->increment,done); | ||
1105 | } | ||
1106 | else | ||
1107 | #endif | ||
1108 | { | ||
1109 | if(vc_mode & DMODE_STEREO) { | ||
1110 | if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND)) | ||
1111 | vnf->current=MixStereoSurround | ||
1112 | (s,ptr,vnf->current,vnf->increment,done); | ||
1113 | else | ||
1114 | vnf->current=MixStereoNormal | ||
1115 | (s,ptr,vnf->current,vnf->increment,done); | ||
1116 | } else | ||
1117 | vnf->current=MixMonoNormal | ||
1118 | (s,ptr,vnf->current,vnf->increment,done); | ||
1119 | } | ||
1120 | } else { | ||
1121 | vnf->lastvalL = vnf->lastvalR = 0; | ||
1122 | /* update sample position */ | ||
1123 | vnf->current=endpos; | ||
1124 | } | ||
1125 | |||
1126 | todo -= done; | ||
1127 | ptr += (vc_mode & DMODE_STEREO)?(done<<1):done; | ||
1128 | } | ||
1129 | } | ||
1130 | |||
1131 | #define _IN_VIRTCH_ | ||
1132 | |||
1133 | #define VC1_SilenceBytes VC2_SilenceBytes | ||
1134 | #define VC1_WriteSamples VC2_WriteSamples | ||
1135 | #define VC1_WriteBytes VC2_WriteBytes | ||
1136 | #define VC1_Exit VC2_Exit | ||
1137 | #define VC1_VoiceSetVolume VC2_VoiceSetVolume | ||
1138 | #define VC1_VoiceGetVolume VC2_VoiceGetVolume | ||
1139 | #define VC1_VoiceSetPanning VC2_VoiceSetPanning | ||
1140 | #define VC1_VoiceGetPanning VC2_VoiceGetPanning | ||
1141 | #define VC1_VoiceSetFrequency VC2_VoiceSetFrequency | ||
1142 | #define VC1_VoiceGetFrequency VC2_VoiceGetFrequency | ||
1143 | #define VC1_VoicePlay VC2_VoicePlay | ||
1144 | #define VC1_VoiceStop VC2_VoiceStop | ||
1145 | #define VC1_VoiceStopped VC2_VoiceStopped | ||
1146 | #define VC1_VoiceGetPosition VC2_VoiceGetPosition | ||
1147 | #define VC1_SampleUnload VC2_SampleUnload | ||
1148 | #define VC1_SampleLoad VC2_SampleLoad | ||
1149 | #define VC1_SampleSpace VC2_SampleSpace | ||
1150 | #define VC1_SampleLength VC2_SampleLength | ||
1151 | #define VC1_VoiceRealVolume VC2_VoiceRealVolume | ||
1152 | |||
1153 | #include "virtch_common.c" | ||
1154 | #undef _IN_VIRTCH_ | ||
1155 | |||
1156 | void VC2_WriteSamples(SBYTE* buf,ULONG todo) | ||
1157 | { | ||
1158 | int left,portion=0; | ||
1159 | SBYTE *buffer; | ||
1160 | int t,pan,vol; | ||
1161 | |||
1162 | todo*=SAMPLING_FACTOR; | ||
1163 | |||
1164 | while(todo) { | ||
1165 | if(!tickleft) { | ||
1166 | if(vc_mode & DMODE_SOFT_MUSIC) md_player(); | ||
1167 | tickleft=(md_mixfreq*125L*SAMPLING_FACTOR)/(md_bpm*50L); | ||
1168 | tickleft&=~(SAMPLING_FACTOR-1); | ||
1169 | } | ||
1170 | left = MIN(tickleft, (int)todo); | ||
1171 | buffer = buf; | ||
1172 | tickleft -= left; | ||
1173 | todo -= left; | ||
1174 | buf += samples2bytes(left)/SAMPLING_FACTOR; | ||
1175 | |||
1176 | while(left) { | ||
1177 | portion = MIN(left, samplesthatfit); | ||
1178 | memset(vc_tickbuf,0,portion<<((vc_mode&DMODE_STEREO)?3:2)); | ||
1179 | for(t=0;t<vc_softchn;t++) { | ||
1180 | vnf = &vinf[t]; | ||
1181 | |||
1182 | if(vnf->kick) { | ||
1183 | vnf->current=((SLONGLONG)(vnf->start))<<FRACBITS; | ||
1184 | vnf->kick = 0; | ||
1185 | vnf->active = 1; | ||
1186 | vnf->click = CLICK_BUFFER; | ||
1187 | vnf->rampvol = 0; | ||
1188 | } | ||
1189 | |||
1190 | if(!vnf->frq) vnf->active = 0; | ||
1191 | |||
1192 | if(vnf->active) { | ||
1193 | vnf->increment=((SLONGLONG)(vnf->frq)<<(FRACBITS-SAMPLING_SHIFT)) | ||
1194 | /md_mixfreq; | ||
1195 | if(vnf->flags&SF_REVERSE) vnf->increment=-vnf->increment; | ||
1196 | vol = vnf->vol; pan = vnf->pan; | ||
1197 | |||
1198 | vnf->oldlvol=vnf->lvolsel;vnf->oldrvol=vnf->rvolsel; | ||
1199 | if(vc_mode & DMODE_STEREO) { | ||
1200 | if(pan!=PAN_SURROUND) { | ||
1201 | vnf->lvolsel=(vol*(PAN_RIGHT-pan))>>8; | ||
1202 | vnf->rvolsel=(vol*pan)>>8; | ||
1203 | } else { | ||
1204 | vnf->lvolsel=vnf->rvolsel=(vol * 256L) / 480; | ||
1205 | } | ||
1206 | } else | ||
1207 | vnf->lvolsel=vol; | ||
1208 | |||
1209 | idxsize=(vnf->size)?((SLONGLONG)(vnf->size)<<FRACBITS)-1:0; | ||
1210 | idxlend=(vnf->repend)?((SLONGLONG)(vnf->repend)<<FRACBITS)-1:0; | ||
1211 | idxlpos=(SLONGLONG)(vnf->reppos)<<FRACBITS; | ||
1212 | AddChannel(vc_tickbuf,portion); | ||
1213 | } | ||
1214 | } | ||
1215 | |||
1216 | if(md_mode & DMODE_NOISEREDUCTION) { | ||
1217 | MixLowPass(vc_tickbuf, portion); | ||
1218 | } | ||
1219 | |||
1220 | if(md_reverb) { | ||
1221 | if(md_reverb>15) md_reverb=15; | ||
1222 | MixReverb(vc_tickbuf,portion); | ||
1223 | } | ||
1224 | |||
1225 | if (vc_callback) { | ||
1226 | vc_callback((unsigned char*)vc_tickbuf, portion); | ||
1227 | } | ||
1228 | |||
1229 | if(vc_mode & DMODE_FLOAT) | ||
1230 | Mix32toFP((float*)buffer,vc_tickbuf,portion); | ||
1231 | else if(vc_mode & DMODE_16BITS) | ||
1232 | Mix32to16((SWORD*)buffer,vc_tickbuf,portion); | ||
1233 | else | ||
1234 | Mix32to8((SBYTE*)buffer,vc_tickbuf,portion); | ||
1235 | |||
1236 | buffer += samples2bytes(portion) / SAMPLING_FACTOR; | ||
1237 | left -= portion; | ||
1238 | } | ||
1239 | } | ||
1240 | } | ||
1241 | |||
1242 | int VC2_Init(void) | ||
1243 | { | ||
1244 | VC_SetupPointers(); | ||
1245 | |||
1246 | if (!(md_mode&DMODE_HQMIXER)) | ||
1247 | return VC1_Init(); | ||
1248 | |||
1249 | if(!(Samples=(SWORD**)MikMod_amalloc(MAXSAMPLEHANDLES*sizeof(SWORD*)))) { | ||
1250 | _mm_errno = MMERR_INITIALIZING_MIXER; | ||
1251 | return 1; | ||
1252 | } | ||
1253 | if(!vc_tickbuf) { | ||
1254 | if(!(vc_tickbuf=(SLONG*)MikMod_amalloc((TICKLSIZE+32)*sizeof(SLONG)))) { | ||
1255 | _mm_errno = MMERR_INITIALIZING_MIXER; | ||
1256 | return 1; | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | if(md_mode & DMODE_STEREO) { | ||
1261 | Mix32toFP = Mix32ToFP_Stereo; | ||
1262 | #if ((defined HAVE_ALTIVEC || defined HAVE_SSE2) && (SAMPLING_FACTOR == 4)) | ||
1263 | if (md_mode & DMODE_SIMDMIXER) | ||
1264 | Mix32to16 = Mix32To16_Stereo_SIMD_4Tap; | ||
1265 | else | ||
1266 | #endif | ||
1267 | Mix32to16 = Mix32To16_Stereo; | ||
1268 | Mix32to8 = Mix32To8_Stereo; | ||
1269 | MixReverb = MixReverb_Stereo; | ||
1270 | MixLowPass = MixLowPass_Stereo; | ||
1271 | } else { | ||
1272 | Mix32toFP = Mix32ToFP_Normal; | ||
1273 | Mix32to16 = Mix32To16_Normal; | ||
1274 | Mix32to8 = Mix32To8_Normal; | ||
1275 | MixReverb = MixReverb_Normal; | ||
1276 | MixLowPass = MixLowPass_Normal; | ||
1277 | } | ||
1278 | |||
1279 | md_mode |= DMODE_INTERP; | ||
1280 | vc_mode = md_mode; | ||
1281 | return 0; | ||
1282 | } | ||
1283 | |||
1284 | int VC2_PlayStart(void) | ||
1285 | { | ||
1286 | md_mode|=DMODE_INTERP; | ||
1287 | |||
1288 | samplesthatfit = TICKLSIZE; | ||
1289 | if(vc_mode & DMODE_STEREO) samplesthatfit >>= 1; | ||
1290 | tickleft = 0; | ||
1291 | |||
1292 | RVc1 = (5000L * md_mixfreq) / (REVERBERATION * 10); | ||
1293 | RVc2 = (5078L * md_mixfreq) / (REVERBERATION * 10); | ||
1294 | RVc3 = (5313L * md_mixfreq) / (REVERBERATION * 10); | ||
1295 | RVc4 = (5703L * md_mixfreq) / (REVERBERATION * 10); | ||
1296 | RVc5 = (6250L * md_mixfreq) / (REVERBERATION * 10); | ||
1297 | RVc6 = (6953L * md_mixfreq) / (REVERBERATION * 10); | ||
1298 | RVc7 = (7813L * md_mixfreq) / (REVERBERATION * 10); | ||
1299 | RVc8 = (8828L * md_mixfreq) / (REVERBERATION * 10); | ||
1300 | |||
1301 | if(!(RVbufL1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1; | ||
1302 | if(!(RVbufL2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; | ||
1303 | if(!(RVbufL3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; | ||
1304 | if(!(RVbufL4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1; | ||
1305 | if(!(RVbufL5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1; | ||
1306 | if(!(RVbufL6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; | ||
1307 | if(!(RVbufL7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; | ||
1308 | if(!(RVbufL8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; | ||
1309 | |||
1310 | /* allocate reverb buffers for the right channel if in stereo mode only. */ | ||
1311 | if (vc_mode & DMODE_STEREO) { | ||
1312 | if(!(RVbufR1=(SLONG*)MikMod_calloc((RVc1+1),sizeof(SLONG)))) return 1; | ||
1313 | if(!(RVbufR2=(SLONG*)MikMod_calloc((RVc2+1),sizeof(SLONG)))) return 1; | ||
1314 | if(!(RVbufR3=(SLONG*)MikMod_calloc((RVc3+1),sizeof(SLONG)))) return 1; | ||
1315 | if(!(RVbufR4=(SLONG*)MikMod_calloc((RVc4+1),sizeof(SLONG)))) return 1; | ||
1316 | if(!(RVbufR5=(SLONG*)MikMod_calloc((RVc5+1),sizeof(SLONG)))) return 1; | ||
1317 | if(!(RVbufR6=(SLONG*)MikMod_calloc((RVc6+1),sizeof(SLONG)))) return 1; | ||
1318 | if(!(RVbufR7=(SLONG*)MikMod_calloc((RVc7+1),sizeof(SLONG)))) return 1; | ||
1319 | if(!(RVbufR8=(SLONG*)MikMod_calloc((RVc8+1),sizeof(SLONG)))) return 1; | ||
1320 | } | ||
1321 | |||
1322 | RVRindex = 0; | ||
1323 | return 0; | ||
1324 | } | ||
1325 | |||
1326 | void VC2_PlayStop(void) | ||
1327 | { | ||
1328 | MikMod_free(RVbufL1); | ||
1329 | MikMod_free(RVbufL2); | ||
1330 | MikMod_free(RVbufL3); | ||
1331 | MikMod_free(RVbufL4); | ||
1332 | MikMod_free(RVbufL5); | ||
1333 | MikMod_free(RVbufL6); | ||
1334 | MikMod_free(RVbufL7); | ||
1335 | MikMod_free(RVbufL8); | ||
1336 | MikMod_free(RVbufR1); | ||
1337 | MikMod_free(RVbufR2); | ||
1338 | MikMod_free(RVbufR3); | ||
1339 | MikMod_free(RVbufR4); | ||
1340 | MikMod_free(RVbufR5); | ||
1341 | MikMod_free(RVbufR6); | ||
1342 | MikMod_free(RVbufR7); | ||
1343 | MikMod_free(RVbufR8); | ||
1344 | |||
1345 | RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; | ||
1346 | RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; | ||
1347 | } | ||
1348 | |||
1349 | int VC2_SetNumVoices(void) | ||
1350 | { | ||
1351 | int t; | ||
1352 | |||
1353 | md_mode|=DMODE_INTERP; | ||
1354 | |||
1355 | if(!(vc_softchn=md_softchn)) return 0; | ||
1356 | |||
1357 | MikMod_free(vinf); | ||
1358 | if(!(vinf=(VINFO*)MikMod_calloc(vc_softchn,sizeof(VINFO)))) return 1; | ||
1359 | |||
1360 | for(t=0;t<vc_softchn;t++) { | ||
1361 | vinf[t].frq=10000; | ||
1362 | vinf[t].pan=(t&1)?PAN_LEFT:PAN_RIGHT; | ||
1363 | } | ||
1364 | |||
1365 | return 0; | ||
1366 | } | ||
1367 | |||
1368 | #endif /* ! NO_HQMIXER */ | ||
1369 | |||
1370 | /* ex:set ts=4: */ | ||
diff --git a/apps/plugins/mikmod/virtch_common.c b/apps/plugins/mikmod/virtch_common.c index e13f6d1c51..3395120a47 100644 --- a/apps/plugins/mikmod/virtch_common.c +++ b/apps/plugins/mikmod/virtch_common.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,90 +20,96 @@ | |||
20 | 20 | ||
21 | /*============================================================================== | 21 | /*============================================================================== |
22 | 22 | ||
23 | $Id: virtch_common.c,v 1.2 2005/03/30 19:11:50 realtech Exp $ | 23 | $Id$ |
24 | 24 | ||
25 | Common source parts between the two software mixers. | 25 | Common source parts between the two software mixers. |
26 | This file is probably the ugliest part of libmikmod... | 26 | This file is probably the ugliest part of libmikmod... |
27 | 27 | ||
28 | ==============================================================================*/ | 28 | ==============================================================================*/ |
29 | 29 | ||
30 | #ifndef _IN_VIRTCH_ | 30 | #if defined(HAVE_CONFIG_H) && !defined(_IN_VIRTCH_) /* config.h isn't guarded */ |
31 | 31 | #include "config.h" | |
32 | #endif | ||
32 | #include "mikmod_internals.h" | 33 | #include "mikmod_internals.h" |
33 | 34 | ||
34 | extern int VC1_Init(void); | 35 | #ifndef NO_HQMIXER |
35 | //extern int VC2_Init(void); | 36 | extern ULONG VC1_SilenceBytes(SBYTE*,ULONG); |
36 | static int (*VC_Init_ptr)(void)=VC1_Init; | 37 | extern ULONG VC2_SilenceBytes(SBYTE*,ULONG); |
38 | extern ULONG VC1_WriteBytes(SBYTE*,ULONG); | ||
39 | extern ULONG VC2_WriteBytes(SBYTE*,ULONG); | ||
37 | extern void VC1_Exit(void); | 40 | extern void VC1_Exit(void); |
38 | //extern void VC2_Exit(void); | 41 | extern void VC2_Exit(void); |
39 | static void (*VC_Exit_ptr)(void)=VC1_Exit; | 42 | extern UWORD VC1_VoiceGetVolume(UBYTE); |
40 | extern int VC1_SetNumVoices(void); | 43 | extern UWORD VC2_VoiceGetVolume(UBYTE); |
41 | //extern int VC2_SetNumVoices(void); | 44 | extern ULONG VC1_VoiceGetPanning(UBYTE); |
42 | static int (*VC_SetNumVoices_ptr)(void); | 45 | extern ULONG VC2_VoiceGetPanning(UBYTE); |
46 | extern void VC1_VoiceSetFrequency(UBYTE,ULONG); | ||
47 | extern void VC2_VoiceSetFrequency(UBYTE,ULONG); | ||
48 | extern ULONG VC1_VoiceGetFrequency(UBYTE); | ||
49 | extern ULONG VC2_VoiceGetFrequency(UBYTE); | ||
50 | extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); | ||
51 | extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); | ||
52 | extern void VC1_VoiceStop(UBYTE); | ||
53 | extern void VC2_VoiceStop(UBYTE); | ||
54 | extern int VC1_VoiceStopped(UBYTE); | ||
55 | extern int VC2_VoiceStopped(UBYTE); | ||
56 | extern SLONG VC1_VoiceGetPosition(UBYTE); | ||
57 | extern SLONG VC2_VoiceGetPosition(UBYTE); | ||
58 | extern void VC1_VoiceSetVolume(UBYTE,UWORD); | ||
59 | extern void VC2_VoiceSetVolume(UBYTE,UWORD); | ||
60 | extern void VC1_VoiceSetPanning(UBYTE,ULONG); | ||
61 | extern void VC2_VoiceSetPanning(UBYTE,ULONG); | ||
62 | extern void VC1_SampleUnload(SWORD); | ||
63 | extern void VC2_SampleUnload(SWORD); | ||
64 | extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int); | ||
65 | extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int); | ||
43 | extern ULONG VC1_SampleSpace(int); | 66 | extern ULONG VC1_SampleSpace(int); |
44 | //extern ULONG VC2_SampleSpace(int); | 67 | extern ULONG VC2_SampleSpace(int); |
45 | static ULONG (*VC_SampleSpace_ptr)(int); | ||
46 | extern ULONG VC1_SampleLength(int,SAMPLE*); | 68 | extern ULONG VC1_SampleLength(int,SAMPLE*); |
47 | //extern ULONG VC2_SampleLength(int,SAMPLE*); | 69 | extern ULONG VC2_SampleLength(int,SAMPLE*); |
70 | extern ULONG VC1_VoiceRealVolume(UBYTE); | ||
71 | extern ULONG VC2_VoiceRealVolume(UBYTE); | ||
72 | #endif | ||
73 | |||
74 | |||
75 | #ifndef _IN_VIRTCH_ | ||
76 | |||
77 | #ifndef NO_HQMIXER | ||
78 | extern int VC1_Init(void); | ||
79 | extern int VC2_Init(void); | ||
80 | static int (*VC_Init_ptr)(void)=VC1_Init; | ||
81 | static void (*VC_Exit_ptr)(void)=VC1_Exit; | ||
82 | extern int VC1_SetNumVoices(void); | ||
83 | extern int VC2_SetNumVoices(void); | ||
84 | static int (*VC_SetNumVoices_ptr)(void); | ||
85 | static ULONG (*VC_SampleSpace_ptr)(int); | ||
48 | static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*); | 86 | static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*); |
49 | 87 | ||
50 | extern int VC1_PlayStart(void); | 88 | extern int VC2_PlayStart(void); |
51 | //extern int VC2_PlayStart(void); | 89 | static int (*VC_PlayStart_ptr)(void); |
52 | static int (*VC_PlayStart_ptr)(void); | ||
53 | extern void VC1_PlayStop(void); | ||
54 | extern void VC2_PlayStop(void); | 90 | extern void VC2_PlayStop(void); |
55 | static void (*VC_PlayStop_ptr)(void); | 91 | static void (*VC_PlayStop_ptr)(void); |
56 | 92 | ||
57 | extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int); | ||
58 | //extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int); | ||
59 | static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int); | 93 | static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int); |
60 | extern void VC1_SampleUnload(SWORD); | ||
61 | //extern void VC2_SampleUnload(SWORD); | ||
62 | static void (*VC_SampleUnload_ptr)(SWORD); | 94 | static void (*VC_SampleUnload_ptr)(SWORD); |
63 | 95 | ||
64 | extern ULONG VC1_WriteBytes(SBYTE*,ULONG); | ||
65 | //extern ULONG VC2_WriteBytes(SBYTE*,ULONG); | ||
66 | static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG); | 96 | static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG); |
67 | extern ULONG VC1_SilenceBytes(SBYTE*,ULONG); | ||
68 | //extern ULONG VC2_SilenceBytes(SBYTE*,ULONG); | ||
69 | static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG); | 97 | static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG); |
70 | 98 | ||
71 | extern void VC1_VoiceSetVolume(UBYTE,UWORD); | ||
72 | //extern void VC2_VoiceSetVolume(UBYTE,UWORD); | ||
73 | static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD); | 99 | static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD); |
74 | extern UWORD VC1_VoiceGetVolume(UBYTE); | ||
75 | //extern UWORD VC2_VoiceGetVolume(UBYTE); | ||
76 | static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE); | 100 | static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE); |
77 | extern void VC1_VoiceSetFrequency(UBYTE,ULONG); | ||
78 | //extern void VC2_VoiceSetFrequency(UBYTE,ULONG); | ||
79 | static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG); | 101 | static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG); |
80 | extern ULONG VC1_VoiceGetFrequency(UBYTE); | ||
81 | //extern ULONG VC2_VoiceGetFrequency(UBYTE); | ||
82 | static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE); | 102 | static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE); |
83 | extern void VC1_VoiceSetPanning(UBYTE,ULONG); | ||
84 | //extern void VC2_VoiceSetPanning(UBYTE,ULONG); | ||
85 | static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG); | 103 | static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG); |
86 | extern ULONG VC1_VoiceGetPanning(UBYTE); | ||
87 | //extern ULONG VC2_VoiceGetPanning(UBYTE); | ||
88 | static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE); | 104 | static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE); |
89 | extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); | ||
90 | //extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); | ||
91 | static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); | 105 | static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); |
92 | 106 | ||
93 | extern void VC1_VoiceStop(UBYTE); | ||
94 | //extern void VC2_VoiceStop(UBYTE); | ||
95 | static void (*VC_VoiceStop_ptr)(UBYTE); | 107 | static void (*VC_VoiceStop_ptr)(UBYTE); |
96 | extern int VC1_VoiceStopped(UBYTE); | ||
97 | //extern int VC2_VoiceStopped(UBYTE); | ||
98 | static int (*VC_VoiceStopped_ptr)(UBYTE); | 108 | static int (*VC_VoiceStopped_ptr)(UBYTE); |
99 | extern SLONG VC1_VoiceGetPosition(UBYTE); | ||
100 | //extern SLONG VC2_VoiceGetPosition(UBYTE); | ||
101 | static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE); | 109 | static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE); |
102 | extern ULONG VC1_VoiceRealVolume(UBYTE); | ||
103 | //extern ULONG VC2_VoiceRealVolume(UBYTE); | ||
104 | static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE); | 110 | static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE); |
105 | 111 | ||
106 | #if defined __STDC__ || defined _MSC_VER || defined MPW_C | 112 | #if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C |
107 | #define VC_PROC0(suffix) \ | 113 | #define VC_PROC0(suffix) \ |
108 | MIKMODAPI void VC_##suffix (void) { VC_##suffix##_ptr(); } | 114 | MIKMODAPI void VC_##suffix (void) { VC_##suffix##_ptr(); } |
109 | 115 | ||
@@ -121,7 +127,9 @@ MIKMODAPI void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); } | |||
121 | 127 | ||
122 | #define VC_FUNC2(suffix,ret,typ1,typ2) \ | 128 | #define VC_FUNC2(suffix,ret,typ1,typ2) \ |
123 | MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); } | 129 | MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); } |
130 | |||
124 | #else | 131 | #else |
132 | |||
125 | #define VC_PROC0(suffix) \ | 133 | #define VC_PROC0(suffix) \ |
126 | MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); } | 134 | MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); } |
127 | 135 | ||
@@ -158,18 +166,18 @@ VC_PROC2(VoiceSetFrequency,UBYTE,ULONG) | |||
158 | VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE) | 166 | VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE) |
159 | VC_PROC2(VoiceSetPanning,UBYTE,ULONG) | 167 | VC_PROC2(VoiceSetPanning,UBYTE,ULONG) |
160 | VC_FUNC1(VoiceGetPanning,ULONG,UBYTE) | 168 | VC_FUNC1(VoiceGetPanning,ULONG,UBYTE) |
161 | 169 | ||
162 | void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) | 170 | void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) { |
163 | { VC_VoicePlay_ptr(a,b,c,d,e,f,g); } | 171 | VC_VoicePlay_ptr(a,b,c,d,e,f,g); |
172 | } | ||
164 | 173 | ||
165 | VC_PROC1(VoiceStop,UBYTE) | 174 | VC_PROC1(VoiceStop,UBYTE) |
166 | VC_FUNC1(VoiceStopped,int,UBYTE) | 175 | VC_FUNC1(VoiceStopped,int,UBYTE) |
167 | VC_FUNC1(VoiceGetPosition,SLONG,UBYTE) | 176 | VC_FUNC1(VoiceGetPosition,SLONG,UBYTE) |
168 | VC_FUNC1(VoiceRealVolume,ULONG,UBYTE) | 177 | VC_FUNC1(VoiceRealVolume,ULONG,UBYTE) |
169 | 178 | ||
170 | void VC_SetupPointers(void) | 179 | void VC_SetupPointers(void) |
171 | { | 180 | { |
172 | /* | ||
173 | if (md_mode&DMODE_HQMIXER) { | 181 | if (md_mode&DMODE_HQMIXER) { |
174 | VC_Init_ptr=VC2_Init; | 182 | VC_Init_ptr=VC2_Init; |
175 | VC_Exit_ptr=VC2_Exit; | 183 | VC_Exit_ptr=VC2_Exit; |
@@ -194,7 +202,6 @@ void VC_SetupPointers(void) | |||
194 | VC_VoiceGetPosition_ptr=VC2_VoiceGetPosition; | 202 | VC_VoiceGetPosition_ptr=VC2_VoiceGetPosition; |
195 | VC_VoiceRealVolume_ptr=VC2_VoiceRealVolume; | 203 | VC_VoiceRealVolume_ptr=VC2_VoiceRealVolume; |
196 | } else { | 204 | } else { |
197 | */ | ||
198 | VC_Init_ptr=VC1_Init; | 205 | VC_Init_ptr=VC1_Init; |
199 | VC_Exit_ptr=VC1_Exit; | 206 | VC_Exit_ptr=VC1_Exit; |
200 | VC_SetNumVoices_ptr=VC1_SetNumVoices; | 207 | VC_SetNumVoices_ptr=VC1_SetNumVoices; |
@@ -217,10 +224,11 @@ void VC_SetupPointers(void) | |||
217 | VC_VoiceStopped_ptr=VC1_VoiceStopped; | 224 | VC_VoiceStopped_ptr=VC1_VoiceStopped; |
218 | VC_VoiceGetPosition_ptr=VC1_VoiceGetPosition; | 225 | VC_VoiceGetPosition_ptr=VC1_VoiceGetPosition; |
219 | VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume; | 226 | VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume; |
220 | //} | 227 | } |
221 | } | 228 | } |
229 | #endif/* !NO_HQMIXER */ | ||
222 | 230 | ||
223 | #else | 231 | #else /* _IN_VIRTCH_ */ |
224 | 232 | ||
225 | #ifndef _VIRTCH_COMMON_ | 233 | #ifndef _VIRTCH_COMMON_ |
226 | #define _VIRTCH_COMMON_ | 234 | #define _VIRTCH_COMMON_ |
@@ -248,9 +256,7 @@ ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo) | |||
248 | todo=samples2bytes(bytes2samples(todo)); | 256 | todo=samples2bytes(bytes2samples(todo)); |
249 | 257 | ||
250 | /* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */ | 258 | /* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */ |
251 | if(vc_mode & DMODE_FLOAT) | 259 | if(vc_mode &(DMODE_16BITS|DMODE_FLOAT)) |
252 | memset(buf,0,todo); | ||
253 | else if(vc_mode & DMODE_16BITS) | ||
254 | memset(buf,0,todo); | 260 | memset(buf,0,todo); |
255 | else | 261 | else |
256 | memset(buf,0x80,todo); | 262 | memset(buf,0x80,todo); |
@@ -276,14 +282,14 @@ ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo) | |||
276 | 282 | ||
277 | void VC1_Exit(void) | 283 | void VC1_Exit(void) |
278 | { | 284 | { |
279 | if(vc_tickbuf) MikMod_free(vc_tickbuf); | 285 | MikMod_free(vinf); |
280 | if(vinf) MikMod_free(vinf); | 286 | MikMod_afree(vc_tickbuf); |
281 | if(Samples) MikMod_free(Samples); | 287 | MikMod_afree(Samples); |
282 | 288 | ||
283 | vc_tickbuf = NULL; | 289 | vc_tickbuf = NULL; |
284 | vinf = NULL; | 290 | vinf = NULL; |
285 | Samples = NULL; | 291 | Samples = NULL; |
286 | 292 | ||
287 | VC_SetupPointers(); | 293 | VC_SetupPointers(); |
288 | } | 294 | } |
289 | 295 | ||
@@ -309,19 +315,19 @@ ULONG VC1_VoiceGetFrequency(UBYTE voice) | |||
309 | 315 | ||
310 | void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags) | 316 | void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags) |
311 | { | 317 | { |
312 | vinf[voice].flags = flags; | 318 | vinf[voice].flags = flags; |
313 | vinf[voice].handle = handle; | 319 | vinf[voice].handle = handle; |
314 | vinf[voice].start = start; | 320 | vinf[voice].start = start; |
315 | vinf[voice].size = size; | 321 | vinf[voice].size = size; |
316 | vinf[voice].reppos = reppos; | 322 | vinf[voice].reppos = reppos; |
317 | vinf[voice].repend = repend; | 323 | vinf[voice].repend = repend; |
318 | vinf[voice].kick = 1; | 324 | vinf[voice].kick = 1; |
319 | } | 325 | } |
320 | 326 | ||
321 | void VC1_VoiceStop(UBYTE voice) | 327 | void VC1_VoiceStop(UBYTE voice) |
322 | { | 328 | { |
323 | vinf[voice].active = 0; | 329 | vinf[voice].active = 0; |
324 | } | 330 | } |
325 | 331 | ||
326 | int VC1_VoiceStopped(UBYTE voice) | 332 | int VC1_VoiceStopped(UBYTE voice) |
327 | { | 333 | { |
@@ -334,7 +340,7 @@ SLONG VC1_VoiceGetPosition(UBYTE voice) | |||
334 | } | 340 | } |
335 | 341 | ||
336 | void VC1_VoiceSetVolume(UBYTE voice,UWORD vol) | 342 | void VC1_VoiceSetVolume(UBYTE voice,UWORD vol) |
337 | { | 343 | { |
338 | /* protect against clicks if volume variation is too high */ | 344 | /* protect against clicks if volume variation is too high */ |
339 | if(abs((int)vinf[voice].vol-(int)vol)>32) | 345 | if(abs((int)vinf[voice].vol-(int)vol)>32) |
340 | vinf[voice].rampvol=CLICK_BUFFER; | 346 | vinf[voice].rampvol=CLICK_BUFFER; |
@@ -353,9 +359,8 @@ void VC1_VoiceSetPanning(UBYTE voice,ULONG pan) | |||
353 | 359 | ||
354 | void VC1_SampleUnload(SWORD handle) | 360 | void VC1_SampleUnload(SWORD handle) |
355 | { | 361 | { |
356 | if (handle<MAXSAMPLEHANDLES) { | 362 | if (Samples && (handle < MAXSAMPLEHANDLES)) { |
357 | if (Samples[handle]) | 363 | MikMod_afree(Samples[handle]); |
358 | MikMod_free(Samples[handle]); | ||
359 | Samples[handle]=NULL; | 364 | Samples[handle]=NULL; |
360 | } | 365 | } |
361 | } | 366 | } |
@@ -364,10 +369,15 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type) | |||
364 | { | 369 | { |
365 | SAMPLE *s = sload->sample; | 370 | SAMPLE *s = sload->sample; |
366 | int handle; | 371 | int handle; |
367 | ULONG t, length,loopstart,loopend; | 372 | ULONG t, length,loopstart,loopend,looplen; |
368 | 373 | ||
369 | if(type==MD_HARDWARE) return -1; | 374 | if(type==MD_HARDWARE) return -1; |
370 | 375 | ||
376 | if(s->length > MAX_SAMPLE_SIZE) { | ||
377 | _mm_errno = MMERR_NOT_A_STREAM; /* better error? */ | ||
378 | return -1; | ||
379 | } | ||
380 | |||
371 | /* Find empty slot to put sample address in */ | 381 | /* Find empty slot to put sample address in */ |
372 | for(handle=0;handle<MAXSAMPLEHANDLES;handle++) | 382 | for(handle=0;handle<MAXSAMPLEHANDLES;handle++) |
373 | if(!Samples[handle]) break; | 383 | if(!Samples[handle]) break; |
@@ -376,7 +386,7 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type) | |||
376 | _mm_errno = MMERR_OUT_OF_HANDLES; | 386 | _mm_errno = MMERR_OUT_OF_HANDLES; |
377 | return -1; | 387 | return -1; |
378 | } | 388 | } |
379 | 389 | ||
380 | /* Reality check for loop settings */ | 390 | /* Reality check for loop settings */ |
381 | if (s->loopend > s->length) | 391 | if (s->loopend > s->length) |
382 | s->loopend = s->length; | 392 | s->loopend = s->length; |
@@ -390,22 +400,26 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type) | |||
390 | SL_SampleSigned(sload); | 400 | SL_SampleSigned(sload); |
391 | SL_Sample8to16(sload); | 401 | SL_Sample8to16(sload); |
392 | 402 | ||
393 | if(!(Samples[handle]=(SWORD*)MikMod_malloc((length+20)<<1))) { | 403 | if(!(Samples[handle]=(SWORD*)MikMod_amalloc((length+20)<<1))) { |
394 | _mm_errno = MMERR_SAMPLE_TOO_BIG; | 404 | _mm_errno = MMERR_SAMPLE_TOO_BIG; |
395 | return -1; | 405 | return -1; |
396 | } | 406 | } |
397 | 407 | ||
398 | /* read sample into buffer */ | 408 | /* read sample into buffer */ |
399 | if (SL_Load(Samples[handle],sload,length)) | 409 | if (SL_Load(Samples[handle],sload,length)) { |
410 | MikMod_afree(Samples[handle]); | ||
411 | Samples[handle]=NULL; | ||
400 | return -1; | 412 | return -1; |
413 | } | ||
401 | 414 | ||
402 | /* Unclick sample */ | 415 | /* Unclick sample */ |
403 | if(s->flags & SF_LOOP) { | 416 | if(s->flags & SF_LOOP) { |
417 | looplen = loopend - loopstart;/* handle short samples */ | ||
404 | if(s->flags & SF_BIDI) | 418 | if(s->flags & SF_BIDI) |
405 | for(t=0;t<16;t++) | 419 | for(t=0;t<16 && t<looplen;t++) |
406 | Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1]; | 420 | Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1]; |
407 | else | 421 | else |
408 | for(t=0;t<16;t++) | 422 | for(t=0;t<16 && t<looplen;t++) |
409 | Samples[handle][loopend+t]=Samples[handle][t+loopstart]; | 423 | Samples[handle][loopend+t]=Samples[handle][t+loopstart]; |
410 | } else | 424 | } else |
411 | for(t=0;t<16;t++) | 425 | for(t=0;t<16;t++) |
@@ -416,13 +430,13 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type) | |||
416 | 430 | ||
417 | ULONG VC1_SampleSpace(int type) | 431 | ULONG VC1_SampleSpace(int type) |
418 | { | 432 | { |
419 | (void)type; | 433 | (void)type; |
420 | return vc_memory; | 434 | return vc_memory; |
421 | } | 435 | } |
422 | 436 | ||
423 | ULONG VC1_SampleLength(int type,SAMPLE* s) | 437 | ULONG VC1_SampleLength(int type,SAMPLE* s) |
424 | { | 438 | { |
425 | (void)type; | 439 | (void)type; |
426 | if (!s) return 0; | 440 | if (!s) return 0; |
427 | 441 | ||
428 | return (s->length*((s->flags&SF_16BITS)?2:1))+16; | 442 | return (s->length*((s->flags&SF_16BITS)?2:1))+16; |
@@ -456,11 +470,8 @@ ULONG VC1_VoiceRealVolume(UBYTE voice) | |||
456 | return abs(k-j); | 470 | return abs(k-j); |
457 | } | 471 | } |
458 | 472 | ||
473 | #endif /* _VIRTCH_COMMON_ */ | ||
459 | 474 | ||
460 | #endif | 475 | #endif /* _IN_VIRTCH_ */ |
461 | |||
462 | MikMod_callback_t vc_callback; | ||
463 | |||
464 | #endif | ||
465 | 476 | ||
466 | /* ex:set ts=4: */ | 477 | /* ex:set ts=4: */ |
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config index 96228085c9..84f096a409 100644 --- a/apps/plugins/viewers.config +++ b/apps/plugins/viewers.config | |||
@@ -44,7 +44,6 @@ asy,viewers/mikmod,7 | |||
44 | dsm,viewers/mikmod,7 | 44 | dsm,viewers/mikmod,7 |
45 | far,viewers/mikmod,7 | 45 | far,viewers/mikmod,7 |
46 | gdm,viewers/mikmod,7 | 46 | gdm,viewers/mikmod,7 |
47 | gt2,viewers/mikmod,7 | ||
48 | imf,viewers/mikmod,7 | 47 | imf,viewers/mikmod,7 |
49 | it,viewers/mikmod,7 | 48 | it,viewers/mikmod,7 |
50 | m15,viewers/mikmod,7 | 49 | m15,viewers/mikmod,7 |
@@ -57,6 +56,7 @@ stm,viewers/mikmod,7 | |||
57 | stx,viewers/mikmod,7 | 56 | stx,viewers/mikmod,7 |
58 | ult,viewers/mikmod,7 | 57 | ult,viewers/mikmod,7 |
59 | uni,viewers/mikmod,7 | 58 | uni,viewers/mikmod,7 |
59 | umx,viewers/mikmod,7 | ||
60 | xm,viewers/mikmod,7 | 60 | xm,viewers/mikmod,7 |
61 | pd,viewers/pdbox,2 | 61 | pd,viewers/pdbox,2 |
62 | rsp,viewers/searchengine,8 | 62 | rsp,viewers/searchengine,8 |