This commit is contained in:
Paul 2000-10-11 16:47:03 +00:00
parent f9b956d088
commit 45a65d892c
5 changed files with 362 additions and 95 deletions

View file

@ -74,6 +74,7 @@ char *s_mem[3];
Params: Params:
Returns: Returns:
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
int ploopid=0;
void CPaulScene::init() void CPaulScene::init()
{ {
s_fontBank.initialise(&standardFont); s_fontBank.initialise(&standardFont);
@ -87,6 +88,8 @@ void CPaulScene::init()
//CXAStream::Init(); //CXAStream::Init();
PAUL_DBGMSG("initialised.."); PAUL_DBGMSG("initialised..");
ploopid=CSoundMediator::playSfx(0);
} }
@ -133,12 +136,14 @@ int pkill=0;
#include "sound\speech.h" #include "sound\speech.h"
int mvol=10; int mvol=10;
int svol=255; int svol=255;
VECTOR ppos;
void CPaulScene::think() void CPaulScene::think()
{ {
int pad; int pad;
int sfxId=-1; int sfxId=-1;
int setVolumes=false; int setSfxVolume=false;
int setSongVolume=false;
pad=PadGetDown(0); pad=PadGetDown(0);
if(pad&PAD_R1) if(pad&PAD_R1)
@ -164,39 +169,51 @@ void CPaulScene::think()
if(sfxId!=-1) if(sfxId!=-1)
{ {
CSoundMediator::playSfx(sfxId); CSoundMediator::playSfx(sfxId);
} }
if(pad&PAD_START) if(pad&PAD_START)
{ {
PAUL_DBGMSG("stop %d",pkill);
CSoundMediator::stopSfx((xmPlayingId)pkill); CSoundMediator::stopSfx((xmPlayingId)pkill);
} }
if(pad&PAD_R2)
{
PAUL_DBGMSG("stop all");
CSoundMediator::stopAllSound();
}
//CSoundMediator::setposition((xmPlayingId)ploopid,&ppos);
pad=PadGetHeld(0); pad=PadGetHeld(0);
if(pad&PAD_UP) if(pad&PAD_UP)
{ {
if(++mvol>CSoundMediator::MAX_VOLUME)mvol=CSoundMediator::MAX_VOLUME; mvol+=16;
setVolumes=true; if(mvol>CSoundMediator::MAX_VOLUME)mvol=CSoundMediator::MAX_VOLUME;
setSongVolume=true;
} }
if(pad&PAD_DOWN) if(pad&PAD_DOWN)
{ {
if(--mvol<CSoundMediator::MIN_VOLUME)mvol=CSoundMediator::MIN_VOLUME; mvol-=16;
setVolumes=true; if(mvol<CSoundMediator::MIN_VOLUME)mvol=CSoundMediator::MIN_VOLUME;
setSongVolume=true;
} }
if(pad&PAD_RIGHT) if(pad&PAD_RIGHT)
{ {
if(++svol>CSoundMediator::MAX_VOLUME)svol=CSoundMediator::MAX_VOLUME; svol+=16;
setVolumes=true; if(svol>CSoundMediator::MAX_VOLUME)svol=CSoundMediator::MAX_VOLUME;
setSfxVolume=true;
} }
if(pad&PAD_LEFT) if(pad&PAD_LEFT)
{ {
if(--svol<CSoundMediator::MIN_VOLUME)svol=CSoundMediator::MIN_VOLUME; svol-=16;
setVolumes=true; if(svol<CSoundMediator::MIN_VOLUME)svol=CSoundMediator::MIN_VOLUME;
setSfxVolume=true;
} }
if(setVolumes) if(setSongVolume) CSoundMediator::setVolume(CSoundMediator::SONG,mvol);
if(setSfxVolume) CSoundMediator::setVolume(CSoundMediator::SFX,svol);
if(setSongVolume||setSfxVolume)
{ {
CSoundMediator::setVolume(CSoundMediator::SONG,mvol); PAUL_DBGMSG("song:%d sfx:%d",mvol,svol);
CSoundMediator::setVolume(CSoundMediator::SFX,svol);
} }
//CXAStream::ControlXA(); //CXAStream::ControlXA();

View file

@ -28,6 +28,10 @@ adjust channels ( watery-mario64 style music changes )
#include "system\dbg.h" #include "system\dbg.h"
#endif #endif
#ifndef __UTILS_HEADER__
#include "utils\utils.h"
#endif
/* Std Lib /* Std Lib
------- */ ------- */
@ -112,9 +116,6 @@ static ReverbDetails s_reverbDetails[CSoundMediator::NUM_REVERBTYPES]=
{ SPU_REV_MODE_ECHO, 75, 0x3000, 100 }, // ECHO_TEST { SPU_REV_MODE_ECHO, 75, 0x3000, 100 }, // ECHO_TEST
}; };
//
int s_songChannelCount=10;
//
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
@ -139,12 +140,11 @@ void CSoundMediator::initialise()
s_targetVolume[i]=INITIAL_VOLUME; s_targetVolume[i]=INITIAL_VOLUME;
s_volumeDirty[i]=true; s_volumeDirty[i]=true;
} }
setSongToFadedIn();
// ASSERT(CXAStream::MIN_VOLUME==0); // Just incase someone decides to change any of these.. things in here will break ( PKG ) // ASSERT(CXAStream::MIN_VOLUME==0); // Just incase someone decides to change any of these.. things in here will break ( PKG )
// ASSERT(CXAStream::MAX_VOLUME==32767); // ASSERT(CXAStream::MAX_VOLUME==32767);
// Initial reverb settings // Initial reverb settings
setReverbType(ECHO_TEST); setReverbType(NONE);//ECHO_TEST);
SOUND_DBGMSG("Sound mediator initialised"); SOUND_DBGMSG("Sound mediator initialised");
s_initialised=true; s_initialised=true;
@ -211,23 +211,20 @@ void CSoundMediator::think(int _frames)
dirty++; dirty++;
} }
// Manual update of anything that needs it // Update of anything that needs it
// CXAStream::ControlXA(); // CXAStream::ControlXA();
s_xmplaySound->think(); 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])
{ {
if(s_songPlayingId!=NOT_PLAYING) s_xmplaySound->setMasterSongVolume(s_currentVolume[SONG]);
{ s_volumeDirty[SONG]=false;
int vol=(s_currentVolume[SONG]*((s_currentVolume[SONGFADE]>>1)+128))>>8;
s_xmplaySound->setVolume(s_songPlayingId,(char)vol);
}
s_volumeDirty[SONG]=s_volumeDirty[SONGFADE]=false;
} }
if(s_volumeDirty[SFX]) if(s_volumeDirty[SFX])
{ {
s_xmplaySound->setMasterSfxVolume(s_currentVolume[SFX]);
s_volumeDirty[SFX]=false; s_volumeDirty[SFX]=false;
} }
// if(s_volumeDirty[SPEECH]) // if(s_volumeDirty[SPEECH])
@ -283,8 +280,8 @@ void CSoundMediator::playSong()
ASSERT(s_songModId!=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_songModId,s_songChannelCount); s_songPlayingId=s_xmplaySound->playSong(s_songSampleId,s_songModId);
s_volumeDirty[SONG]=true; // Force a volume update // s_volumeDirty[SONG]=true; // Force a volume update
} }
@ -335,10 +332,12 @@ void CSoundMediator::setSfxBank(SFXBANKID _bankId)
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
Function: Function:
Purpose: Purpose:
Params: Params: Pass _lock as true if you wanna keep hold of one-shot sfx.
This'll be necessary if you have a *long* one-shot at the
same time as *lots* of other sfx.
Returns: Returns:
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
xmPlayingId CSoundMediator::playSfx(int _sfxId) xmPlayingId CSoundMediator::playSfx(int _sfxId,int _lock=false)
{ {
int sfxChannelMask; int sfxChannelMask;
xmPlayingId playId; xmPlayingId playId;
@ -356,18 +355,44 @@ xmPlayingId CSoundMediator::playSfx(int _sfxId)
else else
{ {
playId=s_xmplaySound->playSfx(s_sfxSampleId,s_sfxModId,sfx->m_pattern,sfx->m_channelMask,20); playId=s_xmplaySound->playSfx(s_sfxSampleId,s_sfxModId,sfx->m_pattern,sfx->m_channelMask,20);
if(playId!=NOT_PLAYING) if(!_lock&&playId!=NOT_PLAYING)
{ {
s_xmplaySound->unlockPlayingId(playId); // We really don't care about one-shot sfx.. s_xmplaySound->unlockPlayingId(playId); // We really don't care about one-shot sfx..
playId=NOT_PLAYING; playId=NOT_PLAYING;
} }
} }
s_volumeDirty[SFX]=true; // Force a volume update // s_volumeDirty[SFX]=true; // Force a volume update
return playId; return playId;
} }
/*----------------------------------------------------------------------
Function:
Purpose: Calculate volume and panning for a sound base upon its
position in space. Takes a position in space which describes
the sound position relative to the camera/microphone.
Volume comes from distance from origin and panning comes from
the position along the x axis.
Params:
Returns:
---------------------------------------------------------------------- */
void CSoundMediator::setposition(xmPlayingId _playingId,VECTOR *pos)
{
int volume,pan;
volume=CXMPlaySound::MAX_VOLUME-(CalcLengthV(pos));
if(volume<CXMPlaySound::MIN_VOLUME)volume=CXMPlaySound::MIN_VOLUME;
pan=(pos->vx/2)+CXMPlaySound::PAN_CENTRE;
if(pan<CXMPlaySound::PAN_LEFT)pan=CXMPlaySound::PAN_LEFT;
else if(pan>CXMPlaySound::PAN_RIGHT)pan=CXMPlaySound::PAN_RIGHT;
s_xmplaySound->setVolume(_playingId,volume);
s_xmplaySound->setPanning(_playingId,pan);
}
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
Function: Function:
Purpose: Purpose:
@ -423,5 +448,17 @@ int CSoundMediator::getVolume(VOLUMETYPE _type)
} }
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CSoundMediator::stopAllSound()
{
s_xmplaySound->stopAndUnlockAllSound();
}
/*=========================================================================== /*===========================================================================
end */ end */

View file

@ -66,8 +66,6 @@ public:
SFX, SFX,
SPEECH, SPEECH,
SONGFADE,
NUM_VOLUMETYPES, NUM_VOLUMETYPES,
}; };
@ -98,13 +96,11 @@ public:
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 setSongToFadedIn() {setVolume(SONGFADE,255);}
// SFX interface // SFX interface
static void setSfxBank(SFXBANKID _bankId); static void setSfxBank(SFXBANKID _bankId);
static xmPlayingId playSfx(int _sfxId); static xmPlayingId playSfx(int _sfxId,int _lock=false);
// static void setposition(int _playId,vector pos ); static void setposition(xmPlayingId _playingId,VECTOR *pos);
static void stopSfx(xmPlayingId _playingId); static void stopSfx(xmPlayingId _playingId);
// Speech interface // Speech interface
@ -113,7 +109,7 @@ public:
// 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:

View file

@ -89,12 +89,12 @@ void CXMPlaySound::initialise()
// Clear internal data // Clear internal data
for(i=0;i<MAX_XM_SONGS;i++) for(i=0;i<MAX_XM_SONGS;i++)
{ {
XMMod *mod=&s_xmMods[i]; XMMod *mod=&m_xmMods[i];
mod->m_refCount=0; mod->m_refCount=0;
} }
for(i=0;i<MAX_XM_VABS;i++) for(i=0;i<MAX_XM_VABS;i++)
{ {
XMVab *vab=&s_xmVabs[i]; XMVab *vab=&m_xmVabs[i];
vab->m_refCount=0; vab->m_refCount=0;
} }
@ -104,6 +104,8 @@ void CXMPlaySound::initialise()
m_spuChannelUse[i].m_locked=false; m_spuChannelUse[i].m_locked=false;
} }
m_masterSongVolume=0;
m_masterSfxVolume=0;
SOUND_DBGMSG("XMPlay sound initialised"); SOUND_DBGMSG("XMPlay sound initialised");
} }
@ -147,7 +149,7 @@ void CXMPlaySound::think()
{ {
if(XM_GetFeedback(ch->m_internalId,&fb)) if(XM_GetFeedback(ch->m_internalId,&fb))
{ {
PAUL_DBGMSG("%d finished.. ( was on chnl %d )",id,i); //PAUL_DBGMSG("%d finished.. ( was on chnl %d )",id,i);
while(ch->m_playingId==id&&i<NUM_SPU_CHANNELS) while(ch->m_playingId==id&&i<NUM_SPU_CHANNELS)
{ {
ch->m_useType=SILENT; ch->m_useType=SILENT;
@ -163,6 +165,72 @@ PAUL_DBGMSG("%d finished.. ( was on chnl %d )",id,i);
} }
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CXMPlaySound::setMasterSongVolume(unsigned char _vol)
{
int i;
spuChannelUse *ch;
xmPlayingId lastId;
// New volume
if(m_masterSongVolume==_vol) return;
m_masterSongVolume=_vol;
// Now update any active songs
ch=m_spuChannelUse;
lastId=NOT_PLAYING;
for(i=0;i<NUM_SPU_CHANNELS;i++,ch++)
{
if(ch->m_playingId!=lastId&&ch->m_useType==SONG)
{
int oldLock=ch->m_locked; // hmm..
ch->m_locked=true; // not too..
setVolume(ch->m_playingId,ch->m_vol);
ch->m_locked=oldLock; // ..ugly I suppose
lastId=ch->m_playingId;
}
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CXMPlaySound::setMasterSfxVolume(unsigned char _vol)
{
int i;
spuChannelUse *ch;
xmPlayingId lastId;
// New volume
if(m_masterSfxVolume==_vol) return;
m_masterSfxVolume=_vol;
// Now update any active sfx
ch=m_spuChannelUse;
lastId=NOT_PLAYING;
for(i=0;i<NUM_SPU_CHANNELS;i++,ch++)
{
if(ch->m_playingId!=lastId&&ch->m_useType==SFX||ch->m_useType==LOOPINGSFX)
{
int oldLock=ch->m_locked; // hmm..
ch->m_locked=true; // not too..
setVolume(ch->m_playingId,ch->m_vol);
ch->m_locked=oldLock; // ..ugly I suppose
lastId=ch->m_playingId;
}
}
}
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
Function: Function:
Purpose: Purpose:
@ -177,7 +245,7 @@ xmSampleId CXMPlaySound::loadSampleData(FileEquate _vhFe,FileEquate _vbFe)
// Is the bank already loaded? // Is the bank already loaded?
vab=s_xmVabs; vab=m_xmVabs;
for(vabId=0;vabId<MAX_XM_VABS;vabId++) for(vabId=0;vabId<MAX_XM_VABS;vabId++)
{ {
if(vab->m_refCount&&vab->m_vhFile==_vhFe&&vab->m_vbFile==_vbFe) if(vab->m_refCount&&vab->m_vhFile==_vhFe&&vab->m_vbFile==_vbFe)
@ -190,7 +258,7 @@ xmSampleId CXMPlaySound::loadSampleData(FileEquate _vhFe,FileEquate _vbFe)
// Find next free vab slot // Find next free vab slot
vabId=0; vabId=0;
vab=s_xmVabs; vab=m_xmVabs;
while(1) while(1)
{ {
ASSERT(vabId<MAX_XM_VABS); ASSERT(vabId<MAX_XM_VABS);
@ -225,7 +293,7 @@ xmModId CXMPlaySound::loadModData(FileEquate _modFe)
XMMod *mod; XMMod *mod;
// Is the mod already loaded? // Is the mod already loaded?
mod=s_xmMods; mod=m_xmMods;
for(modId=0;modId<MAX_XM_SONGS;modId++) for(modId=0;modId<MAX_XM_SONGS;modId++)
{ {
if(mod->m_refCount&&mod->m_file==_modFe) if(mod->m_refCount&&mod->m_file==_modFe)
@ -237,7 +305,7 @@ xmModId CXMPlaySound::loadModData(FileEquate _modFe)
} }
// Find next free song slot // Find next free song slot
mod=s_xmMods; mod=m_xmMods;
modId=0; modId=0;
while(1) while(1)
{ {
@ -245,7 +313,7 @@ xmModId CXMPlaySound::loadModData(FileEquate _modFe)
if(mod->m_refCount==0) if(mod->m_refCount==0)
{ {
mod->m_xmData=(u8*)CFileIO::loadFile(_modFe); mod->m_xmData=(u8*)CFileIO::loadFile(_modFe);
InitXMData(mod->m_xmData,modId,XM_UseS3MPanning); InitXMData(mod->m_xmData,modId,0);//XM_UseS3MPanning);
mod->m_file=_modFe; mod->m_file=_modFe;
mod->m_refCount=1; mod->m_refCount=1;
break; break;
@ -267,7 +335,7 @@ void CXMPlaySound::dumpSampleData(xmSampleId _sampleId)
{ {
XMVab *vab; XMVab *vab;
vab=&s_xmVabs[_sampleId]; vab=&m_xmVabs[_sampleId];
vab->m_refCount--; vab->m_refCount--;
if(vab->m_refCount==0) if(vab->m_refCount==0)
{ {
@ -286,7 +354,7 @@ void CXMPlaySound::dumpModData(xmModId _modId)
{ {
XMMod *mod; XMMod *mod;
mod=&s_xmMods[_modId]; mod=&m_xmMods[_modId];
mod->m_refCount--; mod->m_refCount--;
if(mod->m_refCount==0) if(mod->m_refCount==0)
{ {
@ -318,7 +386,40 @@ void CXMPlaySound::setStereo(int _stereo)
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
void CXMPlaySound::setVolume(xmPlayingId _playingId,unsigned char _volume) void CXMPlaySound::setVolume(xmPlayingId _playingId,unsigned char _volume)
{ {
XM_SetMasterVol(_playingId,_volume>>1); int i;
spuChannelUse *ch;
int vol;
ch=m_spuChannelUse;
for(i=0;i<NUM_SPU_CHANNELS;i++,ch++)
{
if(ch->m_playingId==_playingId)
{
ASSERT(ch->m_locked!=false); // Cant alter unlocked channels!
ch->m_vol=_volume; // Update volume
switch(ch->m_useType)
{
case SILENT:
break;
case SONG:
vol=(_volume*m_masterSongVolume)>>8;
XM_SetMasterVol(ch->m_internalId,vol>>1);
break;
case SFX:
vol=(_volume*m_masterSfxVolume)>>8;
XM_SetMasterVol(ch->m_internalId,vol>>1);
break;
case LOOPINGSFX:
updateLoopingSfx(ch);
break;
}
return;
}
}
ASSERT(0); // Couldn't find the sound to unlock it!
} }
@ -330,7 +431,66 @@ void CXMPlaySound::setVolume(xmPlayingId _playingId,unsigned char _volume)
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
void CXMPlaySound::setPanning(xmPlayingId _playingId,char _pan) void CXMPlaySound::setPanning(xmPlayingId _playingId,char _pan)
{ {
XM_SetMasterPan(_playingId,_pan); int i;
spuChannelUse *ch;
ch=m_spuChannelUse;
for(i=0;i<NUM_SPU_CHANNELS;i++,ch++)
{
if(ch->m_playingId==_playingId)
{
ASSERT(ch->m_locked!=false); // Cant alter unlocked channels!
ch->m_pan=_pan; // Update pan
switch(ch->m_useType)
{
case SILENT:
break;
case SONG:
XM_SetMasterPan(ch->m_internalId,_pan-128);
break;
case SFX:
XM_SetMasterPan(ch->m_internalId,_pan-128);
break;
case LOOPINGSFX:
updateLoopingSfx(ch);
break;
}
return;
}
}
ASSERT(0); // Couldn't find the sound to unlock it!
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CXMPlaySound::stopAndUnlockAllSound()
{
int i;
spuChannelUse *ch;
ch=m_spuChannelUse;
for(i=0;i<NUM_SPU_CHANNELS;i++,ch++)
{
if(ch->m_useType!=SILENT)
{
int oldLock=ch->m_locked; // hmm..
ch->m_locked=true; // not too..
stopPlayingId(ch->m_playingId);
ch->m_locked=oldLock; // ..ugly I suppose
// Need to unlock too
if(oldLock)unlockPlayingId(ch->m_playingId);
}
}
} }
@ -340,31 +500,36 @@ void CXMPlaySound::setPanning(xmPlayingId _playingId,char _pan)
Params: Params:
Returns: Returns:
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
xmPlayingId CXMPlaySound::playSong(xmSampleId _sampleId,xmModId _songId,int _channelCount) xmPlayingId CXMPlaySound::playSong(xmSampleId _sampleId,xmModId _modId)
{ {
int baseChannel; int channelCount,baseChannel;
XMVab *vab; XMVab *vab;
int id; int id;
xmPlayingId retId; xmPlayingId retId;
ASSERT(s_xmVabs[_sampleId].m_refCount!=0); ASSERT(m_xmVabs[_sampleId].m_refCount!=0);
ASSERT(s_xmMods[_songId].m_refCount!=0); ASSERT(m_xmMods[_modId].m_refCount!=0);
baseChannel=findSpareChannels(_channelCount,255); // Let's grab the channel count from the XM data.. :)
channelCount=(short int)*(m_xmMods[_modId].m_xmData+68);
SOUND_DBGMSG("Playing song with %d channels reserved",channelCount);
baseChannel=findSpareChannels(channelCount,255);
if(baseChannel!=-1) if(baseChannel!=-1)
{ {
retId=getNextSparePlayingId(); retId=getNextSparePlayingId();
vab=&s_xmVabs[_sampleId]; vab=&m_xmVabs[_sampleId];
id=XM_Init(vab->m_vabId, // id from XM_VABInit id=XM_Init(vab->m_vabId, // id from XM_VABInit
_songId, // XM id ( as passed to InitXMData ) _modId, // XM id ( as passed to InitXMData )
-1,//baseChannel,//0, // Song id -1, // Let xmplay give us a song id
baseChannel, // First channel baseChannel, // First channel
XM_Loop, // Loop XM_Loop, // Play song continuously
-1, // Play mask -1, // Play all channels
XM_Music, // Music XM_Music, // Music
0); // Pattern to start at 0); // Begin at the beginning
markChannelsAsActive(baseChannel,_channelCount,SONG,retId,id,255); markChannelsAsActive(baseChannel,channelCount,SONG,retId,id,255);
PAUL_DBGMSG("playSong %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+_channelCount-1); setVolume(retId,MAX_VOLUME);
//PAUL_DBGMSG("playSong %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+channelCount-1);
} }
else else
{ {
@ -391,7 +556,7 @@ void CXMPlaySound::unlockPlayingId(xmPlayingId _playingId)
{ {
if(ch->m_playingId==_playingId) if(ch->m_playingId==_playingId)
{ {
PAUL_DBGMSG("unlocking %d",_playingId); //PAUL_DBGMSG("unlocking %d",_playingId);
ASSERT(ch->m_locked!=false); ASSERT(ch->m_locked!=false);
while(ch->m_playingId==_playingId) while(ch->m_playingId==_playingId)
{ {
@ -421,24 +586,21 @@ void CXMPlaySound::stopPlayingId(xmPlayingId _playingId)
{ {
if(ch->m_playingId==_playingId) if(ch->m_playingId==_playingId)
{ {
ASSERT(ch->m_locked!=false); // Cant stop unlocked channels!
switch(ch->m_useType) switch(ch->m_useType)
{ {
case SILENT: case SILENT:
PAUL_DBGMSG("stopping.. woah! %d is already stopped",_playingId);
break; break;
case SONG: case SONG:
PAUL_DBGMSG("stopping song on %d",_playingId);
XM_PlayStop(ch->m_internalId); XM_PlayStop(ch->m_internalId);
break; break;
case SFX: case SFX:
PAUL_DBGMSG("stopping sfx on %d",_playingId);
XM_PlayStop(ch->m_internalId); XM_PlayStop(ch->m_internalId);
break; break;
case LOOPINGSFX: case LOOPINGSFX:
PAUL_DBGMSG("stopping loopingsfx on %d",_playingId);
XM_StopSample(ch->m_internalId); XM_StopSample(ch->m_internalId);
break; break;
} }
@ -461,7 +623,7 @@ void CXMPlaySound::stopPlayingId(xmPlayingId _playingId)
Params: Params:
Returns: Returns:
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
xmPlayingId CXMPlaySound::playSfx(xmSampleId _sampleId,xmModId _songId,int _sfxPattern,int _playMask,u8 _priority) xmPlayingId CXMPlaySound::playSfx(xmSampleId _sampleId,xmModId _modId,int _sfxPattern,int _playMask,u8 _priority)
{ {
int i,j; int i,j;
int maskCopy,channelCount; int maskCopy,channelCount;
@ -472,8 +634,8 @@ xmPlayingId CXMPlaySound::playSfx(xmSampleId _sampleId,xmModId _songId,int _sfxP
int id; int id;
xmPlayingId retId; xmPlayingId retId;
ASSERT(s_xmVabs[_sampleId].m_refCount!=0); ASSERT(m_xmVabs[_sampleId].m_refCount!=0);
ASSERT(s_xmMods[_songId].m_refCount!=0); ASSERT(m_xmMods[_modId].m_refCount!=0);
// Count channels // Count channels
maskCopy=_playMask; maskCopy=_playMask;
@ -490,19 +652,20 @@ xmPlayingId CXMPlaySound::playSfx(xmSampleId _sampleId,xmModId _songId,int _sfxP
if(baseChannel!=-1) if(baseChannel!=-1)
{ {
retId=getNextSparePlayingId(); retId=getNextSparePlayingId();
vab=&s_xmVabs[_sampleId]; vab=&m_xmVabs[_sampleId];
XM_SetSFXRange(baseChannel,channelCount); XM_SetSFXRange(baseChannel,channelCount);
id=XM_Init(vab->m_vabId, // id from XM_VABInit id=XM_Init(vab->m_vabId, // id from XM_VABInit
_songId, // XM id ( as passed to InitXMData ) _modId, // XM id ( as passed to InitXMData )
-1,//baseChannel,//SONGNUM, // Song id -1, // Let xmplay give us a song id
-1, // First channel -1, // Use SFX range to get first channel
XM_NoLoop, // Loop XM_NoLoop, // One-shot
_playMask, // Play mask _playMask, // Play mask
XM_SFX, // Music XM_SFX, // SFX
_sfxPattern); // Pattern to start at _sfxPattern); // SFX pattern to play
XM_ClearSFXRange(); XM_ClearSFXRange();
PAUL_DBGMSG("playSfx %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+channelCount-1); //PAUL_DBGMSG("playSfx %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+channelCount-1);
markChannelsAsActive(baseChannel,channelCount,SFX,retId,id,_priority); markChannelsAsActive(baseChannel,channelCount,SFX,retId,id,_priority);
setVolume(retId,MAX_VOLUME);
} }
else else
{ {
@ -519,7 +682,7 @@ PAUL_DBGMSG("playSfx %d/%d ( on %d-%d )",retId,id,baseChannel,baseChanne
Params: Params:
Returns: Returns:
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
xmPlayingId CXMPlaySound::playLoopingSfx(xmSampleId _sampleId,xmModId _songId,int _soundId,u8 _priority,int _pitch) xmPlayingId CXMPlaySound::playLoopingSfx(xmSampleId _sampleId,xmModId _modId,int _soundId,u8 _priority,int _pitch)
{ {
int baseChannel; int baseChannel;
xmPlayingId retId; xmPlayingId retId;
@ -528,9 +691,10 @@ xmPlayingId CXMPlaySound::playLoopingSfx(xmSampleId _sampleId,xmModId _songId,in
if(baseChannel!=-1) if(baseChannel!=-1)
{ {
retId=getNextSparePlayingId(); retId=getNextSparePlayingId();
PAUL_DBGMSG("playLoopingSfx %d/- ( on %d-%d )",retId,baseChannel,baseChannel); //PAUL_DBGMSG("playLoopingSfx %d/- ( on %d-%d )",retId,baseChannel,baseChannel);
XM_PlaySample(XM_GetSampleAddress(_sampleId,_soundId),baseChannel,0x3fff,0x3fff,_pitch); XM_PlaySample(XM_GetSampleAddress(_sampleId,_soundId),baseChannel,0x3fff,0x3fff,_pitch);
markChannelsAsActive(baseChannel,1,LOOPINGSFX,retId,baseChannel,_priority); markChannelsAsActive(baseChannel,1,LOOPINGSFX,retId,baseChannel,_priority);
setVolume(retId,MAX_VOLUME);
} }
else else
{ {
@ -624,6 +788,8 @@ void CXMPlaySound::markChannelsAsActive(int _baseChannel,int _channelCount,CHANN
details.m_playingId=_playingId; details.m_playingId=_playingId;
details.m_priority=_priority; details.m_priority=_priority;
details.m_locked=true; details.m_locked=true;
details.m_vol=MAX_VOLUME;
details.m_pan=PAN_CENTRE;
ch=&m_spuChannelUse[_baseChannel]; ch=&m_spuChannelUse[_baseChannel];
for(i=_baseChannel;i<_baseChannel+_channelCount;i++,ch++) for(i=_baseChannel;i<_baseChannel+_channelCount;i++,ch++)
@ -649,7 +815,7 @@ void CXMPlaySound::defragSpuMemory()
SOUND_DBGMSG("CXMPlaySound is defragging.."); SOUND_DBGMSG("CXMPlaySound is defragging..");
// Dump banks // Dump banks
vab=s_xmVabs; vab=m_xmVabs;
for(vabId=0;vabId<MAX_XM_VABS;vabId++,vab++) for(vabId=0;vabId<MAX_XM_VABS;vabId++,vab++)
{ {
if(vab->m_refCount) if(vab->m_refCount)
@ -659,7 +825,7 @@ void CXMPlaySound::defragSpuMemory()
} }
// Now reload them // Now reload them
vab=s_xmVabs; vab=m_xmVabs;
for(vabId=0;vabId<MAX_XM_VABS;vabId++,vab++) for(vabId=0;vabId<MAX_XM_VABS;vabId++,vab++)
{ {
if(vab->m_refCount) if(vab->m_refCount)
@ -676,5 +842,34 @@ void CXMPlaySound::defragSpuMemory()
} }
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CXMPlaySound::updateLoopingSfx(spuChannelUse *ch)
{
int actualVol,actualPan;
int leftVol,rightVol;
SpuVoiceAttr attr;
actualVol=(ch->m_vol*m_masterSfxVolume)>>8; // 0=silent, 255=full vol
actualPan=ch->m_pan; // 0=hard left, 255=hard right
leftVol=(actualVol*actualPan)>>2;
rightVol=(actualVol*(255-actualPan))>>2;
ASSERT(leftVol<=0x3fff); ASSERT(leftVol>=0);
ASSERT(rightVol<=0x3fff); ASSERT(rightVol>=0);
attr.voice=(1<<ch->m_internalId);
attr.mask=(SPU_VOICE_VOLL|SPU_VOICE_VOLR);
attr.volume.left=leftVol;
attr.volume.right=rightVol;
SpuSetVoiceAttr(&attr);
}
/*=========================================================================== /*===========================================================================
end */ end */

View file

@ -44,10 +44,23 @@ typedef enum {NOT_PLAYING=-1} xmPlayingId;
class CXMPlaySound class CXMPlaySound
{ {
public: public:
enum
{
MIN_VOLUME=0,
MAX_VOLUME=255,
PAN_LEFT=0,
PAN_CENTRE=127,
PAN_RIGHT=255,
};
void initialise(); void initialise();
void shutdown(); void shutdown();
void think(); void think();
void setMasterSongVolume(unsigned char _vol);
void setMasterSfxVolume(unsigned char _vol);
xmSampleId loadSampleData(FileEquate _vhFe,FileEquate _vbFe); xmSampleId loadSampleData(FileEquate _vhFe,FileEquate _vbFe);
xmModId loadModData(FileEquate _modFe); xmModId loadModData(FileEquate _modFe);
void dumpSampleData(xmSampleId _sampleId); void dumpSampleData(xmSampleId _sampleId);
@ -58,9 +71,11 @@ public:
void setVolume(xmPlayingId _playingId,unsigned char _volume); void setVolume(xmPlayingId _playingId,unsigned char _volume);
void setPanning(xmPlayingId _playingId,char _pan); void setPanning(xmPlayingId _playingId,char _pan);
xmPlayingId playSong(xmSampleId _sampleId,xmModId _songId,int _channelCount); void stopAndUnlockAllSound();
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); xmPlayingId playSong(xmSampleId _sampleId,xmModId _modId);
xmPlayingId playSfx(xmSampleId _sampleId,xmModId _modId,int _sfxPattern,int _playMask,u8 _priority);
xmPlayingId playLoopingSfx(xmSampleId _sampleId,xmModId _modId,int _soundId,u8 _priority,int _pitch=0x400);
void unlockPlayingId(xmPlayingId _playingId); void unlockPlayingId(xmPlayingId _playingId);
void stopPlayingId(xmPlayingId _playingId); void stopPlayingId(xmPlayingId _playingId);
@ -86,7 +101,7 @@ private:
LOOPINGSFX, LOOPINGSFX,
} CHANNELUSETYPE; } CHANNELUSETYPE;
// Internal representation of loaded songs // Internal representation of loaded mods
typedef struct XMMod typedef struct XMMod
{ {
unsigned char *m_xmData; unsigned char *m_xmData;
@ -111,6 +126,7 @@ private:
u8 m_internalId; u8 m_internalId;
u8 m_priority; u8 m_priority;
u8 m_locked; u8 m_locked;
u8 m_vol,m_pan;
} spuChannelUse; } spuChannelUse;
xmPlayingId getNextSparePlayingId(); xmPlayingId getNextSparePlayingId();
@ -119,11 +135,17 @@ private:
void defragSpuMemory(); void defragSpuMemory();
void updateLoopingSfx(spuChannelUse *ch);
unsigned char *m_fhPtr[MAX_XM_HEADERS]; unsigned char *m_fhPtr[MAX_XM_HEADERS];
unsigned char *m_songPtr[MAX_SONG_HEADERS]; unsigned char *m_songPtr[MAX_SONG_HEADERS];
XMMod s_xmMods[MAX_XM_SONGS]; XMMod m_xmMods[MAX_XM_SONGS];
XMVab s_xmVabs[MAX_XM_VABS]; XMVab m_xmVabs[MAX_XM_VABS];
spuChannelUse m_spuChannelUse[NUM_SPU_CHANNELS]; spuChannelUse m_spuChannelUse[NUM_SPU_CHANNELS];
unsigned char m_masterSongVolume;
unsigned char m_masterSfxVolume;
}; };