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:
Solomon Peachy 2020-08-08 21:56:15 -04:00
parent 8c7780bafc
commit b4e70422a3
43 changed files with 5072 additions and 2802 deletions

View file

@ -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

View file

@ -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

View file

@ -20,7 +20,7 @@
/*==============================================================================
$Id: load_669.c,v 1.3 2005/04/07 19:57:38 realtech Exp $
$Id: $
Composer 669 module loader
@ -53,7 +53,7 @@ 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)
@ -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;

View file

@ -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,14 +124,14 @@ 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))
@ -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)
@ -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 {
@ -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)

View file

@ -20,7 +20,7 @@
/*==============================================================================
$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>,
@ -77,7 +77,8 @@ 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,
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,
@ -140,9 +141,11 @@ 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;
@ -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;
@ -278,17 +289,17 @@ 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*/
@ -302,7 +313,7 @@ static int ASY_Load(int curious)
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 */
@ -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 */

View file

@ -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)
@ -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++;
}

View file

@ -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 */
@ -315,7 +325,7 @@ 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);
q->samplename = MikMod_strdup("");
q++;
}
return 1;
@ -328,7 +338,7 @@ 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 */

View file

@ -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';

View file

@ -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
};

View file

@ -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);
@ -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);

View file

@ -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 */
@ -167,7 +166,7 @@ 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,6 +211,13 @@ 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
@ -219,33 +225,34 @@ static void IT_Cleanup(void)
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.
this procedure.
Returns 1 on error
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)
@ -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];
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)
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,7 +697,7 @@ 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;
@ -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);
@ -739,10 +764,12 @@ static int IT_Load(int curious)
}
} 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);
@ -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; \
@ -863,10 +892,6 @@ static int IT_Load(int curious)
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);
@ -946,7 +971,7 @@ 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;
}
}
@ -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;

View file

@ -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,19 +121,19 @@ 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));
}
@ -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,45 +175,46 @@ 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;
}
@ -223,9 +222,9 @@ static int M15_Test(void)
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;
}
/*
@ -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,9 +410,9 @@ 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;
@ -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++;

View file

@ -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);
@ -694,7 +734,7 @@ static CHAR *MED_LoadTitle(void)
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);

View file

@ -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)
@ -190,6 +190,8 @@ static void MOD_Cleanup(void)
{
MikMod_free(mh);
MikMod_free(patbuf);
mh=NULL;
patbuf=NULL;
}
/*
@ -309,8 +311,7 @@ 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;
@ -477,7 +478,7 @@ static int MOD_Load(int curious)
q++;
}
of.modtype = StrDup(descr);
of.modtype = MikMod_strdup(descr);
if (!ML_LoadPatterns())
return 0;

View file

@ -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 */
@ -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)) {

View file

@ -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,13 +331,13 @@ 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 */
@ -442,7 +443,7 @@ static int OKT_Load(int curious)
static CHAR *OKT_LoadTitle(void)
{
return StrDup("");
return MikMod_strdup("");
}
/*========== Loader information */

View file

@ -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,18 +171,18 @@ 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,7 +416,7 @@ 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 */

View file

@ -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
@ -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 */
@ -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)
@ -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;
@ -255,7 +257,7 @@ static int STM_Load(int curious)
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: */

View file

@ -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,6 +114,7 @@ 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;
@ -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 */
@ -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;

View file

@ -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,26 +207,34 @@ 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;
@ -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];

View 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: */

View file

@ -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,7 +504,7 @@ 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);
@ -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);
@ -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;

View file

@ -20,7 +20,7 @@
/*==============================================================================
$Id: load_xm.c,v 1.5 2008/02/29 18:49:03 denis111 Exp $
$Id$
Fasttracker (XM) module loader
@ -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)
@ -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]; \
@ -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,22 +691,24 @@ 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.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])
@ -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 */

View file

@ -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,13 +108,24 @@ 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
#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 */
/* 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
@ -103,25 +133,29 @@ static void _mm_registeralldrivers(void)
#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();

View file

@ -1,6 +1,6 @@
/* 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
@ -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;
}
@ -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;
@ -600,7 +601,7 @@ MIKMODAPI void MikMod_Exit(void)
/* 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;
@ -630,11 +631,11 @@ static int _mm_reset(CHAR *cmdline)
}
}
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,7 +846,7 @@ INIT_MUTEX(lists);
MIKMODAPI int MikMod_InitThreads(void)
{
static int firstcall=1;
static int result=0;
static int result = 0;
if (firstcall) {
firstcall=0;
@ -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;
@ -961,5 +964,5 @@ int MD_DropPrivileges(void)
}
#endif
#endif
/* ex:set ts=4: */
/* ex:set ts=8: */

View file

@ -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
@ -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,8 +733,7 @@ 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);
@ -850,8 +907,7 @@ 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();
@ -891,7 +947,6 @@ 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);
@ -908,11 +963,24 @@ enum plugin_status plugin_start(const void* parameter)
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,11 +1002,10 @@ 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);
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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__)

View file

@ -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;
}
@ -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;
}
@ -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,7 +448,8 @@ 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);
@ -408,7 +457,6 @@ MIKMODAPI CHAR* Player_LoadTitleMem(const char *buffer,int len)
_mm_delete_mem_reader(reader);
}
return result;
}
@ -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;
}
@ -500,24 +578,20 @@ 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);
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();
_mm_rewind(modreader);
_mm_iobase_revert(modreader);
return NULL;
}
@ -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);
}

View file

@ -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();

View file

@ -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) {

View file

@ -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) return d;
if(!d) {
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
}
return align_pointer(d, ALIGN_STRIDE);
#endif
#endif
_mm_errno = MMERR_OUT_OF_MEMORY;
if(_mm_errorhandler) _mm_errorhandler();
return NULL;
}
void MikMod_free(void *data)
{
free(data);
if (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
/* 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: */

View file

@ -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];
}

View file

@ -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;
@ -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;
MMEMREADER* mr;
long siz;
int ret;
if (!reader) { return 0; }
if (!reader || !size || (size > (size_t) LONG_MAX))
return 0;
if (reader->Eof(reader)) { 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; }
mr = (MMEMREADER*) reader;
if (mr->pos >= mr->len) return EOF;
c = ((const unsigned char*) mr->buffer)[mr->pos];
mr->pos++;
pos = ((MMEMREADER*)reader)->pos;
((MMEMREADER*)reader)->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: */

View file

@ -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 */
@ -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;
@ -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,7 +1752,7 @@ 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;
@ -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;
@ -2136,7 +2163,7 @@ static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWO
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,7 +2195,7 @@ 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;
(void)channel;
c = UniGetByte();
inf = UniGetByte();
@ -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;
@ -2401,12 +2432,12 @@ static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
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;
@ -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)) {
@ -2955,7 +2986,7 @@ static void pt_SetupVoices(MODULE *mod)
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)
@ -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)
@ -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;
@ -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);
@ -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: */

View file

@ -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 */
@ -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;
}

View file

@ -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,

View file

@ -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)
@ -232,8 +231,10 @@ static int SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor
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;
@ -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. */
@ -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

File diff suppressed because it is too large Load diff

View file

@ -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(); }
@ -159,8 +167,9 @@ 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)
@ -169,7 +178,6 @@ 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,9 +282,9 @@ 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;
@ -309,13 +315,13 @@ 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)
@ -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;
@ -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: */

View file

@ -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