From c9d1c7c792e106ca124e5561440262fa106d836f Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 5 Oct 2000 14:16:09 +0000 Subject: [PATCH] --- makefile.gaz | 10 +- makefile.gfx | 21 +- source/paul/paul.cpp | 103 ++++++--- source/sound/sound.cpp | 425 +++++++++++++++++++++++++++++++++++ source/sound/sound.h | 142 ++++++++++++ source/sound/spu.cpp | 113 ++++++++++ source/sound/spu.h | 63 ++++++ source/sound/xmplay.cpp | 463 +++++++++++++++++++++++++++++++++++++++ source/sound/xmplay.h | 96 ++++++++ source/system/gstate.cpp | 13 ++ 10 files changed, 1419 insertions(+), 30 deletions(-) create mode 100644 source/sound/sound.cpp create mode 100644 source/sound/sound.h create mode 100644 source/sound/spu.cpp create mode 100644 source/sound/spu.h create mode 100644 source/sound/xmplay.cpp create mode 100644 source/sound/xmplay.h diff --git a/makefile.gaz b/makefile.gaz index ca1ab7be6..a58adc110 100644 --- a/makefile.gaz +++ b/makefile.gaz @@ -74,15 +74,17 @@ pad_src := pads paul_src := paul -# sound_src := sndbank \ -# music \ -# cdxa +sound_src := sound \ + spu \ + xmplay \ + cdxa system_src := main \ gstate \ vid \ dbg \ - vsprintf + vsprintf \ + clickcount utils_src := utils \ sincos diff --git a/makefile.gfx b/makefile.gfx index 172018aea..0ab4c467b 100644 --- a/makefile.gfx +++ b/makefile.gfx @@ -120,6 +120,25 @@ GFX_DATA_OUT += $(UI_GFX_TEX_OUT) #---------------------------------------------------------------------------- # SFX #---------------------------------------------------------------------------- +SFX_IN_DIR := data/SFX +SFX_OUT_DIR := $(DATA_OUT)/SFX + +SFX_LIST := ingame + +SFX_ALL_IN := $(foreach SFX,$(SFX_LIST),$(SFX_IN_DIR)/$(SFX)/$(SFX).PXM $(SFX_IN_DIR)/$(SFX)/$(SFX).VH $(SFX_IN_DIR)/$(SFX)/$(SFX).VB) +SFX_ALL_OUT := $(foreach SFX,$(SFX_LIST),$(SFX_OUT_DIR)/$(SFX).PXM $(SFX_OUT_DIR)/$(SFX).VH $(SFX_OUT_DIR)/$(SFX).VB) + +sfx: $(SFX_ALL_OUT) + +cleansfx: + @$(RM) -f $(SFX_ALL_OUT) + +$(SFX_ALL_OUT) : $(SFX_ALL_IN) + $(CP) $(SFX_ALL_IN) $(SFX_OUT_DIR) + +GRAF_DIRS_TO_MAKE += $(SFX_OUT_DIR) +GFX_DATA_OUT += $(SFX_ALL_OUT) + #---------------------------------------------------------------------------- # Music @@ -127,7 +146,7 @@ GFX_DATA_OUT += $(UI_GFX_TEX_OUT) MUSIC_IN_DIR := data/music MUSIC_OUT_DIR := $(DATA_OUT)/music -MUSIC_LIST := hypermmx +MUSIC_LIST := hypermmx droppop MUSIC_ALL_IN := $(foreach MUSIC,$(MUSIC_LIST),$(MUSIC_IN_DIR)/$(MUSIC)/$(MUSIC).PXM $(MUSIC_IN_DIR)/$(MUSIC)/$(MUSIC).VH $(MUSIC_IN_DIR)/$(MUSIC)/$(MUSIC).VB) MUSIC_ALL_OUT := $(foreach MUSIC,$(MUSIC_LIST),$(MUSIC_OUT_DIR)/$(MUSIC).PXM $(MUSIC_OUT_DIR)/$(MUSIC).VH $(MUSIC_OUT_DIR)/$(MUSIC).VB) diff --git a/source/paul/paul.cpp b/source/paul/paul.cpp index 2814dca9a..292e5691f 100644 --- a/source/paul/paul.cpp +++ b/source/paul/paul.cpp @@ -34,6 +34,14 @@ #include "utils\utils.h" #endif +#ifndef __SOUND_SOUND_H__ +#include "sound\sound.h" +#endif + +#ifndef __PAD_PADS_H__ +#include "pad\pads.h" +#endif + /* Std Lib ------- */ @@ -68,13 +76,17 @@ char *s_mem[3]; ---------------------------------------------------------------------- */ void CPaulScene::init() { - setActiveDbgChannels(DC_PAUL); - PAUL_DBGMSG("this is a message.."); - PAUL_DBGMSG("this is a message.. 2"); - PAUL_DBGMSG("this is a message.. 3"); - s_fontBank.initialise(&standardFont); + CSoundMediator::initialise(); + CSoundMediator::setSong(CSoundMediator::DROPPOP); +// CSoundMediator::playSong(); + + CSoundMediator::setSfxBank(CSoundMediator::INGAME); + + +//CXAStream::Init(); + PAUL_DBGMSG("initialised.."); } @@ -116,34 +128,75 @@ void CPaulScene::render() Params: Returns: ---------------------------------------------------------------------- */ -int trashoff=-1; -int trash=false; +int psfx=3; +#include "sound\speech.h" +int mvol=10; +int svol=255; + void CPaulScene::think() { -// static int arse=0; -// PAUL_DBGMSG("%d\n",arse++); -// ASSERT(arse<100); + int pad; + int sfxId=-1; + int setVolumes=false; - int i; - int size[3]; - - for(i=0;i<3;i++) + pad=PadGetDown(0); + if(pad&PAD_CROSS) { - size[i]=32763;//getRndRange(32768); - s_mem[i]=MemAlloc(size[i],"Test"); + sfxId=psfx; } - PAUL_DBGMSG("%d %d %d",size[0],size[1],size[2]); - - if(trash) + else if(pad&PAD_SQUARE) { - *(s_mem[0]+trashoff)=123; - trash=false; + sfxId=0; + } + else if(pad&PAD_TRIANGLE) + { + sfxId=1; + } + else if(pad&PAD_CIRCLE) + { + sfxId=2; + } + if(sfxId!=-1) + { + CSoundMediator::playSfx(sfxId); +// PAUL_DBGMSG("---- sfx %d",sfxId); + //CSoundMediator::playSpeech(speechId); +// CXAStream::Stop(); +// CXAStream::PlaySpeech(speechId,true); +// PAUL_DBGMSG("----- playing speech %d",speechId); + } +// CXAStream::SetVolume(32700,32700); + + + pad=PadGetHeld(0); + if(pad&PAD_UP) + { + if(++mvol>CSoundMediator::MAX_VOLUME)mvol=CSoundMediator::MAX_VOLUME; + setVolumes=true; + } + if(pad&PAD_DOWN) + { + if(--mvolCSoundMediator::MAX_VOLUME)svol=CSoundMediator::MAX_VOLUME; + setVolumes=true; + } + if(pad&PAD_LEFT) + { + if(--svolinitialise(); + s_xmplaySound=new ("XMPlaySound") CXMPlaySound(); s_xmplaySound->initialise(); + CXAStream::Init(); + + + for(i=0;ishutdown(); delete s_xmplaySound; + s_spuSound->shutdown(); delete s_spuSound; + + SOUND_DBGMSG("Sound mediator shutdown"); + s_initialised=false; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + 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) +{ + int i; + int diff,speed; + int *current,*target,*dirty; + + ASSERT(s_initialised); + + +{ +int id; + +id=-1; +for(i=10;i<24;i++) +{ + if(id!=s_spuChannelUse[i]) + { + id=s_spuChannelUse[i]; + if(id!=-1) + { + 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; + } + } + } + } + +} +} + + + + + + + // Fade to target volume + speed=(_frames*VOLUME_CHANGE_SPEED)>>10; + current=s_currentVolume; + target=s_targetVolume; + dirty=s_volumeDirty; + for(i=0;i0) + { + *current+=speed; + if(*current>*target)*current=*target; + *dirty=true; + } + current++; + target++; + dirty++; + } + + // Manual update of anything that needs it +// CXAStream::ControlXA(); + + // Push through any changes in volume + if(s_volumeDirty[SONG]||s_volumeDirty[SONGFADE]) + { + if(s_songPlayingId!=NOT_PLAYING) + { + 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]) + { + s_volumeDirty[SFX]=false; + } +// if(s_volumeDirty[SPEECH]) +// { +// int vol=s_currentVolume[SPEECH]<<7; +// CXAStream::SetVolume(vol,vol); +// s_volumeDirty[SPEECH]=false; +// } +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CSoundMediator::setSong(SONGID _songId) +{ + XMFILEDATA *song; + + ASSERT(s_songSampleId==NO_SAMPLE); + ASSERT(s_songDataId==NO_SONG); + + song=&s_xmSongData[_songId]; + s_songDataId=s_xmplaySound->loadSongData(song->m_pxm); + s_songSampleId=s_xmplaySound->loadSamples(song->m_vh,song->m_vb); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CSoundMediator::playSong() +{ + ASSERT(s_songSampleId!=NO_SAMPLE); + ASSERT(s_songDataId!=NO_SONG); + ASSERT(s_songPlayingId==NOT_PLAYING); + + s_songPlayingId=s_xmplaySound->playSong(s_songSampleId,s_songDataId,SONG_BASE_CHANNEL); + s_volumeDirty[SONG]=true; // Force a volume update +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CSoundMediator::dumpSong() +{ + ASSERT(s_songSampleId!=NO_SAMPLE); + ASSERT(s_songDataId!=NO_SONG); + + if(s_songPlayingId!=NOT_PLAYING)s_xmplaySound->stopSong(s_songPlayingId); + s_xmplaySound->dumpSamples(s_songSampleId); + s_xmplaySound->dumpSongData(s_songDataId); + + s_songSampleId=NO_SAMPLE; + s_songDataId=NO_SONG; + s_songPlayingId=NOT_PLAYING; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CSoundMediator::setSfxBank(SFXBANKID _bankId) +{ + XMFILEDATA *song; + + ASSERT(s_sfxSampleId==NO_SAMPLE); + ASSERT(s_sfxDataId==NO_SONG); + + song=&s_xmSfxData[_bankId]; + s_sfxDataId=s_xmplaySound->loadSongData(song->m_pxm); + s_sfxSampleId=s_xmplaySound->loadSamples(song->m_vh,song->m_vb); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ + + +int CSoundMediator::playSfx(int _sfxId) +{ + ASSERT(s_sfxSampleId!=NO_SAMPLE); + ASSERT(s_sfxDataId!=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=true; + for(i=SFX_BASE_CHANNEL;iplaySfx(s_sfxSampleId,s_sfxDataId,baseChannel,_sfxId,sfxChannelMask); + s_volumeDirty[SFX]=true; // Force a volume update + +// Clear any dead channels +//for(i=SFX_BASE_CHANNEL;i=MIN_VOLUME&&_val<=MAX_VOLUME); + + s_targetVolume[_type]=_val; + s_volumeDirty[_type]=true; // Otherwise we could miss volume changes under rare conditions +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +int CSoundMediator::getVolume(VOLUMETYPE _type) +{ + return s_targetVolume[_type]; +} + + +/*=========================================================================== + end */ \ No newline at end of file diff --git a/source/sound/sound.h b/source/sound/sound.h new file mode 100644 index 000000000..3531781f3 --- /dev/null +++ b/source/sound/sound.h @@ -0,0 +1,142 @@ +/*========================================================================= + + sound.h + + Author: PKG + Created: + Project: Spongebob + Purpose: + + Copyright (c) 2000 Climax Development Ltd + +===========================================================================*/ + +#ifndef __SOUND_SOUND_H__ +#define __SOUND_SOUND_H__ + +/*---------------------------------------------------------------------- + Includes + -------- */ + +#ifndef __SOUND_XMPLAY_H__ +#include "sound\xmplay.h" +#endif + +#ifndef __SOUND_SPU_H__ +#include "sound\spu.h" +#endif +#ifndef __SOUND_XMPLAY_H__ +#include "sound\xmplay.h" +#endif +#ifndef __CDXAHeader__ +#include "sound\cdxa.h" +#endif + + +/* Std Lib + ------- */ + +/*---------------------------------------------------------------------- + Tyepdefs && Defines + ------------------- */ + +/*---------------------------------------------------------------------- + Structure defintions + -------------------- */ + +class CSoundMediator +{ +public: + typedef enum SONGID + { + HYPERMMX, + DROPPOP, + NUM_SONGIDS, + }; + typedef enum SFXBANKID + { + INGAME, + NUM_SFXBANKIDS, + }; + + typedef enum VOLUMETYPE + { + SONG, + SFX, + SPEECH, + + SONGFADE, + + NUM_VOLUMETYPES, + }; + + typedef enum + { + MIN_VOLUME=0, + MAX_VOLUME=255, + }; + + + // General + static void initialise(); + static void shutdown(); + static void think(int _frames); + + + // Song interface + static void setSong(SONGID _songId); + static void playSong(); + static void dumpSong(); + static void setSongToFadedOut() {setVolume(SONGFADE,0);} + static void setSongToFadedIn() {setVolume(SONGFADE,255);} + + // SFX interface + static void setSfxBank(SFXBANKID _bankId); + static int playSfx(int _sfxId); +// static void stopSfx(int _id); + + // Speech interface + static void playSpeech(SpeechEquate _speech); + + // Control + static void setVolume(VOLUMETYPE _type,int _val); + static int getVolume(VOLUMETYPE _type); +// static void stopAllSound(); + + +private: + enum + { + NUM_SPU_CHANNELS=24, + SONG_BASE_CHANNEL=0, + SONG_CHANNELS=10, + SFX_BASE_CHANNEL=SONG_BASE_CHANNEL+SONG_CHANNELS, + SFX_CHANNELS=NUM_SPU_CHANNELS-SFX_BASE_CHANNEL, + VOLUME_CHANGE_SPEED=2, + INITIAL_VOLUME=192, + }; + + CSoundMediator() {;} + + static int s_initialised; + +// static int s_currentVolume[NUM_VOLUMETYPES]; +// static int s_targetVolume[NUM_VOLUMETYPES]; + +}; + + +/*---------------------------------------------------------------------- + Globals + ------- */ + +/*---------------------------------------------------------------------- + Functions + --------- */ + +/*---------------------------------------------------------------------- */ + +#endif /* __SOUND_SOUND_H__ */ + +/*=========================================================================== + end */ diff --git a/source/sound/spu.cpp b/source/sound/spu.cpp new file mode 100644 index 000000000..9fd3188f2 --- /dev/null +++ b/source/sound/spu.cpp @@ -0,0 +1,113 @@ +/*========================================================================= + + spu.cpp + + Author: PKG + Created: + Project: Spongebob + Purpose: + + Copyright (c) 2000 Climax Development Ltd + +===========================================================================*/ + + +/*---------------------------------------------------------------------- + Includes + -------- */ + +#include "spu.h" + +#ifndef __SYSTEM_DBG_H__ +#include "system\dbg.h" +#endif + +#ifndef __VID_HEADER_ +#include "system\vid.h" +#endif + + +/* Std Lib + ------- */ + +#include + + +/* Data + ---- */ + +/*---------------------------------------------------------------------- + Tyepdefs && Defines + ------------------- */ + +/*---------------------------------------------------------------------- + Structure defintions + -------------------- */ + +/*---------------------------------------------------------------------- + Function Prototypes + ------------------- */ + +/*---------------------------------------------------------------------- + Vars + ---- */ + +char CSpuSound::s_spuManagementTable[SPU_MALLOC_RECSIZ*(MAX_SPU_MANAGEMENT+1)]; + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CSpuSound::initialise() +{ + SpuReverbAttr rev; + SpuEnv env; + + // SPU setup + SpuInit(); + SpuSetTransferMode(SPU_TRANSFER_BY_DMA); + SpuSetTransferStartAddr(0); + SpuWrite0(512*1024); + while(!SpuIsTransferCompleted(SPU_TRANSFER_PEEK))VSync(0); + SpuInitMalloc(MAX_SPU_MANAGEMENT,s_spuManagementTable); + SpuSetCommonMasterVolume(0x3fff,0x3fff); + + // Reverb + rev.mask=(SPU_REV_MODE|SPU_REV_DEPTHL|SPU_REV_DEPTHR); + rev.mode=SPU_REV_MODE_SPACE; + rev.depth.left=0x1000; + rev.depth.right=0x1000; + SpuSetReverbModeParam(&rev); + SpuSetReverb(SPU_ON); + SpuReserveReverbWorkArea(SPU_ON); + SpuSetReverbVoice(SPU_BIT,0x000000); + rev.mask=(SPU_REV_DEPTHL|SPU_REV_DEPTHR); + SpuSetReverbDepth(&rev); + + // Environment + env.mask=SPU_ENV_EVENT_QUEUEING; + env.queueing=SPU_OFF; + SpuSetEnv(&env); + SpuSetTransferCallback(0); + + SOUND_DBGMSG("SPU sound initialised"); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CSpuSound::shutdown() +{ + SOUND_DBGMSG("Spu sound shutdown"); +} + + +/*=========================================================================== + end */ \ No newline at end of file diff --git a/source/sound/spu.h b/source/sound/spu.h new file mode 100644 index 000000000..b0b1eb090 --- /dev/null +++ b/source/sound/spu.h @@ -0,0 +1,63 @@ +/*========================================================================= + + spu.h + + Author: PKG + Created: + Project: Spongebob + Purpose: + + Copyright (c) 2000 Climax Development Ltd + +===========================================================================*/ + +#ifndef __SOUND_SPU_H__ +#define __SOUND_SPU_H__ + +/*---------------------------------------------------------------------- + Includes + -------- */ + +/* Std Lib + ------- */ + +/*---------------------------------------------------------------------- + Tyepdefs && Defines + ------------------- */ + +/*---------------------------------------------------------------------- + Structure defintions + -------------------- */ + +class CSpuSound +{ +public: + void initialise(); + void shutdown(); + +private: + enum + { + MAX_SOUND_BANKS=4, + MAX_SPU_MANAGEMENT=MAX_SOUND_BANKS+30, + }; + + static char s_spuManagementTable[]; + +}; + + +/*---------------------------------------------------------------------- + Globals + ------- */ + +/*---------------------------------------------------------------------- + Functions + --------- */ + +/*---------------------------------------------------------------------- */ + +#endif /* __SOUND_SPU_H__ */ + +/*=========================================================================== + end */ diff --git a/source/sound/xmplay.cpp b/source/sound/xmplay.cpp new file mode 100644 index 000000000..4a85761c4 --- /dev/null +++ b/source/sound/xmplay.cpp @@ -0,0 +1,463 @@ +unsigned char *xmPtr; +/*========================================================================= + + spu.cpp + + Author: PKG + Created: + Project: Spongebob + Purpose: + + Copyright (c) 2000 Climax Development Ltd + +===========================================================================*/ + + +/*---------------------------------------------------------------------- + Includes + -------- */ + +#include "xmplay.h" + +#ifndef __SYSTEM_DBG_H__ +#include "system\dbg.h" +#endif + +#ifndef __VID_HEADER_ +#include "system\vid.h" +#endif + +#ifndef XMPlayer +#include "system\global.h" +#include +#endif + + +/* Std Lib + ------- */ + +/* Data + ---- */ + +/*---------------------------------------------------------------------- + Tyepdefs && Defines + ------------------- */ + +#define XM_SONGID 0 +#define MAX_XM_SONGS 5 +#define MAX_XM_VABS 5 + + +/*---------------------------------------------------------------------- + Structure defintions + -------------------- */ + +typedef struct XMSong +{ + unsigned char *m_xmData; + FileEquate m_file; + int m_refCount; + // refcount these! +}; +static XMSong s_xmSongs[MAX_XM_SONGS]; + +typedef struct XMVab +{ + int m_vabId; + FileEquate m_vhFile,m_vbFile; + int m_refCount; +}; +static XMVab s_xmVabs[MAX_XM_VABS]; + +/*---------------------------------------------------------------------- + Function Prototypes + ------------------- */ + +/*---------------------------------------------------------------------- + Vars + ---- */ + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::initialise() +{ + int size,i; + + +#if defined(__TERRITORY_USA__) || defined(__TERRITORY_JAP__) + XM_OnceOffInit(XM_NTSC); +#else + XM_OnceOffInit(XM_PAL); +#endif + setStereo(true); + size=XM_GetSongSize(); + for(i=0;im_refCount=0; + } + for(i=0;im_refCount=0; + } + + SOUND_DBGMSG("XMPlay sound initialised"); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::shutdown() +{ + SOUND_DBGMSG("XMPlay sound shutdown"); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: +---------------------------------------------------------------------- */ +xmSampleId CXMPlaySound::loadSamples(FileEquate _vhFe,FileEquate _vbFe) +{ + int vabId; + XMVab *vab; + unsigned char *VbPtr,*VhPtr; + + + // Is the bank already loaded? + vab=s_xmVabs; + for(vabId=0;vabIdm_refCount&&vab->m_vhFile==_vhFe&&vab->m_vbFile==_vbFe) + { + // Yup.. + vab->m_refCount++; + return(xmSampleId)vabId; + } + } + + // Find next free vab slot + vabId=0; + vab=s_xmVabs; + while(1) + { + ASSERT(vabIdm_refCount==0) + { + VhPtr=(u8*)CFileIO::loadFile(_vhFe); + VbPtr=(u8*)CFileIO::loadFile(_vbFe); + vab->m_vabId=XM_VABInit(VhPtr,VbPtr); + //defragSpuMemory(); somewhere around here.. + MemFree(VhPtr); + MemFree(VbPtr); + vab->m_vhFile=_vhFe; + vab->m_vbFile=_vbFe; + vab->m_refCount=1; + break; + } + vabId++;vab++; + } + + return (xmSampleId)vabId; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: +---------------------------------------------------------------------- */ +xmSongId CXMPlaySound::loadSongData(FileEquate _songFe) +{ + int songId; + XMSong *song; + + // Is the song already loaded? + song=s_xmSongs; + for(songId=0;songIdm_refCount&&song->m_file==_songFe) + { + // Yup.. + song->m_refCount++; + return(xmSongId)songId; + } + } + + // Find next free song slot + song=s_xmSongs; + songId=0; + while(1) + { + ASSERT(songIdm_refCount==0) + { + song->m_xmData=(u8*)CFileIO::loadFile(_songFe); + InitXMData(song->m_xmData,songId,XM_UseS3MPanning); + song->m_file=_songFe; + song->m_refCount=1; + break; + } + songId++;song++; + } + + return (xmSongId)songId; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::dumpSamples(xmSampleId _sampleId) +{ + XMVab *vab; + + vab=&s_xmVabs[_sampleId]; + vab->m_refCount--; + if(vab->m_refCount==0) + { + XM_CloseVAB(vab->m_vabId); + } +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::dumpSongData(xmSongId _songId) +{ + XMSong *song; + + song=&s_xmSongs[_songId]; + song->m_refCount--; + if(song->m_refCount==0) + { + MemFree(song->m_xmData); + } +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::setStereo(int _stereo) +{ + if(_stereo) + XM_SetStereo(); + else + XM_SetMono(); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::setVolume(xmPlayingSongId _songId,unsigned char _volume) +{ + XM_SetMasterVol(_songId,_volume>>1); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::setPanning(xmPlayingSongId _songId,char _pan) +{ + XM_SetMasterPan(_songId,_pan); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +//int sid=0; +//int chan=0; +xmPlayingSongId CXMPlaySound::playSong(xmSampleId _sampleId,xmSongId _songId,int _baseChannel) +{ + XMVab *vab; + int id; + + ASSERT(s_xmVabs[_sampleId].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 ) + -1, // Song id + _baseChannel, // First channel + XM_Loop, // Loop + -1, // Play mask + XM_Music, // Music + 0); // Pattern to start at + + return (xmPlayingSongId)id; +} + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::stopSong(xmPlayingSongId _songId) +{ + XM_PlayStop(_songId); +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +//int sid=0; +//int chan=0; +int SONGNUM=1; +xmPlayingSongId CXMPlaySound::playSfx(xmSampleId _sampleId,xmSongId _songId,int _baseChannel,int _sfxPattern,int _playMask=-1) +{ + int i, maskCopy,channelCount=0; + XMVab *vab; + int id; + + ASSERT(s_xmVabs[_sampleId].m_refCount!=0); + ASSERT(s_xmSongs[_songId].m_refCount!=0); + + + maskCopy=_playMask; + for(i=0;i<24&&maskCopy;i++) + { + if(maskCopy&1) + channelCount++; + maskCopy>>=1; + } + + vab=&s_xmVabs[_sampleId]; + XM_SetSFXRange(_baseChannel,channelCount); + id=XM_Init(vab->m_vabId, // id from XM_VABInit + _songId, // XM id ( as passed to InitXMData ) + SONGNUM, // Song id + -1, // First channel + XM_NoLoop, // Loop + _playMask, // Play mask + XM_SFX, // Music + _sfxPattern); // Pattern to start at + +SONGNUM++; +if(SONGNUM>=24)SONGNUM=1; +PAUL_DBGMSG("sfx - ret:%d",id); + return (xmPlayingSongId)id; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +int CXMPlaySound::isSfxActive(xmPlayingSongId _id) +{ + XM_Feedback fb; + int ret; + + XM_GetFeedback(_id,&fb); + + ret=fb.Status==XM_PLAYING; +//PAUL_DBGMSG("check %d ( %d )",_id,fb.Status); + return ret; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: Defrag SPU memory by reloading sample banks. Should mean that + bank load order isn't so vital. + Really needs to check for and pause playing sounds first.. hmm.. + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::defragSpuMemory() +{ + int vabId; + XMVab *vab; + unsigned char *VbPtr,*VhPtr; + + + SOUND_DBGMSG("CXMPlaySound is defragging.."); + + // Dump banks + vab=s_xmVabs; + for(vabId=0;vabIdm_refCount) + { + XM_CloseVAB(vab->m_vabId); + } + } + + // Now reload them + vab=s_xmVabs; + for(vabId=0;vabIdm_refCount) + { + VhPtr=(u8*)CFileIO::loadFile(vab->m_vhFile); + VbPtr=(u8*)CFileIO::loadFile(vab->m_vbFile); + vab->m_vabId=XM_VABInit(VhPtr,VbPtr); + MemFree(VhPtr); + MemFree(VbPtr); + } + } + + SOUND_DBGMSG("..done!"); +} + + +/*=========================================================================== + end */ \ No newline at end of file diff --git a/source/sound/xmplay.h b/source/sound/xmplay.h new file mode 100644 index 000000000..7ed74b582 --- /dev/null +++ b/source/sound/xmplay.h @@ -0,0 +1,96 @@ +/*========================================================================= + + xmplay.h + + Author: PKG + Created: + Project: Spongebob + Purpose: + + Copyright (c) 2000 Climax Development Ltd + +===========================================================================*/ + +#ifndef __SOUND_XMPLAY_H__ +#define __SOUND_XMPLAY_H__ + +/*---------------------------------------------------------------------- + Includes + -------- */ + +#ifndef _FILEIO_HEADER_ +#include "fileio\fileio.h" +#endif + + +/* Std Lib + ------- */ + +/*---------------------------------------------------------------------- + Tyepdefs && Defines + ------------------- */ + +// 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 :) +typedef enum {NO_SAMPLE=-1} xmSampleId; +typedef enum {NO_SONG=-1} xmSongId; +typedef enum {NOT_PLAYING=-1} xmPlayingSongId; + + +/*---------------------------------------------------------------------- + Structure defintions + -------------------- */ + +class CXMPlaySound +{ +public: + void initialise(); + void shutdown(); + + xmSampleId loadSamples(FileEquate _vhFe,FileEquate _vbFe); + xmSongId loadSongData(FileEquate _songFe); + void dumpSamples(xmSampleId _sampleId); + void dumpSongData(xmSongId _songId); + + void setStereo(int _stereo); + + void setVolume(xmPlayingSongId _songId,unsigned char _volume); + void setPanning(xmPlayingSongId _songId,char _pan); + + xmPlayingSongId playSong(xmSampleId _sampleId,xmSongId _songId,int _baseChannel); + void stopSong(xmPlayingSongId _songId); + + xmPlayingSongId playSfx(xmSampleId _sampleId,xmSongId _songId,int _baseChannel,int _sfxPattern,int _playMask=-1); + int isSfxActive(xmPlayingSongId _id); + + + +private: + enum + { + MAX_XM_HEADERS=8, + MAX_SONG_HEADERS=24, + }; + + void defragSpuMemory(); + + unsigned char *s_fhPtr[MAX_XM_HEADERS]; + unsigned char *s_songPtr[MAX_SONG_HEADERS]; + +}; + + +/*---------------------------------------------------------------------- + Globals + ------- */ + +/*---------------------------------------------------------------------- + Functions + --------- */ + +/*---------------------------------------------------------------------- */ + +#endif /* __SOUND_XMPLAY_H__ */ + +/*=========================================================================== + end */ diff --git a/source/system/gstate.cpp b/source/system/gstate.cpp index b4d257129..3cc78685b 100644 --- a/source/system/gstate.cpp +++ b/source/system/gstate.cpp @@ -15,12 +15,18 @@ #include "system\global.h" #include "system\gstate.h" +#ifndef __SYSTEM_CLICKCOUNT_H__ +#include "system\clickcount.h" +#endif + + /*****************************************************************************/ static CScene *s_currentScene; static CScene *s_pendingScene; int GameState::s_timeSinceLast; +static CClickCount s_clickCounter; /*****************************************************************************/ @@ -88,8 +94,15 @@ CScene * GameState::getCurrentScene() } /*****************************************************************************/ +static int s_timeSpeed = ONE; void GameState::updateTimer() { + s_timeSinceLast = (s_clickCounter.timeSinceLast() * s_timeSpeed) >> 12; + + if (s_timeSinceLast > 4 * 4096) + { + s_timeSinceLast = 4 * 4096; + } }