summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2020-08-08 21:56:15 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-08-11 03:29:12 +0000
commitb4e70422a3455e327433a7471c929ef100ef3b10 (patch)
treee96c5431a1b22af1fcbc628322b79fb8c3162427
parent8c7780bafc9eabac6b92cfe5a5a00831c3d5fd9d (diff)
downloadrockbox-b4e70422a3455e327433a7471c929ef100ef3b10.tar.gz
rockbox-b4e70422a3455e327433a7471c929ef100ef3b10.zip
mikmod: Upgrade mikmod core from v3.2.0 to v3.3.11
* Get rid of the non-functional GT2 loader * Add the UMX loader * Add HQ mixer routines (and make it configurable) * Allow samplerate to be configured at run/playtime * Support >64KHz mixing/playback * Correctly restore non-boost status (The diff to upstream is much smaller now too!) Change-Id: Iaa4ac901ba9cd4123bb225656976e78271353a72
-rw-r--r--apps/lang/english.lang40
-rw-r--r--apps/plugins/mikmod/SOURCES3
-rw-r--r--apps/plugins/mikmod/load_669.c30
-rw-r--r--apps/plugins/mikmod/load_amf.c72
-rw-r--r--apps/plugins/mikmod/load_asy.c91
-rw-r--r--apps/plugins/mikmod/load_dsm.c29
-rw-r--r--apps/plugins/mikmod/load_far.c38
-rw-r--r--apps/plugins/mikmod/load_gdm.c33
-rw-r--r--apps/plugins/mikmod/load_gt2.c375
-rw-r--r--apps/plugins/mikmod/load_imf.c71
-rw-r--r--apps/plugins/mikmod/load_it.c184
-rw-r--r--apps/plugins/mikmod/load_m15.c107
-rw-r--r--apps/plugins/mikmod/load_med.c74
-rw-r--r--apps/plugins/mikmod/load_mod.c27
-rw-r--r--apps/plugins/mikmod/load_mtm.c34
-rw-r--r--apps/plugins/mikmod/load_okt.c21
-rw-r--r--apps/plugins/mikmod/load_s3m.c50
-rw-r--r--apps/plugins/mikmod/load_stm.c40
-rw-r--r--apps/plugins/mikmod/load_stx.c26
-rw-r--r--apps/plugins/mikmod/load_ult.c40
-rw-r--r--apps/plugins/mikmod/load_umx.c476
-rw-r--r--apps/plugins/mikmod/load_uni.c163
-rw-r--r--apps/plugins/mikmod/load_xm.c129
-rw-r--r--apps/plugins/mikmod/mdreg.c66
-rw-r--r--apps/plugins/mikmod/mdriver.c189
-rw-r--r--apps/plugins/mikmod/mikmod.c133
-rw-r--r--apps/plugins/mikmod/mikmod.h895
-rw-r--r--apps/plugins/mikmod/mikmod_internals.h789
-rw-r--r--apps/plugins/mikmod/mikmod_supp.h3
-rw-r--r--apps/plugins/mikmod/mloader.c319
-rw-r--r--apps/plugins/mikmod/mlreg.c5
-rw-r--r--apps/plugins/mikmod/mlutil.c44
-rw-r--r--apps/plugins/mikmod/mmalloc.c207
-rw-r--r--apps/plugins/mikmod/mmerror.c150
-rw-r--r--apps/plugins/mikmod/mmio.c304
-rw-r--r--apps/plugins/mikmod/mplayer.c410
-rw-r--r--apps/plugins/mikmod/munitrk.c22
-rw-r--r--apps/plugins/mikmod/npertab.c8
-rw-r--r--apps/plugins/mikmod/sloader.c60
-rw-r--r--apps/plugins/mikmod/virtch.c652
-rw-r--r--apps/plugins/mikmod/virtch2.c1370
-rw-r--r--apps/plugins/mikmod/virtch_common.c193
-rw-r--r--apps/plugins/viewers.config2
43 files changed, 5122 insertions, 2852 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 8079884426..5937df64c0 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -15352,6 +15352,46 @@
15352 </voice> 15352 </voice>
15353</phrase> 15353</phrase>
15354<phrase> 15354<phrase>
15355 id: LANG_MIKMOD_HQMIXER
15356 desc: in mikmod settings menu
15357 user: core
15358 <source>
15359 *: none
15360 lowmem: none
15361 swcodec: "HQ Mixer"
15362 </source>
15363 <dest>
15364 *: none
15365 lowmem: none
15366 swcodec: "HQ Mixer"
15367 </dest>
15368 <voice>
15369 *: none
15370 lowmem: none
15371 swcodec: "High Quality Mixer"
15372 </voice>
15373</phrase>
15374<phrase>
15375 id: LANG_MIKMOD_SAMPLERATE
15376 desc: in mikmod settings menu
15377 user: core
15378 <source>
15379 *: none
15380 lowmem: none
15381 swcodec: "Sample Rate"
15382 </source>
15383 <dest>
15384 *: none
15385 lowmem: none
15386 swcodec: "Sample Rate"
15387 </dest>
15388 <voice>
15389 *: none
15390 lowmem: none
15391 swcodec: "Sample Rate"
15392 </voice>
15393</phrase>
15394<phrase>
15355 id: LANG_CPU_BOOST 15395 id: LANG_CPU_BOOST
15356 desc: in mikmod settings menu 15396 desc: in mikmod settings menu
15357 user: core 15397 user: core
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
5load_dsm.c 5load_dsm.c
6load_far.c 6load_far.c
7load_gdm.c 7load_gdm.c
8load_gt2.c
9load_imf.c 8load_imf.c
10load_it.c 9load_it.c
11load_m15.c 10load_m15.c
@@ -17,6 +16,7 @@ load_s3m.c
17load_stm.c 16load_stm.c
18load_stx.c 17load_stx.c
19load_ult.c 18load_ult.c
19load_umx.c
20load_uni.c 20load_uni.c
21load_xm.c 21load_xm.c
22mdreg.c 22mdreg.c
@@ -34,6 +34,7 @@ sloader.c
34strdup.c 34strdup.c
35strstr.c 35strstr.c
36virtch.c 36virtch.c
37virtch2.c
37virtch_common.c 38virtch_common.c
38mikmod.c 39mikmod.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 */
52typedef struct S69HEADER { 52typedef 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;
81static S69HEADER* mh=NULL; 81static S69HEADER* mh=NULL;
82 82
83/* file type identification */ 83/* file type identification */
84static CHAR* S69_Version[]={ 84static 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
139static int S69_LoadPatterns(void) 141static 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
117static int AMF_UnpackTrack(MREADER* modreader) 117static int AMF_UnpackTrack(MREADER* r)
118{ 118{
119 ULONG tracksize; 119 ULONG tracksize;
120 UBYTE row,cmd; 120 UBYTE row,cmd;
@@ -124,20 +124,20 @@ static int AMF_UnpackTrack(MREADER* modreader)
124 memset(track,0,64*sizeof(AMFNOTE)); 124 memset(track,0,64*sizeof(AMFNOTE));
125 125
126 /* read packed track */ 126 /* read packed track */
127 if (modreader) { 127 if (r) {
128 tracksize=_mm_read_I_UWORD(modreader); 128 tracksize=_mm_read_I_UWORD(r);
129 tracksize+=((ULONG)_mm_read_UBYTE(modreader))<<16; 129 tracksize+=((ULONG)_mm_read_UBYTE(r))<<16;
130 if (tracksize) 130 if (tracksize)
131 while(tracksize--) { 131 while(tracksize--) {
132 row=_mm_read_UBYTE(modreader); 132 row=_mm_read_UBYTE(r);
133 cmd=_mm_read_UBYTE(modreader); 133 cmd=_mm_read_UBYTE(r);
134 arg=_mm_read_SBYTE(modreader); 134 arg=_mm_read_SBYTE(r);
135 /* unexpected end of track */ 135 /* unexpected end of track */
136 if(!tracksize) { 136 if(!tracksize) {
137 if((row==0xff)&&(cmd==0xff)&&(arg==-1)) 137 if((row==0xff)&&(cmd==0xff)&&(arg==-1))
138 break; 138 break;
139 /* the last triplet should be FF FF FF, but this is not 139 /* the last triplet should be FF FF FF, but this is not
140 always the case... maybe a bug in m2amf ? 140 always the case... maybe a bug in m2amf ?
141 else 141 else
142 return 0; 142 return 0;
143 */ 143 */
@@ -164,7 +164,7 @@ static int AMF_UnpackTrack(MREADER* modreader)
164 if (cmd==0x83) { 164 if (cmd==0x83) {
165 /* volume without note */ 165 /* volume without note */
166 track[row].volume=(UBYTE)arg+1; 166 track[row].volume=(UBYTE)arg+1;
167 } else 167 } else
168 if (cmd==0xff) { 168 if (cmd==0xff) {
169 /* apparently, some M2AMF version fail to estimate the 169 /* apparently, some M2AMF version fail to estimate the
170 size of the compressed patterns correctly, and end 170 size of the compressed patterns correctly, and end
@@ -322,7 +322,7 @@ static UBYTE* AMF_ConvertTrack(void)
322 of.flags |= UF_PANNING; 322 of.flags |= UF_PANNING;
323 break; 323 break;
324 } 324 }
325 325
326 } 326 }
327 if (track[row].volume) UniVolEffect(VOL_VOLUME,track[row].volume-1); 327 if (track[row].volume) UniVolEffect(VOL_VOLUME,track[row].volume-1);
328 UniNewline(); 328 UniNewline();
@@ -333,13 +333,13 @@ static UBYTE* AMF_ConvertTrack(void)
333static int AMF_Load(int curious) 333static int AMF_Load(int curious)
334{ 334{
335 int u,defaultpanning; 335 int u,defaultpanning;
336 unsigned int t,realtrackcnt,realsmpcnt; 336 unsigned int t,realtrackcnt,realsmpcnt;
337 AMFSAMPLE s; 337 AMFSAMPLE s;
338 SAMPLE *q; 338 SAMPLE *q;
339 UWORD *track_remap; 339 UWORD *track_remap;
340 ULONG samplepos; 340 ULONG samplepos, fileend;
341 int channel_remap[16]; 341 int channel_remap[16];
342 (void)curious; 342 (void)curious;
343 343
344 /* try to read module header */ 344 /* try to read module header */
345 _mm_read_UBYTES(mh->id,3,modreader); 345 _mm_read_UBYTES(mh->id,3,modreader);
@@ -386,7 +386,7 @@ static int AMF_Load(int curious)
386 of.inittempo = mh->songbpm; 386 of.inittempo = mh->songbpm;
387 AMF_Version[AMFTEXTLEN-3]='0'+(mh->version/10); 387 AMF_Version[AMFTEXTLEN-3]='0'+(mh->version/10);
388 AMF_Version[AMFTEXTLEN-1]='0'+(mh->version%10); 388 AMF_Version[AMFTEXTLEN-1]='0'+(mh->version%10);
389 of.modtype = StrDup(AMF_Version); 389 of.modtype = MikMod_strdup(AMF_Version);
390 of.numchn = mh->numchannels; 390 of.numchn = mh->numchannels;
391 of.numtrk = mh->numorders*mh->numchannels; 391 of.numtrk = mh->numorders*mh->numchannels;
392 if (mh->numtracks>of.numtrk) 392 if (mh->numtracks>of.numtrk)
@@ -400,7 +400,7 @@ static int AMF_Load(int curious)
400 /* XXX whenever possible, we should try to determine the original format. 400 /* XXX whenever possible, we should try to determine the original format.
401 Here we assume it was S3M-style wrt bpmlimit... */ 401 Here we assume it was S3M-style wrt bpmlimit... */
402 of.bpmlimit = 32; 402 of.bpmlimit = 32;
403 403
404 /* 404 /*
405 * Play with the panning table. Although the AMF format embeds a 405 * Play with the panning table. Although the AMF format embeds a
406 * panning table, if the module was a MOD or an S3M with default 406 * panning table, if the module was a MOD or an S3M with default
@@ -466,7 +466,10 @@ static int AMF_Load(int curious)
466 s.c2spd =_mm_read_I_UWORD(modreader); 466 s.c2spd =_mm_read_I_UWORD(modreader);
467 if(s.c2spd==8368) s.c2spd=8363; 467 if(s.c2spd==8368) s.c2spd=8363;
468 s.volume =_mm_read_UBYTE(modreader); 468 s.volume =_mm_read_UBYTE(modreader);
469 if(mh->version>=11) { 469 /* "the tribal zone.amf" and "the way its gonna b.amf" by Maelcum
470 * are the only version 10 files I can find, and they have 32 bit
471 * reppos and repend, not 16. */
472 if(mh->version>=10) {/* was 11 */
470 s.reppos =_mm_read_I_ULONG(modreader); 473 s.reppos =_mm_read_I_ULONG(modreader);
471 s.repend =_mm_read_I_ULONG(modreader); 474 s.repend =_mm_read_I_ULONG(modreader);
472 } else { 475 } else {
@@ -475,7 +478,7 @@ static int AMF_Load(int curious)
475 } 478 }
476 479
477 if(_mm_eof(modreader)) { 480 if(_mm_eof(modreader)) {
478 _mm_errno = MMERR_LOADING_SAMPLEINFO; 481 _mm_errno = MMERR_LOADING_SAMPLEINFO;
479 return 0; 482 return 0;
480 } 483 }
481 484
@@ -493,7 +496,7 @@ static int AMF_Load(int curious)
493 } 496 }
494 497
495 /* read track table */ 498 /* read track table */
496 if(!(track_remap=MikMod_calloc(mh->numtracks+1,sizeof(UWORD)))) 499 if(!(track_remap=(UWORD*)MikMod_calloc(mh->numtracks+1,sizeof(UWORD))))
497 return 0; 500 return 0;
498 _mm_read_I_UWORDS(track_remap+1,mh->numtracks,modreader); 501 _mm_read_I_UWORDS(track_remap+1,mh->numtracks,modreader);
499 if(_mm_eof(modreader)) { 502 if(_mm_eof(modreader)) {
@@ -505,9 +508,14 @@ static int AMF_Load(int curious)
505 for(realtrackcnt=t=0;t<=mh->numtracks;t++) 508 for(realtrackcnt=t=0;t<=mh->numtracks;t++)
506 if (realtrackcnt<track_remap[t]) 509 if (realtrackcnt<track_remap[t])
507 realtrackcnt=track_remap[t]; 510 realtrackcnt=track_remap[t];
511 if (realtrackcnt > (int)mh->numtracks) {
512 MikMod_free(track_remap);
513 _mm_errno=MMERR_NOT_A_MODULE;
514 return 0;
515 }
508 for(t=0;t<of.numpat*of.numchn;t++) 516 for(t=0;t<of.numpat*of.numchn;t++)
509 of.patterns[t]=(of.patterns[t]<=mh->numtracks)? 517 of.patterns[t]=(of.patterns[t]<=mh->numtracks)?
510 track_remap[of.patterns[t]]-1:(int)realtrackcnt; 518 track_remap[of.patterns[t]]-1:(int)realtrackcnt;
511 519
512 MikMod_free(track_remap); 520 MikMod_free(track_remap);
513 521
@@ -531,18 +539,32 @@ static int AMF_Load(int curious)
531 for(t=realtrackcnt;t<of.numtrk;t++) of.tracks[t]=NULL; 539 for(t=realtrackcnt;t<of.numtrk;t++) of.tracks[t]=NULL;
532 540
533 /* compute sample offsets */ 541 /* compute sample offsets */
542 if(_mm_eof(modreader)) goto fail;
534 samplepos=_mm_ftell(modreader); 543 samplepos=_mm_ftell(modreader);
544 _mm_fseek(modreader,0,SEEK_END);
545 fileend=_mm_ftell(modreader);
546 _mm_fseek(modreader,samplepos,SEEK_SET);
535 for(realsmpcnt=t=0;t<of.numsmp;t++) 547 for(realsmpcnt=t=0;t<of.numsmp;t++)
536 if(realsmpcnt<of.samples[t].seekpos) 548 if(realsmpcnt<of.samples[t].seekpos)
537 realsmpcnt=of.samples[t].seekpos; 549 realsmpcnt=of.samples[t].seekpos;
538 for(t=1;t<=realsmpcnt;t++) { 550 for(t=1;t<=realsmpcnt;t++) {
539 q=of.samples; 551 q=of.samples;
540 while(q->seekpos!=t) q++; 552 u=0;
553 while(q->seekpos!=t) {
554 if(++u==of.numsmp)
555 goto fail;
556 q++;
557 }
541 q->seekpos=samplepos; 558 q->seekpos=samplepos;
542 samplepos+=q->length; 559 samplepos+=q->length;
543 } 560 }
544 561 if(samplepos>fileend)
562 goto fail;
563
545 return 1; 564 return 1;
565fail:
566 _mm_errno = MMERR_LOADING_SAMPLEINFO;
567 return 0;
546} 568}
547 569
548static CHAR *AMF_LoadTitle(void) 570static CHAR *AMF_LoadTitle(void)
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 */
80UWORD periodtable[]={6848,6464,6096,5760,5424,5120,4832,4560,4304, 80static 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
145static void ConvertNote(MODNOTE *n) 148static 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
224static UBYTE *ConvertTrack(MODNOTE *n) 235static 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. */
238static int ML_LoadPatterns(void) 250static 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
380static CHAR *ASY_LoadTitle(void) 395static 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
92static CHAR* SONGID="SONG"; 92static const CHAR* SONGID="SONG";
93static CHAR* INSTID="INST"; 93static const CHAR* INSTID="INST";
94static CHAR* PATTID="PATT"; 94static const CHAR* PATTID="PATT";
95 95
96static UBYTE blockid[4]; 96static UBYTE blockid[4];
97static ULONG blockln; 97static ULONG blockln;
@@ -101,7 +101,7 @@ static DSMNOTE* dsmbuf=NULL;
101 101
102static CHAR DSM_Version[]="DSIK DSM-format"; 102static CHAR DSM_Version[]="DSIK DSM-format";
103 103
104static unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'}; 104static 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
131static int GetBlockHeader(void) 133static 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;
92static FARHEADER2 *mh2 = NULL; 92static FARHEADER2 *mh2 = NULL;
93static FARNOTE *pat = NULL; 93static FARNOTE *pat = NULL;
94 94
95static unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26}; 95static 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
124static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows) 127static 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 {
114static GDMHEADER *mh=NULL; /* pointer to GDM header */ 114static GDMHEADER *mh=NULL; /* pointer to GDM header */
115static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */ 115static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */
116 116
117CHAR GDM_Version[]="General DigiMusic 1.xx"; 117static CHAR GDM_Version[]="General DigiMusic 1.xx";
118 118
119static int GDM_Test(void) 119static 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
151static int GDM_ReadPattern(void) 153static 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
46typedef 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 */
54typedef 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 */
72typedef 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 */
80typedef 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 */
88typedef 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 */
97typedef 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 */
105typedef 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 */
118typedef 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
124typedef 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 */
130typedef 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
145typedef 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
163typedef 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
172typedef struct ENDC_CHUNK {
173 UBYTE id[4]; /* must be ENDC */
174 ULONG chunk_size;
175 ULONG total_module_size;
176} ENDC_CHUNK;
177
178
179typedef 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
195static 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
315static int GT2_Init(void)
316{
317 return 1;
318}
319
320static 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
332static 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
347static void GT2_Cleanup(void)
348{
349}
350
351static 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
363MIKMODAPI 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
128static int IMF_Test(void) 128static 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
138static int IMF_Init(void) 162static 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
154static int IMF_ReadPattern(SLONG size,UWORD rows) 180static 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
47extern int fprintf(FILE *, const char *, ...); 47extern int fprintf(FILE *, const char *, ...);
48extern int toupper(int);
49#endif 48#endif
50 49
51/*========== Module structure */ 50/*========== Module structure */
@@ -67,7 +66,7 @@ typedef struct ITHEADER {
67 UBYTE initspeed; 66 UBYTE initspeed;
68 UBYTE inittempo; 67 UBYTE inittempo;
69 UBYTE pansep; /* panning separation between channels */ 68 UBYTE pansep; /* panning separation between channels */
70 UBYTE zerobyte; 69 UBYTE zerobyte;
71 UWORD msglength; 70 UWORD msglength;
72 ULONG msgoffset; 71 ULONG msgoffset;
73 UBYTE blank02[4]; 72 UBYTE blank02[4];
@@ -107,19 +106,19 @@ typedef struct ITINSTHEADER {
107 CHAR filename[12]; /* (char) Instrument filename */ 106 CHAR filename[12]; /* (char) Instrument filename */
108 UBYTE zerobyte; /* (byte) Instrument type (always 0) */ 107 UBYTE zerobyte; /* (byte) Instrument type (always 0) */
109 UBYTE volflg; 108 UBYTE volflg;
110 UBYTE volpts; 109 UBYTE volpts;
111 UBYTE volbeg; /* (byte) Volume loop start (node) */ 110 UBYTE volbeg; /* (byte) Volume loop start (node) */
112 UBYTE volend; /* (byte) Volume loop end (node) */ 111 UBYTE volend; /* (byte) Volume loop end (node) */
113 UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */ 112 UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */
114 UBYTE volsusend; /* (byte) Volume Sustain end (node) */ 113 UBYTE volsusend; /* (byte) Volume Sustain end (node) */
115 UBYTE panflg; 114 UBYTE panflg;
116 UBYTE panpts; 115 UBYTE panpts;
117 UBYTE panbeg; /* (byte) channel loop start (node) */ 116 UBYTE panbeg; /* (byte) channel loop start (node) */
118 UBYTE panend; /* (byte) channel loop end (node) */ 117 UBYTE panend; /* (byte) channel loop end (node) */
119 UBYTE pansusbeg; /* (byte) channel sustain begin (node) */ 118 UBYTE pansusbeg; /* (byte) channel sustain begin (node) */
120 UBYTE pansusend; /* (byte) channel Sustain end (node) */ 119 UBYTE pansusend; /* (byte) channel Sustain end (node) */
121 UBYTE pitflg; 120 UBYTE pitflg;
122 UBYTE pitpts; 121 UBYTE pitpts;
123 UBYTE pitbeg; /* (byte) pitch loop start (node) */ 122 UBYTE pitbeg; /* (byte) pitch loop start (node) */
124 UBYTE pitend; /* (byte) pitch loop end (node) */ 123 UBYTE pitend; /* (byte) pitch loop end (node) */
125 UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */ 124 UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */
@@ -149,7 +148,7 @@ typedef struct ITINSTHEADER {
149 UWORD pantick[ITENVCNT]; /* tick value of panning nodes */ 148 UWORD pantick[ITENVCNT]; /* tick value of panning nodes */
150 SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */ 149 SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */
151 UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */ 150 UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */
152} ITINSTHEADER; 151} ITINSTHEADER;
153 152
154/* unpacked note */ 153/* unpacked note */
155 154
@@ -166,8 +165,8 @@ static UBYTE *mask=NULL; /* arrays allocated to 64 elements and used for */
166static ITNOTE *last=NULL; /* uncompressing IT's pattern information */ 165static ITNOTE *last=NULL; /* uncompressing IT's pattern information */
167static int numtrk=0; 166static int numtrk=0;
168static unsigned int old_effect; /* if set, use S3M old-effects stuffs */ 167static unsigned int old_effect; /* if set, use S3M old-effects stuffs */
169 168
170static CHAR* IT_Version[]={ 169static const CHAR* IT_Version[]={
171 "ImpulseTracker . ", 170 "ImpulseTracker . ",
172 "Compressed ImpulseTracker . ", 171 "Compressed ImpulseTracker . ",
173 "ImpulseTracker 2.14p3", 172 "ImpulseTracker 2.14p3",
@@ -177,7 +176,7 @@ static CHAR* IT_Version[]={
177}; 176};
178 177
179/* table for porta-to-note command within volume/panning column */ 178/* table for porta-to-note command within volume/panning column */
180static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255}; 179static const UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255};
181 180
182/*========== Loader code */ 181/*========== Loader code */
183 182
@@ -212,40 +211,48 @@ static void IT_Cleanup(void)
212 MikMod_free(last); 211 MikMod_free(last);
213 MikMod_free(paraptr); 212 MikMod_free(paraptr);
214 MikMod_free(origpositions); 213 MikMod_free(origpositions);
214 mh=NULL;
215 poslookup=NULL;
216 itpat=NULL;
217 mask=NULL;
218 last=NULL;
219 paraptr=NULL;
220 origpositions=NULL;
215} 221}
216 222
217/* Because so many IT files have 64 channels as the set number used, but really 223/* Because so many IT files have 64 channels as the set number used, but really
218 only use far less (usually from 8 to 24 still), I had to make this function, 224 only use far less (usually from 8 to 24 still), I had to make this function,
219 which determines the number of channels that are actually USED by a pattern. 225 which determines the number of channels that are actually USED by a pattern.
220 226
221 NOTE: You must first seek to the file location of the pattern before calling 227 NOTE: You must first seek to the file location of the pattern before calling
222 this procedure. 228 this procedure.
223 229
224 Returns 1 on error 230 Returns 0 on error
225*/ 231*/
226static int IT_GetNumChannels(UWORD patrows) 232static int IT_GetNumChannels(UWORD patrows)
227{ 233{
228 int row=0,flag,ch; 234 int row=0,flag,ch;
229 235
230 do { 236 do {
231 if((flag=_mm_read_UBYTE(modreader))==EOF) { 237 if(_mm_eof(modreader)) {
232 _mm_errno=MMERR_LOADING_PATTERN; 238 _mm_errno=MMERR_LOADING_PATTERN;
233 return 1; 239 return 0;
234 } 240 }
241 flag=_mm_read_UBYTE(modreader);
235 if(!flag) 242 if(!flag)
236 row++; 243 row++;
237 else { 244 else {
238 ch=(flag-1)&63; 245 ch=(flag-1)&63;
239 remap[ch]=0; 246 remap[ch]=0;
240 if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader); 247 if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader);
241 if(mask[ch]&1) (void)_mm_read_UBYTE(modreader); 248 if(mask[ch]&1) _mm_skip_BYTE(modreader);
242 if(mask[ch]&2) (void)_mm_read_UBYTE(modreader); 249 if(mask[ch]&2) _mm_skip_BYTE(modreader);
243 if(mask[ch]&4) (void)_mm_read_UBYTE(modreader); 250 if(mask[ch]&4) _mm_skip_BYTE(modreader);
244 if(mask[ch]&8) { (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader); } 251 if(mask[ch]&8) { _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); }
245 } 252 }
246 } while(row<patrows); 253 } while(row<patrows);
247 254
248 return 0; 255 return 1;
249} 256}
250 257
251static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows) 258static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
@@ -282,7 +289,7 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
282 /* process volume / panning column 289 /* process volume / panning column
283 volume / panning effects do NOT all share the same memory address 290 volume / panning effects do NOT all share the same memory address
284 yet. */ 291 yet. */
285 if(volpan<=64) 292 if(volpan<=64)
286 UniVolEffect(VOL_VOLUME,volpan); 293 UniVolEffect(VOL_VOLUME,volpan);
287 else if(volpan==65) /* fine volume slide up (65-74) - A0 case */ 294 else if(volpan==65) /* fine volume slide up (65-74) - A0 case */
288 UniVolEffect(VOL_VOLSLIDE,0); 295 UniVolEffect(VOL_VOLSLIDE,0);
@@ -324,16 +331,20 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
324 331
325static int IT_ReadPattern(UWORD patrows) 332static int IT_ReadPattern(UWORD patrows)
326{ 333{
327 int row=0,flag,ch,blah; 334 int row=0,flag,ch;
335 unsigned int blah;
328 ITNOTE *itt=itpat,dummy,*n,*l; 336 ITNOTE *itt=itpat,dummy,*n,*l;
337 ITNOTE *ite=&itpat[200*64 -1];
338 UBYTE *m;
329 339
330 memset(itt,255,200*64*sizeof(ITNOTE)); 340 memset(itt,255,200*64*sizeof(ITNOTE));
331 341
332 do { 342 do {
333 if((flag=_mm_read_UBYTE(modreader))==EOF) { 343 if(_mm_eof(modreader)) {
334 _mm_errno = MMERR_LOADING_PATTERN; 344 _mm_errno = MMERR_LOADING_PATTERN;
335 return 0; 345 return 0;
336 } 346 }
347 flag=_mm_read_UBYTE(modreader);
337 if(!flag) { 348 if(!flag) {
338 itt=&itt[of.numchn]; 349 itt=&itt[of.numchn];
339 row++; 350 row++;
@@ -342,29 +353,38 @@ static int IT_ReadPattern(UWORD patrows)
342 if(ch!=-1) { 353 if(ch!=-1) {
343 n=&itt[ch]; 354 n=&itt[ch];
344 l=&last[ch]; 355 l=&last[ch];
345 } else 356 m=&mask[ch];
357 if(n > ite) { /* malformed file */
358 _mm_errno = MMERR_NOT_A_MODULE;
359 return 0;
360 }
361 } else
362 {
346 n=l=&dummy; 363 n=l=&dummy;
364 blah = 0;
365 m=(UBYTE*)&blah;
366 }
347 367
348 if(flag&128) mask[ch]=_mm_read_UBYTE(modreader); 368 if(flag&128) *m=_mm_read_UBYTE(modreader);
349 if(mask[ch]&1) 369 if(*m&1)
350 /* convert IT note off to internal note off */ 370 /* convert IT note off to internal note off */
351 if((l->note=n->note=_mm_read_UBYTE(modreader))==255) 371 if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
352 l->note=n->note=253; 372 l->note=n->note=253;
353 if(mask[ch]&2) 373 if(*m&2)
354 l->ins=n->ins=_mm_read_UBYTE(modreader); 374 l->ins=n->ins=_mm_read_UBYTE(modreader);
355 if(mask[ch]&4) 375 if(*m&4)
356 l->volpan=n->volpan=_mm_read_UBYTE(modreader); 376 l->volpan=n->volpan=_mm_read_UBYTE(modreader);
357 if(mask[ch]&8) { 377 if(*m&8) {
358 l->cmd=n->cmd=_mm_read_UBYTE(modreader); 378 l->cmd=n->cmd=_mm_read_UBYTE(modreader);
359 l->inf=n->inf=_mm_read_UBYTE(modreader); 379 l->inf=n->inf=_mm_read_UBYTE(modreader);
360 } 380 }
361 if(mask[ch]&16) 381 if(*m&16)
362 n->note=l->note; 382 n->note=l->note;
363 if(mask[ch]&32) 383 if(*m&32)
364 n->ins=l->ins; 384 n->ins=l->ins;
365 if(mask[ch]&64) 385 if(*m&64)
366 n->volpan=l->volpan; 386 n->volpan=l->volpan;
367 if(mask[ch]&128) { 387 if(*m&128) {
368 n->cmd=l->cmd; 388 n->cmd=l->cmd;
369 n->inf=l->inf; 389 n->inf=l->inf;
370 } 390 }
@@ -379,38 +399,39 @@ static int IT_ReadPattern(UWORD patrows)
379 return 1; 399 return 1;
380} 400}
381 401
382static void LoadMidiString(MREADER* modreader,CHAR* dest) 402static void LoadMidiString(MREADER* r,CHAR* dest)
383{ 403{
384 CHAR *cur,*last; 404 CHAR *curp,*lastp;
385 405
386 _mm_read_UBYTES(dest,32,modreader); 406 memset(dest,0,33*sizeof(CHAR));/* caller sends midiline[33] */
387 cur=last=dest; 407 _mm_read_UBYTES(dest,32,r);
408 curp=lastp=dest;
388 /* remove blanks and uppercase all */ 409 /* remove blanks and uppercase all */
389 while(*last) { 410 while(*lastp) {
390 if(isalnum((int)*last)) *(cur++)=toupper((int)*last); 411 if(isalnum((int)*lastp)) *(curp++)=toupper((int)*lastp);
391 last++; 412 lastp++;
392 } 413 }
393 *cur=0; 414 *curp=0;
394} 415}
395 416
396/* Load embedded midi information for resonant filters */ 417/* Load embedded midi information for resonant filters */
397static void IT_LoadMidiConfiguration(MREADER* modreader) 418static void IT_LoadMidiConfiguration(MREADER* r)
398{ 419{
399 int i; 420 int i;
400 421
401 memset(filtermacros,0,sizeof(filtermacros)); 422 memset(filtermacros,0,sizeof(filtermacros));
402 memset(filtersettings,0,sizeof(filtersettings)); 423 memset(filtersettings,0,sizeof(filtersettings));
403 424
404 if (modreader) { /* information is embedded in file */ 425 if (r) { /* information is embedded in file */
405 UWORD dat; 426 UWORD dat;
406 CHAR midiline[33]; 427 CHAR midiline[33];
407 428
408 dat=_mm_read_I_UWORD(modreader); 429 dat=_mm_read_I_UWORD(r);
409 _mm_fseek(modreader,8*dat+0x120,SEEK_CUR); 430 _mm_fseek(r,8*dat+0x120,SEEK_CUR);
410 431
411 /* read midi macros */ 432 /* read midi macros */
412 for(i=0;i<UF_MAXMACRO;i++) { 433 for(i=0;i<UF_MAXMACRO;i++) {
413 LoadMidiString(modreader,midiline); 434 LoadMidiString(r,midiline);
414 if((!strncmp(midiline,"F0F00",5))&& 435 if((!strncmp(midiline,"F0F00",5))&&
415 ((midiline[5]=='0')||(midiline[5]=='1'))) 436 ((midiline[5]=='0')||(midiline[5]=='1')))
416 filtermacros[i]=(midiline[5]-'0')|0x80; 437 filtermacros[i]=(midiline[5]-'0')|0x80;
@@ -418,7 +439,7 @@ static void IT_LoadMidiConfiguration(MREADER* modreader)
418 439
419 /* read standalone filters */ 440 /* read standalone filters */
420 for(i=0x80;i<0x100;i++) { 441 for(i=0x80;i<0x100;i++) {
421 LoadMidiString(modreader,midiline); 442 LoadMidiString(r,midiline);
422 if((!strncmp(midiline,"F0F00",5))&& 443 if((!strncmp(midiline,"F0F00",5))&&
423 ((midiline[5]=='0')||(midiline[5]=='1'))) { 444 ((midiline[5]=='0')||(midiline[5]=='1'))) {
424 filtersettings[i].filter=(midiline[5]-'0')|0x80; 445 filtersettings[i].filter=(midiline[5]-'0')|0x80;
@@ -446,7 +467,7 @@ static int IT_Load(int curious)
446 int t,u,lp; 467 int t,u,lp;
447 INSTRUMENT *d; 468 INSTRUMENT *d;
448 SAMPLE *q; 469 SAMPLE *q;
449 /* int compressed=0; */ 470 /*int compressed=0;*/
450 471
451 numtrk=0; 472 numtrk=0;
452 filters=0; 473 filters=0;
@@ -479,6 +500,10 @@ static int IT_Load(int curious)
479 _mm_errno=MMERR_LOADING_HEADER; 500 _mm_errno=MMERR_LOADING_HEADER;
480 return 0; 501 return 0;
481 } 502 }
503 if(mh->ordnum > 256 || mh->insnum > 255 || mh->smpnum > 255 || mh->patnum > 255) {
504 _mm_errno=MMERR_NOT_A_MODULE;
505 return 0;
506 }
482 507
483 /* set module variables */ 508 /* set module variables */
484 of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */ 509 of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */
@@ -506,11 +531,11 @@ static int IT_Load(int curious)
506 /* 2.16 : IT 2.14p3 with resonant filters */ 531 /* 2.16 : IT 2.14p3 with resonant filters */
507 /* 2.15 : IT 2.14p3 (improved compression) */ 532 /* 2.15 : IT 2.14p3 (improved compression) */
508 if((mh->cwt<=0x219)&&(mh->cwt>=0x217)) 533 if((mh->cwt<=0x219)&&(mh->cwt>=0x217))
509 of.modtype=StrDup(IT_Version[mh->cmwt<0x214?4:5]); 534 of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?4:5]);
510 else if (mh->cwt>=0x215) 535 else if (mh->cwt>=0x215)
511 of.modtype=StrDup(IT_Version[mh->cmwt<0x214?2:3]); 536 of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?2:3]);
512 else { 537 else {
513 of.modtype = StrDup(IT_Version[mh->cmwt<0x214?0:1]); 538 of.modtype = MikMod_strdup(IT_Version[mh->cmwt<0x214?0:1]);
514 of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0'; 539 of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0';
515 of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0'; 540 of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0';
516 of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0'; 541 of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0';
@@ -550,7 +575,7 @@ static int IT_Load(int curious)
550 575
551 /* read the order data */ 576 /* read the order data */
552 if(!AllocPositions(mh->ordnum)) return 0; 577 if(!AllocPositions(mh->ordnum)) return 0;
553 if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0; 578 if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
554 579
555 for(t=0;t<mh->ordnum;t++) { 580 for(t=0;t<mh->ordnum;t++) {
556 origpositions[t]=_mm_read_UBYTE(modreader); 581 origpositions[t]=_mm_read_UBYTE(modreader);
@@ -672,14 +697,14 @@ static int IT_Load(int curious)
672 if(s.flag&2) q->flags|=SF_16BITS; 697 if(s.flag&2) q->flags|=SF_16BITS;
673 if((s.flag&8)&&(mh->cwt>=0x214)) { 698 if((s.flag&8)&&(mh->cwt>=0x214)) {
674 q->flags|=SF_ITPACKED; 699 q->flags|=SF_ITPACKED;
675 /* compressed=1; */ 700 /*compressed=1;*/
676 } 701 }
677 if(s.flag&16) q->flags|=SF_LOOP; 702 if(s.flag&16) q->flags|=SF_LOOP;
678 if(s.flag&64) q->flags|=SF_BIDI; 703 if(s.flag&64) q->flags|=SF_BIDI;
679 704
680 if(mh->cwt>=0x200) { 705 if(mh->cwt>=0x200) {
681 if(s.convert&1) q->flags|=SF_SIGNED; 706 if(s.convert&1) q->flags|=SF_SIGNED;
682 if(s.convert&4) q->flags|=SF_DELTA; 707 if(s.convert&4) q->flags|=SF_DELTA;
683 } 708 }
684 q++; 709 q++;
685 } 710 }
@@ -726,7 +751,7 @@ static int IT_Load(int curious)
726 751
727 ih.trkvers = _mm_read_I_UWORD(modreader); 752 ih.trkvers = _mm_read_I_UWORD(modreader);
728 ih.numsmp = _mm_read_UBYTE(modreader); 753 ih.numsmp = _mm_read_UBYTE(modreader);
729 (void)_mm_read_UBYTE(modreader); 754 _mm_skip_BYTE(modreader);
730 _mm_read_string(ih.name,26,modreader); 755 _mm_read_string(ih.name,26,modreader);
731 _mm_read_UBYTES(ih.blank01,6,modreader); 756 _mm_read_UBYTES(ih.blank01,6,modreader);
732 _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader); 757 _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader);
@@ -736,13 +761,15 @@ static int IT_Load(int curious)
736 for(lp=0;lp<ITENVCNT;lp++) { 761 for(lp=0;lp<ITENVCNT;lp++) {
737 ih.oldvoltick[lp] = _mm_read_UBYTE(modreader); 762 ih.oldvoltick[lp] = _mm_read_UBYTE(modreader);
738 ih.volnode[lp] = _mm_read_UBYTE(modreader); 763 ih.volnode[lp] = _mm_read_UBYTE(modreader);
739 } 764 }
740 } else { 765 } else {
741 /* load IT 2xx volume, pan and pitch envelopes */ 766 /* load IT 2xx volume, pan and pitch envelopes */
742#if defined __STDC__ || defined _MSC_VER || defined MPW_C 767#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
743#define IT_LoadEnvelope(name,type) \ 768#define IT_LoadEnvelope(name,type) \
744 ih. name##flg =_mm_read_UBYTE(modreader); \ 769 ih. name##flg =_mm_read_UBYTE(modreader); \
745 ih. name##pts =_mm_read_UBYTE(modreader); \ 770 ih. name##pts =_mm_read_UBYTE(modreader); \
771 if (ih. name##pts > ITENVCNT) \
772 ih. name##pts = ITENVCNT; \
746 ih. name##beg =_mm_read_UBYTE(modreader); \ 773 ih. name##beg =_mm_read_UBYTE(modreader); \
747 ih. name##end =_mm_read_UBYTE(modreader); \ 774 ih. name##end =_mm_read_UBYTE(modreader); \
748 ih. name##susbeg=_mm_read_UBYTE(modreader); \ 775 ih. name##susbeg=_mm_read_UBYTE(modreader); \
@@ -751,11 +778,13 @@ static int IT_Load(int curious)
751 ih. name##node[lp]=_mm_read_##type (modreader); \ 778 ih. name##node[lp]=_mm_read_##type (modreader); \
752 ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \ 779 ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \
753 } \ 780 } \
754 (void)_mm_read_UBYTE(modreader) 781 _mm_skip_BYTE(modreader)
755#else 782#else
756#define IT_LoadEnvelope(name,type) \ 783#define IT_LoadEnvelope(name,type) \
757 ih. name/**/flg =_mm_read_UBYTE(modreader); \ 784 ih. name/**/flg =_mm_read_UBYTE(modreader); \
758 ih. name/**/pts =_mm_read_UBYTE(modreader); \ 785 ih. name/**/pts =_mm_read_UBYTE(modreader); \
786 if (ih. name/**/pts > ITENVCNT) \
787 ih. name/**/pts = ITENVCNT; \
759 ih. name/**/beg =_mm_read_UBYTE(modreader); \ 788 ih. name/**/beg =_mm_read_UBYTE(modreader); \
760 ih. name/**/end =_mm_read_UBYTE(modreader); \ 789 ih. name/**/end =_mm_read_UBYTE(modreader); \
761 ih. name/**/susbeg=_mm_read_UBYTE(modreader); \ 790 ih. name/**/susbeg=_mm_read_UBYTE(modreader); \
@@ -764,7 +793,7 @@ static int IT_Load(int curious)
764 ih. name/**/node[lp]=_mm_read_/**/type (modreader); \ 793 ih. name/**/node[lp]=_mm_read_/**/type (modreader); \
765 ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \ 794 ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \
766 } \ 795 } \
767 (void)_mm_read_UBYTE(modreader) 796 _mm_skip_BYTE(modreader)
768#endif 797#endif
769 798
770 IT_LoadEnvelope(vol,UBYTE); 799 IT_LoadEnvelope(vol,UBYTE);
@@ -772,7 +801,7 @@ static int IT_Load(int curious)
772 IT_LoadEnvelope(pit,SBYTE); 801 IT_LoadEnvelope(pit,SBYTE);
773#undef IT_LoadEnvelope 802#undef IT_LoadEnvelope
774 } 803 }
775 804
776 if(_mm_eof(modreader)) { 805 if(_mm_eof(modreader)) {
777 _mm_errno = MMERR_LOADING_SAMPLEINFO; 806 _mm_errno = MMERR_LOADING_SAMPLEINFO;
778 return 0; 807 return 0;
@@ -791,10 +820,10 @@ static int IT_Load(int curious)
791 820
792 if(ih.volflg&1) d->volflg|=EF_ON; 821 if(ih.volflg&1) d->volflg|=EF_ON;
793 if(ih.volflg&2) d->volflg|=EF_LOOP; 822 if(ih.volflg&2) d->volflg|=EF_LOOP;
794 if(ih.volflg&4) d->volflg|=EF_SUSTAIN; 823 if(ih.volflg&4) d->volflg|=EF_SUSTAIN;
795 824
796 /* XM conversion of IT envelope Array */ 825 /* XM conversion of IT envelope Array */
797 d->volbeg = ih.volbeg; 826 d->volbeg = ih.volbeg;
798 d->volend = ih.volend; 827 d->volend = ih.volend;
799 d->volsusbeg = ih.volsusbeg; 828 d->volsusbeg = ih.volsusbeg;
800 d->volsusend = ih.volsusend; 829 d->volsusend = ih.volsusend;
@@ -807,7 +836,7 @@ static int IT_Load(int curious)
807 d->volpts++; 836 d->volpts++;
808 } else 837 } else
809 break; 838 break;
810 } 839 }
811 } else { 840 } else {
812 d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2; 841 d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2;
813 if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN; 842 if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN;
@@ -827,7 +856,7 @@ static int IT_Load(int curious)
827 d->rpanvar = ih.rpanvar; 856 d->rpanvar = ih.rpanvar;
828 } 857 }
829 858
830#if defined __STDC__ || defined _MSC_VER || defined MPW_C 859#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
831#define IT_ProcessEnvelope(name) \ 860#define IT_ProcessEnvelope(name) \
832 if(ih. name##flg&1) d-> name##flg|=EF_ON; \ 861 if(ih. name##flg&1) d-> name##flg|=EF_ON; \
833 if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \ 862 if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \
@@ -862,11 +891,7 @@ static int IT_Load(int curious)
862#endif 891#endif
863 892
864 IT_ProcessEnvelope(vol); 893 IT_ProcessEnvelope(vol);
865 894
866 // Secunia SA37775
867 if (ih.volpts>= ENVPOINTS)
868 ih.volpts = ENVPOINTS-1;
869
870 for(u=0;u<ih.volpts;u++) 895 for(u=0;u<ih.volpts;u++)
871 d->volenv[u].val=(ih.volnode[u]<<2); 896 d->volenv[u].val=(ih.volnode[u]<<2);
872 897
@@ -887,7 +912,7 @@ static int IT_Load(int curious)
887#ifdef MIKMOD_DEBUG 912#ifdef MIKMOD_DEBUG
888 { 913 {
889 static int warn=0; 914 static int warn=0;
890 915
891 if(!warn) 916 if(!warn)
892 fprintf(stderr, "\rFilter envelopes not supported yet\n"); 917 fprintf(stderr, "\rFilter envelopes not supported yet\n");
893 warn=1; 918 warn=1;
@@ -908,7 +933,7 @@ static int IT_Load(int curious)
908 } 933 }
909 } 934 }
910 935
911 d++; 936 d++;
912 } 937 }
913 } else if(of.flags & UF_LINEAR) { 938 } else if(of.flags & UF_LINEAR) {
914 if(!AllocInstruments()) return 0; 939 if(!AllocInstruments()) return 0;
@@ -946,12 +971,12 @@ static int IT_Load(int curious)
946 return 0; 971 return 0;
947 } 972 }
948 _mm_read_I_ULONG(modreader); 973 _mm_read_I_ULONG(modreader);
949 if(IT_GetNumChannels(packlen)) return 0; 974 if(!IT_GetNumChannels(packlen)) return 0;
950 } 975 }
951 } 976 }
952 977
953 /* give each of them a different number */ 978 /* give each of them a different number */
954 for(t=0;t<UF_MAXCHAN;t++) 979 for(t=0;t<UF_MAXCHAN;t++)
955 if(!remap[t]) 980 if(!remap[t])
956 remap[t]=of.numchn++; 981 remap[t]=of.numchn++;
957 982
@@ -963,6 +988,8 @@ static int IT_Load(int curious)
963 if(!AllocTracks()) return 0; 988 if(!AllocTracks()) return 0;
964 989
965 for(t=0;t<of.numpat;t++) { 990 for(t=0;t<of.numpat;t++) {
991 UWORD packlen;
992
966 /* seek to pattern position */ 993 /* seek to pattern position */
967 if(!paraptr[mh->insnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */ 994 if(!paraptr[mh->insnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */
968 of.pattrows[t]=64; 995 of.pattrows[t]=64;
@@ -975,7 +1002,8 @@ static int IT_Load(int curious)
975 } 1002 }
976 } else { 1003 } else {
977 _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET); 1004 _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET);
978 (void)_mm_read_I_UWORD(modreader); 1005 packlen=_mm_read_I_UWORD(modreader);
1006 (void)packlen; /* unused */
979 of.pattrows[t]=_mm_read_I_UWORD(modreader); 1007 of.pattrows[t]=_mm_read_I_UWORD(modreader);
980 _mm_read_I_ULONG(modreader); 1008 _mm_read_I_ULONG(modreader);
981 if(!IT_ReadPattern(of.pattrows[t])) return 0; 1009 if(!IT_ReadPattern(of.pattrows[t])) return 0;
@@ -991,7 +1019,7 @@ static CHAR *IT_LoadTitle(void)
991 1019
992 _mm_fseek(modreader,4,SEEK_SET); 1020 _mm_fseek(modreader,4,SEEK_SET);
993 if(!_mm_read_UBYTES(s,26,modreader)) return NULL; 1021 if(!_mm_read_UBYTES(s,26,modreader)) return NULL;
994 1022
995 return(DupStr(s,26,0)); 1023 return(DupStr(s,26,0));
996} 1024}
997 1025
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
82static char *signatures[REJECT]={ 82static 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};
86static int siglen[REJECT]={8,4}; 86static const int siglen[REJECT]={8,4};
87 87
88/*========== Loader code */ 88/*========== Loader code */
89 89
90static int LoadModuleHeader(MODULEHEADER *mh) 90static 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 */
148static int CheckPatternType(int numpat) 146static 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)
177static int M15_Test(void) 175static 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
243static int M15_Init(void) 242static 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. */
373static int M15_LoadPatterns(void) 374static 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
399static int M15_Load(int curious) 399static 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
194static void EffectCvt(UBYTE eff, UBYTE dat) 200static 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. */
310static int ML_LoadPatterns(void) 312static 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
113static UBYTE* MTM_Convert(void) 115static 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
443static CHAR *OKT_LoadTitle(void) 444static 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
107static CHAR* S3M_Version[] = { 107static 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 */
116static int numeric[NUMTRACKERS]={14,14,16,16}; 116static 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. */
160static int S3M_GetNumChannels(void) 165static 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
183static int S3M_ReadPattern(void) 188static 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;
90static STMHEADER *mh = NULL; 90static STMHEADER *mh = NULL;
91 91
92/* tracker identifiers */ 92/* tracker identifiers */
93static CHAR* STM_Version[STM_NTRACKERS] = { 93static 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
135static void STM_ConvertNote(STMNOTE *n) 138static 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
225static int STM_LoadPatterns(void) 228static 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
253static int STM_Load(int curious) 255static 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
148static int STX_ReadPattern(void) 153static 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
83static CHAR ULT_Version[ULT_VERSION_LEN]="Ultra Tracker v1.x"; 83static CHAR ULT_Version[ULT_VERSION_LEN+1]="Ultra Tracker v1.x";
84 84
85static ULTEVENT ev; 85static 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
316static CHAR *ULT_LoadTitle(void) 324static 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
53typedef SLONG fci_t; /* FCompactIndex */
54
55#define UPKG_HDR_TAG 0x9e2a83c1
56
57struct _genhist { /* for upkg versions >= 68 */
58 SLONG export_count;
59 SLONG name_count;
60};
61
62struct 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];*/
86typedef 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
95static 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 */
108static 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
144static 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
188static 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
209static 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
235static 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
285static 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
329static 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
343typedef struct _umx_info {
344 int type;
345 SLONG ofs, size;
346 MLOADER* loader;
347} umx_info;
348
349static 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
362static 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
404static 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
415static 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
426static 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
439static 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
465MIKMODAPI 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
97static char* readstring(void) 97static 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
111static int UNI_Test(void) 111static int UNI_Test(void)
@@ -133,7 +133,7 @@ static int UNI_Init(void)
133static void UNI_Cleanup(void) 133static 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
139static UBYTE* readtrack(void) 139static 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)
221static int loadsmp6(void) 221static 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 {
129static XMNOTE *xmpat=NULL; 129static XMNOTE *xmpat=NULL;
130static XMHEADER *mh=NULL; 130static 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
134static ULONG *nextwav=NULL; 134static ULONG *nextwav=NULL;
135static XMWAVHEADER *wh=NULL,*s=NULL; 135static XMWAVHEADER *wh=NULL,*s=NULL;
@@ -155,6 +155,7 @@ static int XM_Init(void)
155static void XM_Cleanup(void) 155static void XM_Cleanup(void)
156{ 156{
157 MikMod_free(mh); 157 MikMod_free(mh);
158 mh=NULL;
158} 159}
159 160
160static int XM_ReadNote(XMNOTE* n) 161static 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
444static int LoadInstruments(void) 445static 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
814bad_hdr: _mm_errno = MMERR_LOADING_HEADER; return 0;
815bad_xm: _mm_errno = MMERR_NOT_A_MODULE; return 0;
805} 816}
806 817
807static CHAR *XM_LoadTitle(void) 818static 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
35static void _mm_registeralldrivers(void) 33static 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
124void MikMod_RegisterAllDrivers(void) 158MIKMODAPI 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
52extern int fprintf(FILE *, const char *, ...); 45extern int fprintf(FILE *, const char *, ...);
53#endif 46#endif
54 47
55static MDRIVER *firstdriver=NULL;
56MIKMODAPI MDRIVER *md_driver=NULL;
57extern MODULE *pf; /* modfile being played */ 48extern MODULE *pf; /* modfile being played */
58 49
50/* EXPORTED GLOBALS */
51MIKMODAPI MDRIVER *md_driver = NULL;
52
59/* Initial global settings */ 53/* Initial global settings */
60MIKMODAPI UWORD md_device = 0; /* autodetect */ 54MIKMODAPI UWORD md_device = 0; /* autodetect */
61MIKMODAPI UWORD md_mixfreq = 44100; 55MIKMODAPI ULONG md_mixfreq = 44100;
62MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS | 56MIKMODAPI 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;
65MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */ 59MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
66MIKMODAPI UBYTE md_reverb = 0; /* no reverb */ 60MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
67MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */ 61MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
68MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */ 62MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
69MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */ 63MIKMODAPI 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() */ 66UWORD 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 69UBYTE md_numchn = 0, md_sngchn = 0, md_sfxchn = 0;
76 void (*md_player)(void) = Player_HandleTick; 70UBYTE md_hardchn = 0, md_softchn= 0;
77static volatile int isplaying=0, initialized = 0; 71
78static UBYTE *sfxinfo; 72MikMod_player_t md_player = Player_HandleTick;
79static int sfxpool; 73
80 74MikMod_callback_t vc_callback = NULL;
81static SAMPLE **md_sample = NULL; 75
76/* PRIVATE VARS */
77static MDRIVER *firstdriver = NULL;
78
79static volatile int isplaying = 0, initialized = 0;
80
81static UBYTE *sfxinfo;
82static int sfxpool;
83
84static SAMPLE **md_sample = NULL;
82 85
83/* Previous driver in use */ 86/* Previous driver in use */
84static SWORD olddevice = -1; 87static 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
233MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias) 237MIKMODAPI 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
253MIKMODAPI MDRIVER *MikMod_DriverByOrdinal(int ordinal) 257MIKMODAPI 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
269SWORD MD_SampleLoad(SAMPLOAD* s, int type) 272SWORD 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
499extern MikMod_callback_t vc_callback;
500
501MIKMODAPI void VC_SetCallback(MikMod_callback_t callback) 502MIKMODAPI void VC_SetCallback(MikMod_callback_t callback)
502{ 503{
503 vc_callback = callback; 504 vc_callback = callback;
504} 505}
505 506
506static int _mm_init(CHAR *cmdline) 507static 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
564MIKMODAPI int MikMod_Init(CHAR *cmdline) 565MIKMODAPI 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. */
603static int _mm_reset(CHAR *cmdline) 604static 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
637MIKMODAPI int MikMod_Reset(CHAR *cmdline) 638MIKMODAPI 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. */
768static SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags) 769static 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);
842MIKMODAPI int MikMod_InitThreads(void) 846MIKMODAPI 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
883CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit) 887CHAR *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... */
920int MD_Access(CHAR *filename) 923int 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
474static struct mikmod_settings settings = 478static 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
484static struct mikmod_settings old_settings; 492static struct mikmod_settings old_settings;
485 493
486static struct configdata config[] = 494static 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
496static void applysettings(void) 508static 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
549static 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
68MIKMODAPI extern long MikMod_GetVersion(void); 86MIKMODAPI 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>
85typedef 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))
124typedef char CHAR;
87#endif 125#endif
88 126
89typedef 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: */
133typedef signed char SBYTE;
134#ifndef _MIKMOD_AMIGA
135typedef 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)
140typedef signed short int SWORD;
141#endif
142#if !((defined __LCC__ && defined _WIN32) || defined(_MIKMOD_AMIGA))
143typedef unsigned short int UWORD;
144#endif
94 145
95typedef signed char SBYTE; /* 1 byte, signed */ 146/* 4 bytes, signed and unsigned: */
96typedef unsigned char UBYTE; /* 1 byte, unsigned */ 147#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(__powerpc64__)
97typedef signed short SWORD; /* 2 bytes, signed */ 148 /* 64 bit architectures: */
98typedef unsigned short UWORD; /* 2 bytes, unsigned */ 149typedef signed int SLONG;
99typedef signed int SLONG; /* 4 bytes, signed */ 150#if !(defined(_WIN32) || defined(_MIKMOD_AMIGA))
100typedef unsigned int ULONG; /* 4 bytes, unsigned */ 151typedef 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 */ 155typedef signed long int SLONG;
105 156#if !(defined(_MIKMOD_OS2) || defined(_MIKMOD_WIN32) || defined(_MIKMOD_AMIGA))
106typedef signed char SBYTE; /* 1 byte, signed */ 157typedef unsigned long int ULONG;
107typedef unsigned char UBYTE; /* 1 byte, unsigned */
108typedef signed short SWORD; /* 2 bytes, signed */
109typedef unsigned short UWORD; /* 2 bytes, unsigned */
110typedef signed long SLONG; /* 4 bytes, signed */
111#if !defined(__OS2__)&&!defined(__EMX__)&&!defined(WIN32)
112typedef 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: */
162typedef 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
121enum { 177enum {
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
220typedef void (MikMod_handler)(void); 303typedef void (MikMod_handler)(void);
@@ -222,12 +305,12 @@ typedef MikMod_handler *MikMod_handler_t;
222 305
223MIKMODAPI extern int MikMod_errno; 306MIKMODAPI extern int MikMod_errno;
224MIKMODAPI extern int MikMod_critical; 307MIKMODAPI extern int MikMod_critical;
225MIKMODAPI extern char *MikMod_strerror(int); 308MIKMODAPI extern const char *MikMod_strerror(int);
226 309
227MIKMODAPI extern MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t); 310MIKMODAPI 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
233struct MDRIVER; 316struct MDRIVER;
@@ -236,15 +319,15 @@ MIKMODAPI extern void MikMod_RegisterAllDrivers(void);
236 319
237MIKMODAPI extern CHAR* MikMod_InfoDriver(void); 320MIKMODAPI extern CHAR* MikMod_InfoDriver(void);
238MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*); 321MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*);
239MIKMODAPI extern int MikMod_DriverFromAlias(CHAR*); 322MIKMODAPI extern int MikMod_DriverFromAlias(const CHAR*);
240MIKMODAPI extern struct MDRIVER *MikMod_DriverByOrdinal(int); 323MIKMODAPI extern struct MDRIVER *MikMod_DriverByOrdinal(int);
241 324
242MIKMODAPI extern int MikMod_Init(CHAR*); 325MIKMODAPI extern int MikMod_Init(const CHAR*);
243MIKMODAPI extern void MikMod_Exit(void); 326MIKMODAPI extern void MikMod_Exit(void);
244MIKMODAPI extern int MikMod_Reset(CHAR*); 327MIKMODAPI extern int MikMod_Reset(const CHAR*);
245MIKMODAPI extern int MikMod_SetNumVoices(int,int); 328MIKMODAPI extern int MikMod_SetNumVoices(int,int);
246MIKMODAPI extern int MikMod_Active(void); 329MIKMODAPI extern int MikMod_Active(void);
247MIKMODAPI extern int MikMod_EnableOutput(void); 330MIKMODAPI extern int MikMod_EnableOutput(void);
248MIKMODAPI extern void MikMod_DisableOutput(void); 331MIKMODAPI extern void MikMod_DisableOutput(void);
249MIKMODAPI extern void MikMod_Update(void); 332MIKMODAPI extern void MikMod_Update(void);
250 333
@@ -253,33 +336,34 @@ MIKMODAPI extern void MikMod_Lock(void);
253MIKMODAPI extern void MikMod_Unlock(void); 336MIKMODAPI extern void MikMod_Unlock(void);
254 337
255MIKMODAPI extern void* MikMod_malloc(size_t); 338MIKMODAPI extern void* MikMod_malloc(size_t);
256MIKMODAPI extern void* MikMod_realloc(void *, size_t);
257MIKMODAPI extern void* MikMod_calloc(size_t,size_t); 339MIKMODAPI extern void* MikMod_calloc(size_t,size_t);
258MIKMODAPI extern void MikMod_free(void*); 340MIKMODAPI extern void* MikMod_realloc(void*,size_t);
341MIKMODAPI extern CHAR* MikMod_strdup(const CHAR*);
342MIKMODAPI extern void MikMod_free(void*); /* frees if ptr != NULL */
259 343
260/* 344/*
261 * ========== Reader, Writer 345 * ========== Reader, Writer
262 */ 346 */
263 347
264typedef struct MREADER { 348typedef 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
274typedef struct MWRITER { 358typedef 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
322typedef struct SAMPLE { 406typedef 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
354MIKMODAPI extern SAMPLE *Sample_LoadRaw(CHAR *,ULONG rate, ULONG channel, ULONG flags); 438MIKMODAPI extern SAMPLE *Sample_LoadRaw(const CHAR *,ULONG rate, ULONG channel, ULONG flags);
355MIKMODAPI extern SAMPLE *Sample_LoadRawFP(int fp,ULONG rate,ULONG channel, ULONG flags); 439MIKMODAPI extern SAMPLE *Sample_LoadRawFP(int fp,ULONG rate,ULONG channel, ULONG flags);
356MIKMODAPI extern SAMPLE *Sample_LoadRawMem(const char *buf, int len, ULONG rate, ULONG channel, ULONG flags); 440MIKMODAPI extern SAMPLE *Sample_LoadRawMem(const char *buf, int len, ULONG rate, ULONG channel, ULONG flags);
357MIKMODAPI extern SAMPLE *Sample_LoadRawGeneric(MREADER*reader,ULONG rate, ULONG channel, ULONG flags); 441MIKMODAPI extern SAMPLE *Sample_LoadRawGeneric(MREADER*reader,ULONG rate, ULONG channel, ULONG flags);
358 442
359MIKMODAPI extern SAMPLE *Sample_Load(CHAR*); 443MIKMODAPI extern SAMPLE *Sample_Load(const CHAR*);
360MIKMODAPI extern SAMPLE *Sample_LoadFP(int); 444MIKMODAPI extern SAMPLE *Sample_LoadFP(int);
361MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len); 445MIKMODAPI extern SAMPLE *Sample_LoadMem(const char *buf, int len);
362MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*); 446MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*);
@@ -376,12 +460,12 @@ MIKMODAPI extern SLONG Voice_GetPosition(SBYTE);
376MIKMODAPI extern ULONG Voice_RealVolume(SBYTE); 460MIKMODAPI 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 */
391typedef struct ENVPT { 475typedef 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 */
400typedef struct INSTRUMENT { 484typedef 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
445struct MP_CONTROL; 529struct MP_CONTROL;
446struct MP_VOICE; 530struct 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
471typedef struct MODULE { 555typedef 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 */
484struct INSTRUMENT* instruments; /* all instruments */ 568
485struct 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) */
524struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */ 608 UWORD sngremainder;/* used for song time computation */
525struct 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 */
538typedef struct VOICEINFO { 624typedef 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
551struct MLOADER; 637struct MLOADER;
@@ -572,18 +658,19 @@ MIKMODAPI extern struct MLOADER load_stm; /* ScreamTracker 2 (by Future Crew) */
572MIKMODAPI extern struct MLOADER load_stx; /* STMIK 0.2 (by Future Crew) */ 658MIKMODAPI extern struct MLOADER load_stx; /* STMIK 0.2 (by Future Crew) */
573MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (by Future Crew) */ 659MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (by Future Crew) */
574MIKMODAPI extern struct MLOADER load_ult; /* UltraTracker (by MAS) */ 660MIKMODAPI extern struct MLOADER load_ult; /* UltraTracker (by MAS) */
661MIKMODAPI extern struct MLOADER load_umx; /* Unreal UMX container of Epic Games */
575MIKMODAPI extern struct MLOADER load_uni; /* MikMod and APlayer internal module format */ 662MIKMODAPI extern struct MLOADER load_uni; /* MikMod and APlayer internal module format */
576MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */ 663MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */
577 664
578/* 665/*
579 * ========== Module player 666 * ========== Module player
580 */ 667 */
581 668
582MIKMODAPI extern MODULE* Player_Load(CHAR*,int,int); 669MIKMODAPI extern MODULE* Player_Load(const CHAR*,int,int);
583MIKMODAPI extern MODULE* Player_LoadFP(int,int,int); 670MIKMODAPI extern MODULE* Player_LoadFP(int,int,int);
584MIKMODAPI extern MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curious); 671MIKMODAPI extern MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curious);
585MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,int); 672MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,int);
586MIKMODAPI extern CHAR* Player_LoadTitle(CHAR*); 673MIKMODAPI extern CHAR* Player_LoadTitle(const CHAR*);
587MIKMODAPI extern CHAR* Player_LoadTitleFP(int); 674MIKMODAPI extern CHAR* Player_LoadTitleFP(int);
588MIKMODAPI extern CHAR* Player_LoadTitleMem(const char *buffer,int len); 675MIKMODAPI extern CHAR* Player_LoadTitleMem(const char *buffer,int len);
589MIKMODAPI extern CHAR* Player_LoadTitleGeneric(MREADER*); 676MIKMODAPI extern CHAR* Player_LoadTitleGeneric(MREADER*);
@@ -607,9 +694,9 @@ MIKMODAPI extern void Player_Mute(SLONG,...);
607MIKMODAPI extern void Player_ToggleMute(SLONG,...); 694MIKMODAPI extern void Player_ToggleMute(SLONG,...);
608MIKMODAPI extern int Player_GetChannelVoice(UBYTE); 695MIKMODAPI extern int Player_GetChannelVoice(UBYTE);
609MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE); 696MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE);
610MIKMODAPI extern int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo); 697MIKMODAPI extern int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo);
611MIKMODAPI extern int Player_GetRow(void); 698MIKMODAPI extern int Player_GetRow(void);
612MIKMODAPI extern int Player_GetOrder(void); 699MIKMODAPI extern int Player_GetOrder(void);
613 700
614typedef void (*MikMod_player_t)(void); 701typedef void (*MikMod_player_t)(void);
615typedef void (*MikMod_callback_t)(unsigned char *data, size_t len); 702typedef 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
626enum { 713enum {
627 MD_MUSIC = 0, 714 MD_MUSIC = 0,
628 MD_SNDFX 715 MD_SNDFX
629}; 716};
630 717
631enum { 718enum {
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
652struct SAMPLOAD; 740struct SAMPLOAD;
741
653typedef struct MDRIVER { 742typedef struct MDRIVER {
654struct 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). */
702MIKMODAPI extern UWORD md_device; /* device */ 791MIKMODAPI extern UWORD md_device; /* device */
703MIKMODAPI extern UWORD md_mixfreq; /* mixing frequency */ 792MIKMODAPI extern ULONG md_mixfreq; /* mixing frequency */
704MIKMODAPI extern UWORD md_mode; /* mode. See DMODE_? flags above */ 793MIKMODAPI 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
711MIKMODAPI extern struct MDRIVER drv_nos; /* no sound */ 800MIKMODAPI extern struct MDRIVER drv_nos; /* no sound */
712#if 0
713MIKMODAPI extern struct MDRIVER drv_pipe; /* piped output */ 801MIKMODAPI extern struct MDRIVER drv_pipe; /* piped output */
714MIKMODAPI extern struct MDRIVER drv_raw; /* raw file disk writer [music.raw] */ 802MIKMODAPI extern struct MDRIVER drv_raw; /* raw file disk writer [music.raw] */
715MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */ 803MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */
@@ -717,42 +805,53 @@ MIKMODAPI extern struct MDRIVER drv_wav; /* RIFF WAVE file disk writer [music
717MIKMODAPI extern struct MDRIVER drv_aiff; /* AIFF file disk writer [music.aiff] */ 805MIKMODAPI extern struct MDRIVER drv_aiff; /* AIFF file disk writer [music.aiff] */
718 806
719MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */ 807MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */
720MIKMODAPI extern struct MDRIVER drv_sam9407; /* Linux sam9407 driver */ 808MIKMODAPI extern struct MDRIVER drv_sam9407;/* Linux sam9407 driver */
721 809
722MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */ 810MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */
811MIKMODAPI extern struct MDRIVER drv_ahi; /* Amiga AHI */
723MIKMODAPI extern struct MDRIVER drv_aix; /* AIX audio device */ 812MIKMODAPI extern struct MDRIVER drv_aix; /* AIX audio device */
724MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */ 813MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */
725MIKMODAPI extern struct MDRIVER drv_esd; /* Enlightened sound daemon (EsounD) */ 814MIKMODAPI extern struct MDRIVER drv_esd; /* Enlightened sound daemon (EsounD) */
815MIKMODAPI extern struct MDRIVER drv_pulseaudio; /* PulseAudio */
726MIKMODAPI extern struct MDRIVER drv_hp; /* HP-UX audio device */ 816MIKMODAPI extern struct MDRIVER drv_hp; /* HP-UX audio device */
727MIKMODAPI extern struct MDRIVER drv_nas; /* Network Audio System (NAS) */ 817MIKMODAPI extern struct MDRIVER drv_nas; /* Network Audio System (NAS) */
728MIKMODAPI extern struct MDRIVER drv_oss; /* OpenSound System (Linux,FreeBSD...) */ 818MIKMODAPI extern struct MDRIVER drv_oss; /* OpenSound System (Linux,FreeBSD...) */
819MIKMODAPI extern struct MDRIVER drv_openal; /* OpenAL driver */
820MIKMODAPI extern struct MDRIVER drv_sdl; /* SDL audio driver */
729MIKMODAPI extern struct MDRIVER drv_sgi; /* SGI audio library */ 821MIKMODAPI extern struct MDRIVER drv_sgi; /* SGI audio library */
822MIKMODAPI extern struct MDRIVER drv_sndio; /* OpenBSD sndio */
730MIKMODAPI extern struct MDRIVER drv_sun; /* Sun/NetBSD/OpenBSD audio device */ 823MIKMODAPI extern struct MDRIVER drv_sun; /* Sun/NetBSD/OpenBSD audio device */
731 824
732MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */ 825MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */
733MIKMODAPI extern struct MDRIVER drv_os2; /* OS/2 MMPM/2 */ 826MIKMODAPI extern struct MDRIVER drv_os2; /* OS/2 MMPM/2 */
734 827
735MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */ 828MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */
829MIKMODAPI extern struct MDRIVER drv_xaudio2;/* Win32 XAudio2 driver */
736MIKMODAPI extern struct MDRIVER drv_win; /* Win32 multimedia API driver */ 830MIKMODAPI extern struct MDRIVER drv_win; /* Win32 multimedia API driver */
737 831
738MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager driver */ 832MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager driver */
739MIKMODAPI extern struct MDRIVER drv_osx; /* MacOS X CoreAudio Driver */ 833MIKMODAPI extern struct MDRIVER drv_osx; /* MacOS X CoreAudio Driver */
740 834
835MIKMODAPI extern struct MDRIVER drv_dc; /* Dreamcast driver */
741MIKMODAPI extern struct MDRIVER drv_gp32; /* GP32 Sound driver */ 836MIKMODAPI extern struct MDRIVER drv_gp32; /* GP32 Sound driver */
837MIKMODAPI extern struct MDRIVER drv_psp; /* PlayStation Portable driver */
838MIKMODAPI extern struct MDRIVER drv_n64; /* Nintendo64 driver */
742 839
743MIKMODAPI extern struct MDRIVER drv_wss; /* DOS WSS driver */ 840MIKMODAPI extern struct MDRIVER drv_wss; /* DOS WSS driver */
744MIKMODAPI extern struct MDRIVER drv_sb; /* DOS SB driver */ 841MIKMODAPI extern struct MDRIVER drv_sb; /* DOS S/B driver */
745#endif 842
843MIKMODAPI 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
748MIKMODAPI extern int VC_Init(void); 847MIKMODAPI extern int VC_Init(void);
749MIKMODAPI extern void VC_Exit(void); 848MIKMODAPI extern void VC_Exit(void);
750MIKMODAPI extern void VC_SetCallback(MikMod_callback_t callback); 849MIKMODAPI extern void VC_SetCallback(MikMod_callback_t callback);
751MIKMODAPI extern int VC_SetNumVoices(void); 850MIKMODAPI extern int VC_SetNumVoices(void);
752MIKMODAPI extern ULONG VC_SampleSpace(int); 851MIKMODAPI extern ULONG VC_SampleSpace(int);
753MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*); 852MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*);
754 853
755MIKMODAPI extern int VC_PlayStart(void); 854MIKMODAPI extern int VC_PlayStart(void);
756MIKMODAPI extern void VC_PlayStop(void); 855MIKMODAPI extern void VC_PlayStop(void);
757 856
758MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int); 857MIKMODAPI 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) && \
49typedef long SLONGLONG; 55 (defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__))
56typedef 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 60typedef long long SLONGLONG;
52#elif defined(__WATCOMC__) 61#elif defined(__WATCOMC__)
53typedef __int64 SLONGLONG; 62typedef __int64 SLONGLONG;
54#elif defined(WIN32) && !defined(__MWERKS__) 63#elif defined(_WIN32) && !defined(__MWERKS__)
55typedef LONGLONG SLONGLONG; 64typedef LONGLONG SLONGLONG;
56#elif macintosh && !TYPE_LONGLONG 65#elif defined(macintosh) && !TYPE_LONGLONG
57#include <Types.h> 66#include <Types.h>
58typedef SInt64 SLONGLONG; 67typedef SInt64 SLONGLONG;
68#else
69typedef long long SLONGLONG;
59#endif 70#endif
71typedef 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 */
75typedef long long SINTPTR_T;
60#else 76#else
61typedef long long SLONGLONG; 77/* long should be pointer-sized for all others : */
78typedef long SINTPTR_T;
62#endif 79#endif
80typedef 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;
106DECLARE_MUTEX(lists); 127DECLARE_MUTEX(lists);
107DECLARE_MUTEX(vars); 128DECLARE_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
111extern MREADER* _mm_new_mem_reader(const void *buffer, int len); 136extern MREADER* _mm_new_mem_reader(const void *buffer, long len);
112extern void _mm_delete_mem_reader(MREADER *reader); 137extern void _mm_delete_mem_reader(MREADER *reader);
113 138
114extern MREADER* _mm_new_file_reader(int fp); 139extern MREADER* _mm_new_file_reader(int fp);
@@ -117,33 +142,32 @@ extern void _mm_delete_file_reader(MREADER*);
117extern MWRITER* _mm_new_file_writer(int fp); 142extern MWRITER* _mm_new_file_writer(int fp);
118extern void _mm_delete_file_writer(MWRITER*); 143extern void _mm_delete_file_writer(MWRITER*);
119 144
120extern int _mm_FileExists(CHAR *fname); 145extern 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
139extern void _mm_iobase_setcur(MREADER*); 165extern void _mm_iobase_setcur(MREADER*);
140extern void _mm_iobase_revert(MREADER*); 166extern void _mm_iobase_revert(MREADER*);
141extern int _mm_fopen(CHAR*,CHAR*); 167extern int _mm_fopen(const CHAR *, const CHAR *);
142extern int _mm_fclose(int); 168extern int _mm_fclose(int);
143#if !defined(ROCKBOX) 169extern void _mm_write_string(const CHAR*,MWRITER*);
144extern void _mm_write_string(CHAR*,MWRITER*); 170extern int _mm_read_string (CHAR*,int,MREADER*);
145#endif
146extern int _mm_read_string (CHAR*,int,MREADER*);
147 171
148extern SWORD _mm_read_M_SWORD(MREADER*); 172extern SWORD _mm_read_M_SWORD(MREADER*);
149extern SWORD _mm_read_I_SWORD(MREADER*); 173extern 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. */
193typedef struct SAMPLOAD { 219typedef 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*);
209extern void SL_Sample16to8(SAMPLOAD*); 235extern void SL_Sample16to8(SAMPLOAD*);
210extern void SL_SampleSigned(SAMPLOAD*); 236extern void SL_SampleSigned(SAMPLOAD*);
211extern void SL_SampleUnsigned(SAMPLOAD*); 237extern void SL_SampleUnsigned(SAMPLOAD*);
212extern int SL_LoadSamples(void); 238extern int SL_LoadSamples(void);
213extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*); 239extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*);
214extern int SL_Load(void*,SAMPLOAD*,ULONG); 240extern int SL_Load(void*,SAMPLOAD*,ULONG);
215extern int SL_Init(SAMPLOAD*); 241extern int SL_Init(SAMPLOAD*);
216extern void SL_Exit(SAMPLOAD*); 242extern void SL_Exit(SAMPLOAD*);
217 243
@@ -233,126 +259,126 @@ extern UBYTE* UniDup(void);
233extern int UniInit(void); 259extern int UniInit(void);
234extern void UniCleanup(void); 260extern void UniCleanup(void);
235extern void UniEffect(UWORD,UWORD); 261extern 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)
238extern void UniPTEffect(UBYTE,UBYTE); 264extern void UniPTEffect(UBYTE,UBYTE);
239extern void UniVolEffect(UWORD,UBYTE); 265extern void UniVolEffect(UWORD,UBYTE);
240 266
241/*========== Module Commands */ 267/*========== Module Commands */
242 268
243enum { 269enum {
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
318extern UWORD unioperands[UNI_LAST]; 344extern const UWORD unioperands[UNI_LAST];
319 345
320/* IT / S3M Extended SS effects: */ 346/* IT / S3M Extended SS effects: */
321enum { 347enum {
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 */
339enum { 365enum {
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
357typedef struct FILTER { 383typedef 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
408typedef struct ENVPR { 434typedef 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
421typedef struct MP_CHANNEL { 447typedef 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
445typedef struct MP_CONTROL { 471typedef 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). */
520typedef struct MP_VOICE { 546typedef 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
541typedef struct MLOADER { 567typedef struct MLOADER {
542struct 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 */
553extern MREADER* modreader; 579extern MREADER* modreader;
554extern UWORD finetune[16];
555extern MODULE of; /* static unimod loading space */ 580extern MODULE of; /* static unimod loading space */
556extern UWORD npertab[7*OCTAVE]; /* used by the original MOD loaders */ 581extern const UWORD finetune[16];
582extern const UWORD npertab[7*OCTAVE];/* used by the original MOD loaders */
557 583
558extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ 584extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */
559extern UBYTE* poslookup; /* lookup table for pattern jumps after 585extern UBYTE* poslookup; /* lookup table for pattern jumps after
560 blank pattern removal */ 586 blank pattern removal */
561extern UWORD poslookupcnt; 587extern UWORD poslookupcnt;
562extern UWORD* origpositions; 588extern UWORD* origpositions;
563 589
@@ -577,8 +603,7 @@ extern int AllocPatterns(void);
577extern int AllocTracks(void); 603extern int AllocTracks(void);
578extern int AllocInstruments(void); 604extern int AllocInstruments(void);
579extern int AllocSamples(void); 605extern int AllocSamples(void);
580extern CHAR* DupStr(CHAR*,UWORD,int); 606extern CHAR* DupStr(const CHAR*, UWORD, int);
581extern CHAR* StrDup(CHAR *s);
582 607
583/* loader utility functions */ 608/* loader utility functions */
584extern int* AllocLinear(void); 609extern int* AllocLinear(void);
@@ -588,28 +613,38 @@ extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int);
588extern void S3MIT_CreateOrders(int); 613extern 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). */
596extern UWORD getlinearperiod(UWORD,ULONG); 621extern UWORD getlinearperiod(UWORD,ULONG);
597extern ULONG getfrequency(UWORD,ULONG); 622extern ULONG getfrequency(UWORD,ULONG);
598 623
599/* loader shared data */ 624/* loader shared data */
600#define STM_NTRACKERS 3 625#define STM_NTRACKERS 3
601extern CHAR *STM_Signatures[STM_NTRACKERS]; 626extern const CHAR *STM_Signatures[STM_NTRACKERS];
602 627
603/*========== Player interface */ 628/*========== Player interface */
604 629
605extern int Player_Init(MODULE*); 630extern int Player_Init(MODULE*);
606extern void Player_Exit(MODULE*); 631extern void Player_Exit(MODULE*);
607extern void Player_HandleTick(void); 632extern void Player_HandleTick(void);
608 633
634/*========== UnPackers */
635
636typedef int (*MUNPACKER) (struct MREADER*,
637 void** /* unpacked data out */ ,
638 long* /* unpacked data size */ );
639extern int PP20_Unpack(MREADER*, void**, long*);
640extern int MMCMP_Unpack(MREADER*, void**, long*);
641extern int XPK_Unpack(MREADER*, void**, long*);
642extern 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 */
615extern UWORD md_bpm; /* current song / hardware BPM rate */ 650extern 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. */
628extern void (*md_player)(void); 663extern MikMod_player_t md_player;
629 664
630extern SWORD MD_SampleLoad(SAMPLOAD*,int); 665extern SWORD MD_SampleLoad(SAMPLOAD*,int);
631extern void MD_SampleUnload(SWORD); 666extern void MD_SampleUnload(SWORD);
@@ -636,17 +671,17 @@ extern ULONG MD_SampleLength(int,SAMPLE*);
636extern void unsignedtoulaw(char *,int); 671extern void unsignedtoulaw(char *,int);
637 672
638/* Parameter extraction helper */ 673/* Parameter extraction helper */
639extern CHAR *MD_GetAtom(CHAR*,CHAR*,int); 674extern CHAR *MD_GetAtom(const CHAR*, const CHAR*, int);
640 675
641/* Internal software mixer stuff */ 676/* Internal software mixer stuff */
642extern void VC_SetupPointers(void); 677extern void VC_SetupPointers(void);
643extern int VC1_Init(void); 678extern int VC1_Init(void);
644extern int VC2_Init(void); 679extern 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 */
648extern int MD_Access(CHAR *); 683extern int MD_Access(const CHAR *);
649extern int MD_DropPrivileges(void); 684extern 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*);
659extern void _mm_registerloader(struct MLOADER*); 694extern void _mm_registerloader(struct MLOADER*);
660extern int MikMod_Active_internal(void); 695extern int MikMod_Active_internal(void);
661extern void MikMod_DisableOutput_internal(void); 696extern void MikMod_DisableOutput_internal(void);
662extern int MikMod_EnableOutput_internal(void); 697extern int MikMod_EnableOutput_internal(void);
663extern void MikMod_Exit_internal(void); 698extern void MikMod_Exit_internal(void);
664extern int MikMod_SetNumVoices_internal(int,int); 699extern int MikMod_SetNumVoices_internal(int,int);
665extern void Player_Exit_internal(MODULE*); 700extern void Player_Exit_internal(MODULE*);
666extern void Player_Stop_internal(void); 701extern void Player_Stop_internal(void);
667extern int Player_Paused_internal(void); 702extern int Player_Paused_internal(void);
@@ -673,6 +708,15 @@ extern void Voice_SetVolume_internal(SBYTE,UWORD);
673extern void Voice_Stop_internal(SBYTE); 708extern void Voice_Stop_internal(SBYTE);
674extern int Voice_Stopped_internal(SBYTE); 709extern int Voice_Stopped_internal(SBYTE);
675 710
711extern int VC1_PlayStart(void);
712extern int VC2_PlayStart(void);
713extern void VC1_PlayStop(void);
714extern void VC2_PlayStop(void);
715extern int VC1_SetNumVoices(void);
716extern int VC2_SetNumVoices(void);
717
718extern 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 */
721static inline vector float vec_mul( const vector float a, const vector float b) 771static 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 */
727static inline vector float vec_load_ps1(const float *pF ) 776static 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 */
734static inline const vector float vec_setzero() 782static inline vector float vec_setzero() {
735{ 783 return (vector float) (0.);
736 return (const vector float) (0.);
737} 784}
738 785
739static inline vector signed char vec_set1_8(unsigned char splatchar) 786static 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 */
757static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) 803static 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). */
763static inline vector signed int vec_hiqq(vector signed int a) 808static 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
785static __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). 829static __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
854extern "C" {
855#endif
856void* MikMod_amalloc(size_t);
857void 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
51static MLOADER *firstloader=NULL; 51static MLOADER *firstloader=NULL;
52 52
53UWORD finetune[16]={ 53#ifndef NO_DEPACKERS
54static MUNPACKER unpackers[] = {
55 PP20_Unpack,
56 MMCMP_Unpack,
57 XPK_Unpack,
58 S404_Unpack,
59 NULL
60};
61#endif
62
63const 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
90MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr) 103MIKMODAPI 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
123int ReadLinedComment(UWORD len,UWORD linelen) 136int 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)
207int AllocInstruments(void) 220int 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. */
261CHAR *DupStr(CHAR* s,UWORD len,int strict) 274CHAR *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
287CHAR *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
295static void ML_XFreeSample(SAMPLE *s) 300static 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
302static void ML_XFreeInstrument(INSTRUMENT *i) 309static void ML_XFreeInstrument(INSTRUMENT *i)
303{ 310{
304 if(i->insname) MikMod_free(i->insname); 311 MikMod_free(i->insname);
305} 312}
306 313
307static void ML_FreeEx(MODULE *mf) 314static 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
338static MODULE *ML_AllocUniMod(void) 347static MODULE *ML_AllocUniMod(void)
339{ 348{
340 MODULE *mf; 349 return (MODULE *) MikMod_malloc(sizeof(MODULE));
350}
351
352#ifndef NO_DEPACKERS
353static 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
345static void Player_Free_internal(MODULE *mf) 368static void Player_Free_internal(MODULE *mf)
346{ 369{
@@ -360,25 +383,50 @@ MIKMODAPI void Player_Free(MODULE *mf)
360static CHAR* Player_LoadTitle_internal(MREADER *reader) 383static 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
384MIKMODAPI CHAR* Player_LoadTitleFP(int fp) 432MIKMODAPI 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
415MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader) 463MIKMODAPI 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
427MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename) 475MIKMODAPI 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
589MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious) 666MIKMODAPI 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'. */
603MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,int curious) 680MIKMODAPI 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
60void MikMod_RegisterAllLoaders(void) 61MIKMODAPI 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
46CHAR *STM_Signatures[STM_NTRACKERS] = { 46const CHAR *STM_Signatures[STM_NTRACKERS] = {
47 "!Scream!", 47 "!Scream!",
48 "BMOD2STM", 48 "BMOD2STM",
49 "WUZAMOD!" 49 "WUZAMOD!"
50}; 50};
51 51
52CHAR *STM_Version[STM_NTRACKERS] = { 52const 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
73int* noteindex=NULL; /* remap value for linear period modules */ 73int* noteindex=NULL; /* remap value for linear period modules */
74static int noteindexcount=0; 74static unsigned noteindexcount=0;
75 75
76int *AllocLinear(void) 76int *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
85void FreeLinear(void) 85void 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
94int speed_to_finetune(ULONG speed,int sample) 92int 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 */
144void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags) 142void 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
37static 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
50static 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
58void* 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 */
85void* MikMod_malloc(size_t size) 55void* 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
87void 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
100void* 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 */
107void* 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 */
123void* MikMod_calloc(size_t nitems,size_t size) 113void* 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
161void MikMod_free(void *data) 123void 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 { 129CHAR *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
43CHAR *_mm_errmsg[MMERR_MAX+1] = 43#define _mmerr_invalid "Invalid error code"
44
45static 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
183MIKMODAPI char *MikMod_strerror(int code) 285MIKMODAPI 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);
66extern size_t fwrite(const void *, size_t, size_t, FILE *); 68extern 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 */
72static int _mm_MemReader_Eof(MREADER* reader); 72static int _mm_MemReader_Eof(MREADER* reader);
73static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size); 73static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size);
@@ -75,16 +75,13 @@ static int _mm_MemReader_Get(MREADER* reader);
75static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence); 75static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence);
76static long _mm_MemReader_Tell(MREADER* reader); 76static long _mm_MemReader_Tell(MREADER* reader);
77 77
78//static long _mm_iobase=0,temp_iobase=0; 78int _mm_fopen(const CHAR* fname, const CHAR* attrib)
79
80int _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
97int _mm_FileExists(CHAR* fname) 94int _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
131typedef struct MFILEREADER { 128typedef struct MFILEREADER {
132 MREADER core; 129 MREADER core;
133 int file; 130 int file;
134} MFILEREADER; 131} MFILEREADER;
135 132
136static int _mm_FileReader_Eof(MREADER* reader) 133static 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
144static int _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size) 141static 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
150static int _mm_FileReader_Get(MREADER* reader) 147static int _mm_FileReader_Get(MREADER* reader)
@@ -160,7 +157,7 @@ static int _mm_FileReader_Get(MREADER* reader)
160static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence) 157static 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
174MREADER *_mm_new_file_reader(int fp) 171MREADER *_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
188void _mm_delete_file_reader (MREADER* reader) 185void _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
195typedef struct MFILEWRITER { 192typedef struct MFILEWRITER {
196 MWRITER core; 193 MWRITER core;
197 int file; 194 int file;
198} MFILEWRITER; 195} MFILEWRITER;
199 196
200static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence) 197static 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
212static int _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size) 209static 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
222static int _mm_FileWriter_Put(MWRITER* writer,int value) 218static 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
230MWRITER *_mm_new_file_writer(int fp) 226MWRITER *_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
243void _mm_delete_file_writer (MWRITER* writer) 239void _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
251typedef struct MMEMREADER { 246typedef 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
258void _mm_delete_mem_reader(MREADER* reader) 253void _mm_delete_mem_reader(MREADER* reader)
259{ 254{
260 if (reader) { MikMod_free(reader); } 255 MikMod_free(reader);
261} 256}
262 257
263MREADER *_mm_new_mem_reader(const void *buffer, int len) 258MREADER *_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
280static int _mm_MemReader_Eof(MREADER* reader) 275static 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
289static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size) 283static 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
319static int _mm_MemReader_Get(MREADER* reader) 318static 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
331static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence) 331static 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)
354static long _mm_MemReader_Tell(MREADER* reader) 361static 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 */
363void _mm_write_string(CHAR* data,MWRITER* writer) 370
371void _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 421void _mm_write_M_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
414#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ 422{
415void _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) \ 426void _mm_write_M_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
422void _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
429DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD) 431void _mm_write_I_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
430DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD) 432{
431DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD) 433 while(cnt-- > 0) _mm_write_I_SWORD(*(buffer++),writer);
432DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD) 434}
433 435
434DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG) 436void _mm_write_I_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
435DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG) 437{
436DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG) 438 while(cnt-- > 0) _mm_write_I_UWORD(*(buffer++),writer);
437DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG) 439}
440
441void _mm_write_M_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
442{
443 while(cnt-- > 0) _mm_write_M_SLONG(*(buffer++),writer);
444}
445
446void _mm_write_M_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
447{
448 while(cnt-- > 0) _mm_write_M_ULONG(*(buffer++),writer);
449}
450
451void _mm_write_I_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
452{
453 while(cnt-- > 0) _mm_write_I_SLONG(*(buffer++),writer);
454}
455
456void _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
441int _mm_read_string(CHAR* buffer,int number,MREADER* reader) 463int _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
446UWORD _mm_read_M_UWORD(MREADER* reader) 468UWORD _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 516int _mm_read_M_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
495#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ 517{
496int _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) \ 522int _mm_read_M_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
504int _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
512DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD) 528int _mm_read_I_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
513DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD) 529{
514DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD) 530 while(cnt-- > 0) *(buffer++)=_mm_read_I_SWORD(reader);
515DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD) 531 return !reader->Eof(reader);
532}
533
534int _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
540int _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
517DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG) 546int _mm_read_M_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
518DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG) 547{
519DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG) 548 while(cnt-- > 0) *(buffer++)=_mm_read_M_ULONG(reader);
520DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG) 549 return !reader->Eof(reader);
550}
551
552int _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
558int _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
46extern int fprintf(FILE *, const char *, ...); 48extern int fprintf(int, const char *, ...);
47extern long int random(void); 49extern long int random(void);
48#endif 50#endif
49 51
50/* The currently playing module */ 52/* The currently playing module */
51MODULE *pf = NULL; 53MODULE *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
55static UWORD oldperiods[OCTAVE*2]={ 59static 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
62static UBYTE VibratoTable[32]={ 66static 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
67static UBYTE avibtab[128]={ 71static 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) */
79static ULONG lintab[768]={ 83static 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
179static UWORD logtab[104]={ 183static 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
208static SBYTE PanbrelloTable[256]={ 212static 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 */
228static int getrandom(int ceil) 232static 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
786static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 796static 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
799static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 809static 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
819static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 829static 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
842static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 852static 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
878static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 896static 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
894static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 912static 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
2168static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 2195static 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
2219static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) 2246static 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
2310typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD); 2337typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD);
2311 2338
2312static effect_func effects[UNI_LAST] = { 2339static 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
2377static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a) 2404static 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)
3166MIKMODAPI void Player_SetVolume(SWORD volume) 3202MIKMODAPI 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
3313static void Player_Unmute_internal(SLONG arg1,va_list ap) 3351static 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)
3499MIKMODAPI void Player_SetSpeed(UWORD speed) 3537MIKMODAPI 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
3543MIKMODAPI int Player_GetOrder(void) 3580MIKMODAPI 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 */
3553MIKMODAPI int Player_GetRow(void) 3590MIKMODAPI 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
40UWORD unioperands[UNI_LAST]={ 40const 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
239static int MyCmp(UBYTE* a,UBYTE* b,UWORD l) 239static 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. */
276UBYTE* UniDup(void) 276UBYTE* 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
289int UniInit(void) 289int UniInit(void)
@@ -296,7 +296,7 @@ int UniInit(void)
296 296
297void UniCleanup(void) 297void 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
35UWORD npertab[7 * OCTAVE] = { 35const 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 {
56int SL_Init(SAMPLOAD* s) 56int 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)
68void SL_Exit(SAMPLOAD *s) 68void 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 */
78static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt) 77static 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 */
152static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt) 151static 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
225static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,int dither) 224static 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
340int SL_Load(void* buffer,SAMPLOAD *smp,ULONG length) 349int 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)
407static ULONG RealSpeed(SAMPLOAD *s) 416static 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
412static int DitherSamples(SAMPLOAD* samplist,int type) 421static 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
474int SL_LoadSamples(void) 483int 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
487void SL_Sample16to8(SAMPLOAD* s) 496void 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
135static size_t MixSIMDMonoNormal(const SWORD* srce,SLONG* dest,size_t index, size_t increment,size_t todo) 131# if !defined(NATIVE_64BIT_INT)
132static 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
150static size_t MixSIMDStereoNormal(const SWORD* srce, SLONG* dest, size_t index, size_t increment,size_t todo) 148static 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
260static SLONG Mix32MonoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 269static 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 */
285static SLONG Mix32StereoNormal(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 293static 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 317static SLONG Mix32SurroundNormal(const SWORD* srce,SLONG* dest,SLONG idx,SLONG increment,SLONG todo)
310static 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
336static SLONG Mix32MonoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 344static 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
371static SLONG Mix32StereoInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 379static 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
411static SLONG Mix32SurroundInterp(const SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) 419static 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
463static SLONGLONG MixMonoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 471static 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
477static SLONGLONG MixStereoNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 485static 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
493static SLONGLONG MixSurroundNormal(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 501static 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
519static SLONGLONG MixMonoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 528static 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
554static SLONGLONG MixStereoInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 563static 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
594static SLONGLONG MixSurroundInterp(const SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) 603static 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
642static void (*MixReverb)(SLONG* srce,NATIVE count); 651static 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 */
844static void Mix32ToFP_SIMD(float* dste,SLONG* srce,NATIVE count) 853static 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
892static void Mix32To16_SIMD(SWORD* dste,SLONG* srce,NATIVE count) 898/* PC: Ok, Mac Ok */
893{ 899static 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 */
927static void Mix32To8_SIMD(SBYTE* dste,SLONG* srce,NATIVE count) 931static 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
964static void AddChannel(SLONG* ptr,NATIVE todo) 965static 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
1220int VC1_Init(void) 1246int 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
1280void VC1_PlayStop(void) 1312void 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
105typedef 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
128static SWORD **Samples;
129static VINFO *vinf=NULL,*vnf;
130static long tickleft,samplesthatfit,vc_memory=0;
131static int vc_softchn;
132static SLONGLONG idxsize,idxlpos,idxlend;
133static SLONG *vc_tickbuf=NULL;
134static UWORD vc_mode;
135
136#ifdef _MSC_VER
137/* Weird bug in compiler */ /* FIXME is this still needed? */
138typedef void (*MikMod_callback_t)(unsigned char *data, size_t len);
139#endif
140
141/* Reverb control variables */
142
143static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8;
144static ULONG RVRindex;
145
146/* For Mono or Left Channel */
147static 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) */
151static 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
163static 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
195static 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
238static 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
281static 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
317static __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
325static 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 }
438end:
439 vnf->lastvalL=vnf->lvolsel*sample;
440 vnf->lastvalR=vnf->rvolsel*sample;
441 return idx;
442}
443
444static 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 */
519static 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
564static 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
604static void(*Mix32toFP)(float* dste,const SLONG *srce,NATIVE count);
605static void(*Mix32to16)(SWORD* dste,const SLONG *srce,NATIVE count);
606static void(*Mix32to8)(SBYTE* dste,const SLONG *srce,NATIVE count);
607static 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
614static 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
644static 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
684static void (*MixLowPass)(SLONG* srce,NATIVE count);
685
686static int nLeftNR, nRightNR;
687
688static 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
707static 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
726static 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
745static 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
772static 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
792static 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
815static 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
834static 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 */
860static 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 */
938static 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
1009static 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
1156void 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
1242int 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
1284int 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
1326void 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
1349int 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
34extern int VC1_Init(void); 35#ifndef NO_HQMIXER
35//extern int VC2_Init(void); 36extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
36static int (*VC_Init_ptr)(void)=VC1_Init; 37extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
38extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
39extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
37extern void VC1_Exit(void); 40extern void VC1_Exit(void);
38//extern void VC2_Exit(void); 41extern void VC2_Exit(void);
39static void (*VC_Exit_ptr)(void)=VC1_Exit; 42extern UWORD VC1_VoiceGetVolume(UBYTE);
40extern int VC1_SetNumVoices(void); 43extern UWORD VC2_VoiceGetVolume(UBYTE);
41//extern int VC2_SetNumVoices(void); 44extern ULONG VC1_VoiceGetPanning(UBYTE);
42static int (*VC_SetNumVoices_ptr)(void); 45extern ULONG VC2_VoiceGetPanning(UBYTE);
46extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
47extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
48extern ULONG VC1_VoiceGetFrequency(UBYTE);
49extern ULONG VC2_VoiceGetFrequency(UBYTE);
50extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
51extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
52extern void VC1_VoiceStop(UBYTE);
53extern void VC2_VoiceStop(UBYTE);
54extern int VC1_VoiceStopped(UBYTE);
55extern int VC2_VoiceStopped(UBYTE);
56extern SLONG VC1_VoiceGetPosition(UBYTE);
57extern SLONG VC2_VoiceGetPosition(UBYTE);
58extern void VC1_VoiceSetVolume(UBYTE,UWORD);
59extern void VC2_VoiceSetVolume(UBYTE,UWORD);
60extern void VC1_VoiceSetPanning(UBYTE,ULONG);
61extern void VC2_VoiceSetPanning(UBYTE,ULONG);
62extern void VC1_SampleUnload(SWORD);
63extern void VC2_SampleUnload(SWORD);
64extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
65extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
43extern ULONG VC1_SampleSpace(int); 66extern ULONG VC1_SampleSpace(int);
44//extern ULONG VC2_SampleSpace(int); 67extern ULONG VC2_SampleSpace(int);
45static ULONG (*VC_SampleSpace_ptr)(int);
46extern ULONG VC1_SampleLength(int,SAMPLE*); 68extern ULONG VC1_SampleLength(int,SAMPLE*);
47//extern ULONG VC2_SampleLength(int,SAMPLE*); 69extern ULONG VC2_SampleLength(int,SAMPLE*);
70extern ULONG VC1_VoiceRealVolume(UBYTE);
71extern ULONG VC2_VoiceRealVolume(UBYTE);
72#endif
73
74
75#ifndef _IN_VIRTCH_
76
77#ifndef NO_HQMIXER
78extern int VC1_Init(void);
79extern int VC2_Init(void);
80static int (*VC_Init_ptr)(void)=VC1_Init;
81static void (*VC_Exit_ptr)(void)=VC1_Exit;
82extern int VC1_SetNumVoices(void);
83extern int VC2_SetNumVoices(void);
84static int (*VC_SetNumVoices_ptr)(void);
85static ULONG (*VC_SampleSpace_ptr)(int);
48static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*); 86static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
49 87
50extern int VC1_PlayStart(void); 88extern int VC2_PlayStart(void);
51//extern int VC2_PlayStart(void); 89static int (*VC_PlayStart_ptr)(void);
52static int (*VC_PlayStart_ptr)(void);
53extern void VC1_PlayStop(void);
54extern void VC2_PlayStop(void); 90extern void VC2_PlayStop(void);
55static void (*VC_PlayStop_ptr)(void); 91static void (*VC_PlayStop_ptr)(void);
56 92
57extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
58//extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
59static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int); 93static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int);
60extern void VC1_SampleUnload(SWORD);
61//extern void VC2_SampleUnload(SWORD);
62static void (*VC_SampleUnload_ptr)(SWORD); 94static void (*VC_SampleUnload_ptr)(SWORD);
63 95
64extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
65//extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
66static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG); 96static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG);
67extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
68//extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
69static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG); 97static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG);
70 98
71extern void VC1_VoiceSetVolume(UBYTE,UWORD);
72//extern void VC2_VoiceSetVolume(UBYTE,UWORD);
73static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD); 99static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD);
74extern UWORD VC1_VoiceGetVolume(UBYTE);
75//extern UWORD VC2_VoiceGetVolume(UBYTE);
76static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE); 100static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE);
77extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
78//extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
79static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG); 101static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG);
80extern ULONG VC1_VoiceGetFrequency(UBYTE);
81//extern ULONG VC2_VoiceGetFrequency(UBYTE);
82static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE); 102static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE);
83extern void VC1_VoiceSetPanning(UBYTE,ULONG);
84//extern void VC2_VoiceSetPanning(UBYTE,ULONG);
85static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG); 103static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG);
86extern ULONG VC1_VoiceGetPanning(UBYTE);
87//extern ULONG VC2_VoiceGetPanning(UBYTE);
88static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE); 104static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE);
89extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
90//extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
91static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); 105static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
92 106
93extern void VC1_VoiceStop(UBYTE);
94//extern void VC2_VoiceStop(UBYTE);
95static void (*VC_VoiceStop_ptr)(UBYTE); 107static void (*VC_VoiceStop_ptr)(UBYTE);
96extern int VC1_VoiceStopped(UBYTE);
97//extern int VC2_VoiceStopped(UBYTE);
98static int (*VC_VoiceStopped_ptr)(UBYTE); 108static int (*VC_VoiceStopped_ptr)(UBYTE);
99extern SLONG VC1_VoiceGetPosition(UBYTE);
100//extern SLONG VC2_VoiceGetPosition(UBYTE);
101static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE); 109static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE);
102extern ULONG VC1_VoiceRealVolume(UBYTE);
103//extern ULONG VC2_VoiceRealVolume(UBYTE);
104static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE); 110static 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) \
108MIKMODAPI void VC_##suffix (void) { VC_##suffix##_ptr(); } 114MIKMODAPI 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) \
123MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); } 129MIKMODAPI 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) \
126MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); } 134MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); }
127 135
@@ -158,18 +166,18 @@ VC_PROC2(VoiceSetFrequency,UBYTE,ULONG)
158VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE) 166VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE)
159VC_PROC2(VoiceSetPanning,UBYTE,ULONG) 167VC_PROC2(VoiceSetPanning,UBYTE,ULONG)
160VC_FUNC1(VoiceGetPanning,ULONG,UBYTE) 168VC_FUNC1(VoiceGetPanning,ULONG,UBYTE)
161 169
162void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) 170void 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
165VC_PROC1(VoiceStop,UBYTE) 174VC_PROC1(VoiceStop,UBYTE)
166VC_FUNC1(VoiceStopped,int,UBYTE) 175VC_FUNC1(VoiceStopped,int,UBYTE)
167VC_FUNC1(VoiceGetPosition,SLONG,UBYTE) 176VC_FUNC1(VoiceGetPosition,SLONG,UBYTE)
168VC_FUNC1(VoiceRealVolume,ULONG,UBYTE) 177VC_FUNC1(VoiceRealVolume,ULONG,UBYTE)
169 178
170void VC_SetupPointers(void) 179void 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
277void VC1_Exit(void) 283void 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
310void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags) 316void 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
321void VC1_VoiceStop(UBYTE voice) 327void VC1_VoiceStop(UBYTE voice)
322{ 328{
323 vinf[voice].active = 0; 329 vinf[voice].active = 0;
324} 330}
325 331
326int VC1_VoiceStopped(UBYTE voice) 332int VC1_VoiceStopped(UBYTE voice)
327{ 333{
@@ -334,7 +340,7 @@ SLONG VC1_VoiceGetPosition(UBYTE voice)
334} 340}
335 341
336void VC1_VoiceSetVolume(UBYTE voice,UWORD vol) 342void 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
354void VC1_SampleUnload(SWORD handle) 360void 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
417ULONG VC1_SampleSpace(int type) 431ULONG VC1_SampleSpace(int type)
418{ 432{
419 (void)type; 433 (void)type;
420 return vc_memory; 434 return vc_memory;
421} 435}
422 436
423ULONG VC1_SampleLength(int type,SAMPLE* s) 437ULONG 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
462MikMod_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
44dsm,viewers/mikmod,7 44dsm,viewers/mikmod,7
45far,viewers/mikmod,7 45far,viewers/mikmod,7
46gdm,viewers/mikmod,7 46gdm,viewers/mikmod,7
47gt2,viewers/mikmod,7
48imf,viewers/mikmod,7 47imf,viewers/mikmod,7
49it,viewers/mikmod,7 48it,viewers/mikmod,7
50m15,viewers/mikmod,7 49m15,viewers/mikmod,7
@@ -57,6 +56,7 @@ stm,viewers/mikmod,7
57stx,viewers/mikmod,7 56stx,viewers/mikmod,7
58ult,viewers/mikmod,7 57ult,viewers/mikmod,7
59uni,viewers/mikmod,7 58uni,viewers/mikmod,7
59umx,viewers/mikmod,7
60xm,viewers/mikmod,7 60xm,viewers/mikmod,7
61pd,viewers/pdbox,2 61pd,viewers/pdbox,2
62rsp,viewers/searchengine,8 62rsp,viewers/searchengine,8