This commit is contained in:
Paul 2000-10-05 14:16:09 +00:00
parent 95c3a77a70
commit c9d1c7c792
10 changed files with 1419 additions and 30 deletions

View File

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

View File

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

View File

@ -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(--mvol<CSoundMediator::MIN_VOLUME)mvol=CSoundMediator::MIN_VOLUME;
setVolumes=true;
}
if(pad&PAD_RIGHT)
{
if(++svol>CSoundMediator::MAX_VOLUME)svol=CSoundMediator::MAX_VOLUME;
setVolumes=true;
}
if(pad&PAD_LEFT)
{
if(--svol<CSoundMediator::MIN_VOLUME)svol=CSoundMediator::MIN_VOLUME;
setVolumes=true;
}
if(setVolumes)
{
CSoundMediator::setVolume(CSoundMediator::SONG,mvol);
CSoundMediator::setVolume(CSoundMediator::SFX,svol);
}
for(i=0;i<3;i++)
{
MemFree(s_mem[i]);
}
CSoundMediator::think(GameState::getTimeSinceLast());
//CXAStream::ControlXA();
}

425
source/sound/sound.cpp Normal file
View File

@ -0,0 +1,425 @@
/*=========================================================================
sound.cpp
Author: PKG
Created:
Project: Spongebob
Purpose:
Copyright (c) 2000 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "sound.h"
#ifndef __SYSTEM_DBG_H__
#include "system\dbg.h"
#endif
/* Std Lib
------- */
/* Data
---- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
typedef struct XMFILEDATA
{
FileEquate m_vh,m_vb,m_pxm;
};
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
static XMFILEDATA s_xmSongData[CSoundMediator::NUM_SONGIDS]=
{
{ MUSIC_HYPERMMX_VH, MUSIC_HYPERMMX_VB, MUSIC_HYPERMMX_PXM }, // HYPERMMX
{ MUSIC_DROPPOP_VH, MUSIC_DROPPOP_VB, MUSIC_DROPPOP_PXM }, // DROPPOP
};
static XMFILEDATA s_xmSfxData[CSoundMediator::NUM_SFXBANKIDS]=
{
{ SFX_INGAME_VH, SFX_INGAME_VB, SFX_INGAME_PXM }, // INGAME
};
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];
static CSpuSound *s_spuSound;
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;
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CSoundMediator::initialise()
{
int i;
ASSERT(!s_initialised);
s_spuSound=new ("SPUSound") CSpuSound(); s_spuSound->initialise();
s_xmplaySound=new ("XMPlaySound") CXMPlaySound(); s_xmplaySound->initialise();
CXAStream::Init();
for(i=0;i<NUM_VOLUMETYPES;i++)
{
s_currentVolume[i]=MIN_VOLUME;
s_targetVolume[i]=INITIAL_VOLUME;
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::MAX_VOLUME==32767);
SOUND_DBGMSG("Sound mediator initialised");
s_initialised=true;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CSoundMediator::shutdown()
{
ASSERT(0);
ASSERT(s_initialised);
s_xmplaySound->shutdown(); 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;i<NUM_VOLUMETYPES;i++)
{
diff=*target-*current;
if(diff<0)
{
*current-=speed;
if(*current<*target)*current=*target;
*dirty=true;
}
else if(diff>0)
{
*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;i<NUM_SPU_CHANNELS-channelCount+1;i++)
{
valid=true;
for(j=i;j<i+channelCount&&valid;j++)
{
if(s_spuChannelUse[j]!=-1) valid=false;
}
if(valid==true) break;
}
ASSERT(valid!=false);
baseChannel=i;
// Play!
playId=s_xmplaySound->playSfx(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<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::playSpeech(SpeechEquate _speech)
{
// if(CXAStream::IsPlaying())
// CXAStream::Stop();
// CXAStream::PlaySpeech(_speech);
// s_volumeDirty[SPEECH]=true; // Force a volume update
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CSoundMediator::setVolume(VOLUMETYPE _type,int _val)
{
ASSERT(_val>=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 */

142
source/sound/sound.h Normal file
View File

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

113
source/sound/spu.cpp Normal file
View File

@ -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 <libspu.h>
/* 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 */

63
source/sound/spu.h Normal file
View File

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

463
source/sound/xmplay.cpp Normal file
View File

@ -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 <xmplay.h>
#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;i<MAX_SONG_HEADERS;i++)
{
s_songPtr[i]=(u8*)MemAlloc(size,"XMSong");
XM_SetSongAddress(s_songPtr[i]);
}
size=XM_GetFileHeaderSize();
for(i=0;i<MAX_XM_HEADERS;i++)
{
s_fhPtr[i]=(u8*)MemAlloc(size,"XMHeader");
XM_SetFileHeaderAddress(s_fhPtr[i]);
}
VidAddVSyncFunc(XM_Update);
// Clear internal data
for(i=0;i<MAX_XM_SONGS;i++)
{
XMSong *song=&s_xmSongs[i];
song->m_refCount=0;
}
for(i=0;i<MAX_XM_VABS;i++)
{
XMVab *vab=&s_xmVabs[i];
vab->m_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;vabId<MAX_XM_VABS;vabId++)
{
if(vab->m_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(vabId<MAX_XM_VABS);
if(vab->m_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;songId<MAX_XM_SONGS;songId++)
{
if(song->m_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(songId<MAX_XM_SONGS);
if(song->m_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;vabId<MAX_XM_VABS;vabId++,vab++)
{
if(vab->m_refCount)
{
XM_CloseVAB(vab->m_vabId);
}
}
// Now reload them
vab=s_xmVabs;
for(vabId=0;vabId<MAX_XM_VABS;vabId++,vab++)
{
if(vab->m_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 */

96
source/sound/xmplay.h Normal file
View File

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

View File

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