mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
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
This commit is contained in:
parent
8c7780bafc
commit
b4e70422a3
43 changed files with 5072 additions and 2802 deletions
|
@ -15351,6 +15351,46 @@
|
|||
swcodec: "Surround"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
id: LANG_MIKMOD_HQMIXER
|
||||
desc: in mikmod settings menu
|
||||
user: core
|
||||
<source>
|
||||
*: none
|
||||
lowmem: none
|
||||
swcodec: "HQ Mixer"
|
||||
</source>
|
||||
<dest>
|
||||
*: none
|
||||
lowmem: none
|
||||
swcodec: "HQ Mixer"
|
||||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
lowmem: none
|
||||
swcodec: "High Quality Mixer"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
id: LANG_MIKMOD_SAMPLERATE
|
||||
desc: in mikmod settings menu
|
||||
user: core
|
||||
<source>
|
||||
*: none
|
||||
lowmem: none
|
||||
swcodec: "Sample Rate"
|
||||
</source>
|
||||
<dest>
|
||||
*: none
|
||||
lowmem: none
|
||||
swcodec: "Sample Rate"
|
||||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
lowmem: none
|
||||
swcodec: "Sample Rate"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
id: LANG_CPU_BOOST
|
||||
desc: in mikmod settings menu
|
||||
|
|
|
@ -5,7 +5,6 @@ load_asy.c
|
|||
load_dsm.c
|
||||
load_far.c
|
||||
load_gdm.c
|
||||
load_gt2.c
|
||||
load_imf.c
|
||||
load_it.c
|
||||
load_m15.c
|
||||
|
@ -17,6 +16,7 @@ load_s3m.c
|
|||
load_stm.c
|
||||
load_stx.c
|
||||
load_ult.c
|
||||
load_umx.c
|
||||
load_uni.c
|
||||
load_xm.c
|
||||
mdreg.c
|
||||
|
@ -34,6 +34,7 @@ sloader.c
|
|||
strdup.c
|
||||
strstr.c
|
||||
virtch.c
|
||||
virtch2.c
|
||||
virtch_common.c
|
||||
mikmod.c
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_669.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id: $
|
||||
|
||||
Composer 669 module loader
|
||||
|
||||
|
@ -49,11 +49,11 @@ extern int fprintf(FILE *, const char *, ...);
|
|||
/*========== Module structure */
|
||||
|
||||
/* header */
|
||||
typedef struct S69HEADER {
|
||||
typedef struct S69HEADER {
|
||||
UBYTE marker[2];
|
||||
CHAR message[108];
|
||||
UBYTE nos;
|
||||
UBYTE rbnop;
|
||||
UBYTE RBnop;
|
||||
UBYTE looporder;
|
||||
UBYTE orders[0x80];
|
||||
UBYTE tempos[0x80];
|
||||
|
@ -81,7 +81,7 @@ static S69NOTE* s69pat=NULL;
|
|||
static S69HEADER* mh=NULL;
|
||||
|
||||
/* file type identification */
|
||||
static CHAR* S69_Version[]={
|
||||
static const CHAR* S69_Version[]={
|
||||
"Composer 669",
|
||||
"Extended 669"
|
||||
};
|
||||
|
@ -134,6 +134,8 @@ static void S69_Cleanup(void)
|
|||
{
|
||||
MikMod_free(s69pat);
|
||||
MikMod_free(mh);
|
||||
mh=NULL;
|
||||
s69pat=NULL;
|
||||
}
|
||||
|
||||
static int S69_LoadPatterns(void)
|
||||
|
@ -142,7 +144,7 @@ static int S69_LoadPatterns(void)
|
|||
UBYTE note,inst,vol,effect,lastfx,lastval;
|
||||
S69NOTE *cur;
|
||||
int tracks=0;
|
||||
|
||||
|
||||
if(!AllocPatterns()) return 0;
|
||||
if(!AllocTracks()) return 0;
|
||||
|
||||
|
@ -226,7 +228,7 @@ static int S69_LoadPatterns(void)
|
|||
case 5: /* set speed */
|
||||
if (effect)
|
||||
UniPTEffect(0xf,effect);
|
||||
else
|
||||
else
|
||||
if(mh->marker[0]!=0x69) {
|
||||
#ifdef MIKMOD_DEBUG
|
||||
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)
|
|||
int i;
|
||||
SAMPLE *current;
|
||||
S69SAMPLE sample;
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* module header */
|
||||
_mm_read_UBYTES(mh->marker,2,modreader);
|
||||
_mm_read_UBYTES(mh->message,108,modreader);
|
||||
mh->nos=_mm_read_UBYTE(modreader);
|
||||
mh->rbnop=_mm_read_UBYTE(modreader);
|
||||
mh->RBnop=_mm_read_UBYTE(modreader);
|
||||
mh->looporder=_mm_read_UBYTE(modreader);
|
||||
_mm_read_UBYTES(mh->orders,0x80,modreader);
|
||||
for(i=0;i<0x80;i++)
|
||||
|
@ -281,9 +283,9 @@ static int S69_Load(int curious)
|
|||
of.initspeed=4;
|
||||
of.inittempo=78;
|
||||
of.songname=DupStr(mh->message,36,1);
|
||||
of.modtype=StrDup(S69_Version[memcmp(mh->marker,"JN",2)==0]);
|
||||
of.modtype=MikMod_strdup(S69_Version[memcmp(mh->marker,"JN",2)==0]);
|
||||
of.numchn=8;
|
||||
of.numpat=mh->rbnop;
|
||||
of.numpat=mh->RBnop;
|
||||
of.numins=of.numsmp=mh->nos;
|
||||
of.numtrk=of.numchn*of.numpat;
|
||||
of.flags=UF_XMPERIODS|UF_LINEAR;
|
||||
|
@ -292,7 +294,7 @@ static int S69_Load(int curious)
|
|||
for(i=36+35;(i>=36+0)&&(mh->message[i]==' ');i--) mh->message[i]=0;
|
||||
for(i=72+35;(i>=72+0)&&(mh->message[i]==' ');i--) mh->message[i]=0;
|
||||
if((mh->message[0])||(mh->message[36])||(mh->message[72]))
|
||||
if((of.comment=(CHAR*)MikMod_malloc(3*(36+1)+1))) {
|
||||
if((of.comment=(CHAR*)MikMod_malloc(3*(36+1)+1)) != NULL) {
|
||||
strncpy(of.comment,mh->message,36);
|
||||
strcat(of.comment,"\r");
|
||||
if (mh->message[36]) strncat(of.comment,mh->message+36,36);
|
||||
|
@ -304,7 +306,7 @@ static int S69_Load(int curious)
|
|||
|
||||
if(!AllocPositions(0x80)) return 0;
|
||||
for(i=0;i<0x80;i++) {
|
||||
if(mh->orders[i]>=mh->rbnop) break;
|
||||
if(mh->orders[i]>=mh->RBnop) break;
|
||||
of.positions[i]=mh->orders[i];
|
||||
}
|
||||
of.numpos=i;
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,8 +20,6 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_amf.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
|
||||
DMP Advanced Module Format loader
|
||||
|
||||
==============================================================================*/
|
||||
|
@ -112,9 +110,11 @@ static void AMF_Cleanup(void)
|
|||
{
|
||||
MikMod_free(mh);
|
||||
MikMod_free(track);
|
||||
mh=NULL;
|
||||
track=NULL;
|
||||
}
|
||||
|
||||
static int AMF_UnpackTrack(MREADER* modreader)
|
||||
static int AMF_UnpackTrack(MREADER* r)
|
||||
{
|
||||
ULONG tracksize;
|
||||
UBYTE row,cmd;
|
||||
|
@ -124,20 +124,20 @@ static int AMF_UnpackTrack(MREADER* modreader)
|
|||
memset(track,0,64*sizeof(AMFNOTE));
|
||||
|
||||
/* read packed track */
|
||||
if (modreader) {
|
||||
tracksize=_mm_read_I_UWORD(modreader);
|
||||
tracksize+=((ULONG)_mm_read_UBYTE(modreader))<<16;
|
||||
if (r) {
|
||||
tracksize=_mm_read_I_UWORD(r);
|
||||
tracksize+=((ULONG)_mm_read_UBYTE(r))<<16;
|
||||
if (tracksize)
|
||||
while(tracksize--) {
|
||||
row=_mm_read_UBYTE(modreader);
|
||||
cmd=_mm_read_UBYTE(modreader);
|
||||
arg=_mm_read_SBYTE(modreader);
|
||||
row=_mm_read_UBYTE(r);
|
||||
cmd=_mm_read_UBYTE(r);
|
||||
arg=_mm_read_SBYTE(r);
|
||||
/* unexpected end of track */
|
||||
if(!tracksize) {
|
||||
if((row==0xff)&&(cmd==0xff)&&(arg==-1))
|
||||
break;
|
||||
/* the last triplet should be FF FF FF, but this is not
|
||||
always the case... maybe a bug in m2amf ?
|
||||
always the case... maybe a bug in m2amf ?
|
||||
else
|
||||
return 0;
|
||||
*/
|
||||
|
@ -164,7 +164,7 @@ static int AMF_UnpackTrack(MREADER* modreader)
|
|||
if (cmd==0x83) {
|
||||
/* volume without note */
|
||||
track[row].volume=(UBYTE)arg+1;
|
||||
} else
|
||||
} else
|
||||
if (cmd==0xff) {
|
||||
/* apparently, some M2AMF version fail to estimate the
|
||||
size of the compressed patterns correctly, and end
|
||||
|
@ -322,7 +322,7 @@ static UBYTE* AMF_ConvertTrack(void)
|
|||
of.flags |= UF_PANNING;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (track[row].volume) UniVolEffect(VOL_VOLUME,track[row].volume-1);
|
||||
UniNewline();
|
||||
|
@ -333,13 +333,13 @@ static UBYTE* AMF_ConvertTrack(void)
|
|||
static int AMF_Load(int curious)
|
||||
{
|
||||
int u,defaultpanning;
|
||||
unsigned int t,realtrackcnt,realsmpcnt;
|
||||
unsigned int t,realtrackcnt,realsmpcnt;
|
||||
AMFSAMPLE s;
|
||||
SAMPLE *q;
|
||||
UWORD *track_remap;
|
||||
ULONG samplepos;
|
||||
ULONG samplepos, fileend;
|
||||
int channel_remap[16];
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* try to read module header */
|
||||
_mm_read_UBYTES(mh->id,3,modreader);
|
||||
|
@ -386,7 +386,7 @@ static int AMF_Load(int curious)
|
|||
of.inittempo = mh->songbpm;
|
||||
AMF_Version[AMFTEXTLEN-3]='0'+(mh->version/10);
|
||||
AMF_Version[AMFTEXTLEN-1]='0'+(mh->version%10);
|
||||
of.modtype = StrDup(AMF_Version);
|
||||
of.modtype = MikMod_strdup(AMF_Version);
|
||||
of.numchn = mh->numchannels;
|
||||
of.numtrk = mh->numorders*mh->numchannels;
|
||||
if (mh->numtracks>of.numtrk)
|
||||
|
@ -400,7 +400,7 @@ static int AMF_Load(int curious)
|
|||
/* XXX whenever possible, we should try to determine the original format.
|
||||
Here we assume it was S3M-style wrt bpmlimit... */
|
||||
of.bpmlimit = 32;
|
||||
|
||||
|
||||
/*
|
||||
* Play with the panning table. Although the AMF format embeds a
|
||||
* panning table, if the module was a MOD or an S3M with default
|
||||
|
@ -466,7 +466,10 @@ static int AMF_Load(int curious)
|
|||
s.c2spd =_mm_read_I_UWORD(modreader);
|
||||
if(s.c2spd==8368) s.c2spd=8363;
|
||||
s.volume =_mm_read_UBYTE(modreader);
|
||||
if(mh->version>=11) {
|
||||
/* "the tribal zone.amf" and "the way its gonna b.amf" by Maelcum
|
||||
* are the only version 10 files I can find, and they have 32 bit
|
||||
* reppos and repend, not 16. */
|
||||
if(mh->version>=10) {/* was 11 */
|
||||
s.reppos =_mm_read_I_ULONG(modreader);
|
||||
s.repend =_mm_read_I_ULONG(modreader);
|
||||
} else {
|
||||
|
@ -475,7 +478,7 @@ static int AMF_Load(int curious)
|
|||
}
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -493,7 +496,7 @@ static int AMF_Load(int curious)
|
|||
}
|
||||
|
||||
/* read track table */
|
||||
if(!(track_remap=MikMod_calloc(mh->numtracks+1,sizeof(UWORD))))
|
||||
if(!(track_remap=(UWORD*)MikMod_calloc(mh->numtracks+1,sizeof(UWORD))))
|
||||
return 0;
|
||||
_mm_read_I_UWORDS(track_remap+1,mh->numtracks,modreader);
|
||||
if(_mm_eof(modreader)) {
|
||||
|
@ -505,9 +508,14 @@ static int AMF_Load(int curious)
|
|||
for(realtrackcnt=t=0;t<=mh->numtracks;t++)
|
||||
if (realtrackcnt<track_remap[t])
|
||||
realtrackcnt=track_remap[t];
|
||||
if (realtrackcnt > (int)mh->numtracks) {
|
||||
MikMod_free(track_remap);
|
||||
_mm_errno=MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
for(t=0;t<of.numpat*of.numchn;t++)
|
||||
of.patterns[t]=(of.patterns[t]<=mh->numtracks)?
|
||||
track_remap[of.patterns[t]]-1:(int)realtrackcnt;
|
||||
track_remap[of.patterns[t]]-1:(int)realtrackcnt;
|
||||
|
||||
MikMod_free(track_remap);
|
||||
|
||||
|
@ -531,18 +539,32 @@ static int AMF_Load(int curious)
|
|||
for(t=realtrackcnt;t<of.numtrk;t++) of.tracks[t]=NULL;
|
||||
|
||||
/* compute sample offsets */
|
||||
if(_mm_eof(modreader)) goto fail;
|
||||
samplepos=_mm_ftell(modreader);
|
||||
_mm_fseek(modreader,0,SEEK_END);
|
||||
fileend=_mm_ftell(modreader);
|
||||
_mm_fseek(modreader,samplepos,SEEK_SET);
|
||||
for(realsmpcnt=t=0;t<of.numsmp;t++)
|
||||
if(realsmpcnt<of.samples[t].seekpos)
|
||||
realsmpcnt=of.samples[t].seekpos;
|
||||
for(t=1;t<=realsmpcnt;t++) {
|
||||
q=of.samples;
|
||||
while(q->seekpos!=t) q++;
|
||||
u=0;
|
||||
while(q->seekpos!=t) {
|
||||
if(++u==of.numsmp)
|
||||
goto fail;
|
||||
q++;
|
||||
}
|
||||
q->seekpos=samplepos;
|
||||
samplepos+=q->length;
|
||||
}
|
||||
|
||||
if(samplepos>fileend)
|
||||
goto fail;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CHAR *AMF_LoadTitle(void)
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,15 +20,15 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_asy.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
ASYLUM Music Format v1.0 (.amf) loader
|
||||
adapted from load_mod.c by Raphael Assenat <raph@raphnet.net>,
|
||||
with the help of the AMF2MOD utility sourcecode,
|
||||
written to convert crusader's amf files into 8
|
||||
channels mod file in 1995 by Mr. P / Powersource
|
||||
mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca
|
||||
|
||||
mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca
|
||||
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
|
@ -76,8 +76,9 @@ typedef struct MODNOTE {
|
|||
|
||||
/* This table is taken from AMF2MOD.C
|
||||
* written in 1995 by Mr. P / Powersource
|
||||
* mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca */
|
||||
UWORD periodtable[]={6848,6464,6096,5760,5424,5120,4832,4560,4304,
|
||||
* mrp@fish.share.net, ac054@sfn.saskatoon.sk.ca */
|
||||
static const UWORD periodtable[] = {
|
||||
6848,6464,6096,5760,5424,5120,4832,4560,4304,
|
||||
4064,3840,3628,3424,3232,3048,2880,2712,2560,
|
||||
2416,2280,2152,2032,1920,1814,1712,1616,1524,
|
||||
1440,1356,1280,1208,1140,1076,1016, 960, 907,
|
||||
|
@ -108,7 +109,7 @@ static int ASY_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
|
|||
modtype = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -140,14 +141,16 @@ static void ASY_Cleanup(void)
|
|||
{
|
||||
MikMod_free(mh);
|
||||
MikMod_free(patbuf);
|
||||
mh = NULL;
|
||||
patbuf = NULL;
|
||||
}
|
||||
|
||||
static void ConvertNote(MODNOTE *n)
|
||||
static int ConvertNote(MODNOTE *n)
|
||||
{
|
||||
UBYTE instrument, effect, effdat, note;
|
||||
UWORD period;
|
||||
UBYTE lastnote = 0;
|
||||
|
||||
|
||||
instrument = n->b&0x1f;
|
||||
effect = n->c;
|
||||
effdat = n->d;
|
||||
|
@ -158,10 +161,10 @@ static void ConvertNote(MODNOTE *n)
|
|||
} else {
|
||||
period = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Convert the period to a note number */
|
||||
note = 0;
|
||||
if (period)
|
||||
if (period)
|
||||
{
|
||||
for (note = 0; note < 7 * OCTAVE; note++)
|
||||
if (period >= npertab[note])
|
||||
|
@ -186,8 +189,8 @@ static void ConvertNote(MODNOTE *n)
|
|||
UniInstrument(instrument - 1);
|
||||
/* ...otherwise, only adjust volume... */
|
||||
else {
|
||||
/* ...unless an effect was specified,
|
||||
* which forces a new note to be
|
||||
/* ...unless an effect was specified,
|
||||
* which forces a new note to be
|
||||
* played */
|
||||
if (effect || effdat) {
|
||||
UniInstrument(instrument - 1);
|
||||
|
@ -218,7 +221,15 @@ static void ConvertNote(MODNOTE *n)
|
|||
if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0))
|
||||
effdat &= 0xf0;
|
||||
|
||||
if (effect == 0x1b) {
|
||||
return 0; /* UniEffect(UNI_S3MEFFECTQ,dat) ? */
|
||||
}
|
||||
if (effect > 0xf) {
|
||||
return 0; /* return -1 to fail? */
|
||||
}
|
||||
|
||||
UniPTEffect(effect, effdat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UBYTE *ConvertTrack(MODNOTE *n)
|
||||
|
@ -227,7 +238,8 @@ static UBYTE *ConvertTrack(MODNOTE *n)
|
|||
|
||||
UniReset();
|
||||
for (t = 0; t < 64; t++) {
|
||||
ConvertNote(n);
|
||||
if (ConvertNote(n) < 0)
|
||||
return NULL;
|
||||
UniNewline();
|
||||
n += of.numchn;
|
||||
}
|
||||
|
@ -237,8 +249,7 @@ static UBYTE *ConvertTrack(MODNOTE *n)
|
|||
/* Loads all patterns of a modfile and converts them into the 3 byte format. */
|
||||
static int ML_LoadPatterns(void)
|
||||
{
|
||||
int t, tracks = 0;
|
||||
unsigned int s;
|
||||
unsigned int t, s, tracks = 0;
|
||||
|
||||
if (!AllocPatterns()) {
|
||||
return 0;
|
||||
|
@ -246,7 +257,7 @@ static int ML_LoadPatterns(void)
|
|||
if (!AllocTracks()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate temporary buffer for loading and converting the patterns */
|
||||
if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
|
||||
return 0;
|
||||
|
@ -278,31 +289,31 @@ static int ASY_Load(int curious)
|
|||
MSAMPINFO *s;
|
||||
CHAR *descr=asylum;
|
||||
ULONG seekpos;
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
// no title in asylum amf files :(
|
||||
strcpy(mh->songname, "");
|
||||
/* no title in asylum amf files :( */
|
||||
mh->songname[0] = '\0';
|
||||
|
||||
_mm_fseek(modreader, 0x23, SEEK_SET);
|
||||
mh->num_patterns = _mm_read_UBYTE(modreader);
|
||||
mh->num_orders = _mm_read_UBYTE(modreader);
|
||||
|
||||
// skip unknown byte
|
||||
(void)_mm_read_UBYTE(modreader);
|
||||
|
||||
/* skip unknown byte */
|
||||
_mm_skip_BYTE(modreader);
|
||||
_mm_read_UBYTES(mh->positions, 256, modreader);
|
||||
|
||||
|
||||
/* read samples headers*/
|
||||
for (t = 0; t < 64; t++) {
|
||||
s = &mh->samples[t];
|
||||
|
||||
|
||||
_mm_fseek(modreader, 0x126 + (t*37), SEEK_SET);
|
||||
|
||||
|
||||
_mm_read_string(s->samplename, 22, modreader);
|
||||
s->samplename[21] = 0; /* just in case */
|
||||
|
||||
|
||||
s->finetune = _mm_read_UBYTE(modreader);
|
||||
s->volume = _mm_read_UBYTE(modreader);
|
||||
(void)_mm_read_UBYTE(modreader); // skip unknown byte
|
||||
_mm_skip_BYTE(modreader);/* skip unknown byte */
|
||||
s->length = _mm_read_I_ULONG(modreader);
|
||||
s->reppos = _mm_read_I_ULONG(modreader);
|
||||
s->replen = _mm_read_I_ULONG(modreader);
|
||||
|
@ -324,12 +335,16 @@ static int ASY_Load(int curious)
|
|||
of.numpat = mh->num_patterns;
|
||||
of.numtrk = of.numpat * of.numchn;
|
||||
|
||||
|
||||
/* Copy positions (orders) */
|
||||
if (!AllocPositions(of.numpos))
|
||||
return 0;
|
||||
for (t = 0; t < of.numpos; t++) {
|
||||
of.positions[t] = mh->positions[t];
|
||||
if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
|
||||
/* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, init the sampleinfo structures */
|
||||
|
@ -343,7 +358,7 @@ static int ASY_Load(int curious)
|
|||
for (t = 0; t < of.numins; t++) {
|
||||
/* convert the samplename */
|
||||
q->samplename = DupStr(s->samplename, 23, 1);
|
||||
|
||||
|
||||
/* init the sampleinfo variables */
|
||||
q->speed = finetune[s->finetune & 0xf];
|
||||
q->volume = s->volume & 0x7f;
|
||||
|
@ -351,16 +366,16 @@ static int ASY_Load(int curious)
|
|||
q->loopstart = (ULONG)s->reppos;
|
||||
q->loopend = (ULONG)q->loopstart + (s->replen);
|
||||
q->length = (ULONG)s->length;
|
||||
|
||||
|
||||
q->flags = SF_SIGNED;
|
||||
|
||||
|
||||
q->seekpos = seekpos;
|
||||
seekpos += q->length;
|
||||
|
||||
|
||||
if ((s->replen) > 2) {
|
||||
q->flags |= SF_LOOP;
|
||||
}
|
||||
|
||||
|
||||
/* fix replen if repend > length */
|
||||
if (q->loopend > q->length)
|
||||
q->loopend = q->length;
|
||||
|
@ -369,7 +384,7 @@ static int ASY_Load(int curious)
|
|||
q++;
|
||||
}
|
||||
|
||||
of.modtype = StrDup(descr);
|
||||
of.modtype = MikMod_strdup(descr);
|
||||
|
||||
if (!ML_LoadPatterns())
|
||||
return 0;
|
||||
|
@ -379,9 +394,7 @@ static int ASY_Load(int curious)
|
|||
|
||||
static CHAR *ASY_LoadTitle(void)
|
||||
{
|
||||
CHAR *s = ""; // no titles
|
||||
|
||||
return (DupStr(s, 21, 1));
|
||||
return MikMod_strdup("");
|
||||
}
|
||||
|
||||
/*========== Loader information */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_dsm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
DSIK internal format (DSM) module loader
|
||||
|
||||
|
@ -89,9 +89,9 @@ typedef struct DSMNOTE {
|
|||
|
||||
/*========== Loader variables */
|
||||
|
||||
static CHAR* SONGID="SONG";
|
||||
static CHAR* INSTID="INST";
|
||||
static CHAR* PATTID="PATT";
|
||||
static const CHAR* SONGID="SONG";
|
||||
static const CHAR* INSTID="INST";
|
||||
static const CHAR* PATTID="PATT";
|
||||
|
||||
static UBYTE blockid[4];
|
||||
static ULONG blockln;
|
||||
|
@ -101,7 +101,7 @@ static DSMNOTE* dsmbuf=NULL;
|
|||
|
||||
static CHAR DSM_Version[]="DSIK DSM-format";
|
||||
|
||||
static unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'};
|
||||
static const unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'};
|
||||
|
||||
/*========== Loader code */
|
||||
|
||||
|
@ -126,6 +126,8 @@ static void DSM_Cleanup(void)
|
|||
{
|
||||
MikMod_free(dsmbuf);
|
||||
MikMod_free(mh);
|
||||
dsmbuf = NULL;
|
||||
mh = NULL;
|
||||
}
|
||||
|
||||
static int GetBlockHeader(void)
|
||||
|
@ -133,7 +135,7 @@ static int GetBlockHeader(void)
|
|||
/* make sure we're at the right position for reading the
|
||||
next riff block, no matter how many bytes read */
|
||||
_mm_fseek(modreader, blocklp+blockln, SEEK_SET);
|
||||
|
||||
|
||||
while(1) {
|
||||
_mm_read_UBYTES(blockid,4,modreader);
|
||||
blockln=_mm_read_I_ULONG(modreader);
|
||||
|
@ -237,7 +239,7 @@ static int DSM_Load(int curious)
|
|||
DSMINST s;
|
||||
SAMPLE *q;
|
||||
int cursmp=0,curpat=0,track=0;
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
blocklp=0;
|
||||
blockln=12;
|
||||
|
@ -266,7 +268,7 @@ static int DSM_Load(int curious)
|
|||
/* set module variables */
|
||||
of.initspeed=mh->speed;
|
||||
of.inittempo=mh->bpm;
|
||||
of.modtype=StrDup(DSM_Version);
|
||||
of.modtype=MikMod_strdup(DSM_Version);
|
||||
of.numchn=mh->numtrk;
|
||||
of.numpat=mh->numpat;
|
||||
of.numtrk=of.numchn*of.numpat;
|
||||
|
@ -286,6 +288,11 @@ static int DSM_Load(int curious)
|
|||
for(t=0;t<mh->numord;t++) {
|
||||
int order=mh->orders[t];
|
||||
if(order==255) order=LAST_PATTERN;
|
||||
else if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
|
||||
/* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
of.positions[of.numpos]=order;
|
||||
if(mh->orders[t]<254) of.numpos++;
|
||||
}
|
||||
|
@ -344,7 +351,7 @@ static CHAR *DSM_LoadTitle(void)
|
|||
|
||||
_mm_fseek(modreader,12,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(s,28,modreader)) return NULL;
|
||||
|
||||
|
||||
return(DupStr(s,28,1));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_far.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Farandole (FAR) module loader
|
||||
|
||||
|
@ -92,7 +92,7 @@ static FARHEADER1 *mh1 = NULL;
|
|||
static FARHEADER2 *mh2 = NULL;
|
||||
static FARNOTE *pat = NULL;
|
||||
|
||||
static unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26};
|
||||
static const unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26};
|
||||
|
||||
/*========== Loader code */
|
||||
|
||||
|
@ -119,6 +119,9 @@ static void FAR_Cleanup(void)
|
|||
MikMod_free(mh1);
|
||||
MikMod_free(mh2);
|
||||
MikMod_free(pat);
|
||||
mh1 = NULL;
|
||||
mh2 = NULL;
|
||||
pat = NULL;
|
||||
}
|
||||
|
||||
static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows)
|
||||
|
@ -180,7 +183,7 @@ static int FAR_Load(int curious)
|
|||
FARSAMPLE s;
|
||||
FARNOTE *crow;
|
||||
UBYTE smap[8];
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* try to read module header (first part) */
|
||||
_mm_read_UBYTES(mh1->id,4,modreader);
|
||||
|
@ -196,7 +199,7 @@ static int FAR_Load(int curious)
|
|||
mh1->stlen = _mm_read_I_UWORD (modreader);
|
||||
|
||||
/* init modfile data */
|
||||
of.modtype = StrDup(FAR_Version);
|
||||
of.modtype = MikMod_strdup(FAR_Version);
|
||||
of.songname = DupStr(mh1->songname,40,1);
|
||||
of.numchn = 16;
|
||||
of.initspeed = mh1->speed;
|
||||
|
@ -207,7 +210,12 @@ static int FAR_Load(int curious)
|
|||
|
||||
/* read songtext into comment field */
|
||||
if(mh1->stlen)
|
||||
if (!ReadLinedComment(mh1->stlen, 66)) return 0;
|
||||
if (!ReadLinedComment(mh1->stlen, 132)) return 0;
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* try to read module header (second part) */
|
||||
_mm_read_UBYTES(mh2->orders,256,modreader);
|
||||
|
@ -238,12 +246,14 @@ static int FAR_Load(int curious)
|
|||
if(!AllocPatterns()) return 0;
|
||||
|
||||
for(t=0;t<of.numpat;t++) {
|
||||
UBYTE rows=0/* ,tempo */;
|
||||
UBYTE rows=0;
|
||||
UBYTE tempo;
|
||||
|
||||
memset(pat,0,256*16*4*sizeof(FARNOTE));
|
||||
if(mh2->patsiz[t]) {
|
||||
rows = _mm_read_UBYTE(modreader);
|
||||
/* tempo = */ (void)_mm_read_UBYTE(modreader);
|
||||
tempo = _mm_read_UBYTE(modreader);
|
||||
(void)tempo; /* unused */
|
||||
|
||||
crow = pat;
|
||||
/* file often allocates 64 rows even if there are less in pattern */
|
||||
|
@ -284,7 +294,7 @@ static int FAR_Load(int curious)
|
|||
of.numins = 0;
|
||||
for(t=0;t<64;t++)
|
||||
if(smap[t>>3]&(1<<(t&7))) of.numins=t+1;
|
||||
of.numsmp = of.numins;
|
||||
of.numsmp = of.numins;
|
||||
|
||||
/* alloc sample structs */
|
||||
if(!AllocSamples()) return 0;
|
||||
|
@ -314,8 +324,8 @@ static int FAR_Load(int curious)
|
|||
|
||||
q->seekpos = _mm_ftell(modreader);
|
||||
_mm_fseek(modreader,q->length,SEEK_CUR);
|
||||
} else
|
||||
q->samplename = DupStr(NULL,0,0);
|
||||
} else
|
||||
q->samplename = MikMod_strdup("");
|
||||
q++;
|
||||
}
|
||||
return 1;
|
||||
|
@ -327,8 +337,8 @@ static CHAR *FAR_LoadTitle(void)
|
|||
|
||||
_mm_fseek(modreader,4,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(s,40,modreader)) return NULL;
|
||||
|
||||
return(DupStr(s,40,1));
|
||||
|
||||
return (DupStr(s,40,1));
|
||||
}
|
||||
|
||||
/*========== Loader information */
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_gdm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
General DigiMusic (GDM) module loader
|
||||
|
||||
|
@ -114,7 +114,7 @@ typedef struct GDMSAMPLE {
|
|||
static GDMHEADER *mh=NULL; /* pointer to GDM header */
|
||||
static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */
|
||||
|
||||
CHAR GDM_Version[]="General DigiMusic 1.xx";
|
||||
static CHAR GDM_Version[]="General DigiMusic 1.xx";
|
||||
|
||||
static int GDM_Test(void)
|
||||
{
|
||||
|
@ -146,36 +146,45 @@ static void GDM_Cleanup(void)
|
|||
{
|
||||
MikMod_free(mh);
|
||||
MikMod_free(gdmbuf);
|
||||
mh=NULL;
|
||||
gdmbuf=NULL;
|
||||
}
|
||||
|
||||
static int GDM_ReadPattern(void)
|
||||
{
|
||||
int pos,flag,ch,i,maxch;
|
||||
int pos,flag,ch,i;
|
||||
GDMNOTE n;
|
||||
UWORD length,x=0;
|
||||
SLONG length,x=0;
|
||||
|
||||
/* get pattern length */
|
||||
length=_mm_read_I_UWORD(modreader)-2;
|
||||
length=(SLONG)_mm_read_I_UWORD(modreader);
|
||||
length-=2;
|
||||
|
||||
/* clear pattern data */
|
||||
memset(gdmbuf,255,32*64*sizeof(GDMNOTE));
|
||||
pos=0;
|
||||
maxch=0;
|
||||
|
||||
while (x<length) {
|
||||
memset(&n,255,sizeof(GDMNOTE));
|
||||
flag=_mm_read_UBYTE(modreader);
|
||||
x++;
|
||||
|
||||
if (_mm_eof(modreader)) {
|
||||
_mm_errno=MMERR_LOADING_PATTERN;
|
||||
if (_mm_eof(modreader))
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch=flag&31;
|
||||
if (ch>maxch) maxch=ch;
|
||||
if (ch > of.numchn)
|
||||
return 0;
|
||||
|
||||
if (!flag) {
|
||||
pos++;
|
||||
if (x==length) {
|
||||
if (pos > 64)
|
||||
return 0;
|
||||
} else {
|
||||
if (pos >= 64)
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (flag&0x60) {
|
||||
|
@ -343,7 +352,7 @@ static int GDM_Load(int curious)
|
|||
SAMPLE *q;
|
||||
GDMSAMPLE s;
|
||||
ULONG position;
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* read header */
|
||||
_mm_read_string(mh->id1,4,modreader);
|
||||
|
@ -390,7 +399,7 @@ static int GDM_Load(int curious)
|
|||
}
|
||||
|
||||
/* now we fill */
|
||||
of.modtype=StrDup(GDM_Version);
|
||||
of.modtype=MikMod_strdup(GDM_Version);
|
||||
of.modtype[18]=mh->majorver+'0';
|
||||
of.modtype[20]=mh->minorver/10+'0';
|
||||
of.modtype[21]=mh->minorver%10+'0';
|
||||
|
|
|
@ -1,375 +0,0 @@
|
|||
/* MikMod sound library
|
||||
(c) 2003-2004 Raphael Assenat and others - see file
|
||||
AUTHORS for complete list.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_gt2.c,v 1.2 2005/03/30 19:09:35 realtech Exp $
|
||||
|
||||
Graoumf tracker format (.GT2)
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
typedef struct GT_NOTE {
|
||||
UBYTE note; /* 24-127, 48 is middle C-2. 0 for no note */
|
||||
UBYTE inst; /* instrument, 1-255, 0 for none */
|
||||
UWORD effect; /* 0 for no FX */
|
||||
UBYTE vv; /* volume, 1-255, 0 for no volume */
|
||||
} GT_NOTE;
|
||||
|
||||
/* general info chunk */
|
||||
typedef struct GT2_CHUNK {
|
||||
UBYTE magic[4]; /* must be 'GT2' */
|
||||
UBYTE version; /* 01 = v0.7, 02=v0.726, 03=v0.731 */
|
||||
ULONG chunk_size;
|
||||
CHAR module_name[33]; /* 32 bytes in file */
|
||||
CHAR comments_author[161]; /* 160 bytes in file */
|
||||
UBYTE date_day;
|
||||
UBYTE date_month;
|
||||
UWORD date_year;
|
||||
CHAR tracker_name[25]; /* 24 in file */
|
||||
UWORD initial_speed;
|
||||
UWORD initial_tempo;
|
||||
UWORD initial_master_volume; /* 000 - fff */
|
||||
UWORD num_voices; /* for the following panning section */
|
||||
UWORD *voice_pannings; /* 000 - 800 - fff */
|
||||
} GT2_CHUNK;
|
||||
|
||||
/* track volume chunk */
|
||||
typedef struct TVOL_CHUNK {
|
||||
UBYTE id[4]; /* must be TVOL */
|
||||
ULONG chunk_size;
|
||||
UWORD num_tracks; /* for the following array */
|
||||
UWORD *track_volumes; /* 0000 - 1000 - FFFF */
|
||||
} TVOL_CHUNK;
|
||||
|
||||
/* extra-comment chunk */
|
||||
typedef struct XCOM_CHUNK {
|
||||
UBYTE id[4]; /* must be XCOM */
|
||||
ULONG chunk_size;
|
||||
ULONG comment_len;
|
||||
CHAR *comment; /* comment_len + 1 allocated */
|
||||
} XCOM_CHUNK;
|
||||
|
||||
/* song chunk */
|
||||
typedef struct SONG_CHUNK {
|
||||
UBYTE id[4]; /* must be SONG */
|
||||
ULONG chunk_size;
|
||||
UWORD song_length;
|
||||
UWORD song_repeat_point;
|
||||
UWORD *patterns; /* pattern numbers */
|
||||
} SONG_CHUNK;
|
||||
|
||||
/* pattern set chunk */
|
||||
typedef struct PATS_CHUNK {
|
||||
UBYTE id[4]; /* must be PATS */
|
||||
ULONG chunk_size;
|
||||
UWORD num_tracks; /* total number of tracks for the song */
|
||||
UWORD num_patterns; /* number of patterns saved */
|
||||
} PATS_CHUNK;
|
||||
|
||||
/* pattern chunk */
|
||||
typedef struct PATD_CHUNK {
|
||||
UBYTE id[4]; /* must be PATD */
|
||||
ULONG chunk_size;
|
||||
UWORD pattern_number;
|
||||
CHAR pattern_name[17]; /* 16 in file */
|
||||
UWORD codage_version; /* only 0 expected for now */
|
||||
/* version 0 (full pattern) */
|
||||
UWORD num_lines;
|
||||
UWORD num_tracks;
|
||||
GT_NOTE *notes; /* sizeof(GT_NOTE) * num_lines * num_tracks */
|
||||
} PATD_CHUNK;
|
||||
|
||||
/* instrument set chunk */
|
||||
typedef struct ORCH_CHUNK {
|
||||
UBYTE id[4]; /* must be ORCH */
|
||||
ULONG chunk_size;
|
||||
UWORD num_instruments; /* number of instruments saved */
|
||||
} ORCH_CHUNK;
|
||||
|
||||
typedef struct INST_NOTE {
|
||||
UBYTE samp_number;/* sample number for midi note */
|
||||
CHAR tranp; /* transposition for note */
|
||||
} INST_NOTE;
|
||||
|
||||
/* instrument chunk */
|
||||
typedef struct INST_CHUNK {
|
||||
UBYTE id[4]; /* must be INST */
|
||||
ULONG chunk_size;
|
||||
UWORD instrument_number;
|
||||
CHAR name[29]; /* 28 in file */
|
||||
UWORD type; /* 0 = sample */
|
||||
UWORD volume; /* volume, 0-255 */
|
||||
UWORD auto_panning; /* autopanning, 000 - 800 - fff, -1 no autopanning */
|
||||
UWORD volume_enveloppe_number;
|
||||
UWORD tone_enveloppe_number;
|
||||
UWORD pan_enveloppe_number;
|
||||
UBYTE reserved[10];
|
||||
INST_NOTE note[128];
|
||||
} INST_CHUNK;
|
||||
|
||||
typedef struct SAMP_CHUNK {
|
||||
UBYTE id[4]; /* must be SAMP */
|
||||
ULONG chunk_size;
|
||||
UWORD sample_number;
|
||||
CHAR name[29]; /* 28 in file */
|
||||
UWORD flags; /* bit0: 0 = mono, 1 = stereo bit1: 0 normal loop, bit2: ping pong loop */
|
||||
UWORD autopanning; /* 000 - 800 - fff */
|
||||
UWORD num_bits; /* 8 or 16 */
|
||||
UWORD rate; /* between 2000 and 65000 */
|
||||
ULONG length; /* bytes */
|
||||
ULONG loop_start; /* bytes */
|
||||
ULONG loop_len; /* bytes */
|
||||
UWORD volume; /* 0 - 255 */
|
||||
UWORD finetune; /* (-8..+7 -> -1..+7/8 halftone) */
|
||||
UWORD codage; /* 0 */
|
||||
UBYTE *data;
|
||||
} SAMP_CHUNK;
|
||||
|
||||
typedef struct xENV_CHUNK {
|
||||
UBYTE id[4]; /* must be VENV, TENV or PENV */
|
||||
ULONG chunk_size;
|
||||
UWORD envelope_number;
|
||||
CHAR name[21]; /* 20 in file */
|
||||
UWORD keyoff_offset;
|
||||
UBYTE *data;
|
||||
} xENV_CHUNK;
|
||||
|
||||
typedef struct ENDC_CHUNK {
|
||||
UBYTE id[4]; /* must be ENDC */
|
||||
ULONG chunk_size;
|
||||
ULONG total_module_size;
|
||||
} ENDC_CHUNK;
|
||||
|
||||
|
||||
typedef union GT_CHUNK
|
||||
{
|
||||
UBYTE id[4]; /* must be TVOL */
|
||||
GT2_CHUNK gt2;
|
||||
TVOL_CHUNK tvol;
|
||||
XCOM_CHUNK xcom;
|
||||
SONG_CHUNK song;
|
||||
PATS_CHUNK pats;
|
||||
PATD_CHUNK patd;
|
||||
ORCH_CHUNK orch;
|
||||
INST_CHUNK inst;
|
||||
SAMP_CHUNK samp;
|
||||
xENV_CHUNK xenv;
|
||||
ENDC_CHUNK endc;
|
||||
} GT_CHUNK;
|
||||
|
||||
static GT_CHUNK *loadChunk(void)
|
||||
{
|
||||
GT_CHUNK *new_chunk = MikMod_malloc(sizeof(GT_CHUNK));
|
||||
|
||||
/* the file chunk id only use 3 bytes, others 4 */
|
||||
_mm_read_UBYTES(new_chunk->id, 3, modreader);
|
||||
if (! (new_chunk->id[0]=='G' &&
|
||||
new_chunk->id[1]=='T' &&
|
||||
new_chunk->id[2]=='2')
|
||||
)
|
||||
{
|
||||
_mm_read_UBYTES(&new_chunk->id[3], 1, modreader);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_chunk->id[3] = ' ';
|
||||
}
|
||||
|
||||
printf(">> %c%c%c%c\n", new_chunk->id[0], new_chunk->id[1], new_chunk->id[2], new_chunk->id[3]);
|
||||
|
||||
if (!memcmp(new_chunk, "GT2", 3)) {
|
||||
_mm_read_UBYTES(&new_chunk->gt2.version, 1, modreader);
|
||||
_mm_read_M_ULONGS(&new_chunk->gt2.chunk_size, 1, modreader);
|
||||
new_chunk->gt2.module_name[32] = 0;
|
||||
_mm_read_UBYTES(&new_chunk->gt2.module_name, 32, modreader);
|
||||
new_chunk->gt2.comments_author[160] = 0;
|
||||
_mm_read_UBYTES(&new_chunk->gt2.comments_author, 160, modreader);
|
||||
_mm_read_UBYTES(&new_chunk->gt2.date_day, 1, modreader);
|
||||
_mm_read_UBYTES(&new_chunk->gt2.date_month, 1, modreader);
|
||||
_mm_read_M_UWORDS(&new_chunk->gt2.date_year, 1, modreader);
|
||||
new_chunk->gt2.tracker_name[24] = 0;
|
||||
_mm_read_UBYTES(&new_chunk->gt2.tracker_name, 24, modreader);
|
||||
_mm_read_M_UWORDS(&new_chunk->gt2.initial_speed, 1, modreader);
|
||||
_mm_read_M_UWORDS(&new_chunk->gt2.initial_tempo, 1, modreader);
|
||||
_mm_read_M_UWORDS(&new_chunk->gt2.initial_master_volume, 1, modreader);
|
||||
_mm_read_M_UWORDS(&new_chunk->gt2.num_voices, 1, modreader);
|
||||
new_chunk->gt2.voice_pannings = MikMod_malloc(2*new_chunk->gt2.num_voices);
|
||||
_mm_read_M_UWORDS(new_chunk->gt2.voice_pannings, new_chunk->gt2.num_voices, modreader);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
if (!memcmp(new_chunk, "TVOL", 4)) {
|
||||
new_chunk->tvol.chunk_size = _mm_read_M_ULONG(modreader);
|
||||
new_chunk->tvol.num_tracks = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->tvol.track_volumes = MikMod_malloc(new_chunk->tvol.num_tracks * 2);
|
||||
_mm_read_M_UWORDS(new_chunk->tvol.track_volumes, new_chunk->tvol.num_tracks, modreader);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
if (!memcmp(new_chunk, "XCOM", 4)) {
|
||||
new_chunk->xcom.chunk_size = _mm_read_M_ULONG(modreader);
|
||||
new_chunk->xcom.comment_len = _mm_read_M_ULONG(modreader);
|
||||
new_chunk->xcom.comment = MikMod_malloc(new_chunk->xcom.comment_len + 1);
|
||||
_mm_read_UBYTES(new_chunk->xcom.comment, new_chunk->xcom.comment_len, modreader);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
if (!memcmp(new_chunk, "SONG", 4)) {
|
||||
new_chunk->song.chunk_size = _mm_read_M_ULONG(modreader);
|
||||
new_chunk->song.song_length = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->song.song_repeat_point = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->song.patterns = MikMod_malloc(2*new_chunk->song.song_length);
|
||||
_mm_read_M_UWORDS(new_chunk->song.patterns, new_chunk->song.song_length, modreader);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
if (!memcmp(new_chunk, "PATS", 4)) {
|
||||
new_chunk->pats.chunk_size = _mm_read_M_ULONG(modreader);
|
||||
new_chunk->pats.num_tracks = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->pats.num_patterns = _mm_read_M_UWORD(modreader);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
if (!memcmp(new_chunk, "PATD", 4)) {
|
||||
new_chunk->patd.chunk_size = _mm_read_M_ULONG(modreader);
|
||||
new_chunk->patd.pattern_number = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->patd.pattern_name[16] = 0;
|
||||
_mm_read_UBYTES(new_chunk->patd.pattern_name, 16, modreader);
|
||||
new_chunk->patd.codage_version = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->patd.num_lines = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->patd.num_tracks = _mm_read_M_UWORD(modreader);
|
||||
new_chunk->patd.notes = MikMod_malloc(5 *
|
||||
new_chunk->patd.num_lines *
|
||||
new_chunk->patd.num_tracks);
|
||||
_mm_read_UBYTES(new_chunk->patd.notes,
|
||||
new_chunk->patd.num_lines * new_chunk->patd.num_tracks * 5,
|
||||
modreader);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
if (!memcmp(new_chunk, "ORCH", 4)) {
|
||||
new_chunk->orch.chunk_size = _mm_read_M_ULONG(modreader);
|
||||
new_chunk->orch.num_instruments = _mm_read_M_UWORD(modreader);
|
||||
return new_chunk;
|
||||
}
|
||||
if (!memcmp(new_chunk, "INST", 4)) {
|
||||
return new_chunk;
|
||||
}
|
||||
if (!memcmp(new_chunk, "SAMP", 4)) {
|
||||
return new_chunk;
|
||||
}
|
||||
if (!memcmp(new_chunk, "VENV", 4)) {
|
||||
return new_chunk;
|
||||
}
|
||||
if (!memcmp(new_chunk, "TENV", 4)) {
|
||||
return new_chunk;
|
||||
}
|
||||
if (!memcmp(new_chunk, "PENV", 4)) {
|
||||
return new_chunk;
|
||||
}
|
||||
if (!memcmp(new_chunk, "ENDC", 4)) {
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
printf("?? %c%c%c%c\n", new_chunk->id[0], new_chunk->id[1], new_chunk->id[2], new_chunk->id[3]);
|
||||
|
||||
MikMod_free(new_chunk);
|
||||
return NULL; // unknown chunk
|
||||
}
|
||||
|
||||
static int GT2_Init(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GT2_Test(void)
|
||||
{
|
||||
UBYTE magic[3];
|
||||
_mm_fseek(modreader, 0, SEEK_SET);
|
||||
|
||||
_mm_read_UBYTES(magic, 3, modreader);
|
||||
|
||||
if (magic[0] == 'G' && magic[1] == 'T' && magic[2] == '2') { return 1; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GT2_Load(int curious)
|
||||
{
|
||||
GT_CHUNK *tmp;
|
||||
(void)curious;
|
||||
|
||||
_mm_fseek(modreader, 0, SEEK_SET);
|
||||
while ( (tmp = loadChunk() ))
|
||||
{
|
||||
printf("%c%c%c%c\n", tmp->id[0], tmp->id[1], tmp->id[2], tmp->id[3]);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void GT2_Cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
static CHAR *GT2_LoadTitle(void)
|
||||
{
|
||||
CHAR title[33];
|
||||
_mm_fseek(modreader, 8, SEEK_SET);
|
||||
|
||||
_mm_read_UBYTES(title, 32, modreader);
|
||||
title[32]=0;
|
||||
|
||||
return (DupStr(title, 32, 1));
|
||||
}
|
||||
|
||||
|
||||
MIKMODAPI MLOADER load_gt2 = {
|
||||
NULL,
|
||||
"Graoumf Tracker 2 module",
|
||||
"Graoumf Tracker 2",
|
||||
GT2_Init,
|
||||
GT2_Test,
|
||||
GT2_Load,
|
||||
GT2_Cleanup,
|
||||
GT2_LoadTitle
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_imf.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Imago Orpheus (IMF) module loader
|
||||
|
||||
|
@ -127,12 +127,36 @@ static IMFHEADER *mh=NULL;
|
|||
|
||||
static int IMF_Test(void)
|
||||
{
|
||||
UBYTE id[4];
|
||||
UBYTE buf[512], *p;
|
||||
int t, chn;
|
||||
|
||||
_mm_fseek(modreader,0x3c,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(id,4,modreader)) return 0;
|
||||
if(!memcmp(id,"IM10",4)) return 1;
|
||||
return 0;
|
||||
if (!_mm_read_UBYTES(buf,4,modreader)) return 0;
|
||||
if (memcmp(buf,"IM10",4) != 0) return 0; /* no magic */
|
||||
|
||||
_mm_fseek(modreader,32,SEEK_SET);
|
||||
if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad ordnum */
|
||||
if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad patnum */
|
||||
if (_mm_read_I_UWORD(modreader) > 256) return 0;/* bad insnum */
|
||||
|
||||
_mm_fseek(modreader,64,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(buf,512,modreader)) return 0;
|
||||
/* verify channel status */
|
||||
for (t = 0, chn = 0, p = &buf[15]; t < 512; t += 16, p += 16) {
|
||||
switch (*p) {
|
||||
case 0: /* channel enabled */
|
||||
case 1: /* channel muted */
|
||||
chn++;
|
||||
break;
|
||||
case 2: /* channel disabled */
|
||||
break;
|
||||
default: /* bad status value */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(!chn) return 0; /* no channels found */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IMF_Init(void)
|
||||
|
@ -149,6 +173,8 @@ static void IMF_Cleanup(void)
|
|||
|
||||
MikMod_free(imfpat);
|
||||
MikMod_free(mh);
|
||||
imfpat=NULL;
|
||||
mh=NULL;
|
||||
}
|
||||
|
||||
static int IMF_ReadPattern(SLONG size,UWORD rows)
|
||||
|
@ -388,7 +414,7 @@ static int IMF_Load(int curious)
|
|||
ULONG *nextwav=NULL;
|
||||
UWORD wavcnt=0;
|
||||
UBYTE id[4];
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* try to read the module header */
|
||||
_mm_read_string(mh->songname,32,modreader);
|
||||
|
@ -410,7 +436,7 @@ static int IMF_Load(int curious)
|
|||
|
||||
/* set module variables */
|
||||
of.songname=DupStr(mh->songname,31,1);
|
||||
of.modtype=StrDup(IMF_Version);
|
||||
of.modtype=MikMod_strdup(IMF_Version);
|
||||
of.numpat=mh->patnum;
|
||||
of.numins=mh->insnum;
|
||||
of.reppos=0;
|
||||
|
@ -467,6 +493,13 @@ static int IMF_Load(int curious)
|
|||
if(!AllocPositions(of.numpos)) return 0;
|
||||
for(t=u=0;t<mh->ordnum;t++)
|
||||
if(mh->orders[t]!=0xff) of.positions[u++]=mh->orders[t];
|
||||
for(t=0;t<of.numpos;t++) {
|
||||
if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
|
||||
/* fprintf(stderr,"position[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* load pattern info */
|
||||
of.numtrk=of.numpat*of.numchn;
|
||||
|
@ -509,16 +542,16 @@ static int IMF_Load(int curious)
|
|||
_mm_read_I_UWORDS(ih.panenv,IMFENVCNT,modreader);
|
||||
_mm_read_I_UWORDS(ih.pitenv,IMFENVCNT,modreader);
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define IMF_FinishLoadingEnvelope(name) \
|
||||
ih. name##pts=_mm_read_UBYTE(modreader); \
|
||||
ih. name##sus=_mm_read_UBYTE(modreader); \
|
||||
ih. name##beg=_mm_read_UBYTE(modreader); \
|
||||
ih. name##end=_mm_read_UBYTE(modreader); \
|
||||
ih. name##flg=_mm_read_UBYTE(modreader); \
|
||||
(void)_mm_read_UBYTE(modreader); \
|
||||
(void)_mm_read_UBYTE(modreader); \
|
||||
(void)_mm_read_UBYTE(modreader)
|
||||
_mm_skip_BYTE(modreader); \
|
||||
_mm_skip_BYTE(modreader); \
|
||||
_mm_skip_BYTE(modreader)
|
||||
#else
|
||||
#define IMF_FinishLoadingEnvelope(name) \
|
||||
ih. name/**/pts=_mm_read_UBYTE(modreader); \
|
||||
|
@ -526,9 +559,9 @@ static int IMF_Load(int curious)
|
|||
ih. name/**/beg=_mm_read_UBYTE(modreader); \
|
||||
ih. name/**/end=_mm_read_UBYTE(modreader); \
|
||||
ih. name/**/flg=_mm_read_UBYTE(modreader); \
|
||||
(void)_mm_read_UBYTE(modreader); \
|
||||
(void)_mm_read_UBYTE(modreader); \
|
||||
(void)_mm_read_UBYTE(modreader)
|
||||
_mm_skip_BYTE(modreader); \
|
||||
_mm_skip_BYTE(modreader); \
|
||||
_mm_skip_BYTE(modreader)
|
||||
#endif
|
||||
|
||||
IMF_FinishLoadingEnvelope(vol);
|
||||
|
@ -541,7 +574,7 @@ static int IMF_Load(int curious)
|
|||
_mm_read_UBYTES(id,4,modreader);
|
||||
/* Looks like Imago Orpheus forgets the signature for empty
|
||||
instruments following a multi-sample instrument... */
|
||||
if(memcmp(id,"II10",4) &&
|
||||
if(memcmp(id,"II10",4) &&
|
||||
(oldnumsmp && memcmp(id,"\x0\x0\x0\x0",4))) {
|
||||
if(nextwav) MikMod_free(nextwav);
|
||||
if(wh) MikMod_free(wh);
|
||||
|
@ -562,7 +595,7 @@ static int IMF_Load(int curious)
|
|||
d->samplenumber[u]=ih.what[u]>ih.numsmp?0xffff:ih.what[u]+of.numsmp;
|
||||
d->volfade=ih.volfade;
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define IMF_ProcessEnvelope(name) \
|
||||
for (u = 0; u < (IMFENVCNT >> 1); u++) { \
|
||||
d-> name##env[u].pos = ih. name##env[u << 1]; \
|
||||
|
@ -613,12 +646,12 @@ static int IMF_Load(int curious)
|
|||
/* allocate more room for sample information if necessary */
|
||||
if(of.numsmp+u==wavcnt) {
|
||||
wavcnt+=IMF_SMPINCR;
|
||||
if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))) {
|
||||
if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))) {
|
||||
if(wh) MikMod_free(wh);
|
||||
_mm_errno=MMERR_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
}
|
||||
if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) {
|
||||
if(!(wh=(IMFWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) {
|
||||
MikMod_free(nextwav);
|
||||
_mm_errno=MMERR_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
|
@ -627,7 +660,7 @@ static int IMF_Load(int curious)
|
|||
}
|
||||
|
||||
_mm_read_string(s->samplename,13,modreader);
|
||||
(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);
|
||||
_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);
|
||||
s->length =_mm_read_I_ULONG(modreader);
|
||||
s->loopstart =_mm_read_I_ULONG(modreader);
|
||||
s->loopend =_mm_read_I_ULONG(modreader);
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_it.c,v 1.4 2010/01/12 03:30:32 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Impulse tracker (IT) module loader
|
||||
|
||||
|
@ -45,7 +45,6 @@
|
|||
|
||||
#ifdef SUNOS
|
||||
extern int fprintf(FILE *, const char *, ...);
|
||||
extern int toupper(int);
|
||||
#endif
|
||||
|
||||
/*========== Module structure */
|
||||
|
@ -67,7 +66,7 @@ typedef struct ITHEADER {
|
|||
UBYTE initspeed;
|
||||
UBYTE inittempo;
|
||||
UBYTE pansep; /* panning separation between channels */
|
||||
UBYTE zerobyte;
|
||||
UBYTE zerobyte;
|
||||
UWORD msglength;
|
||||
ULONG msgoffset;
|
||||
UBYTE blank02[4];
|
||||
|
@ -107,19 +106,19 @@ typedef struct ITINSTHEADER {
|
|||
CHAR filename[12]; /* (char) Instrument filename */
|
||||
UBYTE zerobyte; /* (byte) Instrument type (always 0) */
|
||||
UBYTE volflg;
|
||||
UBYTE volpts;
|
||||
UBYTE volpts;
|
||||
UBYTE volbeg; /* (byte) Volume loop start (node) */
|
||||
UBYTE volend; /* (byte) Volume loop end (node) */
|
||||
UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */
|
||||
UBYTE volsusend; /* (byte) Volume Sustain end (node) */
|
||||
UBYTE panflg;
|
||||
UBYTE panpts;
|
||||
UBYTE panpts;
|
||||
UBYTE panbeg; /* (byte) channel loop start (node) */
|
||||
UBYTE panend; /* (byte) channel loop end (node) */
|
||||
UBYTE pansusbeg; /* (byte) channel sustain begin (node) */
|
||||
UBYTE pansusend; /* (byte) channel Sustain end (node) */
|
||||
UBYTE pitflg;
|
||||
UBYTE pitpts;
|
||||
UBYTE pitpts;
|
||||
UBYTE pitbeg; /* (byte) pitch loop start (node) */
|
||||
UBYTE pitend; /* (byte) pitch loop end (node) */
|
||||
UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */
|
||||
|
@ -149,7 +148,7 @@ typedef struct ITINSTHEADER {
|
|||
UWORD pantick[ITENVCNT]; /* tick value of panning nodes */
|
||||
SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */
|
||||
UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */
|
||||
} ITINSTHEADER;
|
||||
} ITINSTHEADER;
|
||||
|
||||
/* unpacked note */
|
||||
|
||||
|
@ -166,8 +165,8 @@ static UBYTE *mask=NULL; /* arrays allocated to 64 elements and used for */
|
|||
static ITNOTE *last=NULL; /* uncompressing IT's pattern information */
|
||||
static int numtrk=0;
|
||||
static unsigned int old_effect; /* if set, use S3M old-effects stuffs */
|
||||
|
||||
static CHAR* IT_Version[]={
|
||||
|
||||
static const CHAR* IT_Version[]={
|
||||
"ImpulseTracker . ",
|
||||
"Compressed ImpulseTracker . ",
|
||||
"ImpulseTracker 2.14p3",
|
||||
|
@ -177,7 +176,7 @@ static CHAR* IT_Version[]={
|
|||
};
|
||||
|
||||
/* table for porta-to-note command within volume/panning column */
|
||||
static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255};
|
||||
static const UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255};
|
||||
|
||||
/*========== Loader code */
|
||||
|
||||
|
@ -212,40 +211,48 @@ static void IT_Cleanup(void)
|
|||
MikMod_free(last);
|
||||
MikMod_free(paraptr);
|
||||
MikMod_free(origpositions);
|
||||
mh=NULL;
|
||||
poslookup=NULL;
|
||||
itpat=NULL;
|
||||
mask=NULL;
|
||||
last=NULL;
|
||||
paraptr=NULL;
|
||||
origpositions=NULL;
|
||||
}
|
||||
|
||||
/* Because so many IT files have 64 channels as the set number used, but really
|
||||
only use far less (usually from 8 to 24 still), I had to make this function,
|
||||
which determines the number of channels that are actually USED by a pattern.
|
||||
|
||||
NOTE: You must first seek to the file location of the pattern before calling
|
||||
this procedure.
|
||||
|
||||
Returns 1 on error
|
||||
NOTE: You must first seek to the file location of the pattern before calling
|
||||
this procedure.
|
||||
|
||||
Returns 0 on error
|
||||
*/
|
||||
static int IT_GetNumChannels(UWORD patrows)
|
||||
{
|
||||
int row=0,flag,ch;
|
||||
|
||||
do {
|
||||
if((flag=_mm_read_UBYTE(modreader))==EOF) {
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno=MMERR_LOADING_PATTERN;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
flag=_mm_read_UBYTE(modreader);
|
||||
if(!flag)
|
||||
row++;
|
||||
else {
|
||||
ch=(flag-1)&63;
|
||||
remap[ch]=0;
|
||||
if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader);
|
||||
if(mask[ch]&1) (void)_mm_read_UBYTE(modreader);
|
||||
if(mask[ch]&2) (void)_mm_read_UBYTE(modreader);
|
||||
if(mask[ch]&4) (void)_mm_read_UBYTE(modreader);
|
||||
if(mask[ch]&8) { (void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader); }
|
||||
if(mask[ch]&1) _mm_skip_BYTE(modreader);
|
||||
if(mask[ch]&2) _mm_skip_BYTE(modreader);
|
||||
if(mask[ch]&4) _mm_skip_BYTE(modreader);
|
||||
if(mask[ch]&8) { _mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader); }
|
||||
}
|
||||
} while(row<patrows);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
|
||||
|
@ -282,7 +289,7 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
|
|||
/* process volume / panning column
|
||||
volume / panning effects do NOT all share the same memory address
|
||||
yet. */
|
||||
if(volpan<=64)
|
||||
if(volpan<=64)
|
||||
UniVolEffect(VOL_VOLUME,volpan);
|
||||
else if(volpan==65) /* fine volume slide up (65-74) - A0 case */
|
||||
UniVolEffect(VOL_VOLSLIDE,0);
|
||||
|
@ -324,16 +331,20 @@ static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows)
|
|||
|
||||
static int IT_ReadPattern(UWORD patrows)
|
||||
{
|
||||
int row=0,flag,ch,blah;
|
||||
int row=0,flag,ch;
|
||||
unsigned int blah;
|
||||
ITNOTE *itt=itpat,dummy,*n,*l;
|
||||
ITNOTE *ite=&itpat[200*64 -1];
|
||||
UBYTE *m;
|
||||
|
||||
memset(itt,255,200*64*sizeof(ITNOTE));
|
||||
|
||||
do {
|
||||
if((flag=_mm_read_UBYTE(modreader))==EOF) {
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_PATTERN;
|
||||
return 0;
|
||||
}
|
||||
flag=_mm_read_UBYTE(modreader);
|
||||
if(!flag) {
|
||||
itt=&itt[of.numchn];
|
||||
row++;
|
||||
|
@ -342,29 +353,38 @@ static int IT_ReadPattern(UWORD patrows)
|
|||
if(ch!=-1) {
|
||||
n=&itt[ch];
|
||||
l=&last[ch];
|
||||
} else
|
||||
m=&mask[ch];
|
||||
if(n > ite) { /* malformed file */
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
n=l=&dummy;
|
||||
blah = 0;
|
||||
m=(UBYTE*)&blah;
|
||||
}
|
||||
|
||||
if(flag&128) mask[ch]=_mm_read_UBYTE(modreader);
|
||||
if(mask[ch]&1)
|
||||
if(flag&128) *m=_mm_read_UBYTE(modreader);
|
||||
if(*m&1)
|
||||
/* convert IT note off to internal note off */
|
||||
if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
|
||||
if((l->note=n->note=_mm_read_UBYTE(modreader))==255)
|
||||
l->note=n->note=253;
|
||||
if(mask[ch]&2)
|
||||
if(*m&2)
|
||||
l->ins=n->ins=_mm_read_UBYTE(modreader);
|
||||
if(mask[ch]&4)
|
||||
if(*m&4)
|
||||
l->volpan=n->volpan=_mm_read_UBYTE(modreader);
|
||||
if(mask[ch]&8) {
|
||||
if(*m&8) {
|
||||
l->cmd=n->cmd=_mm_read_UBYTE(modreader);
|
||||
l->inf=n->inf=_mm_read_UBYTE(modreader);
|
||||
}
|
||||
if(mask[ch]&16)
|
||||
if(*m&16)
|
||||
n->note=l->note;
|
||||
if(mask[ch]&32)
|
||||
if(*m&32)
|
||||
n->ins=l->ins;
|
||||
if(mask[ch]&64)
|
||||
if(*m&64)
|
||||
n->volpan=l->volpan;
|
||||
if(mask[ch]&128) {
|
||||
if(*m&128) {
|
||||
n->cmd=l->cmd;
|
||||
n->inf=l->inf;
|
||||
}
|
||||
|
@ -379,38 +399,39 @@ static int IT_ReadPattern(UWORD patrows)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void LoadMidiString(MREADER* modreader,CHAR* dest)
|
||||
static void LoadMidiString(MREADER* r,CHAR* dest)
|
||||
{
|
||||
CHAR *cur,*last;
|
||||
CHAR *curp,*lastp;
|
||||
|
||||
_mm_read_UBYTES(dest,32,modreader);
|
||||
cur=last=dest;
|
||||
memset(dest,0,33*sizeof(CHAR));/* caller sends midiline[33] */
|
||||
_mm_read_UBYTES(dest,32,r);
|
||||
curp=lastp=dest;
|
||||
/* remove blanks and uppercase all */
|
||||
while(*last) {
|
||||
if(isalnum((int)*last)) *(cur++)=toupper((int)*last);
|
||||
last++;
|
||||
while(*lastp) {
|
||||
if(isalnum((int)*lastp)) *(curp++)=toupper((int)*lastp);
|
||||
lastp++;
|
||||
}
|
||||
*cur=0;
|
||||
*curp=0;
|
||||
}
|
||||
|
||||
/* Load embedded midi information for resonant filters */
|
||||
static void IT_LoadMidiConfiguration(MREADER* modreader)
|
||||
static void IT_LoadMidiConfiguration(MREADER* r)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(filtermacros,0,sizeof(filtermacros));
|
||||
memset(filtersettings,0,sizeof(filtersettings));
|
||||
|
||||
if (modreader) { /* information is embedded in file */
|
||||
if (r) { /* information is embedded in file */
|
||||
UWORD dat;
|
||||
CHAR midiline[33];
|
||||
|
||||
dat=_mm_read_I_UWORD(modreader);
|
||||
_mm_fseek(modreader,8*dat+0x120,SEEK_CUR);
|
||||
dat=_mm_read_I_UWORD(r);
|
||||
_mm_fseek(r,8*dat+0x120,SEEK_CUR);
|
||||
|
||||
/* read midi macros */
|
||||
for(i=0;i<UF_MAXMACRO;i++) {
|
||||
LoadMidiString(modreader,midiline);
|
||||
LoadMidiString(r,midiline);
|
||||
if((!strncmp(midiline,"F0F00",5))&&
|
||||
((midiline[5]=='0')||(midiline[5]=='1')))
|
||||
filtermacros[i]=(midiline[5]-'0')|0x80;
|
||||
|
@ -418,7 +439,7 @@ static void IT_LoadMidiConfiguration(MREADER* modreader)
|
|||
|
||||
/* read standalone filters */
|
||||
for(i=0x80;i<0x100;i++) {
|
||||
LoadMidiString(modreader,midiline);
|
||||
LoadMidiString(r,midiline);
|
||||
if((!strncmp(midiline,"F0F00",5))&&
|
||||
((midiline[5]=='0')||(midiline[5]=='1'))) {
|
||||
filtersettings[i].filter=(midiline[5]-'0')|0x80;
|
||||
|
@ -446,7 +467,7 @@ static int IT_Load(int curious)
|
|||
int t,u,lp;
|
||||
INSTRUMENT *d;
|
||||
SAMPLE *q;
|
||||
/* int compressed=0; */
|
||||
/*int compressed=0;*/
|
||||
|
||||
numtrk=0;
|
||||
filters=0;
|
||||
|
@ -479,6 +500,10 @@ static int IT_Load(int curious)
|
|||
_mm_errno=MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
if(mh->ordnum > 256 || mh->insnum > 255 || mh->smpnum > 255 || mh->patnum > 255) {
|
||||
_mm_errno=MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set module variables */
|
||||
of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */
|
||||
|
@ -506,11 +531,11 @@ static int IT_Load(int curious)
|
|||
/* 2.16 : IT 2.14p3 with resonant filters */
|
||||
/* 2.15 : IT 2.14p3 (improved compression) */
|
||||
if((mh->cwt<=0x219)&&(mh->cwt>=0x217))
|
||||
of.modtype=StrDup(IT_Version[mh->cmwt<0x214?4:5]);
|
||||
of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?4:5]);
|
||||
else if (mh->cwt>=0x215)
|
||||
of.modtype=StrDup(IT_Version[mh->cmwt<0x214?2:3]);
|
||||
of.modtype=MikMod_strdup(IT_Version[mh->cmwt<0x214?2:3]);
|
||||
else {
|
||||
of.modtype = StrDup(IT_Version[mh->cmwt<0x214?0:1]);
|
||||
of.modtype = MikMod_strdup(IT_Version[mh->cmwt<0x214?0:1]);
|
||||
of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0';
|
||||
of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0';
|
||||
of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0';
|
||||
|
@ -550,7 +575,7 @@ static int IT_Load(int curious)
|
|||
|
||||
/* read the order data */
|
||||
if(!AllocPositions(mh->ordnum)) return 0;
|
||||
if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
|
||||
if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
|
||||
|
||||
for(t=0;t<mh->ordnum;t++) {
|
||||
origpositions[t]=_mm_read_UBYTE(modreader);
|
||||
|
@ -672,14 +697,14 @@ static int IT_Load(int curious)
|
|||
if(s.flag&2) q->flags|=SF_16BITS;
|
||||
if((s.flag&8)&&(mh->cwt>=0x214)) {
|
||||
q->flags|=SF_ITPACKED;
|
||||
/* compressed=1; */
|
||||
/*compressed=1;*/
|
||||
}
|
||||
if(s.flag&16) q->flags|=SF_LOOP;
|
||||
if(s.flag&64) q->flags|=SF_BIDI;
|
||||
|
||||
if(mh->cwt>=0x200) {
|
||||
if(s.convert&1) q->flags|=SF_SIGNED;
|
||||
if(s.convert&4) q->flags|=SF_DELTA;
|
||||
if(s.convert&4) q->flags|=SF_DELTA;
|
||||
}
|
||||
q++;
|
||||
}
|
||||
|
@ -726,7 +751,7 @@ static int IT_Load(int curious)
|
|||
|
||||
ih.trkvers = _mm_read_I_UWORD(modreader);
|
||||
ih.numsmp = _mm_read_UBYTE(modreader);
|
||||
(void)_mm_read_UBYTE(modreader);
|
||||
_mm_skip_BYTE(modreader);
|
||||
_mm_read_string(ih.name,26,modreader);
|
||||
_mm_read_UBYTES(ih.blank01,6,modreader);
|
||||
_mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader);
|
||||
|
@ -736,13 +761,15 @@ static int IT_Load(int curious)
|
|||
for(lp=0;lp<ITENVCNT;lp++) {
|
||||
ih.oldvoltick[lp] = _mm_read_UBYTE(modreader);
|
||||
ih.volnode[lp] = _mm_read_UBYTE(modreader);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* load IT 2xx volume, pan and pitch envelopes */
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define IT_LoadEnvelope(name,type) \
|
||||
ih. name##flg =_mm_read_UBYTE(modreader); \
|
||||
ih. name##pts =_mm_read_UBYTE(modreader); \
|
||||
if (ih. name##pts > ITENVCNT) \
|
||||
ih. name##pts = ITENVCNT; \
|
||||
ih. name##beg =_mm_read_UBYTE(modreader); \
|
||||
ih. name##end =_mm_read_UBYTE(modreader); \
|
||||
ih. name##susbeg=_mm_read_UBYTE(modreader); \
|
||||
|
@ -751,11 +778,13 @@ static int IT_Load(int curious)
|
|||
ih. name##node[lp]=_mm_read_##type (modreader); \
|
||||
ih. name##tick[lp]=_mm_read_I_UWORD(modreader); \
|
||||
} \
|
||||
(void)_mm_read_UBYTE(modreader)
|
||||
_mm_skip_BYTE(modreader)
|
||||
#else
|
||||
#define IT_LoadEnvelope(name,type) \
|
||||
ih. name/**/flg =_mm_read_UBYTE(modreader); \
|
||||
ih. name/**/pts =_mm_read_UBYTE(modreader); \
|
||||
if (ih. name/**/pts > ITENVCNT) \
|
||||
ih. name/**/pts = ITENVCNT; \
|
||||
ih. name/**/beg =_mm_read_UBYTE(modreader); \
|
||||
ih. name/**/end =_mm_read_UBYTE(modreader); \
|
||||
ih. name/**/susbeg=_mm_read_UBYTE(modreader); \
|
||||
|
@ -764,7 +793,7 @@ static int IT_Load(int curious)
|
|||
ih. name/**/node[lp]=_mm_read_/**/type (modreader); \
|
||||
ih. name/**/tick[lp]=_mm_read_I_UWORD(modreader); \
|
||||
} \
|
||||
(void)_mm_read_UBYTE(modreader)
|
||||
_mm_skip_BYTE(modreader)
|
||||
#endif
|
||||
|
||||
IT_LoadEnvelope(vol,UBYTE);
|
||||
|
@ -772,7 +801,7 @@ static int IT_Load(int curious)
|
|||
IT_LoadEnvelope(pit,SBYTE);
|
||||
#undef IT_LoadEnvelope
|
||||
}
|
||||
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
|
@ -791,10 +820,10 @@ static int IT_Load(int curious)
|
|||
|
||||
if(ih.volflg&1) d->volflg|=EF_ON;
|
||||
if(ih.volflg&2) d->volflg|=EF_LOOP;
|
||||
if(ih.volflg&4) d->volflg|=EF_SUSTAIN;
|
||||
if(ih.volflg&4) d->volflg|=EF_SUSTAIN;
|
||||
|
||||
/* XM conversion of IT envelope Array */
|
||||
d->volbeg = ih.volbeg;
|
||||
d->volbeg = ih.volbeg;
|
||||
d->volend = ih.volend;
|
||||
d->volsusbeg = ih.volsusbeg;
|
||||
d->volsusend = ih.volsusend;
|
||||
|
@ -807,7 +836,7 @@ static int IT_Load(int curious)
|
|||
d->volpts++;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2;
|
||||
if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN;
|
||||
|
@ -827,7 +856,7 @@ static int IT_Load(int curious)
|
|||
d->rpanvar = ih.rpanvar;
|
||||
}
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define IT_ProcessEnvelope(name) \
|
||||
if(ih. name##flg&1) d-> name##flg|=EF_ON; \
|
||||
if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \
|
||||
|
@ -862,11 +891,7 @@ static int IT_Load(int curious)
|
|||
#endif
|
||||
|
||||
IT_ProcessEnvelope(vol);
|
||||
|
||||
// Secunia SA37775
|
||||
if (ih.volpts>= ENVPOINTS)
|
||||
ih.volpts = ENVPOINTS-1;
|
||||
|
||||
|
||||
for(u=0;u<ih.volpts;u++)
|
||||
d->volenv[u].val=(ih.volnode[u]<<2);
|
||||
|
||||
|
@ -887,7 +912,7 @@ static int IT_Load(int curious)
|
|||
#ifdef MIKMOD_DEBUG
|
||||
{
|
||||
static int warn=0;
|
||||
|
||||
|
||||
if(!warn)
|
||||
fprintf(stderr, "\rFilter envelopes not supported yet\n");
|
||||
warn=1;
|
||||
|
@ -908,7 +933,7 @@ static int IT_Load(int curious)
|
|||
}
|
||||
}
|
||||
|
||||
d++;
|
||||
d++;
|
||||
}
|
||||
} else if(of.flags & UF_LINEAR) {
|
||||
if(!AllocInstruments()) return 0;
|
||||
|
@ -946,12 +971,12 @@ static int IT_Load(int curious)
|
|||
return 0;
|
||||
}
|
||||
_mm_read_I_ULONG(modreader);
|
||||
if(IT_GetNumChannels(packlen)) return 0;
|
||||
if(!IT_GetNumChannels(packlen)) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* give each of them a different number */
|
||||
for(t=0;t<UF_MAXCHAN;t++)
|
||||
for(t=0;t<UF_MAXCHAN;t++)
|
||||
if(!remap[t])
|
||||
remap[t]=of.numchn++;
|
||||
|
||||
|
@ -963,6 +988,8 @@ static int IT_Load(int curious)
|
|||
if(!AllocTracks()) return 0;
|
||||
|
||||
for(t=0;t<of.numpat;t++) {
|
||||
UWORD packlen;
|
||||
|
||||
/* seek to pattern position */
|
||||
if(!paraptr[mh->insnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */
|
||||
of.pattrows[t]=64;
|
||||
|
@ -975,7 +1002,8 @@ static int IT_Load(int curious)
|
|||
}
|
||||
} else {
|
||||
_mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET);
|
||||
(void)_mm_read_I_UWORD(modreader);
|
||||
packlen=_mm_read_I_UWORD(modreader);
|
||||
(void)packlen; /* unused */
|
||||
of.pattrows[t]=_mm_read_I_UWORD(modreader);
|
||||
_mm_read_I_ULONG(modreader);
|
||||
if(!IT_ReadPattern(of.pattrows[t])) return 0;
|
||||
|
@ -991,7 +1019,7 @@ static CHAR *IT_LoadTitle(void)
|
|||
|
||||
_mm_fseek(modreader,4,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(s,26,modreader)) return NULL;
|
||||
|
||||
|
||||
return(DupStr(s,26,0));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_m15.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
15 instrument MOD loader
|
||||
Also supports Ultimate Sound Tracker (old M15 format)
|
||||
|
@ -79,33 +79,31 @@ static int ust_loader = 0; /* if TRUE, load as an ust module. */
|
|||
|
||||
/* known file formats which can confuse the loader */
|
||||
#define REJECT 2
|
||||
static char *signatures[REJECT]={
|
||||
static const char *signatures[REJECT]={
|
||||
"CAKEWALK", /* cakewalk midi files */
|
||||
"SZDD" /* Microsoft compressed files */
|
||||
};
|
||||
static int siglen[REJECT]={8,4};
|
||||
static const int siglen[REJECT]={8,4};
|
||||
|
||||
/*========== Loader code */
|
||||
|
||||
static int LoadModuleHeader(MODULEHEADER *mh)
|
||||
static int LoadModuleHeader(MODULEHEADER *h)
|
||||
{
|
||||
int t,u;
|
||||
|
||||
_mm_read_string(mh->songname,20,modreader);
|
||||
mh->songname[20]=0; /* just in case */
|
||||
_mm_read_string(h->songname,20,modreader);
|
||||
|
||||
/* sanity check : title should contain printable characters and a bunch
|
||||
of null chars */
|
||||
for(t=0;t<20;t++)
|
||||
if((mh->songname[t])&&(mh->songname[t]<32)) return 0;
|
||||
for(t=0;(mh->songname[t])&&(t<20);t++);
|
||||
if(t<20) for(;t<20;t++) if(mh->songname[t]) return 0;
|
||||
if((h->songname[t])&&(h->songname[t]<32)) return 0;
|
||||
for(t=0;(h->songname[t])&&(t<20);t++);
|
||||
if(t<20) for(;t<20;t++) if(h->songname[t]) return 0;
|
||||
|
||||
for(t=0;t<15;t++) {
|
||||
MSAMPINFO *s=&mh->samples[t];
|
||||
MSAMPINFO *s=&h->samples[t];
|
||||
|
||||
_mm_read_string(s->samplename,22,modreader);
|
||||
s->samplename[22]=0; /* just in case */
|
||||
s->length =_mm_read_M_UWORD(modreader);
|
||||
s->finetune =_mm_read_UBYTE(modreader);
|
||||
s->volume =_mm_read_UBYTE(modreader);
|
||||
|
@ -123,26 +121,26 @@ static int LoadModuleHeader(MODULEHEADER *mh)
|
|||
if(s->finetune>>4) return 0;
|
||||
}
|
||||
|
||||
mh->songlength =_mm_read_UBYTE(modreader);
|
||||
mh->magic1 =_mm_read_UBYTE(modreader); /* should be 127 */
|
||||
h->songlength =_mm_read_UBYTE(modreader);
|
||||
h->magic1 =_mm_read_UBYTE(modreader); /* should be 127 */
|
||||
|
||||
/* sanity check : no more than 128 positions, restart position in range */
|
||||
if((!mh->songlength)||(mh->songlength>128)) return 0;
|
||||
if((!h->songlength)||(h->songlength>128)) return 0;
|
||||
/* values encountered so far are 0x6a and 0x78 */
|
||||
if(((mh->magic1&0xf8)!=0x78)&&(mh->magic1!=0x6a)&&(mh->magic1>mh->songlength)) return 0;
|
||||
if(((h->magic1&0xf8)!=0x78)&&(h->magic1!=0x6a)&&(h->magic1>h->songlength)) return 0;
|
||||
|
||||
_mm_read_UBYTES(mh->positions,128,modreader);
|
||||
_mm_read_UBYTES(h->positions,128,modreader);
|
||||
|
||||
/* sanity check : pattern range is 0..63 */
|
||||
for(t=0;t<128;t++)
|
||||
if(mh->positions[t]>63) return 0;
|
||||
if(h->positions[t]>63) return 0;
|
||||
|
||||
return(!_mm_eof(modreader));
|
||||
}
|
||||
|
||||
/* Checks the patterns in the modfile for UST / 15-inst indications.
|
||||
For example, if an effect 3xx is found, it is assumed that the song
|
||||
is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST.
|
||||
For example, if an effect 3xx is found, it is assumed that the song
|
||||
is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST.
|
||||
|
||||
Returns: 0 indecisive; 1 = UST; 2 = 15-inst */
|
||||
static int CheckPatternType(int numpat)
|
||||
|
@ -152,7 +150,7 @@ static int CheckPatternType(int numpat)
|
|||
|
||||
for(t=0;t<numpat*(64U*4);t++) {
|
||||
/* Load the pattern into the temp buffer and scan it */
|
||||
(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);
|
||||
_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);
|
||||
eff = _mm_read_UBYTE(modreader);
|
||||
dat = _mm_read_UBYTE(modreader);
|
||||
|
||||
|
@ -177,55 +175,56 @@ static int CheckPatternType(int numpat)
|
|||
static int M15_Test(void)
|
||||
{
|
||||
int t, numpat;
|
||||
MODULEHEADER mh;
|
||||
MODULEHEADER h;
|
||||
|
||||
ust_loader = 0;
|
||||
if(!LoadModuleHeader(&mh)) return 0;
|
||||
memset(&h, 0, sizeof(MODULEHEADER));
|
||||
if(!LoadModuleHeader(&h)) return 0;
|
||||
|
||||
/* reject other file types */
|
||||
for(t=0;t<REJECT;t++)
|
||||
if(!memcmp(mh.songname,signatures[t],siglen[t])) return 0;
|
||||
if(!memcmp(h.songname,signatures[t],siglen[t])) return 0;
|
||||
|
||||
if(mh.magic1>127) return 0;
|
||||
if((!mh.songlength)||(mh.songlength>mh.magic1)) return 0;
|
||||
if(h.magic1>127) return 0;
|
||||
if((!h.songlength)||(h.songlength>h.magic1)) return 0;
|
||||
|
||||
for(t=0;t<15;t++) {
|
||||
/* all finetunes should be zero */
|
||||
if(mh.samples[t].finetune) return 0;
|
||||
if(h.samples[t].finetune) return 0;
|
||||
|
||||
/* all volumes should be <= 64 */
|
||||
if(mh.samples[t].volume>64) return 0;
|
||||
if(h.samples[t].volume>64) return 0;
|
||||
|
||||
/* all instrument names should begin with s, st-, or a number */
|
||||
if((mh.samples[t].samplename[0]=='s')||
|
||||
(mh.samples[t].samplename[0]=='S')) {
|
||||
if((memcmp(mh.samples[t].samplename,"st-",3)) &&
|
||||
(memcmp(mh.samples[t].samplename,"ST-",3)) &&
|
||||
(*mh.samples[t].samplename))
|
||||
if((h.samples[t].samplename[0]=='s')||
|
||||
(h.samples[t].samplename[0]=='S')) {
|
||||
if((memcmp(h.samples[t].samplename,"st-",3)) &&
|
||||
(memcmp(h.samples[t].samplename,"ST-",3)) &&
|
||||
(*h.samples[t].samplename))
|
||||
ust_loader = 1;
|
||||
} else
|
||||
if(!isdigit((int)mh.samples[t].samplename[0]))
|
||||
if(!isdigit((int)h.samples[t].samplename[0]))
|
||||
ust_loader = 1;
|
||||
|
||||
if(mh.samples[t].length>4999||mh.samples[t].reppos>9999) {
|
||||
if(h.samples[t].length>4999||h.samples[t].reppos>9999) {
|
||||
ust_loader = 0;
|
||||
if(mh.samples[t].length>32768) return 0;
|
||||
if(h.samples[t].length>32768) return 0;
|
||||
}
|
||||
|
||||
/* if loop information is incorrect as words, but correct as bytes,
|
||||
this is likely to be an ust-style module */
|
||||
if((mh.samples[t].reppos+mh.samples[t].replen>mh.samples[t].length)&&
|
||||
(mh.samples[t].reppos+mh.samples[t].replen<(mh.samples[t].length<<1))){
|
||||
if((h.samples[t].reppos+h.samples[t].replen>h.samples[t].length)&&
|
||||
(h.samples[t].reppos+h.samples[t].replen<(h.samples[t].length<<1))) {
|
||||
ust_loader = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!ust_loader) return 1;
|
||||
if(!ust_loader) return 1;
|
||||
}
|
||||
|
||||
for(numpat=0,t=0;t<mh.songlength;t++)
|
||||
if(mh.positions[t]>numpat)
|
||||
numpat = mh.positions[t];
|
||||
for(numpat=0,t=0;t<h.songlength;t++)
|
||||
if(h.positions[t]>numpat)
|
||||
numpat = h.positions[t];
|
||||
numpat++;
|
||||
switch(CheckPatternType(numpat)) {
|
||||
case 0: /* indecisive, so check more clues... */
|
||||
|
@ -242,7 +241,7 @@ static int M15_Test(void)
|
|||
|
||||
static int M15_Init(void)
|
||||
{
|
||||
if(!(mh=(MODULEHEADER*)MikMod_malloc(sizeof(MODULEHEADER)))) return 0;
|
||||
if(!(mh=(MODULEHEADER*)MikMod_calloc(1,sizeof(MODULEHEADER)))) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -250,6 +249,8 @@ static void M15_Cleanup(void)
|
|||
{
|
||||
MikMod_free(mh);
|
||||
MikMod_free(patbuf);
|
||||
mh=NULL;
|
||||
patbuf=NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -331,7 +332,7 @@ static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect)
|
|||
case 1:
|
||||
UniPTEffect(0,effdat);
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
if(effdat&0xf) UniPTEffect(1,effdat&0xf);
|
||||
else if(effdat>>2) UniPTEffect(2,effdat>>2);
|
||||
break;
|
||||
|
@ -351,7 +352,7 @@ static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect)
|
|||
}
|
||||
if (effect == 8)
|
||||
of.flags |= UF_PANNING;
|
||||
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
@ -372,8 +373,7 @@ static UBYTE *M15_ConvertTrack(MODNOTE* n)
|
|||
/* Loads all patterns of a modfile and converts them into the 3 byte format. */
|
||||
static int M15_LoadPatterns(void)
|
||||
{
|
||||
int t,tracks=0;
|
||||
unsigned int s;
|
||||
unsigned int t,s,tracks=0;
|
||||
|
||||
if(!AllocPatterns()) return 0;
|
||||
if(!AllocTracks()) return 0;
|
||||
|
@ -398,9 +398,10 @@ static int M15_LoadPatterns(void)
|
|||
|
||||
static int M15_Load(int curious)
|
||||
{
|
||||
int t,scan;
|
||||
unsigned int t,scan;
|
||||
SAMPLE *q;
|
||||
MSAMPINFO *s;
|
||||
(void)curious;
|
||||
|
||||
/* try to read module header */
|
||||
if(!LoadModuleHeader(mh)) {
|
||||
|
@ -409,14 +410,14 @@ static int M15_Load(int curious)
|
|||
}
|
||||
|
||||
if(ust_loader)
|
||||
of.modtype = StrDup("Ultimate Soundtracker");
|
||||
of.modtype = MikMod_strdup("Ultimate Soundtracker");
|
||||
else
|
||||
of.modtype = StrDup("Soundtracker");
|
||||
of.modtype = MikMod_strdup("Soundtracker");
|
||||
|
||||
/* set module variables */
|
||||
of.initspeed = 6;
|
||||
of.inittempo = 125;
|
||||
of.numchn = 4;
|
||||
of.numchn = 4;
|
||||
of.songname = DupStr(mh->songname,21,1);
|
||||
of.numpos = mh->songlength;
|
||||
of.reppos = 0;
|
||||
|
@ -467,7 +468,7 @@ static int M15_Load(int curious)
|
|||
q->length = s->length<<1;
|
||||
|
||||
q->flags = SF_SIGNED;
|
||||
if(ust_loader) q->flags |= SF_UST_LOOP;
|
||||
if(ust_loader) q->flags |= SF_UST_LOOP;
|
||||
if(s->replen>2) q->flags |= SF_LOOP;
|
||||
|
||||
s++;
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_med.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Amiga MED module loader
|
||||
|
||||
|
@ -189,6 +189,12 @@ static void MED_Cleanup(void)
|
|||
MikMod_free(ba);
|
||||
MikMod_free(mmd0pat);
|
||||
MikMod_free(mmd1pat);
|
||||
me = NULL;
|
||||
mh = NULL;
|
||||
ms = NULL;
|
||||
ba = NULL;
|
||||
mmd0pat = NULL;
|
||||
mmd1pat = NULL;
|
||||
}
|
||||
|
||||
static void EffectCvt(UBYTE eff, UBYTE dat)
|
||||
|
@ -338,7 +344,13 @@ static int LoadMEDPatterns(void)
|
|||
of.numchn = numtracks;
|
||||
if (numlines > maxlines)
|
||||
maxlines = numlines;
|
||||
/* sanity check */
|
||||
if (numtracks > 64)
|
||||
return 0;
|
||||
}
|
||||
/* sanity check */
|
||||
if (! of.numchn) /* docs say 4, 8, 12 or 16 */
|
||||
return 0;
|
||||
|
||||
of.numtrk = of.numpat * of.numchn;
|
||||
if (!AllocTracks())
|
||||
|
@ -346,10 +358,8 @@ static int LoadMEDPatterns(void)
|
|||
if (!AllocPatterns())
|
||||
return 0;
|
||||
|
||||
if (!
|
||||
(mmd0pat =
|
||||
(MMD0NOTE *)MikMod_calloc(of.numchn * (maxlines + 1),
|
||||
sizeof(MMD0NOTE)))) return 0;
|
||||
if (!(mmd0pat = (MMD0NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), sizeof(MMD0NOTE))))
|
||||
return 0;
|
||||
|
||||
/* second read: read and convert patterns */
|
||||
for (t = 0; t < of.numpat; t++) {
|
||||
|
@ -388,7 +398,15 @@ static int LoadMMD1Patterns(void)
|
|||
of.numchn = numtracks;
|
||||
if (numlines > maxlines)
|
||||
maxlines = numlines;
|
||||
/* sanity check */
|
||||
if (numtracks > 64)
|
||||
return 0;
|
||||
if (numlines >= 3200) /* per docs */
|
||||
return 0;
|
||||
}
|
||||
/* sanity check */
|
||||
if (! of.numchn) /* docs say 4, 8, 12 or 16 */
|
||||
return 0;
|
||||
|
||||
of.numtrk = of.numpat * of.numchn;
|
||||
if (!AllocTracks())
|
||||
|
@ -396,10 +414,8 @@ static int LoadMMD1Patterns(void)
|
|||
if (!AllocPatterns())
|
||||
return 0;
|
||||
|
||||
if (!
|
||||
(mmd1pat =
|
||||
(MMD1NOTE *)MikMod_calloc(of.numchn * (maxlines + 1),
|
||||
sizeof(MMD1NOTE)))) return 0;
|
||||
if (!(mmd1pat = (MMD1NOTE *)MikMod_calloc(of.numchn * (maxlines + 1), sizeof(MMD1NOTE))))
|
||||
return 0;
|
||||
|
||||
/* second read: really read and convert patterns */
|
||||
for (t = 0; t < of.numpat; t++) {
|
||||
|
@ -471,6 +487,11 @@ static int MED_Load(int curious)
|
|||
ms->numblocks = _mm_read_M_UWORD(modreader);
|
||||
ms->songlen = _mm_read_M_UWORD(modreader);
|
||||
_mm_read_UBYTES(ms->playseq, 256, modreader);
|
||||
/* sanity check */
|
||||
if (ms->numblocks > 255 || ms->songlen > 256) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
ms->deftempo = _mm_read_M_UWORD(modreader);
|
||||
ms->playtransp = _mm_read_SBYTE(modreader);
|
||||
ms->flags = _mm_read_UBYTE(modreader);
|
||||
|
@ -479,6 +500,11 @@ static int MED_Load(int curious)
|
|||
_mm_read_UBYTES(ms->trkvol, 16, modreader);
|
||||
ms->mastervol = _mm_read_UBYTE(modreader);
|
||||
ms->numsamples = _mm_read_UBYTE(modreader);
|
||||
/* sanity check */
|
||||
if (ms->numsamples > 64) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for a bad header */
|
||||
if (_mm_eof(modreader)) {
|
||||
|
@ -505,6 +531,14 @@ static int MED_Load(int curious)
|
|||
me->songname = _mm_read_M_ULONG(modreader);
|
||||
me->songnamelen = _mm_read_M_ULONG(modreader);
|
||||
me->dumps = _mm_read_M_ULONG(modreader);
|
||||
/* sanity check */
|
||||
if (me->annolen > 0xffff) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
/* truncate insane songnamelen (fail instead??) */
|
||||
if (me->songnamelen > 256)
|
||||
me->songnamelen = 256;
|
||||
}
|
||||
|
||||
/* seek to and read the samplepointer array */
|
||||
|
@ -526,8 +560,14 @@ static int MED_Load(int curious)
|
|||
/* copy song positions */
|
||||
if (!AllocPositions(ms->songlen))
|
||||
return 0;
|
||||
for (t = 0; t < ms->songlen; t++)
|
||||
for (t = 0; t < ms->songlen; t++) {
|
||||
of.positions[t] = ms->playseq[t];
|
||||
if (of.positions[t]>ms->numblocks) { /* SANITIY CHECK */
|
||||
/* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],ms->numblocks);*/
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
decimalvolumes = (ms->flags & 0x10) ? 0 : 1;
|
||||
bpmtempos = (ms->flags2 & 0x20) ? 1 : 0;
|
||||
|
@ -571,7 +611,7 @@ static int MED_Load(int curious)
|
|||
of.flags |= UF_HIGHBPM;
|
||||
}
|
||||
MED_Version[12] = mh->id;
|
||||
of.modtype = StrDup(MED_Version);
|
||||
of.modtype = MikMod_strdup(MED_Version);
|
||||
of.numchn = 0; /* will be counted later */
|
||||
of.numpat = ms->numblocks;
|
||||
of.numpos = ms->songlen;
|
||||
|
@ -582,7 +622,7 @@ static int MED_Load(int curious)
|
|||
char *name;
|
||||
|
||||
_mm_fseek(modreader, me->songname, SEEK_SET);
|
||||
name = MikMod_malloc(me->songnamelen);
|
||||
name = (char *) MikMod_malloc(me->songnamelen);
|
||||
_mm_read_UBYTES(name, me->songnamelen, modreader);
|
||||
of.songname = DupStr(name, me->songnamelen, 1);
|
||||
MikMod_free(name);
|
||||
|
@ -684,17 +724,17 @@ static CHAR *MED_LoadTitle(void)
|
|||
{
|
||||
ULONG posit, namelen;
|
||||
CHAR *name, *retvalue = NULL;
|
||||
|
||||
|
||||
_mm_fseek(modreader, 0x20, SEEK_SET);
|
||||
posit = _mm_read_M_ULONG(modreader);
|
||||
|
||||
|
||||
if (posit) {
|
||||
_mm_fseek(modreader, posit + 0x2C, SEEK_SET);
|
||||
posit = _mm_read_M_ULONG(modreader);
|
||||
namelen = _mm_read_M_ULONG(modreader);
|
||||
|
||||
_mm_fseek(modreader, posit, SEEK_SET);
|
||||
name = MikMod_malloc(namelen);
|
||||
name = (CHAR*) MikMod_malloc(namelen);
|
||||
_mm_read_UBYTES(name, namelen, modreader);
|
||||
retvalue = DupStr(name, namelen, 1);
|
||||
MikMod_free(name);
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_mod.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Generic MOD loader (Protracker, StarTracker, FastTracker, etc)
|
||||
|
||||
|
@ -108,7 +108,7 @@ static int MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr)
|
|||
*numchn = 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Star Tracker */
|
||||
if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) &&
|
||||
(isdigit(id[3]))) {
|
||||
|
@ -190,6 +190,8 @@ static void MOD_Cleanup(void)
|
|||
{
|
||||
MikMod_free(mh);
|
||||
MikMod_free(patbuf);
|
||||
mh=NULL;
|
||||
patbuf=NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -277,7 +279,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
|
|||
/* Handle ``heavy'' volumes correctly */
|
||||
if ((effect == 0xc) && (effdat > 0x40))
|
||||
effdat = 0x40;
|
||||
|
||||
|
||||
/* An isolated 100, 200 or 300 effect should be ignored (no
|
||||
"standalone" porta memory in mod files). However, a sequence such
|
||||
as 1XX, 100, 100, 100 is fine. */
|
||||
|
@ -288,7 +290,7 @@ static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect)
|
|||
UniPTEffect(effect, effdat);
|
||||
if (effect == 8)
|
||||
of.flags |= UF_PANNING;
|
||||
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
@ -309,14 +311,13 @@ static UBYTE *ConvertTrack(MODNOTE *n, int numchn)
|
|||
/* Loads all patterns of a modfile and converts them into the 3 byte format. */
|
||||
static int ML_LoadPatterns(void)
|
||||
{
|
||||
int t, tracks = 0;
|
||||
unsigned int s;
|
||||
unsigned int t, s, tracks = 0;
|
||||
|
||||
if (!AllocPatterns())
|
||||
return 0;
|
||||
if (!AllocTracks())
|
||||
return 0;
|
||||
|
||||
|
||||
/* Allocate temporary buffer for loading and converting the patterns */
|
||||
if (!(patbuf = (MODNOTE *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE))))
|
||||
return 0;
|
||||
|
@ -385,10 +386,10 @@ static int MOD_Load(int curious)
|
|||
|
||||
mh->songlength = _mm_read_UBYTE(modreader);
|
||||
|
||||
/* this fixes mods which declare more than 128 positions.
|
||||
/* this fixes mods which declare more than 128 positions.
|
||||
* eg: beatwave.mod */
|
||||
if (mh->songlength > 128) { mh->songlength = 128; }
|
||||
|
||||
|
||||
mh->magic1 = _mm_read_UBYTE(modreader);
|
||||
_mm_read_UBYTES(mh->positions, 128, modreader);
|
||||
_mm_read_UBYTES(mh->magic2, 4, modreader);
|
||||
|
@ -477,11 +478,11 @@ static int MOD_Load(int curious)
|
|||
q++;
|
||||
}
|
||||
|
||||
of.modtype = StrDup(descr);
|
||||
of.modtype = MikMod_strdup(descr);
|
||||
|
||||
if (!ML_LoadPatterns())
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_mtm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
MTM module loader
|
||||
|
||||
|
@ -108,6 +108,8 @@ static void MTM_Cleanup(void)
|
|||
{
|
||||
MikMod_free(mtmtrk);
|
||||
MikMod_free(mh);
|
||||
mtmtrk=NULL;
|
||||
mh=NULL;
|
||||
}
|
||||
|
||||
static UBYTE* MTM_Convert(void)
|
||||
|
@ -145,7 +147,7 @@ static int MTM_Load(int curious)
|
|||
int t,u;
|
||||
MTMSAMPLE s;
|
||||
SAMPLE *q;
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* try to read module header */
|
||||
_mm_read_UBYTES(mh->id,3,modreader);
|
||||
|
@ -169,7 +171,7 @@ static int MTM_Load(int curious)
|
|||
/* set module variables */
|
||||
of.initspeed = 6;
|
||||
of.inittempo = 125;
|
||||
of.modtype = StrDup(MTM_Version);
|
||||
of.modtype = MikMod_strdup(MTM_Version);
|
||||
of.numchn = mh->numchannels;
|
||||
of.numtrk = mh->numtracks+1; /* get number of channels */
|
||||
of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */
|
||||
|
@ -193,7 +195,7 @@ static int MTM_Load(int curious)
|
|||
s.attribute =_mm_read_UBYTE(modreader);
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -218,9 +220,15 @@ static int MTM_Load(int curious)
|
|||
}
|
||||
|
||||
if(!AllocPositions(of.numpos)) return 0;
|
||||
for(t=0;t<of.numpos;t++)
|
||||
for(t=0;t<of.numpos;t++) {
|
||||
of.positions[t]=_mm_read_UBYTE(modreader);
|
||||
for(;t<128;t++) (void)_mm_read_UBYTE(modreader);
|
||||
if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
|
||||
/* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(;t<128;t++) _mm_skip_BYTE(modreader);
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
|
@ -231,12 +239,12 @@ static int MTM_Load(int curious)
|
|||
|
||||
of.tracks[0]=MTM_Convert(); /* track 0 is empty */
|
||||
for(t=1;t<of.numtrk;t++) {
|
||||
int s;
|
||||
int s_idx;
|
||||
|
||||
for(s=0;s<64;s++) {
|
||||
mtmtrk[s].a=_mm_read_UBYTE(modreader);
|
||||
mtmtrk[s].b=_mm_read_UBYTE(modreader);
|
||||
mtmtrk[s].c=_mm_read_UBYTE(modreader);
|
||||
for(s_idx=0;s_idx<64;s_idx++) {
|
||||
mtmtrk[s_idx].a=_mm_read_UBYTE(modreader);
|
||||
mtmtrk[s_idx].b=_mm_read_UBYTE(modreader);
|
||||
mtmtrk[s_idx].c=_mm_read_UBYTE(modreader);
|
||||
}
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_okt.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Oktalyzer (OKT) module loader
|
||||
|
||||
|
@ -203,7 +203,7 @@ static int OKT_doSAMP(int len)
|
|||
s.len = _mm_read_M_ULONG(modreader);
|
||||
s.loopbeg = _mm_read_M_UWORD(modreader) * 2;
|
||||
s.looplen = _mm_read_M_UWORD(modreader) * 2;
|
||||
(void)_mm_read_UBYTE(modreader);
|
||||
_mm_skip_BYTE(modreader);
|
||||
s.volume = _mm_read_UBYTE(modreader);
|
||||
_mm_read_M_UWORD(modreader);
|
||||
|
||||
|
@ -314,6 +314,7 @@ static int OKT_doPBOD(int patnum)
|
|||
}
|
||||
MikMod_free(patbuf);
|
||||
MikMod_free(okttrk);
|
||||
okttrk = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -330,28 +331,28 @@ static int OKT_Load(int curious)
|
|||
int seen_cmod = 0, seen_samp = 0, seen_slen = 0, seen_plen = 0, seen_patt
|
||||
= 0, seen_spee = 0;
|
||||
int patnum = 0, insnum = 0;
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* skip OKTALYZER header */
|
||||
_mm_fseek(modreader, 8, SEEK_SET);
|
||||
of.songname = StrDup("");
|
||||
of.songname = MikMod_strdup("");
|
||||
|
||||
of.modtype = StrDup("Amiga Oktalyzer");
|
||||
of.modtype = MikMod_strdup("Amiga Oktalyzer");
|
||||
of.numpos = of.reppos = 0;
|
||||
|
||||
|
||||
/* default values */
|
||||
of.initspeed = 6;
|
||||
of.inittempo = 125;
|
||||
|
||||
|
||||
while (1) {
|
||||
/* read block header */
|
||||
_mm_read_UBYTES(id, 4, modreader);
|
||||
len = _mm_read_M_ULONG(modreader);
|
||||
|
||||
|
||||
if (_mm_eof(modreader))
|
||||
break;
|
||||
fp = _mm_ftell(modreader);
|
||||
|
||||
|
||||
if (!memcmp(id, "CMOD", 4)) {
|
||||
if (!seen_cmod) {
|
||||
OKT_doCMOD();
|
||||
|
@ -442,7 +443,7 @@ static int OKT_Load(int curious)
|
|||
|
||||
static CHAR *OKT_LoadTitle(void)
|
||||
{
|
||||
return StrDup("");
|
||||
return MikMod_strdup("");
|
||||
}
|
||||
|
||||
/*========== Loader information */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_s3m.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Screamtracker (S3M) module loader
|
||||
|
||||
|
@ -104,7 +104,7 @@ static unsigned int tracker; /* tracker id */
|
|||
|
||||
/* tracker identifiers */
|
||||
#define NUMTRACKERS 4
|
||||
static CHAR* S3M_Version[] = {
|
||||
static const CHAR * S3M_Version[] = {
|
||||
"Screamtracker x.xx",
|
||||
"Imago Orpheus x.xx (S3M format)",
|
||||
"Impulse Tracker x.xx (S3M format)",
|
||||
|
@ -113,7 +113,7 @@ static CHAR* S3M_Version[] = {
|
|||
"Impulse Tracker 2.14p4 (S3M format)"
|
||||
};
|
||||
/* version number position in above array */
|
||||
static int numeric[NUMTRACKERS]={14,14,16,16};
|
||||
static const int numeric[NUMTRACKERS]={14,14,16,16};
|
||||
|
||||
/*========== Loader code */
|
||||
|
||||
|
@ -144,6 +144,11 @@ static void S3M_Cleanup(void)
|
|||
MikMod_free(poslookup);
|
||||
MikMod_free(mh);
|
||||
MikMod_free(origpositions);
|
||||
s3mbuf=NULL;
|
||||
paraptr=NULL;
|
||||
poslookup=NULL;
|
||||
mh=NULL;
|
||||
origpositions=NULL;
|
||||
}
|
||||
|
||||
/* Because so many s3m files have 16 channels as the set number used, but really
|
||||
|
@ -154,9 +159,9 @@ static void S3M_Cleanup(void)
|
|||
global variable 'remap'
|
||||
|
||||
NOTE: You must first seek to the file location of the pattern before calling
|
||||
this procedure.
|
||||
this procedure.
|
||||
|
||||
Returns 1 on fail. */
|
||||
Returns 0 on fail. */
|
||||
static int S3M_GetNumChannels(void)
|
||||
{
|
||||
int row=0,flag,ch;
|
||||
|
@ -166,19 +171,19 @@ static int S3M_GetNumChannels(void)
|
|||
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_PATTERN;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(flag) {
|
||||
ch=flag&31;
|
||||
if(mh->channels[ch]<32) remap[ch] = 0;
|
||||
if(flag&32) {(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);}
|
||||
if(flag&64) (void)_mm_read_UBYTE(modreader);
|
||||
if(flag&128){(void)_mm_read_UBYTE(modreader);(void)_mm_read_UBYTE(modreader);}
|
||||
if(flag&32) {_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
|
||||
if(flag&64) _mm_skip_BYTE(modreader);
|
||||
if(flag&128){_mm_skip_BYTE(modreader);_mm_skip_BYTE(modreader);}
|
||||
} else row++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int S3M_ReadPattern(void)
|
||||
{
|
||||
|
@ -282,6 +287,10 @@ static int S3M_Load(int curious)
|
|||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
if(mh->ordnum > 255 || mh->insnum > 255 || mh->patnum > 255) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* then we can decide the module type */
|
||||
tracker=mh->tracker>>12;
|
||||
|
@ -294,7 +303,7 @@ static int S3M_Load(int curious)
|
|||
tracker=NUMTRACKERS; /* IT 2.14p3 */
|
||||
else tracker--;
|
||||
}
|
||||
of.modtype = StrDup(S3M_Version[tracker]);
|
||||
of.modtype = MikMod_strdup(S3M_Version[tracker]);
|
||||
if(tracker<NUMTRACKERS) {
|
||||
of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0';
|
||||
of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0';
|
||||
|
@ -315,7 +324,7 @@ static int S3M_Load(int curious)
|
|||
|
||||
/* read the order data */
|
||||
if(!AllocPositions(mh->ordnum)) return 0;
|
||||
if(!(origpositions=MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
|
||||
if(!(origpositions=(UWORD*)MikMod_calloc(mh->ordnum,sizeof(UWORD)))) return 0;
|
||||
|
||||
for(t=0;t<mh->ordnum;t++) {
|
||||
origpositions[t]=_mm_read_UBYTE(modreader);
|
||||
|
@ -374,7 +383,8 @@ static int S3M_Load(int curious)
|
|||
_mm_read_string(s.scrs,4,modreader);
|
||||
|
||||
/* ScreamTracker imposes a 64000 bytes (not 64k !) limit */
|
||||
if (s.length > 64000)
|
||||
/* enforce it, if we'll use S3MIT_SCREAM in S3M_ConvertTrack() */
|
||||
if (s.length > 64000 && tracker == 1)
|
||||
s.length = 64000;
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
|
@ -388,7 +398,7 @@ static int S3M_Load(int curious)
|
|||
q->loopstart = s.loopbeg;
|
||||
q->loopend = s.loopend;
|
||||
q->volume = s.volume;
|
||||
q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4;
|
||||
q->seekpos = (((ULONG)s.memsegh)<<16|s.memsegl)<<4;
|
||||
|
||||
if(s.flags&1) q->flags |= SF_LOOP;
|
||||
if(s.flags&4) q->flags |= SF_16BITS;
|
||||
|
@ -406,16 +416,16 @@ static int S3M_Load(int curious)
|
|||
for(t=0;t<of.numpat;t++) {
|
||||
/* seek to pattern position (+2 skip pattern length) */
|
||||
_mm_fseek(modreader,(long)((paraptr[of.numins+t])<<4)+2,SEEK_SET);
|
||||
if(S3M_GetNumChannels()) return 0;
|
||||
if(!S3M_GetNumChannels()) return 0;
|
||||
}
|
||||
|
||||
/* build the remap array */
|
||||
for(t=0;t<32;t++)
|
||||
if(!remap[t])
|
||||
if(!remap[t])
|
||||
remap[t]=of.numchn++;
|
||||
|
||||
/* set panning positions after building remap chart! */
|
||||
for(t=0;t<32;t++)
|
||||
for(t=0;t<32;t++)
|
||||
if((mh->channels[t]<32)&&(remap[t]!=-1)) {
|
||||
if(mh->channels[t]<8)
|
||||
of.panning[remap[t]]=0x30;
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_stm.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Screamtracker 2 (STM) module loader
|
||||
|
||||
|
@ -74,7 +74,7 @@ typedef struct STMHEADER {
|
|||
UBYTE ver_minor;
|
||||
UBYTE inittempo; /* initspeed= stm inittempo>>4 */
|
||||
UBYTE numpat; /* number of patterns */
|
||||
UBYTE globalvol;
|
||||
UBYTE globalvol;
|
||||
UBYTE reserved[13];
|
||||
STMSAMPLE sample[31]; /* STM sample data */
|
||||
UBYTE patorder[128]; /* Docs say 64 - actually 128 */
|
||||
|
@ -90,7 +90,7 @@ static STMNOTE *stmbuf = NULL;
|
|||
static STMHEADER *mh = NULL;
|
||||
|
||||
/* tracker identifiers */
|
||||
static CHAR* STM_Version[STM_NTRACKERS] = {
|
||||
static const CHAR * STM_Version[STM_NTRACKERS] = {
|
||||
"Screamtracker 2",
|
||||
"Converted by MOD2STM (STM format)",
|
||||
"Wuzamod (STM format)"
|
||||
|
@ -103,6 +103,7 @@ static int STM_Test(void)
|
|||
UBYTE str[44];
|
||||
int t;
|
||||
|
||||
memset(str,0,44);
|
||||
_mm_fseek(modreader,20,SEEK_SET);
|
||||
_mm_read_UBYTES(str,44,modreader);
|
||||
if(str[9]!=2) return 0; /* STM Module = filetype 2 */
|
||||
|
@ -110,7 +111,7 @@ static int STM_Test(void)
|
|||
/* Prevent false positives for S3M files */
|
||||
if(!memcmp(str+40,"SCRM",4))
|
||||
return 0;
|
||||
|
||||
|
||||
for (t=0;t<STM_NTRACKERS;t++)
|
||||
if(!memcmp(str,STM_Signatures[t],8))
|
||||
return 1;
|
||||
|
@ -130,6 +131,8 @@ static void STM_Cleanup(void)
|
|||
{
|
||||
MikMod_free(mh);
|
||||
MikMod_free(stmbuf);
|
||||
mh=NULL;
|
||||
stmbuf=NULL;
|
||||
}
|
||||
|
||||
static void STM_ConvertNote(STMNOTE *n)
|
||||
|
@ -145,7 +148,7 @@ static void STM_ConvertNote(STMNOTE *n)
|
|||
|
||||
if((ins)&&(ins<32)) UniInstrument(ins-1);
|
||||
|
||||
/* special values of [SBYTE0] are handled here
|
||||
/* special values of [SBYTE0] are handled here
|
||||
we have no idea if these strange values will ever be encountered.
|
||||
but it appears as those stms sound correct. */
|
||||
if((note==254)||(note==252)) {
|
||||
|
@ -224,8 +227,7 @@ static UBYTE *STM_ConvertTrack(STMNOTE *n)
|
|||
|
||||
static int STM_LoadPatterns(void)
|
||||
{
|
||||
int t,tracks=0;
|
||||
unsigned int s;
|
||||
unsigned int t,s,tracks=0;
|
||||
|
||||
if(!AllocPatterns()) return 0;
|
||||
if(!AllocTracks()) return 0;
|
||||
|
@ -252,10 +254,10 @@ static int STM_LoadPatterns(void)
|
|||
|
||||
static int STM_Load(int curious)
|
||||
{
|
||||
int t;
|
||||
int t;
|
||||
ULONG MikMod_ISA; /* We must generate our own ISA, it's not stored in stm */
|
||||
SAMPLE *q;
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* try to read stm header */
|
||||
_mm_read_string(mh->songname,20,modreader);
|
||||
|
@ -272,6 +274,10 @@ static int STM_Load(int curious)
|
|||
mh->numpat =_mm_read_UBYTE(modreader);
|
||||
mh->globalvol =_mm_read_UBYTE(modreader);
|
||||
_mm_read_UBYTES(mh->reserved,13,modreader);
|
||||
if(mh->numpat > 128) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(t=0;t<31;t++) {
|
||||
STMSAMPLE *s=&mh->sample[t]; /* STM sample data */
|
||||
|
@ -299,9 +305,7 @@ static int STM_Load(int curious)
|
|||
/* set module variables */
|
||||
for(t=0;t<STM_NTRACKERS;t++)
|
||||
if(!memcmp(mh->trackername,STM_Signatures[t],8)) break;
|
||||
if(t == STM_NTRACKERS)
|
||||
return 0;
|
||||
of.modtype = StrDup(STM_Version[t]);
|
||||
of.modtype = MikMod_strdup(STM_Version[t]);
|
||||
of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */
|
||||
of.numpat = mh->numpat;
|
||||
of.inittempo = 125; /* mh->inittempo+0x1c; */
|
||||
|
@ -316,7 +320,10 @@ static int STM_Load(int curious)
|
|||
/* 99 terminates the patorder list */
|
||||
while((mh->patorder[t]<=99)&&(mh->patorder[t]<mh->numpat)) {
|
||||
of.positions[t]=mh->patorder[t];
|
||||
t++;
|
||||
if(++t == 0x80) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(mh->patorder[t]<=99) t++;
|
||||
of.numpos=t;
|
||||
|
@ -334,7 +341,7 @@ static int STM_Load(int curious)
|
|||
q->speed = (mh->sample[t].c2spd * 8363) / 8448;
|
||||
q->volume = mh->sample[t].volume;
|
||||
q->length = mh->sample[t].length;
|
||||
if (/*(!mh->sample[t].volume)||*/(q->length==1)) q->length=0;
|
||||
if (/*!mh->sample[t].volume || */q->length==1) q->length=0;
|
||||
q->loopstart = mh->sample[t].loopbeg;
|
||||
q->loopend = mh->sample[t].loopend;
|
||||
q->seekpos = MikMod_ISA;
|
||||
|
@ -374,5 +381,4 @@ MIKMODAPI MLOADER load_stm={
|
|||
STM_LoadTitle
|
||||
};
|
||||
|
||||
|
||||
/* ex:set ts=4: */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_stx.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
STMIK 0.2 (STX) module loader
|
||||
|
||||
|
@ -114,13 +114,14 @@ static int STX_Test(void)
|
|||
UBYTE id[8];
|
||||
int t;
|
||||
|
||||
memset(id,0,8);
|
||||
_mm_fseek(modreader,0x3C,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(id,4,modreader)) return 0;
|
||||
if(memcmp(id,"SCRM",4)) return 0;
|
||||
|
||||
_mm_fseek(modreader,0x14,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(id,8,modreader)) return 0;
|
||||
|
||||
|
||||
for(t=0;t<STM_NTRACKERS;t++)
|
||||
if(!memcmp(id,STM_Signatures[t],8)) return 1;
|
||||
|
||||
|
@ -143,6 +144,10 @@ static void STX_Cleanup(void)
|
|||
MikMod_free(paraptr);
|
||||
MikMod_free(poslookup);
|
||||
MikMod_free(mh);
|
||||
stxbuf=NULL;
|
||||
paraptr=NULL;
|
||||
poslookup=NULL;
|
||||
mh=NULL;
|
||||
}
|
||||
|
||||
static int STX_ReadPattern(void)
|
||||
|
@ -297,6 +302,11 @@ static int STX_Load(int curious)
|
|||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
if(mh->ordnum > 256 || !mh->insnum || mh->insnum > 256 ||
|
||||
mh->patnum > 254 || !mh->patnum) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set module variables */
|
||||
of.songname = DupStr(mh->songname,20,1);
|
||||
|
@ -323,10 +333,10 @@ static int STX_Load(int curious)
|
|||
version=_mm_read_I_UWORD(modreader);
|
||||
if(version==mh->patsize) {
|
||||
version = 0x10;
|
||||
of.modtype = StrDup("STMIK 0.2 (STM2STX 1.0)");
|
||||
of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.0)");
|
||||
} else {
|
||||
version = 0x11;
|
||||
of.modtype = StrDup("STMIK 0.2 (STM2STX 1.1)");
|
||||
of.modtype = MikMod_strdup("STMIK 0.2 (STM2STX 1.1)");
|
||||
}
|
||||
|
||||
/* read the order data */
|
||||
|
@ -343,7 +353,7 @@ static int STX_Load(int curious)
|
|||
if(order==255) order=LAST_PATTERN;
|
||||
of.positions[of.numpos]=order;
|
||||
poslookup[t]=of.numpos; /* bug fix for freaky S3Ms */
|
||||
if(of.positions[t]<254) of.numpos++;
|
||||
if(of.positions[t]<254) of.numpos++;
|
||||
else
|
||||
/* special end of song pattern */
|
||||
if((order==LAST_PATTERN)&&(!curious)) break;
|
||||
|
@ -389,7 +399,7 @@ static int STX_Load(int curious)
|
|||
q->loopstart = s.loopbeg;
|
||||
q->loopend = s.loopend;
|
||||
q->volume = s.volume;
|
||||
q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4;
|
||||
q->seekpos = (((ULONG)s.memsegh)<<16|s.memsegl)<<4;
|
||||
q->flags |= SF_SIGNED;
|
||||
|
||||
if(s.flags&1) q->flags |= SF_LOOP;
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_ult.c,v 1.3 2010/01/12 03:30:32 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Ultratracker (ULT) module loader
|
||||
|
||||
|
@ -80,7 +80,7 @@ typedef struct ULTEVENT {
|
|||
#define ULTS_REVERSE 16
|
||||
|
||||
#define ULT_VERSION_LEN 18
|
||||
static CHAR ULT_Version[ULT_VERSION_LEN]="Ultra Tracker v1.x";
|
||||
static CHAR ULT_Version[ULT_VERSION_LEN+1]="Ultra Tracker v1.x";
|
||||
|
||||
static ULTEVENT ev;
|
||||
|
||||
|
@ -130,8 +130,8 @@ static int ULT_Load(int curious)
|
|||
SAMPLE *q;
|
||||
ULTSAMPLE s;
|
||||
ULTHEADER mh;
|
||||
UBYTE nos,noc,rbnop;
|
||||
(void)curious;
|
||||
UBYTE nos,noc,RBnop;
|
||||
(void)curious;
|
||||
|
||||
/* try to read module header */
|
||||
_mm_read_string(mh.id,15,modreader);
|
||||
|
@ -207,29 +207,37 @@ static int ULT_Load(int curious)
|
|||
if(!AllocPositions(256)) return 0;
|
||||
for(t=0;t<256;t++)
|
||||
of.positions[t]=_mm_read_UBYTE(modreader);
|
||||
for(t=0;t<256;t++)
|
||||
|
||||
noc=_mm_read_UBYTE(modreader);
|
||||
RBnop=_mm_read_UBYTE(modreader);
|
||||
|
||||
of.numchn=++noc;
|
||||
of.numpat=++RBnop;
|
||||
of.numtrk=of.numchn*of.numpat;
|
||||
|
||||
for(t=0;t<256;t++) {
|
||||
if(of.positions[t]==255) {
|
||||
of.positions[t]=LAST_PATTERN;
|
||||
break;
|
||||
}
|
||||
if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
|
||||
/* fprintf(stderr,"positions[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
of.numpos=t;
|
||||
|
||||
noc=_mm_read_UBYTE(modreader);
|
||||
rbnop=_mm_read_UBYTE(modreader);
|
||||
|
||||
of.numchn=++noc;
|
||||
of.numpat=++rbnop;
|
||||
of.numtrk=of.numchn*of.numpat;
|
||||
if(!AllocTracks()) return 0;
|
||||
if(!AllocPatterns()) return 0;
|
||||
for(u=0;u<of.numchn;u++)
|
||||
for(t=0;t<of.numpat;t++)
|
||||
of.patterns[(t*of.numchn)+u]=tracks++;
|
||||
|
||||
// SA37775
|
||||
/* Secunia SA37775 / CVE-2009-3996 */
|
||||
if (of.numchn>=UF_MAXCHAN)
|
||||
of.numchn=UF_MAXCHAN - 1;
|
||||
|
||||
|
||||
/* read pan position table for v1.5 and higher */
|
||||
if(mh.id[14]>='3') {
|
||||
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)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static CHAR *ULT_LoadTitle(void)
|
||||
static CHAR * ULT_LoadTitle(void)
|
||||
{
|
||||
CHAR s[32];
|
||||
|
||||
|
|
476
apps/plugins/mikmod/load_umx.c
Normal file
476
apps/plugins/mikmod/load_umx.c
Normal file
|
@ -0,0 +1,476 @@
|
|||
/* MikMod sound library
|
||||
* (c) 2003-2004 Raphael Assenat and others - see file
|
||||
* AUTHORS for complete list.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Epic Games Unreal UMX container loading for libmikmod
|
||||
* Written by O. Sezer <sezero@users.sourceforge.net>
|
||||
*
|
||||
* Records data type/offset info in its Test() function, then acts
|
||||
* as a middle-man, forwarding calls to the real loader units. It
|
||||
* requires that the MREADER implementation in use always respects
|
||||
* its iobase fields. Like all other libmikmod loaders, this code
|
||||
* is not reentrant yet.
|
||||
*
|
||||
* UPKG parsing partially based on Unreal Media Ripper (UMR) v0.3
|
||||
* by Andy Ward <wardwh@swbell.net>, with additional updates
|
||||
* by O. Sezer - see git repo at https://github.com/sezero/umr/
|
||||
*
|
||||
* The cheaper way, i.e. linear search of music object like libxmp
|
||||
* and libmodplug does, is possible. With this however we're using
|
||||
* the embedded offset, size and object type directly from the umx
|
||||
* file, and I feel safer with it.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
|
||||
/*========== upkg defs */
|
||||
|
||||
typedef SLONG fci_t; /* FCompactIndex */
|
||||
|
||||
#define UPKG_HDR_TAG 0x9e2a83c1
|
||||
|
||||
struct _genhist { /* for upkg versions >= 68 */
|
||||
SLONG export_count;
|
||||
SLONG name_count;
|
||||
};
|
||||
|
||||
struct upkg_hdr {
|
||||
ULONG tag; /* UPKG_HDR_TAG */
|
||||
SLONG file_version;
|
||||
ULONG pkg_flags;
|
||||
SLONG name_count; /* number of names in name table (>= 0) */
|
||||
SLONG name_offset; /* offset to name table (>= 0) */
|
||||
SLONG export_count; /* num. exports in export table (>= 0) */
|
||||
SLONG export_offset; /* offset to export table (>= 0) */
|
||||
SLONG import_count; /* num. imports in export table (>= 0) */
|
||||
SLONG import_offset; /* offset to import table (>= 0) */
|
||||
|
||||
/* number of GUIDs in heritage table (>= 1) and table's offset:
|
||||
* only with versions < 68. */
|
||||
SLONG heritage_count;
|
||||
SLONG heritage_offset;
|
||||
/* with versions >= 68: a GUID, a dword for generation count
|
||||
* and export_count and name_count dwords for each generation: */
|
||||
ULONG guid[4];
|
||||
SLONG generation_count;
|
||||
#define UPKG_HDR_SIZE 64 /* 64 bytes up until here */
|
||||
/*struct _genhist *gen;*/
|
||||
};
|
||||
/* compile time assert for upkg_hdr size */
|
||||
/*typedef int _check_hdrsize[2 * (offsetof(struct upkg_hdr, gen) == UPKG_HDR_SIZE) - 1];*/
|
||||
typedef int _check_hdrsize[2 * (sizeof(struct upkg_hdr) == UPKG_HDR_SIZE) - 1];
|
||||
|
||||
/*========== Supported content types */
|
||||
|
||||
#define UMUSIC_IT 0
|
||||
#define UMUSIC_S3M 1
|
||||
#define UMUSIC_XM 2
|
||||
#define UMUSIC_MOD 3
|
||||
|
||||
static const char *mustype[] = {
|
||||
"IT", "S3M", "XM", "MOD",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*========== UPKG parsing */
|
||||
|
||||
/* decode an FCompactIndex.
|
||||
* original documentation by Tim Sweeney was at
|
||||
* http://unreal.epicgames.com/Packages.htm
|
||||
* also see Unreal Wiki:
|
||||
* http://wiki.beyondunreal.com/Legacy:Package_File_Format/Data_Details
|
||||
*/
|
||||
static fci_t get_fci (const char *in, int *pos)
|
||||
{
|
||||
SLONG a;
|
||||
int size;
|
||||
|
||||
size = 1;
|
||||
a = in[0] & 0x3f;
|
||||
|
||||
if (in[0] & 0x40) {
|
||||
size++;
|
||||
a |= (in[1] & 0x7f) << 6;
|
||||
|
||||
if (in[1] & 0x80) {
|
||||
size++;
|
||||
a |= (in[2] & 0x7f) << 13;
|
||||
|
||||
if (in[2] & 0x80) {
|
||||
size++;
|
||||
a |= (in[3] & 0x7f) << 20;
|
||||
|
||||
if (in[3] & 0x80) {
|
||||
size++;
|
||||
a |= (in[4] & 0x3f) << 27;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in[0] & 0x80)
|
||||
a = -a;
|
||||
|
||||
*pos += size;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static int get_objtype (SLONG ofs, int type)
|
||||
{
|
||||
char sig[16];
|
||||
_retry:
|
||||
_mm_fseek(modreader, ofs, SEEK_SET);
|
||||
_mm_read_UBYTES(sig, 16, modreader);
|
||||
if (type == UMUSIC_IT) {
|
||||
if (memcmp(sig, "IMPM", 4) == 0)
|
||||
return UMUSIC_IT;
|
||||
return -1;
|
||||
}
|
||||
if (type == UMUSIC_XM) {
|
||||
if (memcmp(sig, "Extended Module:", 16) != 0)
|
||||
return -1;
|
||||
_mm_read_UBYTES(sig, 16, modreader);
|
||||
if (sig[0] != ' ') return -1;
|
||||
_mm_read_UBYTES(sig, 16, modreader);
|
||||
if (sig[5] != 0x1a) return -1;
|
||||
return UMUSIC_XM;
|
||||
}
|
||||
|
||||
_mm_fseek(modreader, ofs + 44, SEEK_SET);
|
||||
_mm_read_UBYTES(sig, 4, modreader);
|
||||
if (type == UMUSIC_S3M) {
|
||||
if (memcmp(sig, "SCRM", 4) == 0)
|
||||
return UMUSIC_S3M;
|
||||
/*return -1;*/
|
||||
/* SpaceMarines.umx and Starseek.umx from Return to NaPali
|
||||
* report as "s3m" whereas the actual music format is "it" */
|
||||
type = UMUSIC_IT;
|
||||
goto _retry;
|
||||
}
|
||||
|
||||
_mm_fseek(modreader, ofs + 1080, SEEK_SET);
|
||||
_mm_read_UBYTES(sig, 4, modreader);
|
||||
if (type == UMUSIC_MOD) {
|
||||
if (memcmp(sig, "M.K.", 4) == 0 || memcmp(sig, "M!K!", 4) == 0)
|
||||
return UMUSIC_MOD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int read_export (const struct upkg_hdr *hdr,
|
||||
SLONG *ofs, SLONG *objsize)
|
||||
{
|
||||
char buf[40];
|
||||
int idx = 0, t;
|
||||
|
||||
_mm_fseek(modreader, *ofs, SEEK_SET);
|
||||
if (!_mm_read_UBYTES(buf, 40, modreader))
|
||||
return -1;
|
||||
|
||||
if (hdr->file_version < 40) idx += 8; /* 00 00 00 00 00 00 00 00 */
|
||||
if (hdr->file_version < 60) idx += 16; /* 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 */
|
||||
get_fci(&buf[idx], &idx); /* skip junk */
|
||||
t = get_fci(&buf[idx], &idx); /* type_name */
|
||||
if (hdr->file_version > 61) idx += 4; /* skip export size */
|
||||
*objsize = get_fci(&buf[idx], &idx);
|
||||
*ofs += idx; /* offset for real data */
|
||||
|
||||
return t; /* return type_name index */
|
||||
}
|
||||
|
||||
static int read_typname(const struct upkg_hdr *hdr,
|
||||
int idx, char *out)
|
||||
{
|
||||
int i, s;
|
||||
long l;
|
||||
char buf[64];
|
||||
|
||||
if (idx >= hdr->name_count) return -1;
|
||||
buf[63] = '\0';
|
||||
for (i = 0, l = 0; i <= idx; i++) {
|
||||
_mm_fseek(modreader, hdr->name_offset + l, SEEK_SET);
|
||||
_mm_read_UBYTES(buf, 63, modreader);
|
||||
if (hdr->file_version >= 64) {
|
||||
s = *(signed char *)buf; /* numchars *including* terminator */
|
||||
if (s <= 0 || s > 64) return -1;
|
||||
l += s + 5; /* 1 for buf[0], 4 for int32_t name_flags */
|
||||
} else {
|
||||
l += (long)strlen(buf);
|
||||
l += 5; /* 1 for terminator, 4 for int32_t name_flags */
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(out, (hdr->file_version >= 64)? &buf[1] : buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int probe_umx (const struct upkg_hdr *hdr,
|
||||
SLONG *ofs, SLONG *objsize)
|
||||
{
|
||||
int i, idx, t;
|
||||
SLONG s, pos;
|
||||
long fsiz;
|
||||
char buf[64];
|
||||
|
||||
idx = 0;
|
||||
_mm_fseek(modreader, 0, SEEK_END);
|
||||
fsiz = _mm_ftell(modreader);
|
||||
|
||||
/* Find the offset and size of the first IT, S3M or XM
|
||||
* by parsing the exports table. The umx files should
|
||||
* have only one export. Kran32.umx from Unreal has two,
|
||||
* but both pointing to the same music. */
|
||||
if (hdr->export_offset >= fsiz) return -1;
|
||||
memset(buf, 0, 64);
|
||||
_mm_fseek(modreader, hdr->export_offset, SEEK_SET);
|
||||
_mm_read_UBYTES(buf, 64, modreader);
|
||||
|
||||
get_fci(&buf[idx], &idx); /* skip class_index */
|
||||
get_fci(&buf[idx], &idx); /* skip super_index */
|
||||
if (hdr->file_version >= 60) idx += 4; /* skip int32 package_index */
|
||||
get_fci(&buf[idx], &idx); /* skip object_name */
|
||||
idx += 4; /* skip int32 object_flags */
|
||||
|
||||
s = get_fci(&buf[idx], &idx); /* get serial_size */
|
||||
if (s <= 0) return -1;
|
||||
pos = get_fci(&buf[idx],&idx); /* get serial_offset */
|
||||
if (pos < 0 || pos > fsiz - 40) return -1;
|
||||
|
||||
if ((t = read_export(hdr, &pos, &s)) < 0) return -1;
|
||||
if (s <= 0 || s > fsiz - pos) return -1;
|
||||
|
||||
if (read_typname(hdr, t, buf) < 0) return -1;
|
||||
for (i = 0; mustype[i] != NULL; i++) {
|
||||
if (!strcasecmp(buf, mustype[i])) {
|
||||
t = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mustype[i] == NULL) return -1;
|
||||
if ((t = get_objtype(pos, t)) < 0) return -1;
|
||||
|
||||
*ofs = pos;
|
||||
*objsize = s;
|
||||
return t;
|
||||
}
|
||||
|
||||
static SLONG probe_header (void *header)
|
||||
{
|
||||
struct upkg_hdr *hdr;
|
||||
unsigned char *p;
|
||||
ULONG *swp;
|
||||
int i;
|
||||
|
||||
/* byte swap the header - all members are 32 bit LE values */
|
||||
p = (unsigned char *) header;
|
||||
swp = (ULONG *) header;
|
||||
for (i = 0; i < UPKG_HDR_SIZE/4; i++, p += 4) {
|
||||
swp[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||
}
|
||||
|
||||
hdr = (struct upkg_hdr *) header;
|
||||
if (hdr->tag != UPKG_HDR_TAG) {
|
||||
return -1;
|
||||
}
|
||||
if (hdr->name_count < 0 ||
|
||||
hdr->name_offset < 0 ||
|
||||
hdr->export_count < 0 ||
|
||||
hdr->export_offset < 0 ||
|
||||
hdr->import_count < 0 ||
|
||||
hdr->import_offset < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (hdr->file_version) {
|
||||
case 35: case 37: /* Unreal beta - */
|
||||
case 40: case 41: /* 1998 */
|
||||
case 61:/* Unreal */
|
||||
case 62:/* Unreal Tournament */
|
||||
case 63:/* Return to NaPali */
|
||||
case 64:/* Unreal Tournament */
|
||||
case 66:/* Unreal Tournament */
|
||||
case 68:/* Unreal Tournament */
|
||||
case 69:/* Tactical Ops */
|
||||
case 83:/* Mobile Forces */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int process_upkg (SLONG *ofs, SLONG *objsize)
|
||||
{
|
||||
char header[UPKG_HDR_SIZE];
|
||||
|
||||
if (!_mm_read_UBYTES(header, UPKG_HDR_SIZE, modreader))
|
||||
return -1;
|
||||
if (probe_header(header) < 0)
|
||||
return -1;
|
||||
|
||||
return probe_umx((struct upkg_hdr *)header, ofs, objsize);
|
||||
}
|
||||
|
||||
/*========== Loader vars */
|
||||
|
||||
typedef struct _umx_info {
|
||||
int type;
|
||||
SLONG ofs, size;
|
||||
MLOADER* loader;
|
||||
} umx_info;
|
||||
|
||||
static umx_info *umx_data = NULL;
|
||||
|
||||
/*========== Loader code */
|
||||
|
||||
/* Without Test() being called first, Load[Title] is never called.
|
||||
* A Test() is always followed by either a Load() or a LoadTitle().
|
||||
* A Load() is always followed by Cleanup() regardless of success.
|
||||
*
|
||||
* Therefore, in between Test() and LoadTitle() or Load()/Cleanup(),
|
||||
* we must remember the type and the offset of the umx music data,
|
||||
* and always clear it when returning from LoadTitle() or Cleanup().
|
||||
*/
|
||||
|
||||
static int UMX_Test(void)
|
||||
{
|
||||
int type;
|
||||
SLONG ofs = 0, size = 0;
|
||||
|
||||
if (umx_data) {
|
||||
#ifdef MIKMOD_DEBUG
|
||||
fprintf(stderr, "UMX_Test called while a previous instance is active\n");
|
||||
#endif
|
||||
MikMod_free(umx_data);
|
||||
umx_data = NULL;
|
||||
}
|
||||
|
||||
_mm_fseek(modreader, 0, SEEK_SET);
|
||||
type = process_upkg(&ofs, &size);
|
||||
if (type < 0 || type > UMUSIC_MOD)
|
||||
return 0;
|
||||
|
||||
umx_data = (umx_info*) MikMod_calloc(1, sizeof(umx_info));
|
||||
if (!umx_data) return 0;
|
||||
|
||||
umx_data->type = type;
|
||||
umx_data->ofs = ofs;
|
||||
umx_data->size = size;
|
||||
switch (type) {
|
||||
case UMUSIC_IT:
|
||||
umx_data->loader = &load_it;
|
||||
break;
|
||||
case UMUSIC_S3M:
|
||||
umx_data->loader = &load_s3m;
|
||||
break;
|
||||
case UMUSIC_XM:
|
||||
umx_data->loader = &load_xm;
|
||||
break;
|
||||
case UMUSIC_MOD:
|
||||
umx_data->loader = &load_mod;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int UMX_Init(void)
|
||||
{
|
||||
if (!umx_data || !umx_data->loader)
|
||||
return 0;
|
||||
|
||||
if (umx_data->loader->Init)
|
||||
return umx_data->loader->Init();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void UMX_Cleanup(void)
|
||||
{
|
||||
if (!umx_data) return;
|
||||
|
||||
if (umx_data->loader && umx_data->loader->Cleanup)
|
||||
umx_data->loader->Cleanup();
|
||||
|
||||
MikMod_free(umx_data);
|
||||
umx_data = NULL;
|
||||
}
|
||||
|
||||
static int UMX_Load(int curious)
|
||||
{
|
||||
if (!umx_data || !umx_data->loader)
|
||||
return 0;
|
||||
|
||||
_mm_fseek(modreader, umx_data->ofs, SEEK_SET);
|
||||
/* set reader iobase to the umx object offset */
|
||||
_mm_iobase_revert(modreader);
|
||||
_mm_iobase_setcur(modreader);
|
||||
|
||||
return umx_data->loader->Load(curious);
|
||||
}
|
||||
|
||||
static CHAR *UMX_LoadTitle(void)
|
||||
{
|
||||
CHAR *title;
|
||||
|
||||
if (!umx_data) return NULL;
|
||||
|
||||
if (!umx_data->loader) {
|
||||
title = NULL;
|
||||
}
|
||||
else {
|
||||
_mm_fseek(modreader, umx_data->ofs, SEEK_SET);
|
||||
/* set reader iobase to the umx object offset */
|
||||
_mm_iobase_revert(modreader);
|
||||
_mm_iobase_setcur(modreader);
|
||||
|
||||
title = umx_data->loader->LoadTitle();
|
||||
}
|
||||
|
||||
MikMod_free(umx_data);
|
||||
umx_data = NULL;
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
/*========== Loader information */
|
||||
|
||||
MIKMODAPI MLOADER load_umx = {
|
||||
NULL,
|
||||
"UMX",
|
||||
"UMX (Unreal UMX container)",
|
||||
UMX_Init,
|
||||
UMX_Test,
|
||||
UMX_Load,
|
||||
UMX_Cleanup,
|
||||
UMX_LoadTitle
|
||||
};
|
||||
|
||||
/* ex:set ts=8: */
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_uni.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
|
||||
$Id$
|
||||
|
||||
UNIMOD (libmikmod's and APlayer's internal module format) loader
|
||||
|
||||
|
@ -94,18 +94,18 @@ static UNISMP05 *wh=NULL,*s=NULL;
|
|||
|
||||
/*========== Loader code */
|
||||
|
||||
static char* readstring(void)
|
||||
static char * readstring(void)
|
||||
{
|
||||
char *s=NULL;
|
||||
char *str=NULL;
|
||||
UWORD len;
|
||||
|
||||
|
||||
len=_mm_read_I_UWORD(modreader);
|
||||
if(len) {
|
||||
s=MikMod_malloc(len+1);
|
||||
_mm_read_UBYTES(s,len,modreader);
|
||||
s[len]=0;
|
||||
str=(char *) MikMod_malloc(len+1);
|
||||
_mm_read_UBYTES(str,len,modreader);
|
||||
str[len]=0;
|
||||
}
|
||||
return s;
|
||||
return str;
|
||||
}
|
||||
|
||||
static int UNI_Test(void)
|
||||
|
@ -133,7 +133,7 @@ static int UNI_Init(void)
|
|||
static void UNI_Cleanup(void)
|
||||
{
|
||||
MikMod_free(wh);
|
||||
s=NULL;
|
||||
wh = s = NULL;
|
||||
}
|
||||
|
||||
static UBYTE* readtrack(void)
|
||||
|
@ -148,7 +148,7 @@ static UBYTE* readtrack(void)
|
|||
len=_mm_read_I_UWORD(modreader);
|
||||
|
||||
if(!len) return NULL;
|
||||
if(!(t=MikMod_malloc(len))) return NULL;
|
||||
if(!(t=(UBYTE*)MikMod_malloc(len))) return NULL;
|
||||
_mm_read_UBYTES(t,len,modreader);
|
||||
|
||||
/* Check if the track is correct */
|
||||
|
@ -221,65 +221,65 @@ static UBYTE* readtrack(void)
|
|||
static int loadsmp6(void)
|
||||
{
|
||||
int t;
|
||||
SAMPLE *s;
|
||||
SAMPLE *sptr;
|
||||
|
||||
s=of.samples;
|
||||
for(t=0;t<of.numsmp;t++,s++) {
|
||||
sptr=of.samples;
|
||||
for(t=0;t<of.numsmp;t++,sptr++) {
|
||||
int flags;
|
||||
|
||||
flags = _mm_read_M_UWORD(modreader);
|
||||
s->flags=0;
|
||||
if(flags&0x0004) s->flags|=SF_STEREO;
|
||||
if(flags&0x0002) s->flags|=SF_SIGNED;
|
||||
if(flags&0x0001) s->flags|=SF_16BITS;
|
||||
sptr->flags=0;
|
||||
if(flags&0x0004) sptr->flags|=SF_STEREO;
|
||||
if(flags&0x0002) sptr->flags|=SF_SIGNED;
|
||||
if(flags&0x0001) sptr->flags|=SF_16BITS;
|
||||
/* convert flags */
|
||||
if(universion>=0x104) {
|
||||
if(flags&0x2000) s->flags|=SF_UST_LOOP;
|
||||
if(flags&0x1000) s->flags|=SF_OWNPAN;
|
||||
if(flags&0x0800) s->flags|=SF_SUSTAIN;
|
||||
if(flags&0x0400) s->flags|=SF_REVERSE;
|
||||
if(flags&0x0200) s->flags|=SF_BIDI;
|
||||
if(flags&0x0100) s->flags|=SF_LOOP;
|
||||
if(flags&0x0020) s->flags|=SF_ITPACKED;
|
||||
if(flags&0x0010) s->flags|=SF_DELTA;
|
||||
if(flags&0x0008) s->flags|=SF_BIG_ENDIAN;
|
||||
if(flags&0x2000) sptr->flags|=SF_UST_LOOP;
|
||||
if(flags&0x1000) sptr->flags|=SF_OWNPAN;
|
||||
if(flags&0x0800) sptr->flags|=SF_SUSTAIN;
|
||||
if(flags&0x0400) sptr->flags|=SF_REVERSE;
|
||||
if(flags&0x0200) sptr->flags|=SF_BIDI;
|
||||
if(flags&0x0100) sptr->flags|=SF_LOOP;
|
||||
if(flags&0x0020) sptr->flags|=SF_ITPACKED;
|
||||
if(flags&0x0010) sptr->flags|=SF_DELTA;
|
||||
if(flags&0x0008) sptr->flags|=SF_BIG_ENDIAN;
|
||||
} else if(universion>=0x102) {
|
||||
if(flags&0x0800) s->flags|=SF_UST_LOOP;
|
||||
if(flags&0x0400) s->flags|=SF_OWNPAN;
|
||||
if(flags&0x0200) s->flags|=SF_SUSTAIN;
|
||||
if(flags&0x0100) s->flags|=SF_REVERSE;
|
||||
if(flags&0x0080) s->flags|=SF_BIDI;
|
||||
if(flags&0x0040) s->flags|=SF_LOOP;
|
||||
if(flags&0x0020) s->flags|=SF_ITPACKED;
|
||||
if(flags&0x0010) s->flags|=SF_DELTA;
|
||||
if(flags&0x0008) s->flags|=SF_BIG_ENDIAN;
|
||||
if(flags&0x0800) sptr->flags|=SF_UST_LOOP;
|
||||
if(flags&0x0400) sptr->flags|=SF_OWNPAN;
|
||||
if(flags&0x0200) sptr->flags|=SF_SUSTAIN;
|
||||
if(flags&0x0100) sptr->flags|=SF_REVERSE;
|
||||
if(flags&0x0080) sptr->flags|=SF_BIDI;
|
||||
if(flags&0x0040) sptr->flags|=SF_LOOP;
|
||||
if(flags&0x0020) sptr->flags|=SF_ITPACKED;
|
||||
if(flags&0x0010) sptr->flags|=SF_DELTA;
|
||||
if(flags&0x0008) sptr->flags|=SF_BIG_ENDIAN;
|
||||
} else {
|
||||
if(flags&0x400) s->flags|=SF_UST_LOOP;
|
||||
if(flags&0x200) s->flags|=SF_OWNPAN;
|
||||
if(flags&0x100) s->flags|=SF_REVERSE;
|
||||
if(flags&0x080) s->flags|=SF_SUSTAIN;
|
||||
if(flags&0x040) s->flags|=SF_BIDI;
|
||||
if(flags&0x020) s->flags|=SF_LOOP;
|
||||
if(flags&0x010) s->flags|=SF_BIG_ENDIAN;
|
||||
if(flags&0x008) s->flags|=SF_DELTA;
|
||||
if(flags&0x400) sptr->flags|=SF_UST_LOOP;
|
||||
if(flags&0x200) sptr->flags|=SF_OWNPAN;
|
||||
if(flags&0x100) sptr->flags|=SF_REVERSE;
|
||||
if(flags&0x080) sptr->flags|=SF_SUSTAIN;
|
||||
if(flags&0x040) sptr->flags|=SF_BIDI;
|
||||
if(flags&0x020) sptr->flags|=SF_LOOP;
|
||||
if(flags&0x010) sptr->flags|=SF_BIG_ENDIAN;
|
||||
if(flags&0x008) sptr->flags|=SF_DELTA;
|
||||
}
|
||||
|
||||
s->speed = _mm_read_M_ULONG(modreader);
|
||||
s->volume = _mm_read_UBYTE(modreader);
|
||||
s->panning = _mm_read_M_UWORD(modreader);
|
||||
s->length = _mm_read_M_ULONG(modreader);
|
||||
s->loopstart = _mm_read_M_ULONG(modreader);
|
||||
s->loopend = _mm_read_M_ULONG(modreader);
|
||||
s->susbegin = _mm_read_M_ULONG(modreader);
|
||||
s->susend = _mm_read_M_ULONG(modreader);
|
||||
s->globvol = _mm_read_UBYTE(modreader);
|
||||
s->vibflags = _mm_read_UBYTE(modreader);
|
||||
s->vibtype = _mm_read_UBYTE(modreader);
|
||||
s->vibsweep = _mm_read_UBYTE(modreader);
|
||||
s->vibdepth = _mm_read_UBYTE(modreader);
|
||||
s->vibrate = _mm_read_UBYTE(modreader);
|
||||
sptr->speed = _mm_read_M_ULONG(modreader);
|
||||
sptr->volume = _mm_read_UBYTE(modreader);
|
||||
sptr->panning = _mm_read_M_UWORD(modreader);
|
||||
sptr->length = _mm_read_M_ULONG(modreader);
|
||||
sptr->loopstart = _mm_read_M_ULONG(modreader);
|
||||
sptr->loopend = _mm_read_M_ULONG(modreader);
|
||||
sptr->susbegin = _mm_read_M_ULONG(modreader);
|
||||
sptr->susend = _mm_read_M_ULONG(modreader);
|
||||
sptr->globvol = _mm_read_UBYTE(modreader);
|
||||
sptr->vibflags = _mm_read_UBYTE(modreader);
|
||||
sptr->vibtype = _mm_read_UBYTE(modreader);
|
||||
sptr->vibsweep = _mm_read_UBYTE(modreader);
|
||||
sptr->vibdepth = _mm_read_UBYTE(modreader);
|
||||
sptr->vibrate = _mm_read_UBYTE(modreader);
|
||||
|
||||
s->samplename=readstring();
|
||||
sptr->samplename=readstring();
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
|
@ -308,7 +308,7 @@ static int loadinstr6(void)
|
|||
i->rpanvar = _mm_read_UBYTE(modreader);
|
||||
i->volfade = _mm_read_M_UWORD(modreader);
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define UNI_LoadEnvelope6(name) \
|
||||
i-> name##flg=_mm_read_UBYTE(modreader); \
|
||||
i-> name##pts=_mm_read_UBYTE(modreader); \
|
||||
|
@ -373,7 +373,7 @@ static int loadinstr5(void)
|
|||
for(u=0;u<96;u++)
|
||||
i->samplenumber[u]=of.numsmp+_mm_read_UBYTE(modreader);
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define UNI_LoadEnvelope5(name) \
|
||||
i-> name##flg=_mm_read_UBYTE(modreader); \
|
||||
i-> name##pts=_mm_read_UBYTE(modreader); \
|
||||
|
@ -415,7 +415,7 @@ static int loadinstr5(void)
|
|||
/* Allocate more room for sample information if necessary */
|
||||
if(of.numsmp+u==wavcnt) {
|
||||
wavcnt+=UNI_SMPINCR;
|
||||
if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(UNISMP05)))) {
|
||||
if(!(wh=(UNISMP05*)MikMod_realloc(wh,wavcnt*sizeof(UNISMP05)))) {
|
||||
_mm_errno=MMERR_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ static int loadinstr5(void)
|
|||
|
||||
/* sanity check */
|
||||
if(!of.numsmp) {
|
||||
if(wh) { MikMod_free(wh);wh=NULL; }
|
||||
MikMod_free(wh);wh=NULL;
|
||||
_mm_errno=MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
|
@ -504,8 +504,8 @@ static int UNI_Load(int curious)
|
|||
char *modtype,*oldtype=NULL;
|
||||
INSTRUMENT *d;
|
||||
SAMPLE *q;
|
||||
(void)curious;
|
||||
|
||||
(void)curious;
|
||||
|
||||
/* read module header */
|
||||
_mm_read_UBYTES(mh.id,4,modreader);
|
||||
if(mh.id[3]!='N')
|
||||
|
@ -514,11 +514,11 @@ static int UNI_Load(int curious)
|
|||
universion=0x100;
|
||||
|
||||
if(universion>=6) {
|
||||
if (universion==6)
|
||||
(void)_mm_read_UBYTE(modreader);
|
||||
else
|
||||
if (universion==6) {
|
||||
_mm_skip_BYTE(modreader);
|
||||
} else {
|
||||
universion=_mm_read_M_UWORD(modreader);
|
||||
|
||||
}
|
||||
mh.flags =_mm_read_M_UWORD(modreader);
|
||||
mh.numchn =_mm_read_UBYTE(modreader);
|
||||
mh.numvoices =_mm_read_UBYTE(modreader);
|
||||
|
@ -556,7 +556,7 @@ static int UNI_Load(int curious)
|
|||
mh.flags &= UF_XMPERIODS | UF_LINEAR;
|
||||
mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING;
|
||||
}
|
||||
|
||||
|
||||
/* set module parameters */
|
||||
of.flags =mh.flags;
|
||||
of.numchn =mh.numchn;
|
||||
|
@ -578,21 +578,21 @@ static int UNI_Load(int curious)
|
|||
oldtype=readstring();
|
||||
if(oldtype) {
|
||||
size_t len=strlen(oldtype)+20;
|
||||
if(!(modtype=MikMod_malloc(len))) return 0;
|
||||
if(!(modtype=(char*)MikMod_malloc(len))) return 0;
|
||||
#ifdef HAVE_SNPRINTF
|
||||
snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
|
||||
#else
|
||||
sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
|
||||
#endif
|
||||
} else {
|
||||
if(!(modtype=MikMod_malloc(10))) return 0;
|
||||
if(!(modtype=(char*)MikMod_malloc(10))) return 0;
|
||||
#ifdef HAVE_SNPRINTF
|
||||
snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
|
||||
#else
|
||||
sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
|
||||
#endif
|
||||
}
|
||||
of.modtype=StrDup(modtype);
|
||||
of.modtype=MikMod_strdup(modtype);
|
||||
MikMod_free(modtype);MikMod_free(oldtype);
|
||||
of.comment=readstring();
|
||||
|
||||
|
@ -624,9 +624,14 @@ static int UNI_Load(int curious)
|
|||
for(t=0;t<of.numchn;t++) of.panning[t]=mh.panning[t];
|
||||
}
|
||||
/* convert the ``end of song'' pattern code if necessary */
|
||||
if(universion<0x106)
|
||||
for(t=0;t<of.numpos;t++)
|
||||
if(of.positions[t]==255) of.positions[t]=LAST_PATTERN;
|
||||
for(t=0;t<of.numpos;t++) {
|
||||
if(universion<0x106 && of.positions[t]==255) of.positions[t]=LAST_PATTERN;
|
||||
else if (of.positions[t]>of.numpat) { /* SANITIY CHECK */
|
||||
/* fprintf(stderr,"position[%d]=%d > numpat=%d\n",t,of.positions[t],of.numpat);*/
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* instruments and samples */
|
||||
if(universion>=6) {
|
||||
|
@ -642,7 +647,7 @@ static int UNI_Load(int curious)
|
|||
if(!AllocInstruments()) return 0;
|
||||
if(!loadinstr5()) return 0;
|
||||
if(!AllocSamples()) {
|
||||
if(wh) { MikMod_free(wh);wh=NULL; }
|
||||
MikMod_free(wh);wh=NULL;
|
||||
return 0;
|
||||
}
|
||||
if(!loadsmp5()) return 0;
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: load_xm.c,v 1.5 2008/02/29 18:49:03 denis111 Exp $
|
||||
$Id$
|
||||
|
||||
Fasttracker (XM) module loader
|
||||
|
||||
|
@ -59,7 +59,7 @@ typedef struct XMHEADER {
|
|||
UWORD numchn; /* Number of channels (2,4,6,8,10,...,32) */
|
||||
UWORD numpat; /* Number of patterns (max 256) */
|
||||
UWORD numins; /* Number of instruments (max 128) */
|
||||
UWORD flags;
|
||||
UWORD flags;
|
||||
UWORD tempo; /* Default tempo */
|
||||
UWORD bpm; /* Default BPM */
|
||||
UBYTE orders[256]; /* Pattern order table */
|
||||
|
@ -129,7 +129,7 @@ typedef struct XMNOTE {
|
|||
static XMNOTE *xmpat=NULL;
|
||||
static XMHEADER *mh=NULL;
|
||||
|
||||
/* increment unit for sample array MikMod_reallocation */
|
||||
/* increment unit for sample array reallocation */
|
||||
#define XM_SMPINCR 64
|
||||
static ULONG *nextwav=NULL;
|
||||
static XMWAVHEADER *wh=NULL,*s=NULL;
|
||||
|
@ -155,6 +155,7 @@ static int XM_Init(void)
|
|||
static void XM_Cleanup(void)
|
||||
{
|
||||
MikMod_free(mh);
|
||||
mh=NULL;
|
||||
}
|
||||
|
||||
static int XM_ReadNote(XMNOTE* n)
|
||||
|
@ -359,8 +360,8 @@ static int LoadPatterns(int dummypat)
|
|||
return 0;
|
||||
|
||||
/* when packsize is 0, don't try to load a pattern.. it's empty. */
|
||||
if(ph.packsize)
|
||||
for(u=0;u<ph.numrows;u++)
|
||||
if(ph.packsize)
|
||||
for(u=0;u<ph.numrows;u++)
|
||||
for(v=0;v<of.numchn;v++) {
|
||||
if(!ph.packsize) break;
|
||||
|
||||
|
@ -443,11 +444,17 @@ static void FixEnvelope(ENVPT *cur, int pts)
|
|||
|
||||
static int LoadInstruments(void)
|
||||
{
|
||||
int t,u, ck;
|
||||
long filend,ck;
|
||||
int t,u;
|
||||
INSTRUMENT *d;
|
||||
ULONG next=0;
|
||||
UWORD wavcnt=0;
|
||||
|
||||
ck = _mm_ftell(modreader);
|
||||
_mm_fseek(modreader,0,SEEK_END);
|
||||
filend = _mm_ftell(modreader);
|
||||
_mm_fseek(modreader,ck,SEEK_SET);
|
||||
|
||||
if(!AllocInstruments()) return 0;
|
||||
d=of.instruments;
|
||||
for(t=0;t<of.numins;t++,d++) {
|
||||
|
@ -461,12 +468,9 @@ static int LoadInstruments(void)
|
|||
ih.size = _mm_read_I_ULONG(modreader);
|
||||
headend += ih.size;
|
||||
ck = _mm_ftell(modreader);
|
||||
_mm_fseek(modreader,0,SEEK_END);
|
||||
if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) {
|
||||
_mm_fseek(modreader,ck,SEEK_SET);
|
||||
if ((headend<0) || (filend<headend) || (headend<ck)) {
|
||||
break;
|
||||
}
|
||||
_mm_fseek(modreader,ck,SEEK_SET);
|
||||
_mm_read_string(ih.name, 22, modreader);
|
||||
ih.type = _mm_read_UBYTE(modreader);
|
||||
ih.numsmp = _mm_read_I_UWORD(modreader);
|
||||
|
@ -500,7 +504,11 @@ static int LoadInstruments(void)
|
|||
|
||||
/* read the remainder of the header
|
||||
(2 bytes for 1.03, 22 for 1.04) */
|
||||
if (headend>=_mm_ftell(modreader)) for(u=headend-_mm_ftell(modreader);u;u--) (void)_mm_read_UBYTE(modreader);
|
||||
if (headend>=_mm_ftell(modreader)) {
|
||||
for(u=headend-_mm_ftell(modreader);u;u--) {
|
||||
_mm_skip_BYTE(modreader);
|
||||
}
|
||||
}
|
||||
|
||||
/* we can't trust the envelope point count here, as some
|
||||
modules have incorrect values (K_OSPACE.XM reports 32 volume
|
||||
|
@ -509,8 +517,8 @@ static int LoadInstruments(void)
|
|||
if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2;
|
||||
|
||||
if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) {
|
||||
if(nextwav) { MikMod_free(nextwav);nextwav=NULL; }
|
||||
if(wh) { MikMod_free(wh);wh=NULL; }
|
||||
MikMod_free(nextwav);nextwav=NULL;
|
||||
MikMod_free(wh);wh=NULL;
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
|
@ -519,7 +527,7 @@ static int LoadInstruments(void)
|
|||
d->samplenumber[u]=pth.what[u]+of.numsmp;
|
||||
d->volfade = pth.volfade;
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define XM_ProcessEnvelope(name) \
|
||||
for (u = 0; u < (XMENVCNT >> 1); u++) { \
|
||||
d-> name##env[u].pos = pth. name##env[u << 1]; \
|
||||
|
@ -560,7 +568,7 @@ static int LoadInstruments(void)
|
|||
\
|
||||
if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
|
||||
d-> name/**/flg&=~EF_ON
|
||||
#endif
|
||||
#endif
|
||||
|
||||
XM_ProcessEnvelope(vol);
|
||||
XM_ProcessEnvelope(pan);
|
||||
|
@ -577,15 +585,23 @@ static int LoadInstruments(void)
|
|||
everything over */
|
||||
if(mh->version>0x0103) next = 0;
|
||||
for(u=0;u<ih.numsmp;u++,s++) {
|
||||
/* XM sample header is 40 bytes: make sure we won't hit EOF */
|
||||
/* Note: last instrument is at the end of file in version 0x0104 */
|
||||
if(_mm_ftell(modreader)+40>filend) {
|
||||
MikMod_free(nextwav);MikMod_free(wh);
|
||||
nextwav=NULL;wh=NULL;
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
/* Allocate more room for sample information if necessary */
|
||||
if(of.numsmp+u==wavcnt) {
|
||||
wavcnt+=XM_SMPINCR;
|
||||
if(!(nextwav=MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
|
||||
if(wh) { MikMod_free(wh);wh=NULL; }
|
||||
if(!(nextwav=(ULONG*)MikMod_realloc(nextwav,wavcnt*sizeof(ULONG)))){
|
||||
MikMod_free(wh);wh=NULL;
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
}
|
||||
if(!(wh=MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
|
||||
if(!(wh=(XMWAVHEADER*)MikMod_realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
|
||||
MikMod_free(nextwav);nextwav=NULL;
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
return 0;
|
||||
|
@ -610,13 +626,6 @@ static int LoadInstruments(void)
|
|||
|
||||
nextwav[of.numsmp+u]=next;
|
||||
next+=s->length;
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
MikMod_free(nextwav);MikMod_free(wh);
|
||||
nextwav=NULL;wh=NULL;
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(mh->version>0x0103) {
|
||||
|
@ -628,15 +637,15 @@ static int LoadInstruments(void)
|
|||
} else {
|
||||
/* read the remainder of the header */
|
||||
ck = _mm_ftell(modreader);
|
||||
_mm_fseek(modreader,0,SEEK_END);
|
||||
if ((headend<0) || (_mm_ftell(modreader)<headend) || (headend<ck)) {
|
||||
_mm_fseek(modreader,ck,SEEK_SET);
|
||||
if ((headend<0) || (filend<headend) || (headend<ck)) {
|
||||
break;
|
||||
}
|
||||
_mm_fseek(modreader,ck,SEEK_SET);
|
||||
for(u=headend-_mm_ftell(modreader);u;u--) (void)_mm_read_UBYTE(modreader);
|
||||
for(u=headend-_mm_ftell(modreader);u;u--) {
|
||||
_mm_skip_BYTE(modreader);
|
||||
}
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
/* last instrument is at the end of file in version 0x0104 */
|
||||
if(_mm_eof(modreader) && (mh->version<0x0104 || t<of.numins-1)) {
|
||||
MikMod_free(nextwav);MikMod_free(wh);
|
||||
nextwav=NULL;wh=NULL;
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
|
@ -648,8 +657,8 @@ static int LoadInstruments(void)
|
|||
|
||||
/* sanity check */
|
||||
if(!of.numsmp) {
|
||||
if(nextwav) { MikMod_free(nextwav);nextwav=NULL; }
|
||||
if(wh) { MikMod_free(wh);wh=NULL; }
|
||||
MikMod_free(nextwav);nextwav=NULL;
|
||||
MikMod_free(wh);wh=NULL;
|
||||
_mm_errno = MMERR_LOADING_SAMPLEINFO;
|
||||
return 0;
|
||||
}
|
||||
|
@ -664,17 +673,15 @@ static int XM_Load(int curious)
|
|||
int t,u;
|
||||
int dummypat=0;
|
||||
char tracker[21],modtype[60];
|
||||
(void)curious;
|
||||
(void)curious;
|
||||
|
||||
/* try to read module header */
|
||||
_mm_read_string(mh->id,17,modreader);
|
||||
_mm_read_string(mh->songname,21,modreader);
|
||||
_mm_read_string(mh->trackername,20,modreader);
|
||||
mh->version =_mm_read_I_UWORD(modreader);
|
||||
if((mh->version<0x102)||(mh->version>0x104)) {
|
||||
_mm_errno=MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
if(mh->version < 0x102 || mh->version > 0x104)
|
||||
goto bad_xm;
|
||||
mh->headersize =_mm_read_I_ULONG(modreader);
|
||||
mh->songlength =_mm_read_I_UWORD(modreader);
|
||||
mh->restart =_mm_read_I_UWORD(modreader);
|
||||
|
@ -684,23 +691,25 @@ static int XM_Load(int curious)
|
|||
mh->flags =_mm_read_I_UWORD(modreader);
|
||||
mh->tempo =_mm_read_I_UWORD(modreader);
|
||||
mh->bpm =_mm_read_I_UWORD(modreader);
|
||||
if(!mh->bpm) {
|
||||
_mm_errno=MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
_mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);
|
||||
|
||||
if(_mm_eof(modreader)) {
|
||||
_mm_errno = MMERR_LOADING_HEADER;
|
||||
return 0;
|
||||
}
|
||||
if(mh->numchn > 64) goto bad_xm;
|
||||
if(mh->tempo > 32 || mh->bpm < 32 || mh->bpm > 255)
|
||||
goto bad_xm;
|
||||
if(mh->songlength > 256 || mh->headersize < 20 || mh->headersize > 20+256)
|
||||
goto bad_xm;
|
||||
if(mh->numpat > 256 || mh->numins > 255 || mh->restart > 255)
|
||||
goto bad_xm;
|
||||
/* _mm_read_UBYTES(mh->orders,256,modreader);*/
|
||||
/* _mm_read_UBYTES(mh->orders,mh->headersize-20,modreader);*/
|
||||
_mm_read_UBYTES(mh->orders,mh->songlength,modreader);
|
||||
if(_mm_fseek(modreader, mh->headersize+60, SEEK_SET) || _mm_eof(modreader))
|
||||
goto bad_hdr;
|
||||
|
||||
/* set module variables */
|
||||
of.initspeed = mh->tempo;
|
||||
of.initspeed = mh->tempo;
|
||||
of.inittempo = mh->bpm;
|
||||
strncpy(tracker,mh->trackername,20);tracker[20]=0;
|
||||
for(t=20;(tracker[t]<=' ')&&(t>=0);t--) tracker[t]=0;
|
||||
|
||||
for(t=20;(t>=0)&&(tracker[t]<=' ');t--) tracker[t]=0;
|
||||
|
||||
/* some modules have the tracker name empty */
|
||||
if (!tracker[0])
|
||||
strcpy(tracker,"Unknown tracker");
|
||||
|
@ -712,7 +721,7 @@ static int XM_Load(int curious)
|
|||
sprintf(modtype,"%s (XM format %d.%02d)",
|
||||
tracker,mh->version>>8,mh->version&0xff);
|
||||
#endif
|
||||
of.modtype = StrDup(modtype);
|
||||
of.modtype = MikMod_strdup(modtype);
|
||||
of.numchn = mh->numchn;
|
||||
of.numpat = mh->numpat;
|
||||
of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */
|
||||
|
@ -720,8 +729,7 @@ static int XM_Load(int curious)
|
|||
of.numpos = mh->songlength; /* copy the songlength */
|
||||
of.reppos = mh->restart<mh->songlength?mh->restart:0;
|
||||
of.numins = mh->numins;
|
||||
of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS |
|
||||
UF_PANNING;
|
||||
of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | UF_PANNING;
|
||||
if(mh->flags&1) of.flags |= UF_LINEAR;
|
||||
of.bpmlimit = 32;
|
||||
|
||||
|
@ -802,16 +810,19 @@ static int XM_Load(int curious)
|
|||
MikMod_free(wh);MikMod_free(nextwav);
|
||||
wh=NULL;nextwav=NULL;
|
||||
return 1;
|
||||
|
||||
bad_hdr: _mm_errno = MMERR_LOADING_HEADER; return 0;
|
||||
bad_xm: _mm_errno = MMERR_NOT_A_MODULE; return 0;
|
||||
}
|
||||
|
||||
static CHAR *XM_LoadTitle(void)
|
||||
{
|
||||
CHAR s[21];
|
||||
CHAR str[21];
|
||||
|
||||
_mm_fseek(modreader,17,SEEK_SET);
|
||||
if(!_mm_read_UBYTES(s,21,modreader)) return NULL;
|
||||
if(!_mm_read_UBYTES(str, 21, modreader)) return NULL;
|
||||
|
||||
return(DupStr(s,21,1));
|
||||
return(DupStr(str,21,1));
|
||||
}
|
||||
|
||||
/*========== Loader information */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,8 +20,6 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mdreg.c,v 1.2 2005/03/30 19:11:13 realtech Exp $
|
||||
|
||||
Routine for registering all drivers in libmikmod for the current platform.
|
||||
|
||||
==============================================================================*/
|
||||
|
@ -34,12 +32,13 @@
|
|||
|
||||
static void _mm_registeralldrivers(void)
|
||||
{
|
||||
#if 0
|
||||
|
||||
/* Register network drivers */
|
||||
#ifdef DRV_AF
|
||||
_mm_registerdriver(&drv_AF);
|
||||
#endif
|
||||
#ifdef DRV_PULSEAUDIO
|
||||
_mm_registerdriver(&drv_pulseaudio);
|
||||
#endif
|
||||
#ifdef DRV_ESD
|
||||
_mm_registerdriver(&drv_esd);
|
||||
#endif
|
||||
|
@ -51,8 +50,22 @@ static void _mm_registeralldrivers(void)
|
|||
#ifdef DRV_ULTRA
|
||||
_mm_registerdriver(&drv_ultra);
|
||||
#endif
|
||||
#ifdef DRV_SAM9407
|
||||
_mm_registerdriver(&drv_sam9407);
|
||||
#endif
|
||||
|
||||
/* Register hardware drivers - software mixing */
|
||||
/* Register multi-platform drivers -- software mixing */
|
||||
#ifdef DRV_SDL
|
||||
_mm_registerdriver(&drv_sdl);
|
||||
#endif
|
||||
#ifdef DRV_OPENAL
|
||||
_mm_registerdriver(&drv_openal);
|
||||
#endif
|
||||
|
||||
/* Register OS-specific hardware drivers - software mixing */
|
||||
#ifdef DRV_AHI
|
||||
_mm_registerdriver(&drv_ahi);
|
||||
#endif
|
||||
#ifdef DRV_AIX
|
||||
_mm_registerdriver(&drv_aix);
|
||||
#endif
|
||||
|
@ -62,6 +75,9 @@ static void _mm_registeralldrivers(void)
|
|||
#ifdef DRV_HP
|
||||
_mm_registerdriver(&drv_hp);
|
||||
#endif
|
||||
#ifdef DRV_SNDIO
|
||||
_mm_registerdriver(&drv_sndio);
|
||||
#endif
|
||||
#ifdef DRV_OSS
|
||||
_mm_registerdriver(&drv_oss);
|
||||
#endif
|
||||
|
@ -77,6 +93,9 @@ static void _mm_registeralldrivers(void)
|
|||
#ifdef DRV_OS2
|
||||
_mm_registerdriver(&drv_os2);
|
||||
#endif
|
||||
#ifdef DRV_XAUDIO2
|
||||
_mm_registerdriver(&drv_xaudio2);
|
||||
#endif
|
||||
#ifdef DRV_DS
|
||||
_mm_registerdriver(&drv_ds);
|
||||
#endif
|
||||
|
@ -89,39 +108,54 @@ static void _mm_registeralldrivers(void)
|
|||
#ifdef DRV_OSX
|
||||
_mm_registerdriver(&drv_osx);
|
||||
#endif
|
||||
#ifdef DRV_DC
|
||||
_mm_registerdriver(&drv_dc);
|
||||
#endif
|
||||
#ifdef DRV_GP32
|
||||
_mm_registerdriver(&drv_gp32);
|
||||
#endif
|
||||
|
||||
/* dos drivers */
|
||||
#ifdef DRV_PSP
|
||||
_mm_registerdriver(&drv_psp);
|
||||
#endif
|
||||
#ifdef DRV_OSLES
|
||||
_mm_registerdriver(&drv_osles);
|
||||
#endif
|
||||
#ifdef DRV_N64
|
||||
_mm_registerdriver(&drv_n64);
|
||||
#endif
|
||||
|
||||
/* dos drivers - wss first, since some cards emulate sb */
|
||||
#ifdef DRV_WSS
|
||||
/* wss first, since some cards emulate sb */
|
||||
_mm_registerdriver(&drv_wss);
|
||||
#endif
|
||||
#ifdef DRV_SB
|
||||
_mm_registerdriver(&drv_sb);
|
||||
#endif
|
||||
|
||||
|
||||
/* Register disk writers */
|
||||
_mm_registerdriver(&drv_raw);
|
||||
#ifdef DRV_WAV
|
||||
_mm_registerdriver(&drv_wav);
|
||||
#endif
|
||||
#ifdef DRV_AIFF
|
||||
_mm_registerdriver(&drv_aiff);
|
||||
#endif
|
||||
|
||||
#ifdef DRV_RAW
|
||||
_mm_registerdriver(&drv_raw);
|
||||
#endif
|
||||
|
||||
/* Register other drivers */
|
||||
#ifdef DRV_PIPE
|
||||
_mm_registerdriver(&drv_pipe);
|
||||
#endif
|
||||
#ifndef macintosh
|
||||
#if defined(DRV_STDOUT) && !defined(macintosh)
|
||||
_mm_registerdriver(&drv_stdout);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* Register 'nosound' driver */
|
||||
_mm_registerdriver(&drv_nos);
|
||||
}
|
||||
|
||||
void MikMod_RegisterAllDrivers(void)
|
||||
MIKMODAPI void MikMod_RegisterAllDrivers(void)
|
||||
{
|
||||
MUTEX_LOCK(lists);
|
||||
_mm_registeralldrivers();
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/* MikMod sound library
|
||||
(c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
|
||||
for complete list.
|
||||
(c) 1998-2014 Miodrag Vallat and others - see file AUTHORS
|
||||
for a complete list.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,8 +20,6 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mdriver.c,v 1.4 2007/12/03 20:59:05 denis111 Exp $
|
||||
|
||||
These routines are used to access the available soundcard drivers.
|
||||
|
||||
==============================================================================*/
|
||||
|
@ -34,54 +32,59 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if defined unix || (defined __APPLE__ && defined __MACH__)
|
||||
#include <string.h>
|
||||
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
#if (MIKMOD_UNIX)
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
#ifdef SUNOS
|
||||
extern int fprintf(FILE *, const char *, ...);
|
||||
#endif
|
||||
|
||||
static MDRIVER *firstdriver=NULL;
|
||||
MIKMODAPI MDRIVER *md_driver=NULL;
|
||||
extern MODULE *pf; /* modfile being played */
|
||||
|
||||
/* EXPORTED GLOBALS */
|
||||
MIKMODAPI MDRIVER *md_driver = NULL;
|
||||
|
||||
/* Initial global settings */
|
||||
MIKMODAPI UWORD md_device = 0; /* autodetect */
|
||||
MIKMODAPI UWORD md_mixfreq = 44100;
|
||||
MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
|
||||
DMODE_SURROUND |DMODE_SOFT_MUSIC |
|
||||
DMODE_SOFT_SNDFX;
|
||||
MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
|
||||
MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
|
||||
MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
|
||||
MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
|
||||
MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */
|
||||
UWORD md_bpm = 125; /* tempo */
|
||||
MIKMODAPI UWORD md_device = 0; /* autodetect */
|
||||
MIKMODAPI ULONG md_mixfreq = 44100;
|
||||
MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS |
|
||||
DMODE_SURROUND |
|
||||
DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX;
|
||||
MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */
|
||||
MIKMODAPI UBYTE md_reverb = 0; /* no reverb */
|
||||
MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */
|
||||
MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */
|
||||
MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */
|
||||
|
||||
/* Do not modify the numchn variables yourself! use MD_SetVoices() */
|
||||
UBYTE md_numchn=0,md_sngchn=0,md_sfxchn=0;
|
||||
UBYTE md_hardchn=0,md_softchn=0;
|
||||
/* INTERNAL GLOBALS */
|
||||
UWORD md_bpm = 125; /* tempo */
|
||||
|
||||
void (*md_player)(void) = Player_HandleTick;
|
||||
static volatile int isplaying=0, initialized = 0;
|
||||
static UBYTE *sfxinfo;
|
||||
static int sfxpool;
|
||||
/* Do not modify the numchn variables yourself! use MikMod_SetNumVoices() */
|
||||
UBYTE md_numchn = 0, md_sngchn = 0, md_sfxchn = 0;
|
||||
UBYTE md_hardchn = 0, md_softchn= 0;
|
||||
|
||||
static SAMPLE **md_sample = NULL;
|
||||
MikMod_player_t md_player = Player_HandleTick;
|
||||
|
||||
MikMod_callback_t vc_callback = NULL;
|
||||
|
||||
/* PRIVATE VARS */
|
||||
static MDRIVER *firstdriver = NULL;
|
||||
|
||||
static volatile int isplaying = 0, initialized = 0;
|
||||
|
||||
static UBYTE *sfxinfo;
|
||||
static int sfxpool;
|
||||
|
||||
static SAMPLE **md_sample = NULL;
|
||||
|
||||
/* Previous driver in use */
|
||||
static SWORD olddevice = -1;
|
||||
static SWORD olddevice = -1;
|
||||
|
||||
/* Limits the number of hardware voices to the specified amount.
|
||||
This function should only be used by the low-level drivers. */
|
||||
|
@ -183,17 +186,18 @@ MIKMODAPI CHAR* MikMod_InfoDriver(void)
|
|||
|
||||
MUTEX_LOCK(lists);
|
||||
/* compute size of buffer */
|
||||
for(l=firstdriver;l;l=l->next)
|
||||
len+=4+(l->next?1:0)+strlen(l->Version);
|
||||
for(l = firstdriver; l; l = l->next)
|
||||
len += 4 + (l->next ? 1 : 0) + strlen(l->Version);
|
||||
|
||||
if(len)
|
||||
if((list=MikMod_malloc(len*sizeof(CHAR)))) {
|
||||
list[0]=0;
|
||||
/* list all registered device drivers : */
|
||||
for(t=1,l=firstdriver;l;l=l->next,t++)
|
||||
sprintf(list,(l->next)?"%s%2d %s\n":"%s%2d %s",
|
||||
list,t,l->Version);
|
||||
if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
|
||||
CHAR *list_end = list;
|
||||
list[0] = 0;
|
||||
/* list all registered device drivers : */
|
||||
for(t = 1, l = firstdriver; l; l = l->next, t++) {
|
||||
list_end += sprintf(list_end, "%2d %s%s", t, l->Version, (l->next)? "\n" : "");
|
||||
}
|
||||
}
|
||||
MUTEX_UNLOCK(lists);
|
||||
return list;
|
||||
}
|
||||
|
@ -214,7 +218,7 @@ void _mm_registerdriver(struct MDRIVER* drv)
|
|||
}
|
||||
cruise->next = drv;
|
||||
} else
|
||||
firstdriver = drv;
|
||||
firstdriver = drv;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +234,7 @@ MIKMODAPI void MikMod_RegisterDriver(struct MDRIVER* drv)
|
|||
MUTEX_UNLOCK(lists);
|
||||
}
|
||||
|
||||
MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias)
|
||||
MIKMODAPI int MikMod_DriverFromAlias(const CHAR *alias)
|
||||
{
|
||||
int rank=1;
|
||||
MDRIVER *cruise;
|
||||
|
@ -252,18 +256,17 @@ MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias)
|
|||
|
||||
MIKMODAPI MDRIVER *MikMod_DriverByOrdinal(int ordinal)
|
||||
{
|
||||
MDRIVER *cruise;
|
||||
MDRIVER *cruise;
|
||||
|
||||
/* Allow only driver ordinals > 0 */
|
||||
if (!ordinal)
|
||||
return 0;
|
||||
/* Allow only driver ordinals > 0 */
|
||||
if (!ordinal) return NULL;
|
||||
|
||||
MUTEX_LOCK(lists);
|
||||
cruise = firstdriver;
|
||||
while (cruise && --ordinal)
|
||||
cruise = cruise->next;
|
||||
MUTEX_UNLOCK(lists);
|
||||
return cruise;
|
||||
MUTEX_LOCK(lists);
|
||||
cruise = firstdriver;
|
||||
while (cruise && --ordinal)
|
||||
cruise = cruise->next;
|
||||
MUTEX_UNLOCK(lists);
|
||||
return cruise;
|
||||
}
|
||||
|
||||
SWORD MD_SampleLoad(SAMPLOAD* s, int type)
|
||||
|
@ -496,14 +499,12 @@ MIKMODAPI ULONG Voice_RealVolume(SBYTE voice)
|
|||
return result;
|
||||
}
|
||||
|
||||
extern MikMod_callback_t vc_callback;
|
||||
|
||||
MIKMODAPI void VC_SetCallback(MikMod_callback_t callback)
|
||||
{
|
||||
vc_callback = callback;
|
||||
}
|
||||
|
||||
static int _mm_init(CHAR *cmdline)
|
||||
static int _mm_init(const CHAR *cmdline)
|
||||
{
|
||||
UWORD t;
|
||||
|
||||
|
@ -561,7 +562,7 @@ static int _mm_init(CHAR *cmdline)
|
|||
return 0;
|
||||
}
|
||||
|
||||
MIKMODAPI int MikMod_Init(CHAR *cmdline)
|
||||
MIKMODAPI int MikMod_Init(const CHAR *cmdline)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -581,8 +582,8 @@ void MikMod_Exit_internal(void)
|
|||
md_numchn = md_sfxchn = md_sngchn = 0;
|
||||
md_driver = &drv_nos;
|
||||
|
||||
if(sfxinfo) MikMod_free(sfxinfo);
|
||||
if(md_sample) MikMod_free(md_sample);
|
||||
MikMod_free(sfxinfo);
|
||||
MikMod_free(md_sample);
|
||||
md_sample = NULL;
|
||||
sfxinfo = NULL;
|
||||
|
||||
|
@ -598,14 +599,14 @@ MIKMODAPI void MikMod_Exit(void)
|
|||
MUTEX_UNLOCK(vars);
|
||||
}
|
||||
|
||||
/* Reset the driver using the new global variable settings.
|
||||
/* Reset the driver using the new global variable settings.
|
||||
If the driver has not been initialized, it will be now. */
|
||||
static int _mm_reset(CHAR *cmdline)
|
||||
static int _mm_reset(const CHAR *cmdline)
|
||||
{
|
||||
int wasplaying = 0;
|
||||
|
||||
if(!initialized) return _mm_init(cmdline);
|
||||
|
||||
|
||||
if (isplaying) {
|
||||
wasplaying = 1;
|
||||
md_driver->PlayStop();
|
||||
|
@ -629,12 +630,12 @@ static int _mm_reset(CHAR *cmdline)
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (wasplaying) md_driver->PlayStart();
|
||||
|
||||
if (wasplaying) return md_driver->PlayStart();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MIKMODAPI int MikMod_Reset(CHAR *cmdline)
|
||||
MIKMODAPI int MikMod_Reset(const CHAR *cmdline)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -661,8 +662,8 @@ int MikMod_SetNumVoices_internal(int music, int sfx)
|
|||
resume = 1;
|
||||
}
|
||||
|
||||
if(sfxinfo) MikMod_free(sfxinfo);
|
||||
if(md_sample) MikMod_free(md_sample);
|
||||
MikMod_free(sfxinfo);
|
||||
MikMod_free(md_sample);
|
||||
md_sample = NULL;
|
||||
sfxinfo = NULL;
|
||||
|
||||
|
@ -764,7 +765,7 @@ MIKMODAPI int MikMod_Active(void)
|
|||
allocated for use as sound effects (loops through voices, skipping all active
|
||||
criticals).
|
||||
|
||||
Returns the voice that the sound is being played on. */
|
||||
Returns the voice that the sound is being played on. */
|
||||
static SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags)
|
||||
{
|
||||
int orig=sfxpool;/* for cases where all channels are critical */
|
||||
|
@ -825,12 +826,15 @@ MIKMODAPI long MikMod_GetVersion(void)
|
|||
#ifdef HAVE_PTHREAD
|
||||
#define INIT_MUTEX(name) \
|
||||
pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
#elif defined(__OS2__)||defined(__EMX__)
|
||||
#define INIT_MUTEX(name) \
|
||||
HMTX _mm_mutex_##name
|
||||
#elif defined(WIN32)
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#define INIT_MUTEX(name) \
|
||||
HANDLE _mm_mutex_##name
|
||||
|
||||
#else
|
||||
#define INIT_MUTEX(name) \
|
||||
void *_mm_mutex_##name = NULL
|
||||
|
@ -842,8 +846,8 @@ INIT_MUTEX(lists);
|
|||
MIKMODAPI int MikMod_InitThreads(void)
|
||||
{
|
||||
static int firstcall=1;
|
||||
static int result=0;
|
||||
|
||||
static int result = 0;
|
||||
|
||||
if (firstcall) {
|
||||
firstcall=0;
|
||||
#ifdef HAVE_PTHREAD
|
||||
|
@ -855,9 +859,9 @@ MIKMODAPI int MikMod_InitThreads(void)
|
|||
result=0;
|
||||
} else
|
||||
result=1;
|
||||
#elif defined(WIN32)
|
||||
if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,"libmikmod(lists)")))||
|
||||
(!(_mm_mutex_vars=CreateMutex(NULL,FALSE,"libmikmod(vars)"))))
|
||||
#elif defined(_WIN32)
|
||||
if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,TEXT("libmikmod(lists)"))))||
|
||||
(!(_mm_mutex_vars=CreateMutex(NULL,FALSE,TEXT("libmikmod(vars)")))))
|
||||
result=0;
|
||||
else
|
||||
result=1;
|
||||
|
@ -880,24 +884,24 @@ MIKMODAPI void MikMod_Lock(void)
|
|||
|
||||
/*========== Parameter extraction helper */
|
||||
|
||||
CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit)
|
||||
CHAR *MD_GetAtom(const CHAR *atomname, const CHAR *cmdline, int implicit)
|
||||
{
|
||||
CHAR *ret=NULL;
|
||||
|
||||
if(cmdline) {
|
||||
CHAR *buf=strstr(cmdline,atomname);
|
||||
const CHAR *buf=strstr(cmdline,atomname);
|
||||
|
||||
if((buf)&&((buf==cmdline)||(*(buf-1)==','))) {
|
||||
CHAR *ptr=buf+strlen(atomname);
|
||||
const CHAR *ptr=buf+strlen(atomname);
|
||||
|
||||
if(*ptr=='=') {
|
||||
for(buf=++ptr;(*ptr)&&((*ptr)!=',');ptr++);
|
||||
ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
|
||||
ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
|
||||
if(ret)
|
||||
strncpy(ret,buf,ptr-buf);
|
||||
} else if((*ptr==',')||(!*ptr)) {
|
||||
if(implicit) {
|
||||
ret=MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
|
||||
ret=(CHAR *)MikMod_malloc((1+ptr-buf)*sizeof(CHAR));
|
||||
if(ret)
|
||||
strncpy(ret,buf,ptr-buf);
|
||||
}
|
||||
|
@ -907,8 +911,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined unix || (defined __APPLE__ && defined __MACH__)
|
||||
#if (MIKMOD_UNIX)
|
||||
|
||||
/*========== Posix helper functions */
|
||||
|
||||
|
@ -917,7 +920,7 @@ CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,int implicit)
|
|||
reasonable. Returns 1 if it is safe to rewrite the file, 0 otherwise.
|
||||
The goal is to prevent a setuid root libmikmod application from overriding
|
||||
files like /etc/passwd with digital sound... */
|
||||
int MD_Access(CHAR *filename)
|
||||
int MD_Access(const CHAR * filename)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
|
@ -934,7 +937,7 @@ int MD_Access(CHAR *filename)
|
|||
} else
|
||||
if(!(buf.st_mode&S_IWOTH)) return 0;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -961,5 +964,5 @@ int MD_DropPrivileges(void)
|
|||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
/* ex:set ts=4: */
|
||||
|
||||
/* ex:set ts=8: */
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
/* Persistent configuration */
|
||||
#define MIKMOD_CONFIGFILE "mikmod.cfg"
|
||||
#define MIKMOD_SETTINGS_MINVERSION 1
|
||||
#define MIKMOD_SETTINGS_VERSION 1
|
||||
#define MIKMOD_SETTINGS_VERSION 2
|
||||
|
||||
#ifdef USETHREADS
|
||||
#define EV_EXIT 9999
|
||||
|
@ -161,7 +161,6 @@ static bool mod_ext(const char ext[])
|
|||
!rb->strcasecmp(ext,".dsm") ||
|
||||
!rb->strcasecmp(ext,".far") ||
|
||||
!rb->strcasecmp(ext,".gdm") ||
|
||||
!rb->strcasecmp(ext,".gt2") ||
|
||||
!rb->strcasecmp(ext,".imf") ||
|
||||
!rb->strcasecmp(ext,".it") ||
|
||||
!rb->strcasecmp(ext,".m15") ||
|
||||
|
@ -174,6 +173,7 @@ static bool mod_ext(const char ext[])
|
|||
!rb->strcasecmp(ext,".stx") ||
|
||||
!rb->strcasecmp(ext,".ult") ||
|
||||
!rb->strcasecmp(ext,".uni") ||
|
||||
!rb->strcasecmp(ext,".umx") ||
|
||||
!rb->strcasecmp(ext,".xm") )
|
||||
return true;
|
||||
else
|
||||
|
@ -305,7 +305,7 @@ static void showinfo(void)
|
|||
rb->lcd_putsxy(1, 1, statustext);
|
||||
sprintf(statustext, "Type: %s", module->modtype);
|
||||
rb->lcd_putsxy(1, 11, statustext);
|
||||
|
||||
|
||||
sprintf(statustext, "Samples: %d", module->numsmp);
|
||||
rb->lcd_putsxy(1, 21, statustext);
|
||||
|
||||
|
@ -315,25 +315,25 @@ static void showinfo(void)
|
|||
rb->lcd_putsxy(1, 31, statustext);
|
||||
}
|
||||
|
||||
sprintf(statustext, "pat: %03d/%03d %2.2X",
|
||||
sprintf(statustext, "pat: %03d/%03d %2.2X",
|
||||
module->sngpos, module->numpos - 1, module->patpos);
|
||||
rb->lcd_putsxy(1, 51, statustext);
|
||||
|
||||
sprintf(statustext, "spd: %d/%d",
|
||||
sprintf(statustext, "spd: %d/%d",
|
||||
module->sngspd, module->bpm);
|
||||
rb->lcd_putsxy(1, 61, statustext);
|
||||
|
||||
sprintf(statustext, "vol: %ddB", rb->global_settings->volume);
|
||||
rb->lcd_putsxy(1, 71, statustext);
|
||||
|
||||
sprintf(statustext, "time: %d:%02d",
|
||||
sprintf(statustext, "time: %d:%02d",
|
||||
(playingtime / 60) % 60, playingtime % 60);
|
||||
rb->lcd_putsxy(1, 81, statustext);
|
||||
|
||||
if (module->flags & UF_NNA)
|
||||
{
|
||||
sprintf(statustext, "chn: %d/%d+%d->%d",
|
||||
module->realchn, module->numchn,
|
||||
module->realchn, module->numchn,
|
||||
module->totalchn - module->realchn,
|
||||
module->totalchn);
|
||||
}
|
||||
|
@ -465,32 +465,44 @@ struct mikmod_settings
|
|||
{
|
||||
int pansep;
|
||||
int reverb;
|
||||
int sample_rate;
|
||||
bool interp;
|
||||
bool reverse;
|
||||
bool surround;
|
||||
bool hqmixer;
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
bool boost;
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct mikmod_settings settings =
|
||||
{
|
||||
128,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1
|
||||
.pansep = 128,
|
||||
.reverb = 0,
|
||||
.sample_rate = -1,
|
||||
.interp = 0,
|
||||
.reverse = 0,
|
||||
.surround = 1,
|
||||
.hqmixer = 0,
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
.boost = 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct mikmod_settings old_settings;
|
||||
|
||||
static struct configdata config[] =
|
||||
static const struct configdata config[] =
|
||||
{
|
||||
{ TYPE_INT, 0, 128, { .int_p = &settings.pansep }, "Panning Separation", NULL},
|
||||
{ TYPE_INT, 0, 15, { .int_p = &settings.reverb }, "Reverberation", NULL},
|
||||
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.interp }, "Interpolation", NULL},
|
||||
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.reverse }, "Reverse Channels", NULL},
|
||||
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.surround }, "Surround", NULL},
|
||||
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.hqmixer }, "HQ Mixer", NULL},
|
||||
{ TYPE_INT, 0, HW_NUM_FREQ-1, { .int_p = &settings.sample_rate }, "Sample Rate", NULL},
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
{ TYPE_BOOL, 0, 1, { .bool_p = &settings.boost }, "CPU Boost", NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
static void applysettings(void)
|
||||
|
@ -498,6 +510,7 @@ static void applysettings(void)
|
|||
md_pansep = settings.pansep;
|
||||
md_reverb = settings.reverb;
|
||||
md_mode = DMODE_STEREO | DMODE_16BITS | DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX;
|
||||
|
||||
if ( settings.interp )
|
||||
{
|
||||
md_mode |= DMODE_INTERP;
|
||||
|
@ -510,6 +523,21 @@ static void applysettings(void)
|
|||
{
|
||||
md_mode |= DMODE_SURROUND;
|
||||
}
|
||||
#ifndef NO_HQMIXER
|
||||
if ( settings.hqmixer )
|
||||
{
|
||||
md_mode |= DMODE_HQMIXER;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (md_mixfreq != rb->hw_freq_sampr[settings.sample_rate]) {
|
||||
md_mixfreq = rb->hw_freq_sampr[settings.sample_rate];
|
||||
// MikMod_Reset(""); BROKEN!
|
||||
rb->pcm_play_stop();
|
||||
rb->mixer_set_frequency(md_mixfreq);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
if ( Player_Active() )
|
||||
{
|
||||
|
@ -518,6 +546,21 @@ static void applysettings(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static const struct opt_items sr_names[HW_NUM_FREQ] = {
|
||||
HW_HAVE_96_([HW_FREQ_96] = { "96kHz", TALK_ID(96, UNIT_KHZ) },)
|
||||
HW_HAVE_88_([HW_FREQ_88] = { "88.2kHz", TALK_ID(88, UNIT_KHZ) },)
|
||||
HW_HAVE_64_([HW_FREQ_64] = { "64kHz", TALK_ID(64, UNIT_KHZ) },)
|
||||
HW_HAVE_48_([HW_FREQ_48] = { "48kHz", TALK_ID(48, UNIT_KHZ) },)
|
||||
HW_HAVE_44_([HW_FREQ_44] = { "44.1kHz", TALK_ID(44, UNIT_KHZ) },)
|
||||
HW_HAVE_32_([HW_FREQ_32] = { "32kHz", TALK_ID(32, UNIT_KHZ) },)
|
||||
HW_HAVE_24_([HW_FREQ_24] = { "24kHz", TALK_ID(24, UNIT_KHZ) },)
|
||||
HW_HAVE_22_([HW_FREQ_22] = { "22.05kHz", TALK_ID(22, UNIT_KHZ) },)
|
||||
HW_HAVE_16_([HW_FREQ_16] = { "16kHz", TALK_ID(16, UNIT_KHZ) },)
|
||||
HW_HAVE_12_([HW_FREQ_12] = { "12kHz", TALK_ID(12, UNIT_KHZ) },)
|
||||
HW_HAVE_11_([HW_FREQ_11] = { "11.025kHz", TALK_ID(11, UNIT_KHZ) },)
|
||||
HW_HAVE_8_( [HW_FREQ_8 ] = { "8kHz", TALK_ID( 8, UNIT_KHZ) },)
|
||||
};
|
||||
|
||||
/**
|
||||
Shows the settings menu
|
||||
*/
|
||||
|
@ -531,6 +574,8 @@ static int settings_menu(void)
|
|||
ID2P(LANG_INTERPOLATION),
|
||||
ID2P(LANG_SWAP_CHANNELS),
|
||||
ID2P(LANG_MIKMOD_SURROUND),
|
||||
ID2P(LANG_MIKMOD_HQMIXER),
|
||||
ID2P(LANG_MIKMOD_SAMPLERATE),
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
ID2P(LANG_CPU_BOOST)
|
||||
#endif
|
||||
|
@ -571,9 +616,22 @@ static int settings_menu(void)
|
|||
break;
|
||||
|
||||
case 5:
|
||||
rb->set_bool(rb->str(LANG_MIKMOD_HQMIXER), &(settings.hqmixer));
|
||||
applysettings();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
rb->set_option(rb->str(LANG_MIKMOD_SAMPLERATE), &(settings.sample_rate), INT, sr_names,
|
||||
HW_NUM_FREQ, NULL);
|
||||
applysettings();
|
||||
break;
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
case 7:
|
||||
rb->set_bool(rb->str(LANG_CPU_BOOST), &(settings.boost));
|
||||
applysettings();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MENU_ATTACHED_USB:
|
||||
return PLUGIN_USB_CONNECTED;
|
||||
|
@ -675,13 +733,12 @@ static int playfile(char* filename)
|
|||
}
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
if ( settings.boost )
|
||||
rb->cpu_boost(true);
|
||||
rb->cpu_boost(settings.boost);
|
||||
#endif
|
||||
#ifdef USETHREADS
|
||||
rb->queue_init(&thread_q, true);
|
||||
if ((thread_id = rb->create_thread(thread, thread_stack,
|
||||
sizeof(thread_stack), 0, "render buffering thread"
|
||||
sizeof(thread_stack), 0, "render buffering thread"
|
||||
IF_PRIO(, PRIORITY_PLAYBACK)
|
||||
IF_COP(, CPU))) == 0)
|
||||
{
|
||||
|
@ -830,11 +887,11 @@ static int playfile(char* filename)
|
|||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
screenupdated = false;
|
||||
break;
|
||||
|
||||
|
||||
case ACTION_WPS_STOP:
|
||||
quit = true;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
|
||||
{
|
||||
|
@ -850,20 +907,19 @@ static int playfile(char* filename)
|
|||
rb->queue_delete(&thread_q);
|
||||
#endif
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
if ( settings.boost )
|
||||
rb->cpu_boost(false);
|
||||
rb->cpu_boost(false);
|
||||
#endif
|
||||
|
||||
Player_Stop();
|
||||
Player_Free(module);
|
||||
|
||||
|
||||
memset(gmbuf, '\0', sizeof(gmbuf));
|
||||
|
||||
|
||||
if ( retval == PLUGIN_OK && entries > 1 && !quit )
|
||||
{
|
||||
retval = change_filename(DIR_NEXT);
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -891,10 +947,9 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
|
||||
rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
|
||||
#endif
|
||||
rb->mixer_set_frequency(SAMPLE_RATE);
|
||||
|
||||
audio_buffer = rb->plugin_get_audio_buffer((size_t *)&audio_buffer_free);
|
||||
|
||||
|
||||
rb->strcpy(np_file, parameter);
|
||||
get_mod_list();
|
||||
if(!entries) {
|
||||
|
@ -903,16 +958,29 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
|
||||
//add_pool(audio_buffer, audio_buffer_free);
|
||||
init_memory_pool(audio_buffer_free, audio_buffer);
|
||||
|
||||
|
||||
MikMod_RegisterDriver(&drv_nos);
|
||||
MikMod_RegisterAllLoaders();
|
||||
MikMod_RegisterErrorHandler(mm_errorhandler);
|
||||
|
||||
md_mixfreq = SAMPLE_RATE;
|
||||
|
||||
configfile_load(MIKMOD_CONFIGFILE, config,
|
||||
ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION);
|
||||
rb->memcpy(&old_settings, &settings, sizeof (settings));
|
||||
|
||||
/* If there's no configured rate, use the default */
|
||||
if (settings.sample_rate == -1) {
|
||||
int i;
|
||||
for (i = 0 ; i < HW_NUM_FREQ ; i++) {
|
||||
if (rb->hw_freq_sampr[i] == SAMPLE_RATE) {
|
||||
settings.sample_rate = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (settings.sample_rate == -1) {
|
||||
settings.sample_rate = HW_NUM_FREQ -1;
|
||||
}
|
||||
}
|
||||
|
||||
applysettings();
|
||||
|
||||
if (MikMod_Init(""))
|
||||
|
@ -934,14 +1002,13 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
|
||||
if (retval == PLUGIN_OK)
|
||||
{
|
||||
rb->splash(0, "Saving Settings");
|
||||
if (rb->memcmp(&settings, &old_settings, sizeof (settings)))
|
||||
{
|
||||
configfile_save(MIKMOD_CONFIGFILE, config,
|
||||
ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION);
|
||||
configfile_save(MIKMOD_CONFIGFILE, config,
|
||||
ARRAYLEN(config), MIKMOD_SETTINGS_MINVERSION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
destroy_memory_pool(audio_buffer);
|
||||
|
||||
return retval;
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,9 @@
|
|||
|
||||
#undef WIN32
|
||||
|
||||
#define NO_DEPACKERS // We don't support these
|
||||
//#define NO_HQMIXER // We don't have the oomph
|
||||
|
||||
#ifndef NO_MMSUPP_DEFINES
|
||||
#define snprintf(...) rb->snprintf(__VA_ARGS__)
|
||||
#define fdprintf(...) rb->fdprintf(__VA_ARGS__)
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mloader.c,v 1.3 2005/04/07 19:57:39 realtech Exp $
|
||||
$Id$
|
||||
|
||||
These routines are used to access the available module loaders
|
||||
|
||||
|
@ -50,7 +50,17 @@ MODULE of;
|
|||
|
||||
static MLOADER *firstloader=NULL;
|
||||
|
||||
UWORD finetune[16]={
|
||||
#ifndef NO_DEPACKERS
|
||||
static MUNPACKER unpackers[] = {
|
||||
PP20_Unpack,
|
||||
MMCMP_Unpack,
|
||||
XPK_Unpack,
|
||||
S404_Unpack,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
const UWORD finetune[16] = {
|
||||
8363,8413,8463,8529,8581,8651,8723,8757,
|
||||
7895,7941,7985,8046,8107,8169,8232,8280
|
||||
};
|
||||
|
@ -63,15 +73,18 @@ MIKMODAPI CHAR* MikMod_InfoLoader(void)
|
|||
|
||||
MUTEX_LOCK(lists);
|
||||
/* compute size of buffer */
|
||||
for(l=firstloader;l;l=l->next) len+=1+(l->next?1:0)+strlen(l->version);
|
||||
for(l = firstloader; l; l = l->next)
|
||||
len += 1 + (l->next ? 1 : 0) + strlen(l->version);
|
||||
|
||||
if(len)
|
||||
if((list=MikMod_malloc(len*sizeof(CHAR)))) {
|
||||
list[0]=0;
|
||||
/* list all registered module loders */
|
||||
for(l=firstloader;l;l=l->next)
|
||||
sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version);
|
||||
if((list=(CHAR*)MikMod_malloc(len*sizeof(CHAR))) != NULL) {
|
||||
CHAR *list_end = list;
|
||||
list[0] = 0;
|
||||
/* list all registered module loders */
|
||||
for(l = firstloader; l; l = l->next) {
|
||||
list_end += sprintf(list_end, "%s%s", l->version, (l->next) ? "\n" : "");
|
||||
}
|
||||
}
|
||||
MUTEX_UNLOCK(lists);
|
||||
return list;
|
||||
}
|
||||
|
@ -84,7 +97,7 @@ void _mm_registerloader(MLOADER* ldr)
|
|||
while(cruise->next) cruise = cruise->next;
|
||||
cruise->next=ldr;
|
||||
} else
|
||||
firstloader=ldr;
|
||||
firstloader=ldr;
|
||||
}
|
||||
|
||||
MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr)
|
||||
|
@ -106,7 +119,7 @@ int ReadComment(UWORD len)
|
|||
|
||||
if(!(of.comment=(CHAR*)MikMod_malloc(len+1))) return 0;
|
||||
_mm_read_UBYTES(of.comment,len,modreader);
|
||||
|
||||
|
||||
/* translate IT linefeeds */
|
||||
for(i=0;i<len;i++)
|
||||
if(of.comment[i]=='\r') of.comment[i]='\n';
|
||||
|
@ -122,44 +135,44 @@ int ReadComment(UWORD len)
|
|||
|
||||
int ReadLinedComment(UWORD len,UWORD linelen)
|
||||
{
|
||||
CHAR *tempcomment,*line,*storage;
|
||||
UWORD total=0,t,lines;
|
||||
int i;
|
||||
/* Adapted from the OpenMPT project, C'ified. */
|
||||
CHAR *buf, *storage, *p;
|
||||
size_t numlines, line, fpos, cpos, lpos, cnt;
|
||||
|
||||
lines = (len + linelen - 1) / linelen;
|
||||
if (len) {
|
||||
if(!(tempcomment=(CHAR*)MikMod_malloc(len+1))) return 0;
|
||||
if(!(storage=(CHAR*)MikMod_malloc(linelen+1))) {
|
||||
MikMod_free(tempcomment);
|
||||
return 0;
|
||||
}
|
||||
memset(tempcomment, ' ', len);
|
||||
_mm_read_UBYTES(tempcomment,len,modreader);
|
||||
if (!linelen) return 0;
|
||||
if (!len) return 1;
|
||||
|
||||
/* compute message length */
|
||||
for(line=tempcomment,total=t=0;t<lines;t++,line+=linelen) {
|
||||
for(i=linelen;(i>=0)&&(line[i]==' ');i--) line[i]=0;
|
||||
for(i=0;i<linelen;i++) if (!line[i]) break;
|
||||
total+=1+i;
|
||||
}
|
||||
if (!(buf = (CHAR *) MikMod_malloc(len))) return 0;
|
||||
numlines = (len + linelen - 1) / linelen;
|
||||
cnt = (linelen + 1) * numlines;
|
||||
if (!(storage = (CHAR *) MikMod_malloc(cnt + 1))) {
|
||||
MikMod_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(total>lines) {
|
||||
if(!(of.comment=(CHAR*)MikMod_malloc(total+1))) {
|
||||
MikMod_free(storage);
|
||||
MikMod_free(tempcomment);
|
||||
return 0;
|
||||
_mm_read_UBYTES(buf,len,modreader);
|
||||
storage[cnt] = 0;
|
||||
for (line = 0, fpos = 0, cpos = 0; line < numlines; line++, fpos += linelen, cpos += (linelen + 1))
|
||||
{
|
||||
cnt = len - fpos;
|
||||
if (cnt > linelen) cnt = linelen;
|
||||
p = storage + cpos;
|
||||
memcpy(p, buf + fpos, cnt);
|
||||
p[cnt] = '\r';
|
||||
/* fix weird chars */
|
||||
for (lpos = 0; lpos < linelen; lpos++, p++) {
|
||||
switch (*p) {
|
||||
case '\0':
|
||||
case '\n':
|
||||
case '\r':
|
||||
*p = ' ';
|
||||
break;
|
||||
}
|
||||
|
||||
/* convert message */
|
||||
for(line=tempcomment,t=0;t<lines;t++,line+=linelen) {
|
||||
for(i=0;i<linelen;i++) if(!(storage[i]=line[i])) break;
|
||||
storage[i]=0; /* if (i==linelen) */
|
||||
strcat(of.comment,storage);strcat(of.comment,"\r");
|
||||
}
|
||||
MikMod_free(storage);
|
||||
MikMod_free(tempcomment);
|
||||
}
|
||||
}
|
||||
|
||||
of.comment = storage;
|
||||
MikMod_free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -169,7 +182,7 @@ int AllocPositions(int total)
|
|||
_mm_errno=MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
}
|
||||
if(!(of.positions=MikMod_calloc(total,sizeof(UWORD)))) return 0;
|
||||
if(!(of.positions=(UWORD*)MikMod_calloc(total,sizeof(UWORD)))) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -207,7 +220,7 @@ int AllocTracks(void)
|
|||
int AllocInstruments(void)
|
||||
{
|
||||
int t,n;
|
||||
|
||||
|
||||
if(!of.numins) {
|
||||
_mm_errno=MMERR_NOT_A_MODULE;
|
||||
return 0;
|
||||
|
@ -216,11 +229,11 @@ int AllocInstruments(void)
|
|||
return 0;
|
||||
|
||||
for(t=0;t<of.numins;t++) {
|
||||
for(n=0;n<INSTNOTES;n++) {
|
||||
for(n=0;n<INSTNOTES;n++) {
|
||||
/* Init note / sample lookup table */
|
||||
of.instruments[t].samplenote[n] = n;
|
||||
of.instruments[t].samplenumber[n] = t;
|
||||
}
|
||||
}
|
||||
of.instruments[t].globvol = 64;
|
||||
}
|
||||
return 1;
|
||||
|
@ -257,8 +270,8 @@ static int ML_LoadSamples(void)
|
|||
}
|
||||
|
||||
/* Creates a CSTR out of a character buffer of 'len' bytes, but strips any
|
||||
terminating non-printing characters like 0, spaces etc. */
|
||||
CHAR *DupStr(CHAR* s,UWORD len,int strict)
|
||||
terminating non-printing characters like 0, spaces etc. */
|
||||
CHAR *DupStr(const CHAR* s, UWORD len, int strict)
|
||||
{
|
||||
UWORD t;
|
||||
CHAR *d=NULL;
|
||||
|
@ -277,48 +290,42 @@ CHAR *DupStr(CHAR* s,UWORD len,int strict)
|
|||
|
||||
/* When the buffer wasn't completely empty, allocate a cstring and copy the
|
||||
buffer into that string, except for any control-chars */
|
||||
if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1)))) {
|
||||
if((d=(CHAR*)MikMod_malloc(sizeof(CHAR)*(len+1))) != NULL) {
|
||||
for(t=0;t<len;t++) d[t]=(s[t]<32)?'.':s[t];
|
||||
d[len]=0;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
CHAR *StrDup(CHAR *s)
|
||||
{
|
||||
size_t l = strlen(s) + 1;
|
||||
CHAR *d = MikMod_malloc(l);
|
||||
strcpy(d, s);
|
||||
return d;
|
||||
}
|
||||
|
||||
static void ML_XFreeSample(SAMPLE *s)
|
||||
{
|
||||
if(s->handle>=0)
|
||||
MD_SampleUnload(s->handle);
|
||||
if(s->samplename) MikMod_free(s->samplename);
|
||||
|
||||
/* moved samplename freeing to our caller ML_FreeEx(),
|
||||
* because we are called conditionally. */
|
||||
}
|
||||
|
||||
static void ML_XFreeInstrument(INSTRUMENT *i)
|
||||
{
|
||||
if(i->insname) MikMod_free(i->insname);
|
||||
MikMod_free(i->insname);
|
||||
}
|
||||
|
||||
static void ML_FreeEx(MODULE *mf)
|
||||
{
|
||||
UWORD t;
|
||||
|
||||
if(mf->songname) MikMod_free(mf->songname);
|
||||
if(mf->comment) MikMod_free(mf->comment);
|
||||
MikMod_free(mf->songname);
|
||||
MikMod_free(mf->comment);
|
||||
|
||||
if(mf->modtype) MikMod_free(mf->modtype);
|
||||
if(mf->positions) MikMod_free(mf->positions);
|
||||
if(mf->patterns) MikMod_free(mf->patterns);
|
||||
if(mf->pattrows) MikMod_free(mf->pattrows);
|
||||
MikMod_free(mf->modtype);
|
||||
MikMod_free(mf->positions);
|
||||
MikMod_free(mf->patterns);
|
||||
MikMod_free(mf->pattrows);
|
||||
|
||||
if(mf->tracks) {
|
||||
for(t=0;t<mf->numtrk;t++)
|
||||
if(mf->tracks[t]) MikMod_free(mf->tracks[t]);
|
||||
MikMod_free(mf->tracks[t]);
|
||||
MikMod_free(mf->tracks);
|
||||
}
|
||||
if(mf->instruments) {
|
||||
|
@ -327,8 +334,10 @@ static void ML_FreeEx(MODULE *mf)
|
|||
MikMod_free(mf->instruments);
|
||||
}
|
||||
if(mf->samples) {
|
||||
for(t=0;t<mf->numsmp;t++)
|
||||
for(t=0;t<mf->numsmp;t++) {
|
||||
MikMod_free(mf->samples[t].samplename);
|
||||
if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]);
|
||||
}
|
||||
MikMod_free(mf->samples);
|
||||
}
|
||||
memset(mf,0,sizeof(MODULE));
|
||||
|
@ -337,11 +346,25 @@ static void ML_FreeEx(MODULE *mf)
|
|||
|
||||
static MODULE *ML_AllocUniMod(void)
|
||||
{
|
||||
MODULE *mf;
|
||||
|
||||
return (mf=MikMod_malloc(sizeof(MODULE)));
|
||||
return (MODULE *) MikMod_malloc(sizeof(MODULE));
|
||||
}
|
||||
|
||||
#ifndef NO_DEPACKERS
|
||||
static int ML_TryUnpack(MREADER *reader,void **out,long *outlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
*out = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
for(i=0;unpackers[i]!=NULL;++i) {
|
||||
_mm_rewind(reader);
|
||||
if(unpackers[i](reader,out,outlen)) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Player_Free_internal(MODULE *mf)
|
||||
{
|
||||
if(mf) {
|
||||
|
@ -360,25 +383,50 @@ MIKMODAPI void Player_Free(MODULE *mf)
|
|||
static CHAR* Player_LoadTitle_internal(MREADER *reader)
|
||||
{
|
||||
MLOADER *l;
|
||||
CHAR *title;
|
||||
#ifndef NO_DEPACKERS
|
||||
void *unpk;
|
||||
long newlen;
|
||||
#endif
|
||||
|
||||
modreader=reader;
|
||||
_mm_errno = 0;
|
||||
_mm_critical = 0;
|
||||
_mm_iobase_setcur(modreader);
|
||||
|
||||
#ifndef NO_DEPACKERS
|
||||
if(ML_TryUnpack(modreader,&unpk,&newlen)) {
|
||||
if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
|
||||
modreader=reader;
|
||||
MikMod_free(unpk);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try to find a loader that recognizes the module */
|
||||
for(l=firstloader;l;l=l->next) {
|
||||
_mm_rewind(modreader);
|
||||
if(l->Test()) break;
|
||||
}
|
||||
|
||||
if(!l) {
|
||||
if(l) {
|
||||
title = l->LoadTitle();
|
||||
}
|
||||
else {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
return NULL;
|
||||
title = NULL;
|
||||
}
|
||||
|
||||
return l->LoadTitle();
|
||||
#ifndef NO_DEPACKERS
|
||||
if (modreader!=reader) {
|
||||
_mm_delete_mem_reader(modreader);
|
||||
modreader=reader;
|
||||
MikMod_free(unpk);
|
||||
}
|
||||
#endif
|
||||
return title;
|
||||
}
|
||||
|
||||
MIKMODAPI CHAR* Player_LoadTitleFP(int fp)
|
||||
|
@ -386,7 +434,7 @@ MIKMODAPI CHAR* Player_LoadTitleFP(int fp)
|
|||
CHAR* result=NULL;
|
||||
MREADER* reader;
|
||||
|
||||
if(fp && (reader=_mm_new_file_reader(fp))) {
|
||||
if(fp && (reader=_mm_new_file_reader(fp)) != NULL) {
|
||||
MUTEX_LOCK(lists);
|
||||
result=Player_LoadTitle_internal(reader);
|
||||
MUTEX_UNLOCK(lists);
|
||||
|
@ -400,22 +448,22 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
|
|||
CHAR *result=NULL;
|
||||
MREADER* reader;
|
||||
|
||||
if ((reader=_mm_new_mem_reader(buffer,len)))
|
||||
if (!buffer || len <= 0) return NULL;
|
||||
if ((reader=_mm_new_mem_reader(buffer,len)) != NULL)
|
||||
{
|
||||
MUTEX_LOCK(lists);
|
||||
result=Player_LoadTitle_internal(reader);
|
||||
MUTEX_UNLOCK(lists);
|
||||
_mm_delete_mem_reader(reader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
|
||||
{
|
||||
{
|
||||
CHAR *result=NULL;
|
||||
|
||||
|
||||
if (reader) {
|
||||
MUTEX_LOCK(lists);
|
||||
result=Player_LoadTitle_internal(reader);
|
||||
|
@ -424,14 +472,14 @@ MIKMODAPI CHAR* Player_LoadTitleGeneric(MREADER *reader)
|
|||
return result;
|
||||
}
|
||||
|
||||
MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename)
|
||||
MIKMODAPI CHAR* Player_LoadTitle(const CHAR* filename)
|
||||
{
|
||||
CHAR* result=NULL;
|
||||
int fp;
|
||||
MREADER* reader;
|
||||
|
||||
if((fp=_mm_fopen(filename,"rb"))) {
|
||||
if((reader=_mm_new_file_reader(fp))) {
|
||||
if((fp=_mm_fopen(filename,"rb")) >= 0) {
|
||||
if((reader=_mm_new_file_reader(fp)) != NULL) {
|
||||
MUTEX_LOCK(lists);
|
||||
result=Player_LoadTitle_internal(reader);
|
||||
MUTEX_UNLOCK(lists);
|
||||
|
@ -449,12 +497,26 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
|
|||
MLOADER *l;
|
||||
int ok;
|
||||
MODULE *mf;
|
||||
#ifndef NO_DEPACKERS
|
||||
void *unpk;
|
||||
long newlen;
|
||||
#endif
|
||||
|
||||
modreader = reader;
|
||||
_mm_errno = 0;
|
||||
_mm_critical = 0;
|
||||
_mm_iobase_setcur(modreader);
|
||||
|
||||
#ifndef NO_DEPACKERS
|
||||
if(ML_TryUnpack(modreader,&unpk,&newlen)) {
|
||||
if(!(modreader=_mm_new_mem_reader(unpk,newlen))) {
|
||||
modreader=reader;
|
||||
MikMod_free(unpk);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try to find a loader that recognizes the module */
|
||||
for(l=firstloader;l;l=l->next) {
|
||||
_mm_rewind(modreader);
|
||||
|
@ -463,15 +525,31 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
|
|||
|
||||
if(!l) {
|
||||
_mm_errno = MMERR_NOT_A_MODULE;
|
||||
#ifndef NO_DEPACKERS
|
||||
if(modreader!=reader) {
|
||||
_mm_delete_mem_reader(modreader);
|
||||
modreader=reader;
|
||||
MikMod_free(unpk);
|
||||
}
|
||||
#endif
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
_mm_rewind(modreader);_mm_iobase_revert(modreader);
|
||||
_mm_rewind(modreader);
|
||||
_mm_iobase_revert(modreader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* init unitrk routines */
|
||||
if(!UniInit()) {
|
||||
#ifndef NO_DEPACKERS
|
||||
if(modreader!=reader) {
|
||||
_mm_delete_mem_reader(modreader);
|
||||
modreader=reader;
|
||||
MikMod_free(unpk);
|
||||
}
|
||||
#endif
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
_mm_rewind(modreader);_mm_iobase_revert(modreader);
|
||||
_mm_rewind(modreader);
|
||||
_mm_iobase_revert(modreader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -487,7 +565,7 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
|
|||
if (!l->Init || l->Init()) {
|
||||
_mm_rewind(modreader);
|
||||
ok = l->Load(curious);
|
||||
if (ok) {
|
||||
if (ok) {
|
||||
/* propagate inflags=flags for in-module samples */
|
||||
for (t = 0; t < of.numsmp; t++)
|
||||
if (of.samples[t].inflags == 0)
|
||||
|
@ -500,27 +578,23 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
|
|||
if (l->Cleanup) l->Cleanup();
|
||||
UniCleanup();
|
||||
|
||||
if(ok) ok = ML_LoadSamples();
|
||||
if(ok) ok = ((mf=ML_AllocUniMod()) != NULL);
|
||||
if(!ok) {
|
||||
ML_FreeEx(&of);
|
||||
#ifndef NO_DEPACKERS
|
||||
if(modreader!=reader) {
|
||||
_mm_delete_mem_reader(modreader);
|
||||
modreader=reader;
|
||||
MikMod_free(unpk);
|
||||
}
|
||||
#endif
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
_mm_rewind(modreader);_mm_iobase_revert(modreader);
|
||||
_mm_rewind(modreader);
|
||||
_mm_iobase_revert(modreader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!ML_LoadSamples()) {
|
||||
ML_FreeEx(&of);
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
_mm_rewind(modreader);_mm_iobase_revert(modreader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!(mf=ML_AllocUniMod())) {
|
||||
ML_FreeEx(&of);
|
||||
_mm_rewind(modreader);_mm_iobase_revert(modreader);
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the module doesn't have any specific panning, create a
|
||||
MOD-like panning, with the channels half-separated. */
|
||||
if (!(of.flags & UF_PANNING))
|
||||
|
@ -539,23 +613,25 @@ static MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,int curio
|
|||
|
||||
if(maxchan<mf->numchn) mf->flags |= UF_NNA;
|
||||
|
||||
if(MikMod_SetNumVoices_internal(maxchan,-1)) {
|
||||
_mm_iobase_revert(modreader);
|
||||
Player_Free(mf);
|
||||
return NULL;
|
||||
}
|
||||
ok = !MikMod_SetNumVoices_internal(maxchan,-1);
|
||||
}
|
||||
if(SL_LoadSamples()) {
|
||||
_mm_iobase_revert(modreader);
|
||||
|
||||
if(ok) ok = !SL_LoadSamples();
|
||||
if(ok) ok = !Player_Init(mf);
|
||||
|
||||
#ifndef NO_DEPACKERS
|
||||
if(modreader!=reader) {
|
||||
_mm_delete_mem_reader(modreader);
|
||||
modreader=reader;
|
||||
MikMod_free(unpk);
|
||||
}
|
||||
#endif
|
||||
_mm_iobase_revert(modreader);
|
||||
|
||||
if(!ok) {
|
||||
Player_Free_internal(mf);
|
||||
return NULL;
|
||||
}
|
||||
if(Player_Init(mf)) {
|
||||
_mm_iobase_revert(modreader);
|
||||
Player_Free_internal(mf);
|
||||
mf=NULL;
|
||||
}
|
||||
_mm_iobase_revert(modreader);
|
||||
return mf;
|
||||
}
|
||||
|
||||
|
@ -577,7 +653,8 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curi
|
|||
MODULE* result=NULL;
|
||||
MREADER* reader;
|
||||
|
||||
if ((reader=_mm_new_mem_reader(buffer, len))) {
|
||||
if (!buffer || len <= 0) return NULL;
|
||||
if ((reader=_mm_new_mem_reader(buffer, len)) != NULL) {
|
||||
result=Player_LoadGeneric(reader,maxchan,curious);
|
||||
_mm_delete_mem_reader(reader);
|
||||
}
|
||||
|
@ -589,9 +666,9 @@ MIKMODAPI MODULE* Player_LoadMem(const char *buffer,int len,int maxchan,int curi
|
|||
MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious)
|
||||
{
|
||||
MODULE* result=NULL;
|
||||
struct MREADER* reader=_mm_new_file_reader (fp);
|
||||
struct MREADER* reader;
|
||||
|
||||
if (reader) {
|
||||
if (fp && (reader=_mm_new_file_reader(fp)) != NULL) {
|
||||
result=Player_LoadGeneric(reader,maxchan,curious);
|
||||
_mm_delete_file_reader(reader);
|
||||
}
|
||||
|
@ -600,12 +677,12 @@ MIKMODAPI MODULE* Player_LoadFP(int fp,int maxchan,int curious)
|
|||
|
||||
/* Open a module via its filename. The loader will initialize the specified
|
||||
song-player 'player'. */
|
||||
MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,int curious)
|
||||
MIKMODAPI MODULE* Player_Load(const CHAR* filename,int maxchan,int curious)
|
||||
{
|
||||
int fp;
|
||||
MODULE *mf=NULL;
|
||||
|
||||
if((fp=_mm_fopen(filename,"rb"))) {
|
||||
if((fp=_mm_fopen(filename,"rb")) >= 0) {
|
||||
mf=Player_LoadFP(fp,maxchan,curious);
|
||||
_mm_fclose(fp);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ static void MikMod_RegisterAllLoaders_internal(void)
|
|||
_mm_registerloader(&load_dsm);
|
||||
_mm_registerloader(&load_far);
|
||||
_mm_registerloader(&load_gdm);
|
||||
_mm_registerloader(&load_gt2);
|
||||
/* _mm_registerloader(&load_gt2);*/ /* load_gt2 isn't complete */
|
||||
_mm_registerloader(&load_it);
|
||||
_mm_registerloader(&load_imf);
|
||||
_mm_registerloader(&load_mod);
|
||||
|
@ -51,13 +51,14 @@ static void MikMod_RegisterAllLoaders_internal(void)
|
|||
_mm_registerloader(&load_stm);
|
||||
_mm_registerloader(&load_stx);
|
||||
_mm_registerloader(&load_ult);
|
||||
_mm_registerloader(&load_umx);
|
||||
_mm_registerloader(&load_uni);
|
||||
_mm_registerloader(&load_xm);
|
||||
|
||||
_mm_registerloader(&load_m15);
|
||||
}
|
||||
|
||||
void MikMod_RegisterAllLoaders(void)
|
||||
MIKMODAPI void MikMod_RegisterAllLoaders(void)
|
||||
{
|
||||
MUTEX_LOCK(lists);
|
||||
MikMod_RegisterAllLoaders_internal();
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mlutil.c,v 1.3 2007/12/06 17:43:10 denis111 Exp $
|
||||
$Id$
|
||||
|
||||
Utility functions for the module loader
|
||||
|
||||
|
@ -43,13 +43,13 @@ extern int fprintf(FILE *, const char *, ...);
|
|||
|
||||
/*========== Shared tracker identifiers */
|
||||
|
||||
CHAR *STM_Signatures[STM_NTRACKERS] = {
|
||||
const CHAR *STM_Signatures[STM_NTRACKERS] = {
|
||||
"!Scream!",
|
||||
"BMOD2STM",
|
||||
"WUZAMOD!"
|
||||
};
|
||||
|
||||
CHAR *STM_Version[STM_NTRACKERS] = {
|
||||
const CHAR *STM_Version[STM_NTRACKERS] = {
|
||||
"Screamtracker 2",
|
||||
"Converted by MOD2STM (STM format)",
|
||||
"Wuzamod (STM format)"
|
||||
|
@ -71,29 +71,27 @@ FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
|
|||
/*========== Linear periods stuff */
|
||||
|
||||
int* noteindex=NULL; /* remap value for linear period modules */
|
||||
static int noteindexcount=0;
|
||||
static unsigned noteindexcount=0;
|
||||
|
||||
int *AllocLinear(void)
|
||||
{
|
||||
if(of.numsmp>noteindexcount) {
|
||||
noteindexcount=of.numsmp;
|
||||
noteindex=MikMod_realloc(noteindex,noteindexcount*sizeof(int));
|
||||
noteindex=(int*)MikMod_realloc(noteindex,noteindexcount*sizeof(int));
|
||||
}
|
||||
return noteindex;
|
||||
}
|
||||
|
||||
void FreeLinear(void)
|
||||
{
|
||||
if(noteindex) {
|
||||
MikMod_free(noteindex);
|
||||
noteindex=NULL;
|
||||
}
|
||||
MikMod_free(noteindex);
|
||||
noteindex=NULL;
|
||||
noteindexcount=0;
|
||||
}
|
||||
|
||||
int speed_to_finetune(ULONG speed,int sample)
|
||||
{
|
||||
ULONG ctmp=0,tmp,note=1,finetune=0;
|
||||
ULONG ctmp=0,tmp,note=1,ft=0;
|
||||
|
||||
speed>>=1;
|
||||
while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) {
|
||||
|
@ -104,16 +102,16 @@ int speed_to_finetune(ULONG speed,int sample)
|
|||
if(tmp!=speed) {
|
||||
if((tmp-speed)<(speed-ctmp))
|
||||
while(tmp>speed)
|
||||
tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune));
|
||||
tmp=getfrequency(of.flags,getlinearperiod(note<<1,--ft));
|
||||
else {
|
||||
note--;
|
||||
while(ctmp<speed)
|
||||
ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++finetune));
|
||||
ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++ft));
|
||||
}
|
||||
}
|
||||
|
||||
noteindex[sample]=note-4*OCTAVE;
|
||||
return finetune;
|
||||
return ft;
|
||||
}
|
||||
|
||||
/*========== Order stuff */
|
||||
|
@ -141,13 +139,9 @@ void S3MIT_CreateOrders(int curious)
|
|||
/*========== Effect stuff */
|
||||
|
||||
/* handles S3M and IT effects */
|
||||
void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
|
||||
void S3MIT_ProcessCmd(UBYTE cmd, UBYTE inf, unsigned int flags)
|
||||
{
|
||||
UBYTE /* hi,*/ lo;
|
||||
|
||||
lo=inf&0xf;
|
||||
/* hi=inf>>4; */
|
||||
|
||||
UBYTE lo = inf&0xF;
|
||||
/* process S3M / IT specific command structure */
|
||||
|
||||
if(cmd!=255) {
|
||||
|
@ -196,7 +190,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
|
|||
case 9: /* Ixy tremor, ontime x, offtime y */
|
||||
if (flags & S3MIT_OLDSTYLE)
|
||||
UniEffect(UNI_S3MEFFECTI,inf);
|
||||
else
|
||||
else
|
||||
UniEffect(UNI_ITEFFECTI,inf);
|
||||
break;
|
||||
case 0xa: /* Jxy arpeggio */
|
||||
|
@ -204,7 +198,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
|
|||
break;
|
||||
case 0xb: /* Kxy Dual command H00 & Dxy */
|
||||
if (flags & S3MIT_OLDSTYLE)
|
||||
UniPTEffect(0x4,0);
|
||||
UniPTEffect(0x4,0);
|
||||
else
|
||||
UniEffect(UNI_ITEFFECTH,0);
|
||||
UniEffect(UNI_S3MEFFECTD,inf);
|
||||
|
@ -218,7 +212,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
|
|||
break;
|
||||
case 0xd: /* Mxx Set Channel Volume */
|
||||
UniEffect(UNI_ITEFFECTM,inf);
|
||||
break;
|
||||
break;
|
||||
case 0xe: /* Nxy Slide Channel Volume */
|
||||
UniEffect(UNI_ITEFFECTN,inf);
|
||||
break;
|
||||
|
@ -233,7 +227,7 @@ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,unsigned int flags)
|
|||
if(inf && !lo && !(flags & S3MIT_OLDSTYLE))
|
||||
UniWriteByte(1);
|
||||
else
|
||||
UniWriteByte(inf);
|
||||
UniWriteByte(inf);
|
||||
break;
|
||||
case 0x12: /* Rxy tremolo speed x, depth y */
|
||||
UniEffect(UNI_S3MEFFECTR,inf);
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mmalloc.c,v 1.3 2007/12/03 20:42:58 denis111 Exp $
|
||||
$Id$
|
||||
|
||||
Dynamic memory routines
|
||||
|
||||
|
@ -30,150 +30,113 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POSIX_MEMALIGN
|
||||
#define _XOPEN_SOURCE 600 /* for posix_memalign */
|
||||
#endif
|
||||
|
||||
#include "string.h"
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
#define ALIGN_STRIDE 16
|
||||
/* not used
|
||||
static void * align_pointer(char *ptr, size_t stride)
|
||||
{
|
||||
char *pptr = ptr + sizeof(void*);
|
||||
char *fptr;
|
||||
size_t err = ((size_t)pptr)&(stride-1);
|
||||
if (err)
|
||||
fptr = pptr + (stride - err);
|
||||
else
|
||||
fptr = pptr;
|
||||
*(size_t*)(fptr - sizeof(void*)) = (size_t)ptr;
|
||||
return fptr;
|
||||
}
|
||||
|
||||
static void *get_pointer(void *data)
|
||||
{
|
||||
unsigned char *_pptr = (unsigned char*)data - sizeof(void*);
|
||||
size_t _ptr = *(size_t*)_pptr;
|
||||
return (void*)_ptr;
|
||||
}
|
||||
*/
|
||||
|
||||
void* MikMod_realloc(void *data, size_t size)
|
||||
{
|
||||
return realloc(data, size);
|
||||
|
||||
#if 0
|
||||
if (data)
|
||||
{
|
||||
#if defined __MACH__
|
||||
void *d = realloc(data, size);
|
||||
if (d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
|
||||
return _aligned_realloc(data, size, ALIGN_STRIDE);
|
||||
#else
|
||||
unsigned char *newPtr = (unsigned char *)realloc(get_pointer(data), size + ALIGN_STRIDE + sizeof(void*));
|
||||
return align_pointer(newPtr, ALIGN_STRIDE);
|
||||
#if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC)
|
||||
#undef WIN32_ALIGNED_MALLOC
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE)
|
||||
# if defined(_WIN64) /* OK with MSVC and MinGW */
|
||||
# define WIN32_ALIGNED_MALLOC
|
||||
# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||
# define WIN32_ALIGNED_MALLOC
|
||||
# elif defined(__MINGW32__)
|
||||
/* no guarantees that msvcrt.dll will have it */
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
return MikMod_malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define PTRSIZE (sizeof(void*))
|
||||
|
||||
/* Same as malloc, but sets error variable _mm_error when fails. Returns a 16-byte aligned pointer */
|
||||
void* MikMod_malloc(size_t size)
|
||||
/* return a 16 byte aligned address */
|
||||
void* MikMod_amalloc(size_t size)
|
||||
{
|
||||
void *d;
|
||||
if(!(d=calloc(1,size))) {
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
}
|
||||
return d;
|
||||
|
||||
#if 0
|
||||
#if defined __MACH__
|
||||
void *d = calloc(1, size);
|
||||
if (d)
|
||||
{
|
||||
#if defined(HAVE_POSIX_MEMALIGN)
|
||||
if (!posix_memalign(&d, 16, size)) {
|
||||
memset(d, 0, size);
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
|
||||
void * d = _aligned_malloc(size, ALIGN_STRIDE);
|
||||
if (d)
|
||||
{
|
||||
#elif defined(WIN32_ALIGNED_MALLOC)
|
||||
d = _aligned_malloc(size, 16);
|
||||
if (d) {
|
||||
ZeroMemory(d, size);
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
void *d = calloc(1, size + ALIGN_STRIDE + sizeof(void*));
|
||||
|
||||
if(!d) {
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
size_t s = (size)? ((size + (PTRSIZE-1)) & ~(PTRSIZE-1)) : PTRSIZE;
|
||||
s += PTRSIZE + 16;
|
||||
d = calloc(1, s);
|
||||
if (d) {
|
||||
char *pptr = (char *)d + PTRSIZE;
|
||||
size_t err = ((size_t)pptr) & 15;
|
||||
char *fptr = pptr + (16 - err);
|
||||
*(size_t*)(fptr - PTRSIZE) = (size_t)d;
|
||||
return fptr;
|
||||
}
|
||||
return align_pointer(d, ALIGN_STRIDE);
|
||||
#endif
|
||||
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MikMod_afree(void *data)
|
||||
{
|
||||
if (!data) return;
|
||||
#if defined(HAVE_POSIX_MEMALIGN)
|
||||
free(data);
|
||||
#elif defined(WIN32_ALIGNED_MALLOC)
|
||||
_aligned_free(data);
|
||||
#else
|
||||
free((void *) *(size_t*)((unsigned char *)data - PTRSIZE));
|
||||
#endif
|
||||
}
|
||||
#endif /* (HAVE_SSE2) || (HAVE_ALTIVEC) */
|
||||
|
||||
void* MikMod_realloc(void *data, size_t size)
|
||||
{
|
||||
if (data) return realloc(data, size);
|
||||
return calloc(1, size);
|
||||
}
|
||||
|
||||
/* Same as malloc, but sets error variable _mm_error when fails */
|
||||
void* MikMod_malloc(size_t size)
|
||||
{
|
||||
return MikMod_calloc(1, size);
|
||||
}
|
||||
|
||||
/* Same as calloc, but sets error variable _mm_error when fails */
|
||||
void* MikMod_calloc(size_t nitems,size_t size)
|
||||
void* MikMod_calloc(size_t nitems, size_t size)
|
||||
{
|
||||
void *d;
|
||||
|
||||
if(!(d=calloc(nitems,size))) {
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
}
|
||||
return d;
|
||||
|
||||
#if 0
|
||||
#if defined __MACH__
|
||||
void *d = calloc(nitems, size);
|
||||
if (d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
|
||||
void * d = _aligned_malloc(size * nitems, ALIGN_STRIDE);
|
||||
if (d)
|
||||
{
|
||||
ZeroMemory(d, size * nitems);
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
void *d = calloc(nitems, size + ALIGN_STRIDE + sizeof(void*));
|
||||
|
||||
if(!d) {
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
}
|
||||
return align_pointer(d, ALIGN_STRIDE);
|
||||
#endif
|
||||
#endif
|
||||
if (d) return d;
|
||||
|
||||
_mm_errno = MMERR_OUT_OF_MEMORY;
|
||||
if(_mm_errorhandler) _mm_errorhandler();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MikMod_free(void *data)
|
||||
{
|
||||
free(data);
|
||||
|
||||
#if 0
|
||||
if (data)
|
||||
{
|
||||
#if defined __MACH__
|
||||
free(data);
|
||||
#elif (defined _WIN32 || defined _WIN64) && !defined(_WIN32_WCE)
|
||||
_aligned_free(data);
|
||||
#else
|
||||
free(get_pointer(data));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (data) free(data);
|
||||
}
|
||||
|
||||
/* like strdup(), but the result must be freed using MikMod_free() */
|
||||
CHAR *MikMod_strdup(const CHAR *s)
|
||||
{
|
||||
size_t l;
|
||||
CHAR *d;
|
||||
|
||||
if (!s) return NULL;
|
||||
|
||||
l = strlen(s) + 1;
|
||||
d = (CHAR *) MikMod_calloc(1, l * sizeof(CHAR));
|
||||
if (d) strcpy(d, s);
|
||||
return d;
|
||||
}
|
||||
|
||||
/* ex:set ts=4: */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mmerror.c,v 1.2 2005/03/30 19:10:41 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Error handling functions.
|
||||
Register an error handler with _mm_RegisterErrorHandler() and you're all set.
|
||||
|
@ -40,7 +40,9 @@
|
|||
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
CHAR *_mm_errmsg[MMERR_MAX+1] =
|
||||
#define _mmerr_invalid "Invalid error code"
|
||||
|
||||
static const char *_mm_errmsg[MMERR_MAX+1] =
|
||||
{
|
||||
/* No error */
|
||||
|
||||
|
@ -82,62 +84,89 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
|
|||
"Unable to set non-blocking mode for audio device",
|
||||
|
||||
/* AudioFile driver errors */
|
||||
|
||||
#ifdef DRV_AF
|
||||
"Cannot find suitable AudioFile audio port",
|
||||
#else
|
||||
_mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* AIX driver errors */
|
||||
|
||||
#ifdef DRV_AIX
|
||||
"Configuration (init step) of audio device failed",
|
||||
"Configuration (control step) of audio device failed",
|
||||
"Configuration (start step) of audio device failed",
|
||||
|
||||
/* ALSA driver errors */
|
||||
|
||||
/* EsounD driver errors */
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* Ultrasound driver errors */
|
||||
|
||||
#ifdef DRV_ULTRA
|
||||
"Ultrasound driver only works in 16 bit stereo 44 KHz",
|
||||
"Ultrasound card could not be reset",
|
||||
"Could not start Ultrasound timer",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* HP driver errors */
|
||||
|
||||
#ifdef DRV_HP
|
||||
"Unable to select 16bit-linear sample format",
|
||||
"Could not select requested sample-rate",
|
||||
"Could not select requested number of channels",
|
||||
"Unable to select audio output",
|
||||
"Unable to get audio description",
|
||||
"Could not set transmission buffer size",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* Open Sound System driver errors */
|
||||
|
||||
#ifdef DRV_OSS
|
||||
"Could not set fragment size",
|
||||
"Could not set sample size",
|
||||
"Could not set mono/stereo setting",
|
||||
"Could not set sample rate",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* SGI driver errors */
|
||||
|
||||
#ifdef DRV_SGI
|
||||
"Unsupported sample rate",
|
||||
"Hardware does not support 16 bit sound",
|
||||
"Hardware does not support 8 bit sound",
|
||||
"Hardware does not support stereo sound",
|
||||
"Hardware does not support mono sound",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* Sun driver errors */
|
||||
|
||||
#ifdef DRV_SUN
|
||||
"Sound device initialization failed",
|
||||
#else
|
||||
_mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* OS/2 drivers errors */
|
||||
|
||||
#if defined(DRV_OS2) || defined(DRV_DART)
|
||||
"Could not set mixing parameters",
|
||||
#else
|
||||
_mmerr_invalid,
|
||||
#endif
|
||||
#ifdef DRV_OS2
|
||||
"Could not create playback semaphores",
|
||||
"Could not create playback timer",
|
||||
"Could not create playback thread",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* DirectSound driver errors */
|
||||
|
||||
#ifdef DRV_DS
|
||||
"Could not set playback priority",
|
||||
"Could not create playback buffers",
|
||||
"Could not set playback format",
|
||||
|
@ -145,22 +174,34 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
|
|||
"Could not register event",
|
||||
"Could not create playback thread",
|
||||
"Could not initialize playback thread",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* Windows Multimedia API driver errors */
|
||||
|
||||
#ifdef DRV_WIN
|
||||
"Invalid device handle",
|
||||
"The resource is already allocated",
|
||||
"Invalid device identifier",
|
||||
"Unsupported output format",
|
||||
"Unknown error",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* Macintosh driver errors */
|
||||
|
||||
#ifdef DRV_MAC
|
||||
"Unsupported sample rate",
|
||||
"Could not start playback",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* MacOS X/Darwin driver errors */
|
||||
|
||||
#ifdef DRV_OSX
|
||||
"Unknown device",
|
||||
"Bad property",
|
||||
"Could not set playback format",
|
||||
|
@ -169,20 +210,81 @@ CHAR *_mm_errmsg[MMERR_MAX+1] =
|
|||
"Could not create playback thread",
|
||||
"Could not start audio device",
|
||||
"Could not create buffer thread",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* DOS driver errors */
|
||||
|
||||
#ifdef DRV_WSS
|
||||
"WSS_STARTDMA",
|
||||
#else
|
||||
_mmerr_invalid,
|
||||
#endif
|
||||
#ifdef DRV_SB
|
||||
"SB_STARTDMA",
|
||||
#else
|
||||
_mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* float32 output */
|
||||
|
||||
"This driver doesn't support 32 bit float output",
|
||||
|
||||
/* OpenAL driver errors */
|
||||
#ifdef DRV_OPENAL
|
||||
"Could not create context",
|
||||
"Could not make context current",
|
||||
"Could not create buffers",
|
||||
"Could not create sources",
|
||||
"Could not change source parameters",
|
||||
"Could not queue buffers",
|
||||
"Could not unqueue buffers",
|
||||
"Could not copy buffer data",
|
||||
"Could not get source parameters",
|
||||
"Could not play source",
|
||||
"Could not stop source",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* ALSA driver errors */
|
||||
#ifdef DRV_ALSA
|
||||
"No ALSA configurations available",
|
||||
"Could not set ALSA output params",
|
||||
"Could not set playback format",
|
||||
"Could not set sample rate",
|
||||
"Could not set mono/stereo setting",
|
||||
"Could not get buffer size from ALSA",
|
||||
"ALSA PCM start error",
|
||||
"ALSA PCM write error",
|
||||
"ALSA PCM recovery failure",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
_mmerr_invalid, _mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* Sndio errors */
|
||||
#ifdef DRV_SNDIO
|
||||
"Could not set SNDIO output params",
|
||||
"Unsupported SNDIO output params",
|
||||
#else
|
||||
_mmerr_invalid, _mmerr_invalid,
|
||||
#endif
|
||||
|
||||
/* Invalid error */
|
||||
|
||||
"Invalid error code"
|
||||
_mmerr_invalid
|
||||
};
|
||||
|
||||
MIKMODAPI char *MikMod_strerror(int code)
|
||||
MIKMODAPI const char *MikMod_strerror(int code)
|
||||
{
|
||||
if ((code<0)||(code>MMERR_MAX)) code=MMERR_MAX+1;
|
||||
if ((code<0)||(code>MMERR_MAX)) code=MMERR_MAX;
|
||||
return _mm_errmsg[code];
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,8 +20,6 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mmio.c,v 1.3 2005/03/30 19:10:58 realtech Exp $
|
||||
|
||||
Portable file I/O routines
|
||||
|
||||
==============================================================================*/
|
||||
|
@ -51,10 +49,14 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "mikmod.h"
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
#ifdef SUNOS
|
||||
|
@ -66,8 +68,6 @@ extern int fseek(FILE *, long, int);
|
|||
extern size_t fwrite(const void *, size_t, size_t, FILE *);
|
||||
#endif
|
||||
|
||||
#define COPY_BUFSIZE 1024
|
||||
|
||||
/* some prototypes */
|
||||
static int _mm_MemReader_Eof(MREADER* reader);
|
||||
static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size);
|
||||
|
@ -75,16 +75,13 @@ static int _mm_MemReader_Get(MREADER* reader);
|
|||
static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence);
|
||||
static long _mm_MemReader_Tell(MREADER* reader);
|
||||
|
||||
//static long _mm_iobase=0,temp_iobase=0;
|
||||
|
||||
int _mm_fopen(CHAR* fname,CHAR* attrib)
|
||||
int _mm_fopen(const CHAR* fname, const CHAR* attrib)
|
||||
{
|
||||
int fp;
|
||||
(void)attrib;
|
||||
|
||||
(void)attrib;
|
||||
//if(!(fp=fopen(fname,attrib))) {
|
||||
// _mm_errno = MMERR_OPENING_FILE;
|
||||
// if(_mm_errorhandler) _mm_errorhandler();
|
||||
// _mm_errno = MMERR_OPENING_FILE;
|
||||
// if(_mm_errorhandler) _mm_errorhandler();
|
||||
//}
|
||||
fp = open(fname, O_RDONLY);
|
||||
if( fp < 0 ) {
|
||||
|
@ -94,7 +91,7 @@ int _mm_fopen(CHAR* fname,CHAR* attrib)
|
|||
return fp;
|
||||
}
|
||||
|
||||
int _mm_FileExists(CHAR* fname)
|
||||
int _mm_FileExists(const CHAR* fname)
|
||||
{
|
||||
int fp;
|
||||
|
||||
|
@ -103,7 +100,7 @@ int _mm_FileExists(CHAR* fname)
|
|||
fp = open(fname, O_RDONLY);
|
||||
if ( fp < 0 ) return 0;
|
||||
close(fp);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -130,12 +127,12 @@ void _mm_iobase_revert(MREADER* reader)
|
|||
|
||||
typedef struct MFILEREADER {
|
||||
MREADER core;
|
||||
int file;
|
||||
int file;
|
||||
} MFILEREADER;
|
||||
|
||||
static int _mm_FileReader_Eof(MREADER* reader)
|
||||
{
|
||||
//return feof(((MFILEREADER*)reader)->file);
|
||||
//return feof(((MFILEREADER*)reader)->file);
|
||||
int size = filesize(((MFILEREADER*)reader)->file);
|
||||
int offset = lseek(((MFILEREADER*)reader)->file, 0, SEEK_CUR);
|
||||
return (size <= 0 || offset < 0 || offset >= size) ? 1 : 0;
|
||||
|
@ -143,8 +140,8 @@ static int _mm_FileReader_Eof(MREADER* reader)
|
|||
|
||||
static int _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size)
|
||||
{
|
||||
//return !!fread(ptr,size,1,((MFILEREADER*)reader)->file);
|
||||
return read(((MFILEREADER*)reader)->file, ptr, size);
|
||||
//return !!fread(ptr,size,1,((MFILEREADER*)reader)->file);
|
||||
}
|
||||
|
||||
static int _mm_FileReader_Get(MREADER* reader)
|
||||
|
@ -160,7 +157,7 @@ static int _mm_FileReader_Get(MREADER* reader)
|
|||
static int _mm_FileReader_Seek(MREADER* reader,long offset,int whence)
|
||||
{
|
||||
//return fseek(((MFILEREADER*)reader)->file,
|
||||
// (whence==SEEK_SET)?offset+reader->iobase:offset,whence);
|
||||
// (whence==SEEK_SET)?offset+reader->iobase:offset,whence);
|
||||
return lseek(((MFILEREADER*)reader)->file,
|
||||
(whence==SEEK_SET)?offset+reader->iobase:offset,whence);
|
||||
}
|
||||
|
@ -173,7 +170,7 @@ static long _mm_FileReader_Tell(MREADER* reader)
|
|||
|
||||
MREADER *_mm_new_file_reader(int fp)
|
||||
{
|
||||
MFILEREADER* reader=(MFILEREADER*)MikMod_malloc(sizeof(MFILEREADER));
|
||||
MFILEREADER* reader=(MFILEREADER*)MikMod_calloc(1,sizeof(MFILEREADER));
|
||||
if (reader) {
|
||||
reader->core.Eof =&_mm_FileReader_Eof;
|
||||
reader->core.Read=&_mm_FileReader_Read;
|
||||
|
@ -187,14 +184,14 @@ MREADER *_mm_new_file_reader(int fp)
|
|||
|
||||
void _mm_delete_file_reader (MREADER* reader)
|
||||
{
|
||||
if(reader) MikMod_free(reader);
|
||||
MikMod_free(reader);
|
||||
}
|
||||
|
||||
/*========== File Writer */
|
||||
|
||||
typedef struct MFILEWRITER {
|
||||
MWRITER core;
|
||||
int file;
|
||||
int file;
|
||||
} MFILEWRITER;
|
||||
|
||||
static int _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence)
|
||||
|
@ -209,27 +206,26 @@ static long _mm_FileWriter_Tell(MWRITER* writer)
|
|||
return lseek(((MFILEWRITER*)writer)->file, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
static int _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size)
|
||||
static int _mm_FileWriter_Write(MWRITER* writer, const void* ptr, size_t size)
|
||||
{
|
||||
//return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size);
|
||||
//return (write(ptr,size,((MFILEWRITER*)writer)->file)==(int)size);
|
||||
(void)writer;
|
||||
(void)ptr;
|
||||
(void)size;
|
||||
return 0;
|
||||
(void)writer;
|
||||
(void)ptr;
|
||||
(void)size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _mm_FileWriter_Put(MWRITER* writer,int value)
|
||||
{
|
||||
(void)writer;
|
||||
(void)value;
|
||||
(void)writer;
|
||||
(void)value;
|
||||
//return fputc(value,((MFILEWRITER*)writer)->file);
|
||||
return 1; // TODO
|
||||
return 1; // TODO
|
||||
}
|
||||
|
||||
MWRITER *_mm_new_file_writer(int fp)
|
||||
{
|
||||
MFILEWRITER* writer=(MFILEWRITER*)MikMod_malloc(sizeof(MFILEWRITER));
|
||||
MFILEWRITER* writer=(MFILEWRITER*)MikMod_calloc(1,sizeof(MFILEWRITER));
|
||||
if (writer) {
|
||||
writer->core.Seek =&_mm_FileWriter_Seek;
|
||||
writer->core.Tell =&_mm_FileWriter_Tell;
|
||||
|
@ -242,12 +238,11 @@ MWRITER *_mm_new_file_writer(int fp)
|
|||
|
||||
void _mm_delete_file_writer (MWRITER* writer)
|
||||
{
|
||||
if(writer) MikMod_free (writer);
|
||||
MikMod_free (writer);
|
||||
}
|
||||
|
||||
/*========== Memory Reader */
|
||||
|
||||
|
||||
typedef struct MMEMREADER {
|
||||
MREADER core;
|
||||
const void *buffer;
|
||||
|
@ -257,12 +252,12 @@ typedef struct MMEMREADER {
|
|||
|
||||
void _mm_delete_mem_reader(MREADER* reader)
|
||||
{
|
||||
if (reader) { MikMod_free(reader); }
|
||||
MikMod_free(reader);
|
||||
}
|
||||
|
||||
MREADER *_mm_new_mem_reader(const void *buffer, int len)
|
||||
MREADER *_mm_new_mem_reader(const void *buffer, long len)
|
||||
{
|
||||
MMEMREADER* reader=(MMEMREADER*)MikMod_malloc(sizeof(MMEMREADER));
|
||||
MMEMREADER* reader=(MMEMREADER*)MikMod_calloc(1,sizeof(MMEMREADER));
|
||||
if (reader)
|
||||
{
|
||||
reader->core.Eof =&_mm_MemReader_Eof;
|
||||
|
@ -279,74 +274,86 @@ MREADER *_mm_new_mem_reader(const void *buffer, int len)
|
|||
|
||||
static int _mm_MemReader_Eof(MREADER* reader)
|
||||
{
|
||||
if (!reader) { return 1; }
|
||||
if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) {
|
||||
return 1;
|
||||
}
|
||||
MMEMREADER* mr = (MMEMREADER*) reader;
|
||||
if (!mr) return 1;
|
||||
if (mr->pos >= mr->len) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _mm_MemReader_Read(MREADER* reader,void* ptr,size_t size)
|
||||
{
|
||||
unsigned char *d=ptr;
|
||||
unsigned char *d;
|
||||
const unsigned char *s;
|
||||
|
||||
if (!reader) { return 0; }
|
||||
MMEMREADER* mr;
|
||||
long siz;
|
||||
int ret;
|
||||
|
||||
if (reader->Eof(reader)) { return 0; }
|
||||
if (!reader || !size || (size > (size_t) LONG_MAX))
|
||||
return 0;
|
||||
|
||||
s = ((MMEMREADER*)reader)->buffer;
|
||||
s += ((MMEMREADER*)reader)->pos;
|
||||
|
||||
if ( ((MMEMREADER*)reader)->pos + (long)size > ((MMEMREADER*)reader)->len)
|
||||
{
|
||||
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len;
|
||||
return 0; /* not enough remaining bytes */
|
||||
mr = (MMEMREADER*) reader;
|
||||
siz = (long) size;
|
||||
if (mr->pos >= mr->len) return 0; /* @ eof */
|
||||
if (mr->pos + siz > mr->len) {
|
||||
siz = mr->len - mr->pos;
|
||||
ret = 0; /* not enough remaining bytes */
|
||||
}
|
||||
else {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
((MMEMREADER*)reader)->pos += (long)size;
|
||||
s = (const unsigned char *) mr->buffer;
|
||||
s += mr->pos;
|
||||
mr->pos += siz;
|
||||
d = (unsigned char *) ptr;
|
||||
|
||||
while (size--)
|
||||
{
|
||||
*d = *s;
|
||||
s++;
|
||||
d++;
|
||||
while (siz) {
|
||||
*d++ = *s++;
|
||||
siz--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _mm_MemReader_Get(MREADER* reader)
|
||||
{
|
||||
int pos;
|
||||
MMEMREADER* mr;
|
||||
int c;
|
||||
|
||||
if (reader->Eof(reader)) { return 0; }
|
||||
|
||||
pos = ((MMEMREADER*)reader)->pos;
|
||||
((MMEMREADER*)reader)->pos++;
|
||||
mr = (MMEMREADER*) reader;
|
||||
if (mr->pos >= mr->len) return EOF;
|
||||
c = ((const unsigned char*) mr->buffer)[mr->pos];
|
||||
mr->pos++;
|
||||
|
||||
return ((unsigned char*)(((MMEMREADER*)reader)->buffer))[pos];
|
||||
return c;
|
||||
}
|
||||
|
||||
static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence)
|
||||
{
|
||||
if (!reader) { return -1; }
|
||||
|
||||
MMEMREADER* mr;
|
||||
|
||||
if (!reader) return -1;
|
||||
mr = (MMEMREADER*) reader;
|
||||
switch(whence)
|
||||
{
|
||||
case SEEK_CUR:
|
||||
((MMEMREADER*)reader)->pos += offset;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
((MMEMREADER*)reader)->pos = offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len - offset - 1;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
mr->pos += offset;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
mr->pos = reader->iobase + offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
mr->pos = mr->len + offset;
|
||||
break;
|
||||
default: /* invalid */
|
||||
return -1;
|
||||
}
|
||||
if ( ((MMEMREADER*)reader)->pos < 0) { ((MMEMREADER*)reader)->pos = 0; }
|
||||
if ( ((MMEMREADER*)reader)->pos > ((MMEMREADER*)reader)->len ) {
|
||||
((MMEMREADER*)reader)->pos = ((MMEMREADER*)reader)->len;
|
||||
if (mr->pos < reader->iobase) {
|
||||
mr->pos = mr->core.iobase;
|
||||
return -1;
|
||||
}
|
||||
if (mr->pos > mr->len) {
|
||||
mr->pos = mr->len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -354,13 +361,14 @@ static int _mm_MemReader_Seek(MREADER* reader,long offset,int whence)
|
|||
static long _mm_MemReader_Tell(MREADER* reader)
|
||||
{
|
||||
if (reader) {
|
||||
return ((MMEMREADER*)reader)->pos;
|
||||
return ((MMEMREADER*)reader)->pos - reader->iobase;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*========== Write functions */
|
||||
void _mm_write_string(CHAR* data,MWRITER* writer)
|
||||
|
||||
void _mm_write_string(const CHAR* data,MWRITER* writer)
|
||||
{
|
||||
if(data)
|
||||
_mm_write_UBYTES(data,strlen(data),writer);
|
||||
|
@ -410,37 +418,51 @@ void _mm_write_I_SLONG(SLONG data,MWRITER* writer)
|
|||
_mm_write_I_ULONG((ULONG)data,writer);
|
||||
}
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \
|
||||
void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \
|
||||
{ \
|
||||
while(number-->0) \
|
||||
_mm_write_##type_name(*(buffer++),writer); \
|
||||
void _mm_write_M_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_M_SWORD(*(buffer++),writer);
|
||||
}
|
||||
#else
|
||||
#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \
|
||||
void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \
|
||||
{ \
|
||||
while(number-->0) \
|
||||
_mm_write_/**/type_name(*(buffer++),writer); \
|
||||
|
||||
void _mm_write_M_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_M_UWORD(*(buffer++),writer);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD)
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD)
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD)
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD)
|
||||
void _mm_write_I_SWORDS(SWORD *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_I_SWORD(*(buffer++),writer);
|
||||
}
|
||||
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG)
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG)
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG)
|
||||
DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG)
|
||||
void _mm_write_I_UWORDS(UWORD *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_I_UWORD(*(buffer++),writer);
|
||||
}
|
||||
|
||||
void _mm_write_M_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_M_SLONG(*(buffer++),writer);
|
||||
}
|
||||
|
||||
void _mm_write_M_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_M_ULONG(*(buffer++),writer);
|
||||
}
|
||||
|
||||
void _mm_write_I_SLONGS(SLONG *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_I_SLONG(*(buffer++),writer);
|
||||
}
|
||||
|
||||
void _mm_write_I_ULONGS(ULONG *buffer,int cnt,MWRITER* writer)
|
||||
{
|
||||
while(cnt-- > 0) _mm_write_I_ULONG(*(buffer++),writer);
|
||||
}
|
||||
|
||||
/*========== Read functions */
|
||||
|
||||
int _mm_read_string(CHAR* buffer,int number,MREADER* reader)
|
||||
int _mm_read_string(CHAR* buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
return reader->Read(reader,buffer,number);
|
||||
return reader->Read(reader,buffer,cnt);
|
||||
}
|
||||
|
||||
UWORD _mm_read_M_UWORD(MREADER* reader)
|
||||
|
@ -491,32 +513,52 @@ SLONG _mm_read_I_SLONG(MREADER* reader)
|
|||
return((SLONG)_mm_read_I_ULONG(reader));
|
||||
}
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \
|
||||
int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \
|
||||
{ \
|
||||
while(number-->0) \
|
||||
*(buffer++)=_mm_read_##type_name(reader); \
|
||||
return !reader->Eof(reader); \
|
||||
int _mm_read_M_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_M_SWORD(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
#else
|
||||
#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \
|
||||
int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \
|
||||
{ \
|
||||
while(number-->0) \
|
||||
*(buffer++)=_mm_read_/**/type_name(reader); \
|
||||
return !reader->Eof(reader); \
|
||||
|
||||
int _mm_read_M_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_M_UWORD(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD)
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD)
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD)
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD)
|
||||
int _mm_read_I_SWORDS(SWORD *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_I_SWORD(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG)
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG)
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG)
|
||||
DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG)
|
||||
int _mm_read_I_UWORDS(UWORD *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_I_UWORD(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
|
||||
int _mm_read_M_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_M_SLONG(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
|
||||
int _mm_read_M_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_M_ULONG(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
|
||||
int _mm_read_I_SLONGS(SLONG *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_I_SLONG(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
|
||||
int _mm_read_I_ULONGS(ULONG *buffer,int cnt,MREADER* reader)
|
||||
{
|
||||
while(cnt-- > 0) *(buffer++)=_mm_read_I_ULONG(reader);
|
||||
return !reader->Eof(reader);
|
||||
}
|
||||
|
||||
/* ex:set ts=4: */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: mplayer.c,v 1.4 2006/08/08 00:06:31 realtech Exp $
|
||||
$Id$
|
||||
|
||||
The Protracker Player Driver
|
||||
|
||||
|
@ -40,31 +40,35 @@
|
|||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
#ifdef SUNOS
|
||||
extern int fprintf(FILE *, const char *, ...);
|
||||
extern int fprintf(int, const char *, ...);
|
||||
extern long int random(void);
|
||||
#endif
|
||||
|
||||
/* The currently playing module */
|
||||
MODULE *pf = NULL;
|
||||
|
||||
#define NUMVOICES(mod) (md_sngchn < (mod)->numvoices ? md_sngchn : (mod)->numvoices)
|
||||
|
||||
#define HIGH_OCTAVE 2 /* number of above-range octaves */
|
||||
|
||||
static UWORD oldperiods[OCTAVE*2]={
|
||||
static const UWORD oldperiods[OCTAVE*2]={
|
||||
0x6b00, 0x6800, 0x6500, 0x6220, 0x5f50, 0x5c80,
|
||||
0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0,
|
||||
0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160,
|
||||
0x3f90, 0x3dc0, 0x3c10, 0x3a40, 0x38b0, 0x3700
|
||||
};
|
||||
|
||||
static UBYTE VibratoTable[32]={
|
||||
static const UBYTE VibratoTable[32]={
|
||||
0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253,
|
||||
255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24
|
||||
};
|
||||
|
||||
static UBYTE avibtab[128]={
|
||||
static const UBYTE avibtab[128]={
|
||||
0, 1, 3, 4, 6, 7, 9,10,12,14,15,17,18,20,21,23,
|
||||
24,25,27,28,30,31,32,34,35,36,38,39,40,41,42,44,
|
||||
45,46,47,48,49,50,51,52,53,54,54,55,56,57,57,58,
|
||||
|
@ -76,7 +80,7 @@ static UBYTE avibtab[128]={
|
|||
};
|
||||
|
||||
/* Triton's linear periods to frequency translation table (for XM modules) */
|
||||
static ULONG lintab[768]={
|
||||
static const ULONG lintab[768]={
|
||||
535232,534749,534266,533784,533303,532822,532341,531861,
|
||||
531381,530902,530423,529944,529466,528988,528511,528034,
|
||||
527558,527082,526607,526131,525657,525183,524709,524236,
|
||||
|
@ -176,7 +180,7 @@ static ULONG lintab[768]={
|
|||
};
|
||||
|
||||
#define LOGFAC 2*16
|
||||
static UWORD logtab[104]={
|
||||
static const UWORD logtab[104]={
|
||||
LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887,
|
||||
LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862,
|
||||
LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838,
|
||||
|
@ -205,7 +209,7 @@ static UWORD logtab[104]={
|
|||
LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431
|
||||
};
|
||||
|
||||
static SBYTE PanbrelloTable[256]={
|
||||
static const SBYTE PanbrelloTable[256]={
|
||||
0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23,
|
||||
24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44,
|
||||
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
|
||||
|
@ -225,12 +229,12 @@ static SBYTE PanbrelloTable[256]={
|
|||
};
|
||||
|
||||
/* returns a random value between 0 and ceil-1, ceil must be a power of two */
|
||||
static int getrandom(int ceil)
|
||||
static int getrandom(int ceilval)
|
||||
{
|
||||
#ifdef HAVE_SRANDOM
|
||||
return random()&(ceil-1);
|
||||
#if defined(HAVE_SRANDOM) && !defined(_MIKMOD_AMIGA)
|
||||
return random()&(ceilval-1);
|
||||
#else
|
||||
return (rand()*ceil)/(RAND_MAX+1.0);
|
||||
return (rand()*ceilval)/(RAND_MAX+1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -246,14 +250,14 @@ static int MP_FindEmptyChannel(MODULE *mod)
|
|||
MP_VOICE *a;
|
||||
ULONG t,k,tvol,pp;
|
||||
|
||||
for (t=0;t<md_sngchn;t++)
|
||||
for (t=0;t<NUMVOICES(mod);t++)
|
||||
if (((mod->voice[t].main.kick==KICK_ABSENT)||
|
||||
(mod->voice[t].main.kick==KICK_ENV))&&
|
||||
Voice_Stopped_internal(t))
|
||||
return t;
|
||||
|
||||
tvol=0xffffffUL;t=-1;a=mod->voice;
|
||||
for (k=0;k<md_sngchn;k++,a++) {
|
||||
for (k=0;k<NUMVOICES(mod);k++,a++) {
|
||||
/* allow us to take over a nonexisting sample */
|
||||
if (!a->main.s)
|
||||
return k;
|
||||
|
@ -325,9 +329,9 @@ static UWORD GetPeriod(UWORD flags, UWORD note, ULONG speed)
|
|||
{
|
||||
if (flags & UF_XMPERIODS) {
|
||||
if (flags & UF_LINEAR)
|
||||
return getlinearperiod(note, speed);
|
||||
return getlinearperiod(note, speed);
|
||||
else
|
||||
return getlogperiod(note, speed);
|
||||
return getlogperiod(note, speed);
|
||||
} else
|
||||
return getoldperiod(note, speed);
|
||||
}
|
||||
|
@ -359,9 +363,15 @@ static SWORD StartEnvelope(ENVPR *t,UBYTE flg,UBYTE pts,UBYTE susbeg,UBYTE susen
|
|||
t->a=0;
|
||||
t->b=((t->flg&EF_SUSTAIN)&&(!(keyoff&KEY_OFF)))?0:1;
|
||||
|
||||
if (!t->pts) { /* FIXME: bad/crafted file. better/more general solution? */
|
||||
t->b=0;
|
||||
return t->env[0].val;
|
||||
}
|
||||
|
||||
/* Imago Orpheus sometimes stores an extra initial point in the envelope */
|
||||
if ((t->pts>=2)&&(t->env[0].pos==t->env[1].pos)) {
|
||||
t->a++;t->b++;
|
||||
t->a++;
|
||||
t->b++;
|
||||
}
|
||||
|
||||
/* Fit in the envelope, still */
|
||||
|
@ -615,10 +625,10 @@ static void DoToneSlide(UWORD tick, MP_CONTROL *a)
|
|||
/* ...make tmpperiod equal tperiod */
|
||||
a->tmpperiod=a->main.period=a->wantedperiod;
|
||||
else if (dist>0) {
|
||||
a->tmpperiod-=a->portspeed;
|
||||
a->tmpperiod-=a->portspeed;
|
||||
a->main.period-=a->portspeed; /* dist>0, slide up */
|
||||
} else {
|
||||
a->tmpperiod+=a->portspeed;
|
||||
a->tmpperiod+=a->portspeed;
|
||||
a->main.period+=a->portspeed; /* dist<0, slide down */
|
||||
}
|
||||
} else
|
||||
|
@ -786,8 +796,8 @@ static int DoPTEffect7(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UBYTE dat;
|
||||
(void)tick;
|
||||
(void)flags;
|
||||
(void)tick;
|
||||
(void)flags;
|
||||
|
||||
dat = UniGetByte();
|
||||
if (mod->panflag)
|
||||
|
@ -799,16 +809,16 @@ static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UBYTE dat;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
|
||||
dat=UniGetByte();
|
||||
if (!tick) {
|
||||
if (dat) a->soffset=(UWORD)dat<<8;
|
||||
a->main.start=a->hioffset|a->soffset;
|
||||
|
||||
if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length))
|
||||
if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length))
|
||||
a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
|
||||
a->main.s->loopstart:a->main.s->length;
|
||||
}
|
||||
|
@ -819,9 +829,9 @@ static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UBYTE dat;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
|
||||
dat=UniGetByte();
|
||||
if (tick)
|
||||
|
@ -842,14 +852,19 @@ static int DoPTEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UBYTE dat;
|
||||
(void)a;
|
||||
(void)channel;
|
||||
(void)a;
|
||||
(void)channel;
|
||||
|
||||
dat=UniGetByte();
|
||||
|
||||
if (tick || mod->patdly2)
|
||||
return 0;
|
||||
|
||||
if (dat >= mod->numpos) { /* crafted file? */
|
||||
/* fprintf(stderr,"DoPTEffectB: numpos=%d, dat=%d -> %d\n",mod->numpos,dat,mod->numpos-1);*/
|
||||
dat=mod->numpos-1;
|
||||
}
|
||||
|
||||
/* Vincent Voois uses a nasty trick in "Universal Bolero" */
|
||||
if (dat == mod->sngpos && mod->patbrk == mod->patpos)
|
||||
return 0;
|
||||
|
@ -857,8 +872,8 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
if (!mod->loop && !mod->patbrk &&
|
||||
(dat < mod->sngpos ||
|
||||
(mod->sngpos == (mod->numpos - 1) && !mod->patbrk) ||
|
||||
(dat == mod->sngpos && (flags & UF_NOWRAP))
|
||||
)) {
|
||||
(dat == mod->sngpos && (flags & UF_NOWRAP)) ) )
|
||||
{
|
||||
/* if we don't loop, better not to skip the end of the
|
||||
pattern, after all... so:
|
||||
mod->patbrk=0; */
|
||||
|
@ -870,6 +885,9 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
mod->sngpos=dat;
|
||||
mod->posjmp=2;
|
||||
mod->patpos=0;
|
||||
/* cancel the FT2 pattern loop (E60) bug.
|
||||
* also see DoEEffects() below for it. */
|
||||
if (flags & UF_FT2QUIRKS) mod->patbrk=0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -878,15 +896,15 @@ static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UBYTE dat;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
|
||||
dat=UniGetByte();
|
||||
if (tick) return 0;
|
||||
if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */
|
||||
else if (dat>64) dat=64;
|
||||
a->tmpvolume=dat;
|
||||
dat=UniGetByte();
|
||||
if (tick) return 0;
|
||||
if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */
|
||||
else if (dat>64) dat=64;
|
||||
a->tmpvolume=dat;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -894,29 +912,33 @@ static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UBYTE dat;
|
||||
(void)a;
|
||||
(void)channel;
|
||||
(void)a;
|
||||
(void)channel;
|
||||
|
||||
dat=UniGetByte();
|
||||
if ((tick)||(mod->patdly2)) return 0;
|
||||
if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&&
|
||||
(dat>mod->pattrows[mod->positions[mod->sngpos]]))
|
||||
dat=mod->pattrows[mod->positions[mod->sngpos]];
|
||||
mod->patbrk=dat;
|
||||
if (!mod->posjmp) {
|
||||
/* don't ask me to explain this code - it makes
|
||||
backwards.s3m and children.xm (heretic's version) play
|
||||
correctly, among others. Take that for granted, or write
|
||||
the page of comments yourself... you might need some
|
||||
aspirin - Miod */
|
||||
if ((mod->sngpos==mod->numpos-1)&&(dat)&&((mod->loop)||
|
||||
(mod->positions[mod->sngpos]==(mod->numpat-1)
|
||||
&& !(flags&UF_NOWRAP)))) {
|
||||
mod->sngpos=0;
|
||||
mod->posjmp=2;
|
||||
} else
|
||||
mod->posjmp=3;
|
||||
}
|
||||
dat=UniGetByte();
|
||||
if ((tick)||(mod->patdly2)) return 0;
|
||||
if (dat && dat >= mod->numrow) { /* crafted file? */
|
||||
/* fprintf(stderr,"DoPTEffectD: numrow=%d, dat=%d -> 0\n",mod->numrow,dat);*/
|
||||
dat=0;
|
||||
}
|
||||
if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&&
|
||||
(dat>mod->pattrows[mod->positions[mod->sngpos]])) {
|
||||
dat=mod->pattrows[mod->positions[mod->sngpos]];
|
||||
}
|
||||
mod->patbrk=dat;
|
||||
if (!mod->posjmp) {
|
||||
/* don't ask me to explain this code - it makes
|
||||
backwards.s3m and children.xm (heretic's version) play
|
||||
correctly, among others. Take that for granted, or write
|
||||
the page of comments yourself... you might need some
|
||||
aspirin - Miod */
|
||||
if ((mod->sngpos==mod->numpos-1)&&(dat)&&
|
||||
((mod->loop) || (mod->positions[mod->sngpos]==(mod->numpat-1) && !(flags&UF_NOWRAP)))) {
|
||||
mod->sngpos=0;
|
||||
mod->posjmp=2;
|
||||
} else
|
||||
mod->posjmp=3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -982,8 +1004,13 @@ static void DoEEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod,
|
|||
} else
|
||||
mod->patpos=a->pat_reppos;
|
||||
} else a->pat_reppos=POS_NONE;
|
||||
} else
|
||||
} else {
|
||||
a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */
|
||||
/* emulate the FT2 pattern loop (E60) bug:
|
||||
* http://milkytracker.org/docs/MilkyTracker.html#fxE6x
|
||||
* roadblas.xm plays correctly with this. */
|
||||
if (flags & UF_FT2QUIRKS) mod->patbrk=mod->patpos;
|
||||
}
|
||||
break;
|
||||
case 0x7: /* set tremolo waveform */
|
||||
a->wavecontrol&=0x0f;
|
||||
|
@ -1065,7 +1092,7 @@ static int DoPTEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
if (tick||mod->patdly2) return 0;
|
||||
if (mod->extspd&&(dat>=mod->bpmlimit))
|
||||
mod->bpm=dat;
|
||||
else
|
||||
else
|
||||
if (dat) {
|
||||
mod->sngspd=(dat>=mod->bpmlimit)?mod->bpmlimit-1:dat;
|
||||
mod->vbtick=0;
|
||||
|
@ -1465,7 +1492,7 @@ static int DoXMEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
a->s3mvolslide = inf;
|
||||
else
|
||||
inf = a->s3mvolslide;
|
||||
|
||||
|
||||
if (tick) {
|
||||
lo=inf&0xf;
|
||||
hi=inf>>4;
|
||||
|
@ -1608,7 +1635,7 @@ static int DoXMEffectL(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
INSTRUMENT *i=a->main.i;
|
||||
MP_VOICE *aout;
|
||||
|
||||
if ((aout=a->slave)) {
|
||||
if ((aout=a->slave) != NULL) {
|
||||
if (aout->venv.env) {
|
||||
points=i->volenv[i->volpts-1].pos;
|
||||
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)
|
|||
/* if we don't come from another note, ignore the slide and play the note
|
||||
as is */
|
||||
if (!a->oldnote || !a->main.period)
|
||||
return;
|
||||
return;
|
||||
|
||||
if ((!tick)&&(a->newsamp)){
|
||||
a->main.kick=KICK_NOTE;
|
||||
|
@ -1725,15 +1752,15 @@ static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat)
|
|||
difference between those two values */
|
||||
dist=a->main.period-a->wantedperiod;
|
||||
|
||||
/* if they are equal or if portamentospeed is too big... */
|
||||
/* if they are equal or if portamentospeed is too big... */
|
||||
if ((!dist)||((a->portspeed<<2)>abs(dist)))
|
||||
/* ... make tmpperiod equal tperiod */
|
||||
a->tmpperiod=a->main.period=a->wantedperiod;
|
||||
else
|
||||
if (dist>0) {
|
||||
if (dist>0) {
|
||||
a->tmpperiod-=a->portspeed<<2;
|
||||
a->main.period-=a->portspeed<<2; /* dist>0 slide up */
|
||||
} else {
|
||||
} else {
|
||||
a->tmpperiod+=a->portspeed<<2;
|
||||
a->main.period+=a->portspeed<<2; /* dist<0 slide down */
|
||||
}
|
||||
|
@ -1762,7 +1789,7 @@ static void DoITVibrato(UWORD tick, MP_CONTROL *a, UBYTE dat)
|
|||
if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
|
||||
}
|
||||
if (!a->main.period)
|
||||
return;
|
||||
return;
|
||||
|
||||
q=(a->vibpos>>2)&0x1f;
|
||||
|
||||
|
@ -1867,7 +1894,7 @@ static int DoITEffectN(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWOR
|
|||
lo=inf&0xf;
|
||||
hi=inf>>4;
|
||||
|
||||
if (!hi)
|
||||
if (!hi)
|
||||
a->main.chanvol-=lo;
|
||||
else
|
||||
if (!lo) {
|
||||
|
@ -2105,13 +2132,13 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
|
|||
switch (c) {
|
||||
case SS_GLISSANDO: /* S1x set glissando voice */
|
||||
DoEEffects(tick, flags, a, mod, channel, 0x30|inf);
|
||||
break;
|
||||
break;
|
||||
case SS_FINETUNE: /* S2x set finetune */
|
||||
DoEEffects(tick, flags, a, mod, channel, 0x50|inf);
|
||||
break;
|
||||
case SS_VIBWAVE: /* S3x set vibrato waveform */
|
||||
DoEEffects(tick, flags, a, mod, channel, 0x40|inf);
|
||||
break;
|
||||
break;
|
||||
case SS_TREMWAVE: /* S4x set tremolo waveform */
|
||||
DoEEffects(tick, flags, a, mod, channel, 0x70|inf);
|
||||
break;
|
||||
|
@ -2130,13 +2157,13 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
|
|||
case SS_SURROUND: /* S9x set surround sound */
|
||||
if (mod->panflag)
|
||||
a->main.panning = mod->panning[channel] = PAN_SURROUND;
|
||||
break;
|
||||
break;
|
||||
case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */
|
||||
if (!tick) {
|
||||
a->hioffset=inf<<16;
|
||||
a->main.start=a->hioffset|a->soffset;
|
||||
|
||||
if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length))
|
||||
if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length))
|
||||
a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
|
||||
a->main.s->loopstart:a->main.s->length;
|
||||
}
|
||||
|
@ -2168,10 +2195,10 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
|
|||
static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UBYTE c, inf;
|
||||
(void)channel;
|
||||
|
||||
c = UniGetByte();
|
||||
inf = UniGetByte();
|
||||
(void)channel;
|
||||
|
||||
c = UniGetByte();
|
||||
inf = UniGetByte();
|
||||
|
||||
if ((!c)&&(!inf)) {
|
||||
c=a->voleffect;
|
||||
|
@ -2219,16 +2246,16 @@ static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
|
|||
static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
|
||||
{
|
||||
UWORD offset=UniGetWord();
|
||||
(void)tick;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
(void)tick;
|
||||
(void)flags;
|
||||
(void)mod;
|
||||
(void)channel;
|
||||
|
||||
if (offset)
|
||||
a->ultoffset=offset;
|
||||
|
||||
a->main.start=a->ultoffset<<2;
|
||||
if ((a->main.s)&&(a->main.start > (SLONG)a->main.s->length))
|
||||
if ((a->main.s)&&(a->main.start>(SLONG)a->main.s->length))
|
||||
a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
|
||||
a->main.s->loopstart:a->main.s->length;
|
||||
|
||||
|
@ -2310,68 +2337,68 @@ static int DoNothing(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD
|
|||
typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD);
|
||||
|
||||
static effect_func effects[UNI_LAST] = {
|
||||
DoNothing, /* 0 */
|
||||
DoNothing, /* UNI_NOTE */
|
||||
DoNothing, /* UNI_INSTRUMENT */
|
||||
DoPTEffect0, /* UNI_PTEFFECT0 */
|
||||
DoPTEffect1, /* UNI_PTEFFECT1 */
|
||||
DoPTEffect2, /* UNI_PTEFFECT2 */
|
||||
DoPTEffect3, /* UNI_PTEFFECT3 */
|
||||
DoPTEffect4, /* UNI_PTEFFECT4 */
|
||||
DoPTEffect5, /* UNI_PTEFFECT5 */
|
||||
DoPTEffect6, /* UNI_PTEFFECT6 */
|
||||
DoPTEffect7, /* UNI_PTEFFECT7 */
|
||||
DoPTEffect8, /* UNI_PTEFFECT8 */
|
||||
DoPTEffect9, /* UNI_PTEFFECT9 */
|
||||
DoPTEffectA, /* UNI_PTEFFECTA */
|
||||
DoPTEffectB, /* UNI_PTEFFECTB */
|
||||
DoPTEffectC, /* UNI_PTEFFECTC */
|
||||
DoPTEffectD, /* UNI_PTEFFECTD */
|
||||
DoPTEffectE, /* UNI_PTEFFECTE */
|
||||
DoPTEffectF, /* UNI_PTEFFECTF */
|
||||
DoS3MEffectA, /* UNI_S3MEFFECTA */
|
||||
DoS3MEffectD, /* UNI_S3MEFFECTD */
|
||||
DoS3MEffectE, /* UNI_S3MEFFECTE */
|
||||
DoS3MEffectF, /* UNI_S3MEFFECTF */
|
||||
DoS3MEffectI, /* UNI_S3MEFFECTI */
|
||||
DoS3MEffectQ, /* UNI_S3MEFFECTQ */
|
||||
DoS3MEffectR, /* UNI_S3MEFFECTR */
|
||||
DoS3MEffectT, /* UNI_S3MEFFECTT */
|
||||
DoS3MEffectU, /* UNI_S3MEFFECTU */
|
||||
DoKeyOff, /* UNI_KEYOFF */
|
||||
DoKeyFade, /* UNI_KEYFADE */
|
||||
DoVolEffects, /* UNI_VOLEFFECTS */
|
||||
DoPTEffect4, /* UNI_XMEFFECT4 */
|
||||
DoXMEffect6, /* UNI_XMEFFECT6 */
|
||||
DoXMEffectA, /* UNI_XMEFFECTA */
|
||||
DoXMEffectE1, /* UNI_XMEFFECTE1 */
|
||||
DoXMEffectE2, /* UNI_XMEFFECTE2 */
|
||||
DoXMEffectEA, /* UNI_XMEFFECTEA */
|
||||
DoXMEffectEB, /* UNI_XMEFFECTEB */
|
||||
DoXMEffectG, /* UNI_XMEFFECTG */
|
||||
DoXMEffectH, /* UNI_XMEFFECTH */
|
||||
DoXMEffectL, /* UNI_XMEFFECTL */
|
||||
DoXMEffectP, /* UNI_XMEFFECTP */
|
||||
DoXMEffectX1, /* UNI_XMEFFECTX1 */
|
||||
DoXMEffectX2, /* UNI_XMEFFECTX2 */
|
||||
DoITEffectG, /* UNI_ITEFFECTG */
|
||||
DoITEffectH, /* UNI_ITEFFECTH */
|
||||
DoITEffectI, /* UNI_ITEFFECTI */
|
||||
DoITEffectM, /* UNI_ITEFFECTM */
|
||||
DoITEffectN, /* UNI_ITEFFECTN */
|
||||
DoITEffectP, /* UNI_ITEFFECTP */
|
||||
DoITEffectT, /* UNI_ITEFFECTT */
|
||||
DoITEffectU, /* UNI_ITEFFECTU */
|
||||
DoITEffectW, /* UNI_ITEFFECTW */
|
||||
DoITEffectY, /* UNI_ITEFFECTY */
|
||||
DoNothing, /* UNI_ITEFFECTZ */
|
||||
DoITEffectS0, /* UNI_ITEFFECTS0 */
|
||||
DoULTEffect9, /* UNI_ULTEFFECT9 */
|
||||
DoMEDSpeed, /* UNI_MEDSPEED */
|
||||
DoMEDEffectF1, /* UNI_MEDEFFECTF1 */
|
||||
DoMEDEffectF2, /* UNI_MEDEFFECTF2 */
|
||||
DoMEDEffectF3, /* UNI_MEDEFFECTF3 */
|
||||
DoOktArp, /* UNI_OKTARP */
|
||||
DoNothing, /* 0 */
|
||||
DoNothing, /* UNI_NOTE */
|
||||
DoNothing, /* UNI_INSTRUMENT */
|
||||
DoPTEffect0, /* UNI_PTEFFECT0 */
|
||||
DoPTEffect1, /* UNI_PTEFFECT1 */
|
||||
DoPTEffect2, /* UNI_PTEFFECT2 */
|
||||
DoPTEffect3, /* UNI_PTEFFECT3 */
|
||||
DoPTEffect4, /* UNI_PTEFFECT4 */
|
||||
DoPTEffect5, /* UNI_PTEFFECT5 */
|
||||
DoPTEffect6, /* UNI_PTEFFECT6 */
|
||||
DoPTEffect7, /* UNI_PTEFFECT7 */
|
||||
DoPTEffect8, /* UNI_PTEFFECT8 */
|
||||
DoPTEffect9, /* UNI_PTEFFECT9 */
|
||||
DoPTEffectA, /* UNI_PTEFFECTA */
|
||||
DoPTEffectB, /* UNI_PTEFFECTB */
|
||||
DoPTEffectC, /* UNI_PTEFFECTC */
|
||||
DoPTEffectD, /* UNI_PTEFFECTD */
|
||||
DoPTEffectE, /* UNI_PTEFFECTE */
|
||||
DoPTEffectF, /* UNI_PTEFFECTF */
|
||||
DoS3MEffectA, /* UNI_S3MEFFECTA */
|
||||
DoS3MEffectD, /* UNI_S3MEFFECTD */
|
||||
DoS3MEffectE, /* UNI_S3MEFFECTE */
|
||||
DoS3MEffectF, /* UNI_S3MEFFECTF */
|
||||
DoS3MEffectI, /* UNI_S3MEFFECTI */
|
||||
DoS3MEffectQ, /* UNI_S3MEFFECTQ */
|
||||
DoS3MEffectR, /* UNI_S3MEFFECTR */
|
||||
DoS3MEffectT, /* UNI_S3MEFFECTT */
|
||||
DoS3MEffectU, /* UNI_S3MEFFECTU */
|
||||
DoKeyOff, /* UNI_KEYOFF */
|
||||
DoKeyFade, /* UNI_KEYFADE */
|
||||
DoVolEffects, /* UNI_VOLEFFECTS */
|
||||
DoPTEffect4, /* UNI_XMEFFECT4 */
|
||||
DoXMEffect6, /* UNI_XMEFFECT6 */
|
||||
DoXMEffectA, /* UNI_XMEFFECTA */
|
||||
DoXMEffectE1, /* UNI_XMEFFECTE1 */
|
||||
DoXMEffectE2, /* UNI_XMEFFECTE2 */
|
||||
DoXMEffectEA, /* UNI_XMEFFECTEA */
|
||||
DoXMEffectEB, /* UNI_XMEFFECTEB */
|
||||
DoXMEffectG, /* UNI_XMEFFECTG */
|
||||
DoXMEffectH, /* UNI_XMEFFECTH */
|
||||
DoXMEffectL, /* UNI_XMEFFECTL */
|
||||
DoXMEffectP, /* UNI_XMEFFECTP */
|
||||
DoXMEffectX1, /* UNI_XMEFFECTX1 */
|
||||
DoXMEffectX2, /* UNI_XMEFFECTX2 */
|
||||
DoITEffectG, /* UNI_ITEFFECTG */
|
||||
DoITEffectH, /* UNI_ITEFFECTH */
|
||||
DoITEffectI, /* UNI_ITEFFECTI */
|
||||
DoITEffectM, /* UNI_ITEFFECTM */
|
||||
DoITEffectN, /* UNI_ITEFFECTN */
|
||||
DoITEffectP, /* UNI_ITEFFECTP */
|
||||
DoITEffectT, /* UNI_ITEFFECTT */
|
||||
DoITEffectU, /* UNI_ITEFFECTU */
|
||||
DoITEffectW, /* UNI_ITEFFECTW */
|
||||
DoITEffectY, /* UNI_ITEFFECTY */
|
||||
DoNothing, /* UNI_ITEFFECTZ */
|
||||
DoITEffectS0, /* UNI_ITEFFECTS0 */
|
||||
DoULTEffect9, /* UNI_ULTEFFECT9 */
|
||||
DoMEDSpeed, /* UNI_MEDSPEED */
|
||||
DoMEDEffectF1, /* UNI_MEDEFFECTF1 */
|
||||
DoMEDEffectF2, /* UNI_MEDEFFECTF2 */
|
||||
DoMEDEffectF3, /* UNI_MEDEFFECTF3 */
|
||||
DoOktArp, /* UNI_OKTARP */
|
||||
};
|
||||
|
||||
static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a)
|
||||
|
@ -2382,10 +2409,14 @@ static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a)
|
|||
int explicitslides = 0;
|
||||
effect_func f;
|
||||
|
||||
while((c=UniGetByte())) {
|
||||
while((c=UniGetByte()) != 0) {
|
||||
#if 0 /* this doesn't normally happen unless things go fubar elsewhere */
|
||||
if (c >= UNI_LAST)
|
||||
fprintf(stderr,"fubar'ed opcode %u\n",c);
|
||||
#endif
|
||||
f = effects[c];
|
||||
if (f != DoNothing)
|
||||
a->sliding = 0;
|
||||
a->sliding = 0;
|
||||
explicitslides |= f(tick, flags, a, mod, channel);
|
||||
}
|
||||
return explicitslides;
|
||||
|
@ -2396,17 +2427,17 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
|
|||
int t;
|
||||
MP_VOICE *aout;
|
||||
|
||||
dat&=0xf;
|
||||
dat&=0xf;
|
||||
aout=(a->slave)?a->slave:NULL;
|
||||
|
||||
switch (dat) {
|
||||
case 0x0: /* past note cut */
|
||||
for (t=0;t<md_sngchn;t++)
|
||||
for (t=0;t<NUMVOICES(mod);t++)
|
||||
if (mod->voice[t].master==a)
|
||||
mod->voice[t].main.fadevol=0;
|
||||
break;
|
||||
case 0x1: /* past note off */
|
||||
for (t=0;t<md_sngchn;t++)
|
||||
for (t=0;t<NUMVOICES(mod);t++)
|
||||
if (mod->voice[t].master==a) {
|
||||
mod->voice[t].main.keyoff|=KEY_OFF;
|
||||
if ((!(mod->voice[t].venv.flg & EF_ON))||
|
||||
|
@ -2415,7 +2446,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
|
|||
}
|
||||
break;
|
||||
case 0x2: /* past note fade */
|
||||
for (t=0;t<md_sngchn;t++)
|
||||
for (t=0;t<NUMVOICES(mod);t++)
|
||||
if (mod->voice[t].master==a)
|
||||
mod->voice[t].main.keyoff|=KEY_FADE;
|
||||
break;
|
||||
|
@ -2427,7 +2458,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
|
|||
break;
|
||||
case 0x5: /* set NNA note off */
|
||||
a->main.nna=(a->main.nna&~NNA_MASK)|NNA_OFF;
|
||||
break;
|
||||
break;
|
||||
case 0x6: /* set NNA note fade */
|
||||
a->main.nna=(a->main.nna&~NNA_MASK)|NNA_FADE;
|
||||
break;
|
||||
|
@ -2442,7 +2473,7 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
|
|||
case 0x9: /* disable panning envelope */
|
||||
if (aout)
|
||||
aout->main.panflg&=~EF_ON;
|
||||
break;
|
||||
break;
|
||||
case 0xa: /* enable panning envelope */
|
||||
if (aout)
|
||||
aout->main.panflg|=EF_ON;
|
||||
|
@ -2470,7 +2501,7 @@ static void pt_UpdateVoices(MODULE *mod, int max_volume)
|
|||
SAMPLE *s;
|
||||
|
||||
mod->totalchn=mod->realchn=0;
|
||||
for (channel=0;channel<md_sngchn;channel++) {
|
||||
for (channel=0;channel<NUMVOICES(mod);channel++) {
|
||||
aout=&mod->voice[channel];
|
||||
i=aout->main.i;
|
||||
s=aout->main.s;
|
||||
|
@ -2484,7 +2515,7 @@ static void pt_UpdateVoices(MODULE *mod, int max_volume)
|
|||
|
||||
if ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_KEYOFF)) {
|
||||
Voice_Play_internal(channel,s,(aout->main.start==-1)?
|
||||
((s->flags&SF_UST_LOOP) ? (SLONG)s->loopstart : 0) : aout->main.start);
|
||||
((s->flags&SF_UST_LOOP)?(SLONG)s->loopstart:0):aout->main.start);
|
||||
aout->main.fadevol=32768;
|
||||
aout->aswppos=0;
|
||||
}
|
||||
|
@ -2687,7 +2718,7 @@ static void pt_Notes(MODULE *mod)
|
|||
UniSetRow(a->row);
|
||||
funky=0;
|
||||
|
||||
while((c=UniGetByte()))
|
||||
while((c=UniGetByte()) != 0)
|
||||
switch (c) {
|
||||
case UNI_NOTE:
|
||||
funky|=1;
|
||||
|
@ -2720,7 +2751,7 @@ static void pt_Notes(MODULE *mod)
|
|||
INSTRUMENT *i;
|
||||
SAMPLE *s;
|
||||
|
||||
if ((i=a->main.i)) {
|
||||
if ((i=a->main.i) != NULL) {
|
||||
if (i->samplenumber[a->anote] >= mod->numsmp) continue;
|
||||
s=&mod->samples[i->samplenumber[a->anote]];
|
||||
a->main.note=i->samplenote[a->anote];
|
||||
|
@ -2809,7 +2840,7 @@ static void pt_EffectsPass1(MODULE *mod)
|
|||
for (channel=0;channel<mod->numchn;channel++) {
|
||||
a=&mod->control[channel];
|
||||
|
||||
if ((aout=a->slave)) {
|
||||
if ((aout=a->slave) != NULL) {
|
||||
a->main.fadevol=aout->main.fadevol;
|
||||
a->main.period=aout->main.period;
|
||||
if (a->main.kick==KICK_KEYOFF)
|
||||
|
@ -2891,7 +2922,7 @@ static void pt_NNA(MODULE *mod)
|
|||
if (a->dct!=DCT_OFF) {
|
||||
int t;
|
||||
|
||||
for (t=0;t<md_sngchn;t++)
|
||||
for (t=0;t<NUMVOICES(mod);t++)
|
||||
if ((!Voice_Stopped_internal(t))&&
|
||||
(mod->voice[t].masterchn==channel)&&
|
||||
(a->main.sample==mod->voice[t].main.sample)) {
|
||||
|
@ -2951,11 +2982,11 @@ static void pt_SetupVoices(MODULE *mod)
|
|||
if ((newchn=MP_FindEmptyChannel(mod))!=-1)
|
||||
a->slave=&mod->voice[a->slavechn=newchn];
|
||||
}
|
||||
} else
|
||||
} else
|
||||
a->slave=&mod->voice[a->slavechn=channel];
|
||||
|
||||
/* assign parts of MP_VOICE only done for a KICK_NOTE */
|
||||
if ((aout=a->slave)) {
|
||||
if ((aout=a->slave) != NULL) {
|
||||
if (aout->mflag && aout->master) aout->master->slave=NULL;
|
||||
aout->master=a;
|
||||
a->slave=aout;
|
||||
|
@ -2984,7 +3015,7 @@ static void pt_EffectsPass2(MODULE *mod)
|
|||
if (!a->row) continue;
|
||||
UniSetRow(a->row);
|
||||
|
||||
while((c=UniGetByte()))
|
||||
while((c=UniGetByte()) != 0)
|
||||
if (c==UNI_ITEFFECTS0) {
|
||||
c=UniGetByte();
|
||||
if ((c>>4)==SS_S7EFFECTS)
|
||||
|
@ -3016,7 +3047,7 @@ void Player_HandleTick(void)
|
|||
pf->sngremainder%=pf->bpm;
|
||||
|
||||
if (++pf->vbtick>=pf->sngspd) {
|
||||
if (pf->pat_repcrazy)
|
||||
if (pf->pat_repcrazy)
|
||||
pf->pat_repcrazy=0; /* play 2 times row 0 */
|
||||
else
|
||||
pf->patpos++;
|
||||
|
@ -3046,6 +3077,9 @@ void Player_HandleTick(void)
|
|||
pf->control[channel].pat_reppos=-1;
|
||||
|
||||
pf->patbrk=pf->posjmp=0;
|
||||
|
||||
if (pf->sngpos<0) pf->sngpos=(SWORD)(pf->numpos-1);
|
||||
|
||||
/* handle the "---" (end of song) pattern since it can occur
|
||||
*inside* the module in some formats */
|
||||
if ((pf->sngpos>=pf->numpos)||
|
||||
|
@ -3060,7 +3094,6 @@ void Player_HandleTick(void)
|
|||
pf->bpm=pf->inittempo<32?32:pf->inittempo;
|
||||
}
|
||||
}
|
||||
if (pf->sngpos<0) pf->sngpos=pf->numpos-1;
|
||||
}
|
||||
|
||||
if (!pf->patdly2)
|
||||
|
@ -3093,7 +3126,7 @@ static void Player_Init_internal(MODULE* mod)
|
|||
mod->control[t].main.chanvol=mod->chanvol[t];
|
||||
mod->control[t].main.panning=mod->panning[t];
|
||||
}
|
||||
|
||||
|
||||
mod->sngtime=0;
|
||||
mod->sngremainder=0;
|
||||
|
||||
|
@ -3133,6 +3166,11 @@ int Player_Init(MODULE* mod)
|
|||
if (!(mod->voice=(MP_VOICE*)MikMod_calloc(md_sngchn,sizeof(MP_VOICE))))
|
||||
return 1;
|
||||
|
||||
/* mod->numvoices was used during loading to clamp md_sngchn.
|
||||
After loading it's used to remember how big mod->voice is.
|
||||
*/
|
||||
mod->numvoices = md_sngchn;
|
||||
|
||||
Player_Init_internal(mod);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3148,10 +3186,8 @@ void Player_Exit_internal(MODULE* mod)
|
|||
pf=NULL;
|
||||
}
|
||||
|
||||
if (mod->control)
|
||||
MikMod_free(mod->control);
|
||||
if (mod->voice)
|
||||
MikMod_free(mod->voice);
|
||||
MikMod_free(mod->control);
|
||||
MikMod_free(mod->voice);
|
||||
mod->control=NULL;
|
||||
mod->voice=NULL;
|
||||
}
|
||||
|
@ -3166,8 +3202,10 @@ void Player_Exit(MODULE* mod)
|
|||
MIKMODAPI void Player_SetVolume(SWORD volume)
|
||||
{
|
||||
MUTEX_LOCK(vars);
|
||||
if (pf)
|
||||
if (pf) {
|
||||
pf->volume=(volume<0)?0:(volume>128)?128:volume;
|
||||
pf->initvolume=pf->volume;
|
||||
}
|
||||
MUTEX_UNLOCK(vars);
|
||||
}
|
||||
|
||||
|
@ -3241,7 +3279,7 @@ MIKMODAPI void Player_NextPosition(void)
|
|||
pf->patbrk=0;
|
||||
pf->vbtick=pf->sngspd;
|
||||
|
||||
for (t=0;t<md_sngchn;t++) {
|
||||
for (t=0;t<NUMVOICES(pf);t++) {
|
||||
Voice_Stop_internal(t);
|
||||
pf->voice[t].main.i=NULL;
|
||||
pf->voice[t].main.s=NULL;
|
||||
|
@ -3266,7 +3304,7 @@ MIKMODAPI void Player_PrevPosition(void)
|
|||
pf->patbrk=0;
|
||||
pf->vbtick=pf->sngspd;
|
||||
|
||||
for (t=0;t<md_sngchn;t++) {
|
||||
for (t=0;t<NUMVOICES(pf);t++) {
|
||||
Voice_Stop_internal(t);
|
||||
pf->voice[t].main.i=NULL;
|
||||
pf->voice[t].main.s=NULL;
|
||||
|
@ -3293,7 +3331,7 @@ MIKMODAPI void Player_SetPosition(UWORD pos)
|
|||
pf->sngpos=pos;
|
||||
pf->vbtick=pf->sngspd;
|
||||
|
||||
for (t=0;t<md_sngchn;t++) {
|
||||
for (t=0;t<NUMVOICES(pf);t++) {
|
||||
Voice_Stop_internal(t);
|
||||
pf->voice[t].main.i=NULL;
|
||||
pf->voice[t].main.s=NULL;
|
||||
|
@ -3303,12 +3341,12 @@ MIKMODAPI void Player_SetPosition(UWORD pos)
|
|||
pf->control[t].main.s=NULL;
|
||||
}
|
||||
pf->forbid=0;
|
||||
|
||||
|
||||
if (!pos)
|
||||
Player_Init_internal(pf);
|
||||
}
|
||||
MUTEX_UNLOCK(vars);
|
||||
}
|
||||
}
|
||||
|
||||
static void Player_Unmute_internal(SLONG arg1,va_list ap)
|
||||
{
|
||||
|
@ -3418,7 +3456,7 @@ static void Player_ToggleMute_internal(SLONG arg1,va_list ap)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (arg1<pf->numchn)
|
||||
if (arg1<pf->numchn)
|
||||
pf->control[arg1].muted=1-pf->control[arg1].muted;
|
||||
break;
|
||||
}
|
||||
|
@ -3465,7 +3503,7 @@ MIKMODAPI UWORD Player_GetChannelPeriod(UBYTE chan)
|
|||
UWORD result=0;
|
||||
|
||||
MUTEX_LOCK(vars);
|
||||
if (pf)
|
||||
if (pf)
|
||||
result=(chan<pf->numchn)?pf->control[chan].main.period:0;
|
||||
MUTEX_UNLOCK(vars);
|
||||
|
||||
|
@ -3499,7 +3537,7 @@ MIKMODAPI void Player_TogglePause(void)
|
|||
MIKMODAPI void Player_SetSpeed(UWORD speed)
|
||||
{
|
||||
MUTEX_LOCK(vars);
|
||||
if (pf)
|
||||
if (pf)
|
||||
pf->sngspd=speed?(speed<32?speed:32):1;
|
||||
MUTEX_UNLOCK(vars);
|
||||
}
|
||||
|
@ -3538,18 +3576,17 @@ MIKMODAPI int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo)
|
|||
return numvoices;
|
||||
}
|
||||
|
||||
|
||||
// Get current module order
|
||||
/* Get current module order */
|
||||
MIKMODAPI int Player_GetOrder(void)
|
||||
{
|
||||
int ret;
|
||||
MUTEX_LOCK(vars);
|
||||
ret = pf ? pf->sngpos :0; // pf->positions[pf->sngpos ? pf->sngpos-1 : 0]: 0;
|
||||
ret = pf ? pf->sngpos :0; /* pf->positions[pf->sngpos ? pf->sngpos-1 : 0]: 0; */
|
||||
MUTEX_UNLOCK(vars);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get current module row
|
||||
/* Get current module row */
|
||||
MIKMODAPI int Player_GetRow(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -3559,5 +3596,4 @@ MIKMODAPI int Player_GetRow(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ex:set ts=4: */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: munitrk.c,v 1.2 2005/03/30 19:11:46 realtech Exp $
|
||||
$Id$
|
||||
|
||||
All routines dealing with the manipulation of UNITRK streams
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
/* Unibuffer chunk size */
|
||||
#define BUFPAGE 128
|
||||
|
||||
UWORD unioperands[UNI_LAST]={
|
||||
const UWORD unioperands[UNI_LAST] = {
|
||||
0, /* not used */
|
||||
1, /* UNI_NOTE */
|
||||
1, /* UNI_INSTRUMENT */
|
||||
|
@ -214,7 +214,7 @@ static int UniExpand(int wanted)
|
|||
unibuf = newbuf;
|
||||
unimax+=BUFPAGE;
|
||||
return 1;
|
||||
} else
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -236,7 +236,7 @@ void UniWriteWord(UWORD data)
|
|||
}
|
||||
}
|
||||
|
||||
static int MyCmp(UBYTE* a,UBYTE* b,UWORD l)
|
||||
static int MyCmp(const UBYTE* a,const UBYTE* b,UWORD l)
|
||||
{
|
||||
UWORD t;
|
||||
|
||||
|
@ -275,15 +275,15 @@ void UniNewline(void)
|
|||
stream. */
|
||||
UBYTE* UniDup(void)
|
||||
{
|
||||
UBYTE *d;
|
||||
void *d;
|
||||
|
||||
if (!UniExpand(unitt-unipc)) return NULL;
|
||||
if (!UniExpand(unipc-unitt)) return NULL;
|
||||
unibuf[unitt] = 0;
|
||||
|
||||
if(!(d=(UBYTE *)MikMod_malloc(unipc))) return NULL;
|
||||
if(!(d=MikMod_malloc(unipc))) return NULL;
|
||||
memcpy(d,unibuf,unipc);
|
||||
|
||||
return d;
|
||||
return (UBYTE *)d;
|
||||
}
|
||||
|
||||
int UniInit(void)
|
||||
|
@ -296,7 +296,7 @@ int UniInit(void)
|
|||
|
||||
void UniCleanup(void)
|
||||
{
|
||||
if(unibuf) MikMod_free(unibuf);
|
||||
MikMod_free(unibuf);
|
||||
unibuf = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: npertab.c,v 1.2 2005/03/30 19:11:47 realtech Exp $
|
||||
$Id$
|
||||
|
||||
MOD format period table. Used by both the MOD and M15 (15-inst mod) Loaders.
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
UWORD npertab[7 * OCTAVE] = {
|
||||
const UWORD npertab[7 * OCTAVE] = {
|
||||
/* Octaves 6 -> 0 */
|
||||
/* C C# D D# E F F# G G# A A# B */
|
||||
0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a,
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: sloader.c,v 1.3 2007/12/06 17:46:08 denis111 Exp $
|
||||
$Id$
|
||||
|
||||
Routines for loading samples. The sample loader utilizes the routines
|
||||
provided by the "registered" sample loader.
|
||||
|
@ -56,7 +56,7 @@ typedef struct ITPACK {
|
|||
int SL_Init(SAMPLOAD* s)
|
||||
{
|
||||
if(!sl_buffer)
|
||||
if(!(sl_buffer=MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
|
||||
if(!(sl_buffer=(SWORD*)MikMod_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0;
|
||||
|
||||
sl_rlength = s->length;
|
||||
if(s->infmt & SF_16BITS) sl_rlength>>=1;
|
||||
|
@ -68,16 +68,15 @@ int SL_Init(SAMPLOAD* s)
|
|||
void SL_Exit(SAMPLOAD *s)
|
||||
{
|
||||
if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR);
|
||||
if(sl_buffer) {
|
||||
MikMod_free(sl_buffer);
|
||||
sl_buffer=NULL;
|
||||
}
|
||||
|
||||
MikMod_free(sl_buffer);
|
||||
sl_buffer=NULL;
|
||||
}
|
||||
|
||||
/* unpack a 8bit IT packed sample */
|
||||
static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
|
||||
static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *out,UWORD count,UWORD* incnt)
|
||||
{
|
||||
SWORD *dest=sl_buffer,*end=sl_buffer+count;
|
||||
SWORD *dest=out,*end=out+count;
|
||||
UWORD x,y,needbits,havebits,new_count=0;
|
||||
UWORD bits = status->bits;
|
||||
UWORD bufbits = status->bufbits;
|
||||
|
@ -145,13 +144,13 @@ static int read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD c
|
|||
status->bufbits = bufbits;
|
||||
status->last = last;
|
||||
status->buf = buf;
|
||||
return (dest-sl_buffer);
|
||||
return (dest-out);
|
||||
}
|
||||
|
||||
/* unpack a 16bit IT packed sample */
|
||||
static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt)
|
||||
static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *out,UWORD count,UWORD* incnt)
|
||||
{
|
||||
SWORD *dest=sl_buffer,*end=sl_buffer+count;
|
||||
SWORD *dest=out,*end=out+count;
|
||||
SLONG x,y,needbits,havebits,new_count=0;
|
||||
UWORD bits = status->bits;
|
||||
UWORD bufbits = status->bufbits;
|
||||
|
@ -219,7 +218,7 @@ static int read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD
|
|||
status->bufbits = bufbits;
|
||||
status->last = last;
|
||||
status->buf = buf;
|
||||
return (dest-sl_buffer);
|
||||
return (dest-out);
|
||||
}
|
||||
|
||||
static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,int dither)
|
||||
|
@ -231,9 +230,11 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
|
|||
int result,c_block=0; /* compression bytes until next block */
|
||||
ITPACK status;
|
||||
UWORD incnt = 0;
|
||||
|
||||
memset(&status, 0, sizeof(status)); /* initialize status */
|
||||
|
||||
|
||||
status.buf = 0;
|
||||
status.last = 0;
|
||||
status.bufbits = 0;
|
||||
status.bits = 0;
|
||||
|
||||
while(length) {
|
||||
stodo=(length<SLBUFSIZE)?length:SLBUFSIZE;
|
||||
|
@ -261,6 +262,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
|
|||
c_block -= stodo;
|
||||
} else {
|
||||
if(infmt&SF_16BITS) {
|
||||
if(_mm_eof(reader)) {
|
||||
_mm_errno=MMERR_NOT_A_STREAM;/* better error? */
|
||||
return 1;
|
||||
}
|
||||
if(infmt&SF_BIG_ENDIAN)
|
||||
_mm_read_M_SWORDS(sl_buffer,stodo,reader);
|
||||
else
|
||||
|
@ -269,6 +274,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
|
|||
SBYTE *src;
|
||||
SWORD *dest;
|
||||
|
||||
if(_mm_eof(reader)) {
|
||||
_mm_errno=MMERR_NOT_A_STREAM;/* better error? */
|
||||
return 1;
|
||||
}
|
||||
reader->Read(reader,sl_buffer,sizeof(SBYTE)*stodo);
|
||||
src = (SBYTE*)sl_buffer;
|
||||
dest = sl_buffer;
|
||||
|
@ -288,7 +297,7 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
|
|||
sl_old = sl_buffer[t];
|
||||
}
|
||||
|
||||
if((infmt^outfmt) & SF_SIGNED)
|
||||
if((infmt^outfmt) & SF_SIGNED)
|
||||
for(t=0;t<stodo;t++)
|
||||
sl_buffer[t]^= 0x8000;
|
||||
|
||||
|
@ -340,7 +349,7 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
|
|||
int SL_Load(void* buffer,SAMPLOAD *smp,ULONG length)
|
||||
{
|
||||
return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor,
|
||||
length,smp->reader,0);
|
||||
length,smp->reader,0);
|
||||
}
|
||||
|
||||
/* Registers a sample for loading when SL_LoadSamples() is called. */
|
||||
|
@ -357,7 +366,7 @@ SAMPLOAD* SL_RegisterSample(SAMPLE* s,int type,MREADER* reader)
|
|||
cruise = sndfxlist;
|
||||
} else
|
||||
return NULL;
|
||||
|
||||
|
||||
/* Allocate and add structure to the END of the list */
|
||||
if(!(news=(SAMPLOAD*)MikMod_malloc(sizeof(SAMPLOAD)))) return NULL;
|
||||
|
||||
|
@ -407,7 +416,7 @@ static ULONG SampleTotal(SAMPLOAD* samplist,int type)
|
|||
static ULONG RealSpeed(SAMPLOAD *s)
|
||||
{
|
||||
return(s->sample->speed/(s->scalefactor?s->scalefactor:1));
|
||||
}
|
||||
}
|
||||
|
||||
static int DitherSamples(SAMPLOAD* samplist,int type)
|
||||
{
|
||||
|
@ -417,7 +426,7 @@ static int DitherSamples(SAMPLOAD* samplist,int type)
|
|||
|
||||
if(!samplist) return 0;
|
||||
|
||||
if((maxsize=MD_SampleSpace(type)*1024))
|
||||
if((maxsize=MD_SampleSpace(type)*1024) != 0)
|
||||
while(SampleTotal(samplist,type)>maxsize) {
|
||||
/* First Pass - check for any 16 bit samples */
|
||||
s = samplist;
|
||||
|
@ -473,15 +482,15 @@ static int DitherSamples(SAMPLOAD* samplist,int type)
|
|||
|
||||
int SL_LoadSamples(void)
|
||||
{
|
||||
int ok;
|
||||
int rc;
|
||||
|
||||
_mm_critical = 0;
|
||||
|
||||
if((!musiclist)&&(!sndfxlist)) return 0;
|
||||
ok=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
|
||||
rc=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX);
|
||||
musiclist=sndfxlist=NULL;
|
||||
|
||||
return ok;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void SL_Sample16to8(SAMPLOAD* s)
|
||||
|
@ -518,5 +527,4 @@ void SL_HalveSample(SAMPLOAD* s,int factor)
|
|||
s->sample->loopend = s->loopend / s->scalefactor;
|
||||
}
|
||||
|
||||
|
||||
/* ex:set ts=4: */
|
||||
|
|
File diff suppressed because it is too large
Load diff
1370
apps/plugins/mikmod/virtch2.c
Normal file
1370
apps/plugins/mikmod/virtch2.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -6,12 +6,12 @@
|
|||
it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
@ -20,90 +20,96 @@
|
|||
|
||||
/*==============================================================================
|
||||
|
||||
$Id: virtch_common.c,v 1.2 2005/03/30 19:11:50 realtech Exp $
|
||||
$Id$
|
||||
|
||||
Common source parts between the two software mixers.
|
||||
This file is probably the ugliest part of libmikmod...
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
#ifndef _IN_VIRTCH_
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(_IN_VIRTCH_) /* config.h isn't guarded */
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "mikmod_internals.h"
|
||||
|
||||
extern int VC1_Init(void);
|
||||
//extern int VC2_Init(void);
|
||||
static int (*VC_Init_ptr)(void)=VC1_Init;
|
||||
#ifndef NO_HQMIXER
|
||||
extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
|
||||
extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
|
||||
extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
|
||||
extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
|
||||
extern void VC1_Exit(void);
|
||||
//extern void VC2_Exit(void);
|
||||
static void (*VC_Exit_ptr)(void)=VC1_Exit;
|
||||
extern int VC1_SetNumVoices(void);
|
||||
//extern int VC2_SetNumVoices(void);
|
||||
static int (*VC_SetNumVoices_ptr)(void);
|
||||
extern void VC2_Exit(void);
|
||||
extern UWORD VC1_VoiceGetVolume(UBYTE);
|
||||
extern UWORD VC2_VoiceGetVolume(UBYTE);
|
||||
extern ULONG VC1_VoiceGetPanning(UBYTE);
|
||||
extern ULONG VC2_VoiceGetPanning(UBYTE);
|
||||
extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
|
||||
extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
|
||||
extern ULONG VC1_VoiceGetFrequency(UBYTE);
|
||||
extern ULONG VC2_VoiceGetFrequency(UBYTE);
|
||||
extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
|
||||
extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
|
||||
extern void VC1_VoiceStop(UBYTE);
|
||||
extern void VC2_VoiceStop(UBYTE);
|
||||
extern int VC1_VoiceStopped(UBYTE);
|
||||
extern int VC2_VoiceStopped(UBYTE);
|
||||
extern SLONG VC1_VoiceGetPosition(UBYTE);
|
||||
extern SLONG VC2_VoiceGetPosition(UBYTE);
|
||||
extern void VC1_VoiceSetVolume(UBYTE,UWORD);
|
||||
extern void VC2_VoiceSetVolume(UBYTE,UWORD);
|
||||
extern void VC1_VoiceSetPanning(UBYTE,ULONG);
|
||||
extern void VC2_VoiceSetPanning(UBYTE,ULONG);
|
||||
extern void VC1_SampleUnload(SWORD);
|
||||
extern void VC2_SampleUnload(SWORD);
|
||||
extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
|
||||
extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
|
||||
extern ULONG VC1_SampleSpace(int);
|
||||
//extern ULONG VC2_SampleSpace(int);
|
||||
static ULONG (*VC_SampleSpace_ptr)(int);
|
||||
extern ULONG VC2_SampleSpace(int);
|
||||
extern ULONG VC1_SampleLength(int,SAMPLE*);
|
||||
//extern ULONG VC2_SampleLength(int,SAMPLE*);
|
||||
extern ULONG VC2_SampleLength(int,SAMPLE*);
|
||||
extern ULONG VC1_VoiceRealVolume(UBYTE);
|
||||
extern ULONG VC2_VoiceRealVolume(UBYTE);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _IN_VIRTCH_
|
||||
|
||||
#ifndef NO_HQMIXER
|
||||
extern int VC1_Init(void);
|
||||
extern int VC2_Init(void);
|
||||
static int (*VC_Init_ptr)(void)=VC1_Init;
|
||||
static void (*VC_Exit_ptr)(void)=VC1_Exit;
|
||||
extern int VC1_SetNumVoices(void);
|
||||
extern int VC2_SetNumVoices(void);
|
||||
static int (*VC_SetNumVoices_ptr)(void);
|
||||
static ULONG (*VC_SampleSpace_ptr)(int);
|
||||
static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
|
||||
|
||||
extern int VC1_PlayStart(void);
|
||||
//extern int VC2_PlayStart(void);
|
||||
static int (*VC_PlayStart_ptr)(void);
|
||||
extern void VC1_PlayStop(void);
|
||||
extern int VC2_PlayStart(void);
|
||||
static int (*VC_PlayStart_ptr)(void);
|
||||
extern void VC2_PlayStop(void);
|
||||
static void (*VC_PlayStop_ptr)(void);
|
||||
|
||||
extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
|
||||
//extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
|
||||
static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int);
|
||||
extern void VC1_SampleUnload(SWORD);
|
||||
//extern void VC2_SampleUnload(SWORD);
|
||||
static void (*VC_SampleUnload_ptr)(SWORD);
|
||||
|
||||
extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
|
||||
//extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
|
||||
static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG);
|
||||
extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
|
||||
//extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
|
||||
static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG);
|
||||
|
||||
extern void VC1_VoiceSetVolume(UBYTE,UWORD);
|
||||
//extern void VC2_VoiceSetVolume(UBYTE,UWORD);
|
||||
static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD);
|
||||
extern UWORD VC1_VoiceGetVolume(UBYTE);
|
||||
//extern UWORD VC2_VoiceGetVolume(UBYTE);
|
||||
static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE);
|
||||
extern void VC1_VoiceSetFrequency(UBYTE,ULONG);
|
||||
//extern void VC2_VoiceSetFrequency(UBYTE,ULONG);
|
||||
static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG);
|
||||
extern ULONG VC1_VoiceGetFrequency(UBYTE);
|
||||
//extern ULONG VC2_VoiceGetFrequency(UBYTE);
|
||||
static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE);
|
||||
extern void VC1_VoiceSetPanning(UBYTE,ULONG);
|
||||
//extern void VC2_VoiceSetPanning(UBYTE,ULONG);
|
||||
static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG);
|
||||
extern ULONG VC1_VoiceGetPanning(UBYTE);
|
||||
//extern ULONG VC2_VoiceGetPanning(UBYTE);
|
||||
static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE);
|
||||
extern void VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
|
||||
//extern void VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
|
||||
static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
|
||||
|
||||
extern void VC1_VoiceStop(UBYTE);
|
||||
//extern void VC2_VoiceStop(UBYTE);
|
||||
static void (*VC_VoiceStop_ptr)(UBYTE);
|
||||
extern int VC1_VoiceStopped(UBYTE);
|
||||
//extern int VC2_VoiceStopped(UBYTE);
|
||||
static int (*VC_VoiceStopped_ptr)(UBYTE);
|
||||
extern SLONG VC1_VoiceGetPosition(UBYTE);
|
||||
//extern SLONG VC2_VoiceGetPosition(UBYTE);
|
||||
static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE);
|
||||
extern ULONG VC1_VoiceRealVolume(UBYTE);
|
||||
//extern ULONG VC2_VoiceRealVolume(UBYTE);
|
||||
static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE);
|
||||
|
||||
#if defined __STDC__ || defined _MSC_VER || defined MPW_C
|
||||
#if defined __STDC__ || defined _MSC_VER || defined __WATCOMC__ || defined MPW_C
|
||||
#define VC_PROC0(suffix) \
|
||||
MIKMODAPI void VC_##suffix (void) { VC_##suffix##_ptr(); }
|
||||
|
||||
|
@ -121,7 +127,9 @@ MIKMODAPI void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); }
|
|||
|
||||
#define VC_FUNC2(suffix,ret,typ1,typ2) \
|
||||
MIKMODAPI ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); }
|
||||
|
||||
#else
|
||||
|
||||
#define VC_PROC0(suffix) \
|
||||
MIKMODAPI void VC_/**/suffix (void) { VC_/**/suffix/**/_ptr(); }
|
||||
|
||||
|
@ -158,18 +166,18 @@ VC_PROC2(VoiceSetFrequency,UBYTE,ULONG)
|
|||
VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE)
|
||||
VC_PROC2(VoiceSetPanning,UBYTE,ULONG)
|
||||
VC_FUNC1(VoiceGetPanning,ULONG,UBYTE)
|
||||
|
||||
void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g)
|
||||
{ VC_VoicePlay_ptr(a,b,c,d,e,f,g); }
|
||||
|
||||
void VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g) {
|
||||
VC_VoicePlay_ptr(a,b,c,d,e,f,g);
|
||||
}
|
||||
|
||||
VC_PROC1(VoiceStop,UBYTE)
|
||||
VC_FUNC1(VoiceStopped,int,UBYTE)
|
||||
VC_FUNC1(VoiceGetPosition,SLONG,UBYTE)
|
||||
VC_FUNC1(VoiceRealVolume,ULONG,UBYTE)
|
||||
|
||||
|
||||
void VC_SetupPointers(void)
|
||||
{
|
||||
/*
|
||||
if (md_mode&DMODE_HQMIXER) {
|
||||
VC_Init_ptr=VC2_Init;
|
||||
VC_Exit_ptr=VC2_Exit;
|
||||
|
@ -194,7 +202,6 @@ void VC_SetupPointers(void)
|
|||
VC_VoiceGetPosition_ptr=VC2_VoiceGetPosition;
|
||||
VC_VoiceRealVolume_ptr=VC2_VoiceRealVolume;
|
||||
} else {
|
||||
*/
|
||||
VC_Init_ptr=VC1_Init;
|
||||
VC_Exit_ptr=VC1_Exit;
|
||||
VC_SetNumVoices_ptr=VC1_SetNumVoices;
|
||||
|
@ -217,10 +224,11 @@ void VC_SetupPointers(void)
|
|||
VC_VoiceStopped_ptr=VC1_VoiceStopped;
|
||||
VC_VoiceGetPosition_ptr=VC1_VoiceGetPosition;
|
||||
VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume;
|
||||
//}
|
||||
}
|
||||
}
|
||||
#endif/* !NO_HQMIXER */
|
||||
|
||||
#else
|
||||
#else /* _IN_VIRTCH_ */
|
||||
|
||||
#ifndef _VIRTCH_COMMON_
|
||||
#define _VIRTCH_COMMON_
|
||||
|
@ -248,9 +256,7 @@ ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo)
|
|||
todo=samples2bytes(bytes2samples(todo));
|
||||
|
||||
/* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */
|
||||
if(vc_mode & DMODE_FLOAT)
|
||||
memset(buf,0,todo);
|
||||
else if(vc_mode & DMODE_16BITS)
|
||||
if(vc_mode &(DMODE_16BITS|DMODE_FLOAT))
|
||||
memset(buf,0,todo);
|
||||
else
|
||||
memset(buf,0x80,todo);
|
||||
|
@ -276,14 +282,14 @@ ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo)
|
|||
|
||||
void VC1_Exit(void)
|
||||
{
|
||||
if(vc_tickbuf) MikMod_free(vc_tickbuf);
|
||||
if(vinf) MikMod_free(vinf);
|
||||
if(Samples) MikMod_free(Samples);
|
||||
MikMod_free(vinf);
|
||||
MikMod_afree(vc_tickbuf);
|
||||
MikMod_afree(Samples);
|
||||
|
||||
vc_tickbuf = NULL;
|
||||
vinf = NULL;
|
||||
Samples = NULL;
|
||||
|
||||
|
||||
VC_SetupPointers();
|
||||
}
|
||||
|
||||
|
@ -309,19 +315,19 @@ ULONG VC1_VoiceGetFrequency(UBYTE voice)
|
|||
|
||||
void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
|
||||
{
|
||||
vinf[voice].flags = flags;
|
||||
vinf[voice].handle = handle;
|
||||
vinf[voice].start = start;
|
||||
vinf[voice].size = size;
|
||||
vinf[voice].reppos = reppos;
|
||||
vinf[voice].repend = repend;
|
||||
vinf[voice].kick = 1;
|
||||
vinf[voice].flags = flags;
|
||||
vinf[voice].handle = handle;
|
||||
vinf[voice].start = start;
|
||||
vinf[voice].size = size;
|
||||
vinf[voice].reppos = reppos;
|
||||
vinf[voice].repend = repend;
|
||||
vinf[voice].kick = 1;
|
||||
}
|
||||
|
||||
void VC1_VoiceStop(UBYTE voice)
|
||||
{
|
||||
vinf[voice].active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int VC1_VoiceStopped(UBYTE voice)
|
||||
{
|
||||
|
@ -334,7 +340,7 @@ SLONG VC1_VoiceGetPosition(UBYTE voice)
|
|||
}
|
||||
|
||||
void VC1_VoiceSetVolume(UBYTE voice,UWORD vol)
|
||||
{
|
||||
{
|
||||
/* protect against clicks if volume variation is too high */
|
||||
if(abs((int)vinf[voice].vol-(int)vol)>32)
|
||||
vinf[voice].rampvol=CLICK_BUFFER;
|
||||
|
@ -353,9 +359,8 @@ void VC1_VoiceSetPanning(UBYTE voice,ULONG pan)
|
|||
|
||||
void VC1_SampleUnload(SWORD handle)
|
||||
{
|
||||
if (handle<MAXSAMPLEHANDLES) {
|
||||
if (Samples[handle])
|
||||
MikMod_free(Samples[handle]);
|
||||
if (Samples && (handle < MAXSAMPLEHANDLES)) {
|
||||
MikMod_afree(Samples[handle]);
|
||||
Samples[handle]=NULL;
|
||||
}
|
||||
}
|
||||
|
@ -364,10 +369,15 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
|
|||
{
|
||||
SAMPLE *s = sload->sample;
|
||||
int handle;
|
||||
ULONG t, length,loopstart,loopend;
|
||||
ULONG t, length,loopstart,loopend,looplen;
|
||||
|
||||
if(type==MD_HARDWARE) return -1;
|
||||
|
||||
if(s->length > MAX_SAMPLE_SIZE) {
|
||||
_mm_errno = MMERR_NOT_A_STREAM; /* better error? */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find empty slot to put sample address in */
|
||||
for(handle=0;handle<MAXSAMPLEHANDLES;handle++)
|
||||
if(!Samples[handle]) break;
|
||||
|
@ -376,7 +386,7 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
|
|||
_mm_errno = MMERR_OUT_OF_HANDLES;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Reality check for loop settings */
|
||||
if (s->loopend > s->length)
|
||||
s->loopend = s->length;
|
||||
|
@ -390,22 +400,26 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
|
|||
SL_SampleSigned(sload);
|
||||
SL_Sample8to16(sload);
|
||||
|
||||
if(!(Samples[handle]=(SWORD*)MikMod_malloc((length+20)<<1))) {
|
||||
if(!(Samples[handle]=(SWORD*)MikMod_amalloc((length+20)<<1))) {
|
||||
_mm_errno = MMERR_SAMPLE_TOO_BIG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read sample into buffer */
|
||||
if (SL_Load(Samples[handle],sload,length))
|
||||
if (SL_Load(Samples[handle],sload,length)) {
|
||||
MikMod_afree(Samples[handle]);
|
||||
Samples[handle]=NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Unclick sample */
|
||||
if(s->flags & SF_LOOP) {
|
||||
looplen = loopend - loopstart;/* handle short samples */
|
||||
if(s->flags & SF_BIDI)
|
||||
for(t=0;t<16;t++)
|
||||
for(t=0;t<16 && t<looplen;t++)
|
||||
Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1];
|
||||
else
|
||||
for(t=0;t<16;t++)
|
||||
for(t=0;t<16 && t<looplen;t++)
|
||||
Samples[handle][loopend+t]=Samples[handle][t+loopstart];
|
||||
} else
|
||||
for(t=0;t<16;t++)
|
||||
|
@ -416,13 +430,13 @@ SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
|
|||
|
||||
ULONG VC1_SampleSpace(int type)
|
||||
{
|
||||
(void)type;
|
||||
(void)type;
|
||||
return vc_memory;
|
||||
}
|
||||
|
||||
ULONG VC1_SampleLength(int type,SAMPLE* s)
|
||||
{
|
||||
(void)type;
|
||||
(void)type;
|
||||
if (!s) return 0;
|
||||
|
||||
return (s->length*((s->flags&SF_16BITS)?2:1))+16;
|
||||
|
@ -456,11 +470,8 @@ ULONG VC1_VoiceRealVolume(UBYTE voice)
|
|||
return abs(k-j);
|
||||
}
|
||||
|
||||
#endif /* _VIRTCH_COMMON_ */
|
||||
|
||||
#endif
|
||||
|
||||
MikMod_callback_t vc_callback;
|
||||
|
||||
#endif
|
||||
#endif /* _IN_VIRTCH_ */
|
||||
|
||||
/* ex:set ts=4: */
|
||||
|
|
|
@ -44,7 +44,6 @@ asy,viewers/mikmod,7
|
|||
dsm,viewers/mikmod,7
|
||||
far,viewers/mikmod,7
|
||||
gdm,viewers/mikmod,7
|
||||
gt2,viewers/mikmod,7
|
||||
imf,viewers/mikmod,7
|
||||
it,viewers/mikmod,7
|
||||
m15,viewers/mikmod,7
|
||||
|
@ -57,6 +56,7 @@ stm,viewers/mikmod,7
|
|||
stx,viewers/mikmod,7
|
||||
ult,viewers/mikmod,7
|
||||
uni,viewers/mikmod,7
|
||||
umx,viewers/mikmod,7
|
||||
xm,viewers/mikmod,7
|
||||
pd,viewers/pdbox,2
|
||||
rsp,viewers/searchengine,8
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue