This commit is contained in:
parent
76f10e2299
commit
06ec0fdcd6
4 changed files with 471 additions and 252 deletions
|
@ -43,8 +43,8 @@ typedef struct XMFILEDATA
|
||||||
|
|
||||||
typedef struct SFXDETAILS
|
typedef struct SFXDETAILS
|
||||||
{
|
{
|
||||||
int m_channels;
|
int m_channelMask;
|
||||||
int m_pattern;
|
int m_pattern; // ..or instrument for loopers
|
||||||
int m_looping;
|
int m_looping;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,10 +71,10 @@ static XMFILEDATA s_xmSfxData[CSoundMediator::NUM_SFXBANKIDS]=
|
||||||
|
|
||||||
static SFXDETAILS s_sfxDetails[]=
|
static SFXDETAILS s_sfxDetails[]=
|
||||||
{
|
{
|
||||||
{ 1, 0, 0 },
|
{ 1, 6, 1 },
|
||||||
{ 1, 1, 0 },
|
{ 1, 1, 0 },
|
||||||
{ 1, 2, 0 },
|
{ 1, 2, 0 },
|
||||||
{ 1, 3, 0 },
|
{ 1, 0, 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,22 +90,21 @@ static SFXDETAILS s_sfxDetails[]=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int CSoundMediator::s_initialised=false;
|
int CSoundMediator::s_initialised=false;
|
||||||
int /*CSoundMediator::*/s_currentVolume[CSoundMediator::NUM_VOLUMETYPES];
|
|
||||||
int /*CSoundMediator::*/s_targetVolume[CSoundMediator::NUM_VOLUMETYPES];
|
|
||||||
int /*CSoundMediator::*/s_volumeDirty[CSoundMediator::NUM_VOLUMETYPES];
|
|
||||||
|
|
||||||
|
int CSoundMediator::s_currentVolume[CSoundMediator::NUM_VOLUMETYPES];
|
||||||
|
int CSoundMediator::s_targetVolume[CSoundMediator::NUM_VOLUMETYPES];
|
||||||
|
int CSoundMediator::s_volumeDirty[CSoundMediator::NUM_VOLUMETYPES];
|
||||||
|
|
||||||
|
xmSampleId CSoundMediator::s_songSampleId=NO_SAMPLE;
|
||||||
|
xmModId CSoundMediator::s_songModId=NO_SONG;
|
||||||
|
xmPlayingId CSoundMediator::s_songPlayingId=NOT_PLAYING;
|
||||||
|
xmSampleId CSoundMediator::s_sfxSampleId=NO_SAMPLE;
|
||||||
|
xmModId CSoundMediator::s_sfxModId=NO_SONG;
|
||||||
|
|
||||||
static CSpuSound *s_spuSound;
|
static CSpuSound *s_spuSound;
|
||||||
|
|
||||||
static CXMPlaySound *s_xmplaySound;
|
static CXMPlaySound *s_xmplaySound;
|
||||||
|
|
||||||
static xmSampleId s_songSampleId=NO_SAMPLE;
|
|
||||||
static xmSongId s_songDataId=NO_SONG;
|
|
||||||
static xmPlayingSongId s_songPlayingId=NOT_PLAYING;
|
|
||||||
|
|
||||||
static xmSampleId s_sfxSampleId=NO_SAMPLE;
|
|
||||||
static xmSongId s_sfxDataId=NO_SONG;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,7 +122,7 @@ void CSoundMediator::initialise()
|
||||||
ASSERT(!s_initialised);
|
ASSERT(!s_initialised);
|
||||||
|
|
||||||
s_spuSound=new ("SPUSound") CSpuSound(); s_spuSound->initialise();
|
s_spuSound=new ("SPUSound") CSpuSound(); s_spuSound->initialise();
|
||||||
s_xmplaySound=new ("XMPlaySound") CXMPlaySound(); s_xmplaySound->initialise();
|
s_xmplaySound=new ("XMPlaySound") CXMPlaySound(); s_xmplaySound->initialise();
|
||||||
CXAStream::Init();
|
CXAStream::Init();
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,9 +137,6 @@ void CSoundMediator::initialise()
|
||||||
// ASSERT(CXAStream::MAX_VOLUME==32767);
|
// ASSERT(CXAStream::MAX_VOLUME==32767);
|
||||||
|
|
||||||
|
|
||||||
PAUL_DBGMSG("song: %d-%d (%d)",SONG_BASE_CHANNEL,SONG_MAX_CHANNEL,SONG_CHANNELS);
|
|
||||||
PAUL_DBGMSG("sfx: %d-%d (%d)",SFX_BASE_CHANNEL,SFX_MAX_CHANNEL,SFX_CHANNELS);
|
|
||||||
|
|
||||||
SOUND_DBGMSG("Sound mediator initialised");
|
SOUND_DBGMSG("Sound mediator initialised");
|
||||||
s_initialised=true;
|
s_initialised=true;
|
||||||
}
|
}
|
||||||
|
@ -172,13 +168,6 @@ ASSERT(0);
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
int tgt=255;
|
|
||||||
int val;
|
|
||||||
static int s_spuChannelUse[24]={-1,-1,-1,-1,-1,-1,
|
|
||||||
-1,-1,-1,-1,-1,-1,
|
|
||||||
-1,-1,-1,-1,-1,-1,
|
|
||||||
-1,-1,-1,-1,-1,-1};
|
|
||||||
|
|
||||||
void CSoundMediator::think(int _frames)
|
void CSoundMediator::think(int _frames)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -188,61 +177,6 @@ void CSoundMediator::think(int _frames)
|
||||||
ASSERT(s_initialised);
|
ASSERT(s_initialised);
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
|
|
||||||
id=-1;
|
|
||||||
for(i=SONG_CHANNELS;i<24;i++)
|
|
||||||
{
|
|
||||||
if(id!=s_spuChannelUse[i])
|
|
||||||
{
|
|
||||||
id=s_spuChannelUse[i];
|
|
||||||
if(id!=-1)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if(id>=5000)
|
|
||||||
{
|
|
||||||
PAUL_DBGMSG("%d is now free.. ( was on chnl %d )",id-5000,i);
|
|
||||||
while(s_spuChannelUse[i]==id&&i<24)
|
|
||||||
{
|
|
||||||
s_spuChannelUse[i++]=-1;
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
else if(id>=100)
|
|
||||||
{
|
|
||||||
while(s_spuChannelUse[i]==id&&i<24)
|
|
||||||
{
|
|
||||||
s_spuChannelUse[i++]+=100;
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
if(!s_xmplaySound->isSfxActive((xmPlayingSongId)id))
|
|
||||||
{
|
|
||||||
PAUL_DBGMSG("%d end.. ( was on chnl %d )",id,i);
|
|
||||||
while(s_spuChannelUse[i]==id&&i<24)
|
|
||||||
{
|
|
||||||
s_spuChannelUse[i++]=-1;
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// PAUL_DBGMSG("channel %d playing",i);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Fade to target volume
|
// Fade to target volume
|
||||||
speed=(_frames*VOLUME_CHANGE_SPEED)>>10;
|
speed=(_frames*VOLUME_CHANGE_SPEED)>>10;
|
||||||
current=s_currentVolume;
|
current=s_currentVolume;
|
||||||
|
@ -270,6 +204,8 @@ PAUL_DBGMSG("%d end.. ( was on chnl %d )",id,i);
|
||||||
|
|
||||||
// Manual update of anything that needs it
|
// Manual update of anything that needs it
|
||||||
// CXAStream::ControlXA();
|
// CXAStream::ControlXA();
|
||||||
|
s_xmplaySound->think();
|
||||||
|
|
||||||
|
|
||||||
// Push through any changes in volume
|
// Push through any changes in volume
|
||||||
if(s_volumeDirty[SONG]||s_volumeDirty[SONGFADE])
|
if(s_volumeDirty[SONG]||s_volumeDirty[SONGFADE])
|
||||||
|
@ -305,11 +241,11 @@ void CSoundMediator::setSong(SONGID _songId)
|
||||||
XMFILEDATA *song;
|
XMFILEDATA *song;
|
||||||
|
|
||||||
ASSERT(s_songSampleId==NO_SAMPLE);
|
ASSERT(s_songSampleId==NO_SAMPLE);
|
||||||
ASSERT(s_songDataId==NO_SONG);
|
ASSERT(s_songModId==NO_SONG);
|
||||||
|
|
||||||
song=&s_xmSongData[_songId];
|
song=&s_xmSongData[_songId];
|
||||||
s_songDataId=s_xmplaySound->loadSongData(song->m_pxm);
|
s_songModId=s_xmplaySound->loadModData(song->m_pxm);
|
||||||
s_songSampleId=s_xmplaySound->loadSamples(song->m_vh,song->m_vb);
|
s_songSampleId=s_xmplaySound->loadSampleData(song->m_vh,song->m_vb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,10 +258,10 @@ void CSoundMediator::setSong(SONGID _songId)
|
||||||
void CSoundMediator::playSong()
|
void CSoundMediator::playSong()
|
||||||
{
|
{
|
||||||
ASSERT(s_songSampleId!=NO_SAMPLE);
|
ASSERT(s_songSampleId!=NO_SAMPLE);
|
||||||
ASSERT(s_songDataId!=NO_SONG);
|
ASSERT(s_songModId!=NO_SONG);
|
||||||
ASSERT(s_songPlayingId==NOT_PLAYING);
|
ASSERT(s_songPlayingId==NOT_PLAYING);
|
||||||
|
|
||||||
s_songPlayingId=s_xmplaySound->playSong(s_songSampleId,s_songDataId,SONG_BASE_CHANNEL);
|
s_songPlayingId=s_xmplaySound->playSong(s_songSampleId,s_songModId,10); // pkg !?
|
||||||
s_volumeDirty[SONG]=true; // Force a volume update
|
s_volumeDirty[SONG]=true; // Force a volume update
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,14 +275,18 @@ void CSoundMediator::playSong()
|
||||||
void CSoundMediator::dumpSong()
|
void CSoundMediator::dumpSong()
|
||||||
{
|
{
|
||||||
ASSERT(s_songSampleId!=NO_SAMPLE);
|
ASSERT(s_songSampleId!=NO_SAMPLE);
|
||||||
ASSERT(s_songDataId!=NO_SONG);
|
ASSERT(s_songModId!=NO_SONG);
|
||||||
|
|
||||||
if(s_songPlayingId!=NOT_PLAYING)s_xmplaySound->stopSong(s_songPlayingId);
|
if(s_songPlayingId!=NOT_PLAYING)
|
||||||
s_xmplaySound->dumpSamples(s_songSampleId);
|
{
|
||||||
s_xmplaySound->dumpSongData(s_songDataId);
|
s_xmplaySound->stopPlayingId(s_songPlayingId);
|
||||||
|
s_xmplaySound->unlockPlayingId(s_songPlayingId);
|
||||||
|
}
|
||||||
|
s_xmplaySound->dumpSampleData(s_songSampleId);
|
||||||
|
s_xmplaySound->dumpModData(s_songModId);
|
||||||
|
|
||||||
s_songSampleId=NO_SAMPLE;
|
s_songSampleId=NO_SAMPLE;
|
||||||
s_songDataId=NO_SONG;
|
s_songModId=NO_SONG;
|
||||||
s_songPlayingId=NOT_PLAYING;
|
s_songPlayingId=NOT_PLAYING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,11 +302,11 @@ void CSoundMediator::setSfxBank(SFXBANKID _bankId)
|
||||||
XMFILEDATA *song;
|
XMFILEDATA *song;
|
||||||
|
|
||||||
ASSERT(s_sfxSampleId==NO_SAMPLE);
|
ASSERT(s_sfxSampleId==NO_SAMPLE);
|
||||||
ASSERT(s_sfxDataId==NO_SONG);
|
ASSERT(s_sfxModId==NO_SONG);
|
||||||
|
|
||||||
song=&s_xmSfxData[_bankId];
|
song=&s_xmSfxData[_bankId];
|
||||||
s_sfxDataId=s_xmplaySound->loadSongData(song->m_pxm);
|
s_sfxModId=s_xmplaySound->loadModData(song->m_pxm);
|
||||||
s_sfxSampleId=s_xmplaySound->loadSamples(song->m_vh,song->m_vb);
|
s_sfxSampleId=s_xmplaySound->loadSampleData(song->m_vh,song->m_vb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -376,60 +316,42 @@ void CSoundMediator::setSfxBank(SFXBANKID _bankId)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
|
xmPlayingId CSoundMediator::playSfx(int _sfxId)
|
||||||
|
|
||||||
int CSoundMediator::playSfx(int _sfxId)
|
|
||||||
{
|
{
|
||||||
|
int sfxChannelMask;
|
||||||
|
xmPlayingId playId;
|
||||||
|
SFXDETAILS *sfx;
|
||||||
|
|
||||||
ASSERT(s_sfxSampleId!=NO_SAMPLE);
|
ASSERT(s_sfxSampleId!=NO_SAMPLE);
|
||||||
ASSERT(s_sfxDataId!=NO_SONG);
|
ASSERT(s_sfxModId!=NO_SONG);
|
||||||
|
|
||||||
int baseChannel;
|
|
||||||
int channelCount=0;
|
|
||||||
int sfxChannelMask,maskCopy;
|
|
||||||
int i,j;
|
|
||||||
int valid;
|
|
||||||
int maskCheck=1;
|
|
||||||
int playId;
|
|
||||||
|
|
||||||
sfxChannelMask=3;
|
|
||||||
|
|
||||||
// Count channels
|
|
||||||
maskCopy=sfxChannelMask;
|
|
||||||
for(i=0;i<24&&maskCopy;i++)
|
|
||||||
{
|
|
||||||
if(maskCopy&1)
|
|
||||||
channelCount++;
|
|
||||||
maskCopy>>=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find some spare channels to play on
|
|
||||||
valid=false;
|
|
||||||
for(i=SFX_BASE_CHANNEL;i<NUM_SPU_CHANNELS-channelCount+1&&valid==false;i++)
|
|
||||||
{
|
|
||||||
valid=true;
|
|
||||||
for(j=i;j<i+channelCount&&valid;j++)
|
|
||||||
{
|
|
||||||
if(s_spuChannelUse[j]!=-1) valid=false; // pkg - tidy up
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ASSERT(valid!=false);
|
|
||||||
baseChannel=i-1;
|
|
||||||
|
|
||||||
// Play!
|
// Play!
|
||||||
playId=s_xmplaySound->playSfx(s_sfxSampleId,s_sfxDataId,baseChannel,_sfxId,sfxChannelMask);
|
sfx=&s_sfxDetails[_sfxId];
|
||||||
|
if(sfx->m_looping)
|
||||||
|
{
|
||||||
|
playId=s_xmplaySound->playLoopingSfx(s_sfxSampleId,s_sfxModId,sfx->m_pattern,10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
playId=s_xmplaySound->playSfx(s_sfxSampleId,s_sfxModId,sfx->m_pattern,sfx->m_channelMask,20);
|
||||||
|
if(playId!=NOT_PLAYING)s_xmplaySound->unlockPlayingId(playId); // We really don't care about one-shot sfx..
|
||||||
|
}
|
||||||
s_volumeDirty[SFX]=true; // Force a volume update
|
s_volumeDirty[SFX]=true; // Force a volume update
|
||||||
|
|
||||||
// Clear any dead channels
|
return playId;
|
||||||
//for(i=SFX_BASE_CHANNEL;i<NUM_SPU_CHANNELS;i++)
|
}
|
||||||
// if(s_spuChannelUse[i]==playId)s_spuChannelUse[i]=-1;
|
|
||||||
|
|
||||||
// Mark channels as active
|
|
||||||
for(i=baseChannel;i<baseChannel+channelCount;i++)
|
|
||||||
{
|
|
||||||
s_spuChannelUse[i]=playId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CSoundMediator::stopSfx(xmPlayingId _id)
|
||||||
|
{
|
||||||
|
s_xmplaySound->stopPlayingId(_id);
|
||||||
|
s_xmplaySound->unlockPlayingId(_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,55 +79,53 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// General
|
// General
|
||||||
static void initialise();
|
static void initialise();
|
||||||
static void shutdown();
|
static void shutdown();
|
||||||
static void think(int _frames);
|
static void think(int _frames);
|
||||||
|
|
||||||
|
|
||||||
// Song interface
|
// Song interface
|
||||||
static void setSong(SONGID _songId);
|
static void setSong(SONGID _songId);
|
||||||
static void playSong();
|
static void playSong();
|
||||||
static void dumpSong();
|
static void dumpSong();
|
||||||
static void setSongToFadedOut() {setVolume(SONGFADE,0);}
|
static void setSongToFadedOut() {setVolume(SONGFADE,0);}
|
||||||
static void setSongToFadedIn() {setVolume(SONGFADE,255);}
|
static void setSongToFadedIn() {setVolume(SONGFADE,255);}
|
||||||
|
|
||||||
// SFX interface
|
// SFX interface
|
||||||
static void setSfxBank(SFXBANKID _bankId);
|
static void setSfxBank(SFXBANKID _bankId);
|
||||||
static int playSfx(int _sfxId);
|
static xmPlayingId playSfx(int _sfxId);
|
||||||
// static void stopSfx(int _id);
|
// static void setposition(int _playId,vector pos );
|
||||||
|
static void stopSfx(xmPlayingId _id);
|
||||||
|
|
||||||
// Speech interface
|
// Speech interface
|
||||||
static void playSpeech(SpeechEquate _speech);
|
static void playSpeech(SpeechEquate _speech);
|
||||||
|
|
||||||
// Control
|
// Control
|
||||||
static void setVolume(VOLUMETYPE _type,int _val);
|
static void setVolume(VOLUMETYPE _type,int _val);
|
||||||
static int getVolume(VOLUMETYPE _type);
|
static int getVolume(VOLUMETYPE _type);
|
||||||
// static void stopAllSound();
|
// static void stopAllSound();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NUM_SPU_CHANNELS=24,
|
|
||||||
|
|
||||||
SONG_BASE_CHANNEL =0,
|
|
||||||
SONG_CHANNELS =10,
|
|
||||||
SONG_MAX_CHANNEL =SONG_BASE_CHANNEL+SONG_CHANNELS-1,
|
|
||||||
|
|
||||||
SFX_BASE_CHANNEL =SONG_MAX_CHANNEL+1,
|
|
||||||
SFX_CHANNELS =NUM_SPU_CHANNELS-SFX_BASE_CHANNEL,
|
|
||||||
SFX_MAX_CHANNEL =SFX_BASE_CHANNEL+SFX_CHANNELS-1,
|
|
||||||
|
|
||||||
VOLUME_CHANGE_SPEED=2,
|
VOLUME_CHANGE_SPEED=2,
|
||||||
INITIAL_VOLUME=192,
|
INITIAL_VOLUME=192,
|
||||||
};
|
};
|
||||||
|
|
||||||
CSoundMediator() {;}
|
CSoundMediator() {;}
|
||||||
|
|
||||||
static int s_initialised;
|
static int s_initialised;
|
||||||
|
|
||||||
// static int s_currentVolume[NUM_VOLUMETYPES];
|
static int s_currentVolume[NUM_VOLUMETYPES];
|
||||||
// static int s_targetVolume[NUM_VOLUMETYPES];
|
static int s_targetVolume[NUM_VOLUMETYPES];
|
||||||
|
static int s_volumeDirty[NUM_VOLUMETYPES];
|
||||||
|
|
||||||
|
static xmSampleId s_songSampleId;
|
||||||
|
static xmModId s_songModId;
|
||||||
|
static xmPlayingId s_songPlayingId;
|
||||||
|
static xmSampleId s_sfxSampleId;
|
||||||
|
static xmModId s_sfxModId;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
unsigned char *xmPtr;
|
|
||||||
/*=========================================================================
|
/*=========================================================================
|
||||||
|
|
||||||
spu.cpp
|
spu.cpp
|
||||||
|
@ -96,14 +95,14 @@ void CXMPlaySound::initialise()
|
||||||
size=XM_GetSongSize();
|
size=XM_GetSongSize();
|
||||||
for(i=0;i<MAX_SONG_HEADERS;i++)
|
for(i=0;i<MAX_SONG_HEADERS;i++)
|
||||||
{
|
{
|
||||||
s_songPtr[i]=(u8*)MemAlloc(size,"XMSong");
|
m_songPtr[i]=(u8*)MemAlloc(size,"XMSong");
|
||||||
XM_SetSongAddress(s_songPtr[i]);
|
XM_SetSongAddress(m_songPtr[i]);
|
||||||
}
|
}
|
||||||
size=XM_GetFileHeaderSize();
|
size=XM_GetFileHeaderSize();
|
||||||
for(i=0;i<MAX_XM_HEADERS;i++)
|
for(i=0;i<MAX_XM_HEADERS;i++)
|
||||||
{
|
{
|
||||||
s_fhPtr[i]=(u8*)MemAlloc(size,"XMHeader");
|
m_fhPtr[i]=(u8*)MemAlloc(size,"XMHeader");
|
||||||
XM_SetFileHeaderAddress(s_fhPtr[i]);
|
XM_SetFileHeaderAddress(m_fhPtr[i]);
|
||||||
}
|
}
|
||||||
VidAddVSyncFunc(XM_Update);
|
VidAddVSyncFunc(XM_Update);
|
||||||
|
|
||||||
|
@ -120,6 +119,13 @@ void CXMPlaySound::initialise()
|
||||||
vab->m_refCount=0;
|
vab->m_refCount=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i=0;i<NUM_SPU_CHANNELS;i++)
|
||||||
|
{
|
||||||
|
m_spuChannelUse[i].m_useType=SILENT;
|
||||||
|
m_spuChannelUse[i].m_locked=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SOUND_DBGMSG("XMPlay sound initialised");
|
SOUND_DBGMSG("XMPlay sound initialised");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,13 +142,60 @@ void CXMPlaySound::shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
int spuflags[24];
|
||||||
|
void CXMPlaySound::think()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int id;
|
||||||
|
spuChannelUse *ch;
|
||||||
|
XM_Feedback fb;
|
||||||
|
|
||||||
|
// Check to see if any of the sounds have finished
|
||||||
|
id=-1;
|
||||||
|
ch=m_spuChannelUse;
|
||||||
|
for(i=0;i<NUM_SPU_CHANNELS;i++)
|
||||||
|
{
|
||||||
|
//pkg tidy
|
||||||
|
// Only unlocked SFX need to be checked
|
||||||
|
if(ch->m_locked==false&&ch->m_useType==SFX)
|
||||||
|
{
|
||||||
|
id=ch->m_playingId;
|
||||||
|
if(id!=-1)
|
||||||
|
{
|
||||||
|
if(XM_GetFeedback(ch->m_internalId,&fb))
|
||||||
|
{
|
||||||
|
PAUL_DBGMSG("%d finished.. ( was on chnl %d )",id,i);
|
||||||
|
while(ch->m_playingId==id&&i<NUM_SPU_CHANNELS)
|
||||||
|
{
|
||||||
|
ch->m_useType=SILENT;
|
||||||
|
ch++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
ch--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ch++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i<24;i++)
|
||||||
|
spuflags[i]=m_spuChannelUse[i].m_useType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
Function:
|
Function:
|
||||||
Purpose:
|
Purpose:
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
xmSampleId CXMPlaySound::loadSamples(FileEquate _vhFe,FileEquate _vbFe)
|
xmSampleId CXMPlaySound::loadSampleData(FileEquate _vhFe,FileEquate _vbFe)
|
||||||
{
|
{
|
||||||
int vabId;
|
int vabId;
|
||||||
XMVab *vab;
|
XMVab *vab;
|
||||||
|
@ -195,7 +248,7 @@ xmSampleId CXMPlaySound::loadSamples(FileEquate _vhFe,FileEquate _vbFe)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
xmSongId CXMPlaySound::loadSongData(FileEquate _songFe)
|
xmModId CXMPlaySound::loadModData(FileEquate _songFe)
|
||||||
{
|
{
|
||||||
int songId;
|
int songId;
|
||||||
XMSong *song;
|
XMSong *song;
|
||||||
|
@ -208,7 +261,7 @@ xmSongId CXMPlaySound::loadSongData(FileEquate _songFe)
|
||||||
{
|
{
|
||||||
// Yup..
|
// Yup..
|
||||||
song->m_refCount++;
|
song->m_refCount++;
|
||||||
return(xmSongId)songId;
|
return(xmModId)songId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +284,7 @@ xmSongId CXMPlaySound::loadSongData(FileEquate _songFe)
|
||||||
songId++;song++;
|
songId++;song++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (xmSongId)songId;
|
return (xmModId)songId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,7 +294,7 @@ xmSongId CXMPlaySound::loadSongData(FileEquate _songFe)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
void CXMPlaySound::dumpSamples(xmSampleId _sampleId)
|
void CXMPlaySound::dumpSampleData(xmSampleId _sampleId)
|
||||||
{
|
{
|
||||||
XMVab *vab;
|
XMVab *vab;
|
||||||
|
|
||||||
|
@ -260,7 +313,7 @@ void CXMPlaySound::dumpSamples(xmSampleId _sampleId)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
void CXMPlaySound::dumpSongData(xmSongId _songId)
|
void CXMPlaySound::dumpModData(xmModId _songId)
|
||||||
{
|
{
|
||||||
XMSong *song;
|
XMSong *song;
|
||||||
|
|
||||||
|
@ -294,7 +347,7 @@ void CXMPlaySound::setStereo(int _stereo)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
void CXMPlaySound::setVolume(xmPlayingSongId _songId,unsigned char _volume)
|
void CXMPlaySound::setVolume(xmPlayingId _songId,unsigned char _volume)
|
||||||
{
|
{
|
||||||
XM_SetMasterVol(_songId,_volume>>1);
|
XM_SetMasterVol(_songId,_volume>>1);
|
||||||
}
|
}
|
||||||
|
@ -306,7 +359,7 @@ void CXMPlaySound::setVolume(xmPlayingSongId _songId,unsigned char _volume)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
void CXMPlaySound::setPanning(xmPlayingSongId _songId,char _pan)
|
void CXMPlaySound::setPanning(xmPlayingId _songId,char _pan)
|
||||||
{
|
{
|
||||||
XM_SetMasterPan(_songId,_pan);
|
XM_SetMasterPan(_songId,_pan);
|
||||||
}
|
}
|
||||||
|
@ -318,38 +371,38 @@ void CXMPlaySound::setPanning(xmPlayingSongId _songId,char _pan)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
//int sid=0;
|
xmPlayingId CXMPlaySound::playSong(xmSampleId _sampleId,xmModId _songId,int _channelCount)
|
||||||
//int chan=0;
|
|
||||||
xmPlayingSongId CXMPlaySound::playSong(xmSampleId _sampleId,xmSongId _songId,int _baseChannel)
|
|
||||||
{
|
{
|
||||||
XMVab *vab;
|
int baseChannel;
|
||||||
int id;
|
XMVab *vab;
|
||||||
|
int id;
|
||||||
|
xmPlayingId retId;
|
||||||
|
|
||||||
ASSERT(s_xmVabs[_sampleId].m_refCount!=0);
|
ASSERT(s_xmVabs[_sampleId].m_refCount!=0);
|
||||||
ASSERT(s_xmSongs[_songId].m_refCount!=0);
|
ASSERT(s_xmSongs[_songId].m_refCount!=0);
|
||||||
|
|
||||||
vab=&s_xmVabs[_sampleId];
|
|
||||||
id=XM_Init(vab->m_vabId, // id from XM_VABInit
|
|
||||||
_songId, // XM id ( as passed to InitXMData )
|
|
||||||
0, // Song id
|
|
||||||
_baseChannel, // First channel
|
|
||||||
XM_Loop, // Loop
|
|
||||||
-1, // Play mask
|
|
||||||
XM_Music, // Music
|
|
||||||
0); // Pattern to start at
|
|
||||||
|
|
||||||
return (xmPlayingSongId)id;
|
baseChannel=findSpareChannels(_channelCount,255);
|
||||||
}
|
if(baseChannel!=-1)
|
||||||
|
{
|
||||||
|
retId=getNextSparePlayingId();
|
||||||
|
vab=&s_xmVabs[_sampleId];
|
||||||
|
id=XM_Init(vab->m_vabId, // id from XM_VABInit
|
||||||
|
_songId, // XM id ( as passed to InitXMData )
|
||||||
|
-1,//baseChannel,//0, // Song id
|
||||||
|
baseChannel, // First channel
|
||||||
|
XM_Loop, // Loop
|
||||||
|
-1, // Play mask
|
||||||
|
XM_Music, // Music
|
||||||
|
0); // Pattern to start at
|
||||||
|
markChannelsAsActive(baseChannel,_channelCount,SONG,retId,id,255);
|
||||||
|
PAUL_DBGMSG("playSong %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+_channelCount-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retId=NOT_PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
return retId;
|
||||||
Function:
|
|
||||||
Purpose:
|
|
||||||
Params:
|
|
||||||
Returns:
|
|
||||||
---------------------------------------------------------------------- */
|
|
||||||
void CXMPlaySound::stopSong(xmPlayingSongId _songId)
|
|
||||||
{
|
|
||||||
XM_PlayStop(_songId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,45 +412,138 @@ void CXMPlaySound::stopSong(xmPlayingSongId _songId)
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
//int sid=0;
|
void CXMPlaySound::unlockPlayingId(xmPlayingId _playingId)
|
||||||
//int chan=0;
|
|
||||||
int SONGNUM=1;
|
|
||||||
xmPlayingSongId CXMPlaySound::playSfx(xmSampleId _sampleId,xmSongId _songId,int _baseChannel,int _sfxPattern,int _playMask=-1)
|
|
||||||
{
|
{
|
||||||
// XM_PlaySample(XM_GetSampleAddress(_sampleId,_sfxPattern),23,0x3fff,0x3fff,0x800);
|
int i;
|
||||||
// return (xmPlayingSongId)0;
|
spuChannelUse *ch;
|
||||||
|
|
||||||
|
ch=m_spuChannelUse;
|
||||||
|
for(i=0;i<NUM_SPU_CHANNELS;i++,ch++)
|
||||||
|
{
|
||||||
|
if(ch->m_playingId==_playingId)
|
||||||
|
{
|
||||||
|
PAUL_DBGMSG("unlocking %d",_playingId);
|
||||||
|
ASSERT(ch->m_locked!=false);
|
||||||
|
while(ch->m_playingId==_playingId)
|
||||||
|
{
|
||||||
|
ch->m_locked=false;
|
||||||
|
ch++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT(0); // Couldn't find the sound to unlock it!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CXMPlaySound::stopPlayingId(xmPlayingId _playingId)
|
||||||
|
{
|
||||||
|
// ASSERT(m_spuChannelUse[_playingId].m_locked!=true); // Unlock channel first!
|
||||||
|
|
||||||
|
|
||||||
|
int i;
|
||||||
|
spuChannelUse *ch;
|
||||||
|
|
||||||
int i, maskCopy,channelCount=0;
|
ch=m_spuChannelUse;
|
||||||
XMVab *vab;
|
for(i=0;i<NUM_SPU_CHANNELS;i++,ch++)
|
||||||
int id;
|
{
|
||||||
|
if(ch->m_playingId==_playingId)
|
||||||
|
{
|
||||||
|
switch(ch->m_useType)
|
||||||
|
{
|
||||||
|
case SILENT:
|
||||||
|
PAUL_DBGMSG("stopping.. woah! %d is already stopped",_playingId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SONG:
|
||||||
|
PAUL_DBGMSG("stopping song on %d",_playingId);
|
||||||
|
XM_PlayStop(ch->m_internalId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SFX:
|
||||||
|
PAUL_DBGMSG("stopping sfx on %d",_playingId);
|
||||||
|
XM_PlayStop(ch->m_internalId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOOPINGSFX:
|
||||||
|
PAUL_DBGMSG("stopping loopingsfx on %d",_playingId);
|
||||||
|
XM_StopSample(ch->m_internalId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(ch->m_playingId==_playingId)
|
||||||
|
{
|
||||||
|
ch->m_useType=SILENT;
|
||||||
|
ch++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT(0); // Couldn't find the sound to stop it!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
xmPlayingId CXMPlaySound::playSfx(xmSampleId _sampleId,xmModId _songId,int _sfxPattern,int _playMask,u8 _priority)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
int maskCopy,channelCount;
|
||||||
|
int valid;
|
||||||
|
int baseChannel;
|
||||||
|
XMVab *vab;
|
||||||
|
int songId;
|
||||||
|
int id;
|
||||||
|
xmPlayingId retId;
|
||||||
|
|
||||||
ASSERT(s_xmVabs[_sampleId].m_refCount!=0);
|
ASSERT(s_xmVabs[_sampleId].m_refCount!=0);
|
||||||
ASSERT(s_xmSongs[_songId].m_refCount!=0);
|
ASSERT(s_xmSongs[_songId].m_refCount!=0);
|
||||||
|
|
||||||
|
// Count channels
|
||||||
maskCopy=_playMask;
|
maskCopy=_playMask;
|
||||||
for(i=0;i<24&&maskCopy;i++)
|
channelCount=0;
|
||||||
|
for(i=0;i<NUM_SPU_CHANNELS&&maskCopy;i++)
|
||||||
{
|
{
|
||||||
if(maskCopy&1)
|
if(maskCopy&1)
|
||||||
channelCount++;
|
channelCount++;
|
||||||
maskCopy>>=1;
|
maskCopy>>=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vab=&s_xmVabs[_sampleId];
|
// Play the sound
|
||||||
XM_SetSFXRange(_baseChannel,channelCount);
|
baseChannel=findSpareChannels(channelCount,_priority);
|
||||||
id=XM_Init(vab->m_vabId, // id from XM_VABInit
|
if(baseChannel!=-1)
|
||||||
_songId, // XM id ( as passed to InitXMData )
|
{
|
||||||
SONGNUM, // Song id
|
retId=getNextSparePlayingId();
|
||||||
-1, // First channel
|
vab=&s_xmVabs[_sampleId];
|
||||||
XM_NoLoop, // Loop
|
XM_SetSFXRange(baseChannel,channelCount);
|
||||||
_playMask, // Play mask
|
id=XM_Init(vab->m_vabId, // id from XM_VABInit
|
||||||
XM_SFX, // Music
|
_songId, // XM id ( as passed to InitXMData )
|
||||||
_sfxPattern); // Pattern to start at
|
-1,//baseChannel,//SONGNUM, // Song id
|
||||||
|
-1, // First channel
|
||||||
SONGNUM++;
|
XM_NoLoop, // Loop
|
||||||
if(SONGNUM>=24)SONGNUM=1;
|
_playMask, // Play mask
|
||||||
//PAUL_DBGMSG("sfx - ret:%d",id);
|
XM_SFX, // Music
|
||||||
return (xmPlayingSongId)id;
|
_sfxPattern); // Pattern to start at
|
||||||
|
XM_ClearSFXRange();
|
||||||
|
PAUL_DBGMSG("playSfx %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+channelCount-1);
|
||||||
|
markChannelsAsActive(baseChannel,channelCount,SFX,retId,id,_priority);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retId=NOT_PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -407,11 +553,139 @@ if(SONGNUM>=24)SONGNUM=1;
|
||||||
Params:
|
Params:
|
||||||
Returns:
|
Returns:
|
||||||
---------------------------------------------------------------------- */
|
---------------------------------------------------------------------- */
|
||||||
int CXMPlaySound::isSfxActive(xmPlayingSongId _id)
|
xmPlayingId CXMPlaySound::playLoopingSfx(xmSampleId _sampleId,xmModId _songId,int _soundId,u8 _priority,int _pitch)
|
||||||
{
|
{
|
||||||
XM_Feedback fb;
|
int baseChannel;
|
||||||
|
xmPlayingId retId;
|
||||||
|
|
||||||
return XM_GetFeedback(_id,&fb)==0;
|
baseChannel=findSpareChannels(1,_priority);
|
||||||
|
if(baseChannel!=-1)
|
||||||
|
{
|
||||||
|
retId=getNextSparePlayingId();
|
||||||
|
PAUL_DBGMSG("playLoopingSfx %d/- ( on %d-%d )",retId,baseChannel,baseChannel);
|
||||||
|
XM_PlaySample(XM_GetSampleAddress(_sampleId,_soundId),baseChannel,0x3fff,0x3fff,_pitch);
|
||||||
|
markChannelsAsActive(baseChannel,1,LOOPINGSFX,retId,baseChannel,_priority);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retId=NOT_PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
xmPlayingId CXMPlaySound::getNextSparePlayingId()
|
||||||
|
{
|
||||||
|
xmPlayingId validId;
|
||||||
|
int i;
|
||||||
|
spuChannelUse *ch;
|
||||||
|
static xmPlayingId nextId=(xmPlayingId)(0-1); // fudge to make first id=0
|
||||||
|
|
||||||
|
|
||||||
|
validId=NOT_PLAYING;
|
||||||
|
while(validId==NOT_PLAYING)
|
||||||
|
{
|
||||||
|
nextId=(xmPlayingId)((nextId+1)&0xff); // gives 256 unique id numbers
|
||||||
|
|
||||||
|
// Is this id still in use?
|
||||||
|
validId=nextId;
|
||||||
|
ch=m_spuChannelUse;
|
||||||
|
for(i=0;i<NUM_SPU_CHANNELS&&validId!=NOT_PLAYING;i++)
|
||||||
|
{
|
||||||
|
if(ch->m_playingId==validId&&!(ch->m_locked==false&&ch->m_useType==SILENT))
|
||||||
|
validId=NOT_PLAYING;
|
||||||
|
ch++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return validId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose: Returns the base channel of a slot big enuf for the
|
||||||
|
requested number of channels
|
||||||
|
Params:
|
||||||
|
Returns: baseChannel or -1 if no space
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
int CXMPlaySound::findSpareChannels(int _channelCount,int _priority)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
int valid;
|
||||||
|
|
||||||
|
// First we search for channels that are marked as unused
|
||||||
|
valid=false;
|
||||||
|
for(i=0;i<NUM_SPU_CHANNELS-_channelCount+1&&valid==false;)
|
||||||
|
{
|
||||||
|
valid=true;
|
||||||
|
for(j=i;j<i+_channelCount&&valid;j++)
|
||||||
|
{
|
||||||
|
if(m_spuChannelUse[j].m_useType!=SILENT) valid=false; // pkg - tidy up
|
||||||
|
}
|
||||||
|
if(valid) return i;
|
||||||
|
i=j;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Couldn't find one.. can we kill off a lower priority sound?
|
||||||
|
if(valid==false)
|
||||||
|
{
|
||||||
|
int lowestPrioity=_priority;
|
||||||
|
int possibleBase=-1;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
// Find the lowest priority sound with enuf spare channels
|
||||||
|
i=0;
|
||||||
|
while(i<24)
|
||||||
|
{
|
||||||
|
if(m_spuChannelUse[i].m_priority<=lowestPriority&&m_spuChannelUse[j].m_useType!=SILENT)
|
||||||
|
{
|
||||||
|
valid=true;
|
||||||
|
id=m_spuChannelUse[i].m_id;
|
||||||
|
for(j=i;j<i+_channelCount&&valid;j++)
|
||||||
|
{
|
||||||
|
if(m_spuChannelUse[j].m_id!=id) valid=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// Can't play it :(
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CXMPlaySound::markChannelsAsActive(int _baseChannel,int _channelCount,CHANNELUSETYPE _useType,xmPlayingId _playingId,int _internalId,u8 _priority)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
spuChannelUse *ch,details;
|
||||||
|
|
||||||
|
|
||||||
|
details.m_useType=_useType;
|
||||||
|
details.m_internalId=_internalId;
|
||||||
|
details.m_playingId=_playingId;
|
||||||
|
details.m_priority=_priority;
|
||||||
|
details.m_locked=true;
|
||||||
|
|
||||||
|
ch=&m_spuChannelUse[_baseChannel];
|
||||||
|
for(i=_baseChannel;i<_baseChannel+_channelCount;i++,ch++)
|
||||||
|
*ch=details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
// This is a bit messy, but makes sure that you can't easily pass the wrong IDs to the xm functions
|
// This is a bit messy, but makes sure that you can't easily pass the wrong IDs to the xm functions
|
||||||
// ( ..something scares me about this way of doing it tho :)
|
// ( ..something scares me about this way of doing it tho :)
|
||||||
typedef enum {NO_SAMPLE=-1} xmSampleId;
|
typedef enum {NO_SAMPLE=-1} xmSampleId;
|
||||||
typedef enum {NO_SONG=-1} xmSongId;
|
typedef enum {NO_SONG=-1} xmModId;
|
||||||
typedef enum {NOT_PLAYING=-1} xmPlayingSongId;
|
typedef enum {NOT_PLAYING=-1} xmPlayingId;
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
|
@ -46,23 +46,24 @@ class CXMPlaySound
|
||||||
public:
|
public:
|
||||||
void initialise();
|
void initialise();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
void think();
|
||||||
|
|
||||||
xmSampleId loadSamples(FileEquate _vhFe,FileEquate _vbFe);
|
xmSampleId loadSampleData(FileEquate _vhFe,FileEquate _vbFe);
|
||||||
xmSongId loadSongData(FileEquate _songFe);
|
xmModId loadModData(FileEquate _songFe);
|
||||||
void dumpSamples(xmSampleId _sampleId);
|
void dumpSampleData(xmSampleId _sampleId);
|
||||||
void dumpSongData(xmSongId _songId);
|
void dumpModData(xmModId _songId);
|
||||||
|
|
||||||
void setStereo(int _stereo);
|
void setStereo(int _stereo);
|
||||||
|
|
||||||
void setVolume(xmPlayingSongId _songId,unsigned char _volume);
|
void setVolume(xmPlayingId _songId,unsigned char _volume);
|
||||||
void setPanning(xmPlayingSongId _songId,char _pan);
|
void setPanning(xmPlayingId _songId,char _pan);
|
||||||
|
|
||||||
xmPlayingSongId playSong(xmSampleId _sampleId,xmSongId _songId,int _baseChannel);
|
xmPlayingId playSong(xmSampleId _sampleId,xmModId _songId,int _channelCount);
|
||||||
void stopSong(xmPlayingSongId _songId);
|
xmPlayingId playSfx(xmSampleId _sampleId,xmModId _songId,int _sfxPattern,int _playMask,u8 _priority);
|
||||||
|
xmPlayingId playLoopingSfx(xmSampleId _sampleId,xmModId _songId,int _soundId,u8 _priority,int _pitch=0x400);
|
||||||
xmPlayingSongId playSfx(xmSampleId _sampleId,xmSongId _songId,int _baseChannel,int _sfxPattern,int _playMask=-1);
|
|
||||||
int isSfxActive(xmPlayingSongId _id);
|
|
||||||
|
|
||||||
|
void unlockPlayingId(xmPlayingId _playingId);
|
||||||
|
void stopPlayingId(xmPlayingId _playingId);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -70,12 +71,36 @@ private:
|
||||||
{
|
{
|
||||||
MAX_XM_HEADERS=8,
|
MAX_XM_HEADERS=8,
|
||||||
MAX_SONG_HEADERS=24,
|
MAX_SONG_HEADERS=24,
|
||||||
|
|
||||||
|
NUM_SPU_CHANNELS=24,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SILENT,
|
||||||
|
SONG,
|
||||||
|
SFX,
|
||||||
|
LOOPINGSFX,
|
||||||
|
} CHANNELUSETYPE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CHANNELUSETYPE m_useType;
|
||||||
|
xmPlayingId m_playingId; // extern id
|
||||||
|
u8 m_internalId;
|
||||||
|
u8 m_priority;
|
||||||
|
u8 m_locked;
|
||||||
|
} spuChannelUse;
|
||||||
|
|
||||||
|
xmPlayingId getNextSparePlayingId();
|
||||||
|
int findSpareChannels(int _channelCount,int _priority);
|
||||||
|
void markChannelsAsActive(int _baseChannel,int _channelCount,CHANNELUSETYPE _useType,xmPlayingId _playingId,int _internalId,u8 _priority);
|
||||||
|
|
||||||
void defragSpuMemory();
|
void defragSpuMemory();
|
||||||
|
|
||||||
unsigned char *s_fhPtr[MAX_XM_HEADERS];
|
unsigned char *m_fhPtr[MAX_XM_HEADERS];
|
||||||
unsigned char *s_songPtr[MAX_SONG_HEADERS];
|
unsigned char *m_songPtr[MAX_SONG_HEADERS];
|
||||||
|
spuChannelUse m_spuChannelUse[NUM_SPU_CHANNELS];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue