/* position adjust channels ( watery-mario64 style music changes ) */ /*========================================================================= 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 #ifndef __UTILS_HEADER__ #include "utils\utils.h" #endif #ifndef __SOUND_SPU_H__ #include "sound\spu.h" #endif /* Std Lib ------- */ /* Data ---- */ /*---------------------------------------------------------------------- Tyepdefs && Defines ------------------- */ /*---------------------------------------------------------------------- Structure defintions -------------------- */ typedef struct XMSONGDATA { FileEquate m_vh,m_vb,m_pxm; int m_startPattern; }; typedef struct XMSFXFILEDATA { FileEquate m_vh,m_vb,m_pxm; }; typedef struct SFXDETAILS { int m_channelMask; int m_pattern; // ..or instrument number for loopers int m_looping; }; /*---------------------------------------------------------------------- Function Prototypes ------------------- */ /*---------------------------------------------------------------------- Vars ---- */ // Static stuff for CSoundMediator 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]; xmSampleId CSoundMediator::s_songSampleId=NO_SAMPLE; FileEquate CSoundMediator::s_songVh=(FileEquate)-1; xmModId CSoundMediator::s_songModId=NO_SONG; FileEquate CSoundMediator::s_songPxm=(FileEquate)-1; xmPlayingId CSoundMediator::s_songPlayingId=NOT_PLAYING; int CSoundMediator::s_songStartPattern=0; xmSampleId CSoundMediator::s_sfxSampleId=NO_SAMPLE; xmModId CSoundMediator::s_sfxModId=NO_SONG; int CSoundMediator::s_canPlaySfx=true; static CSpuSound *s_spuSound; static CXMPlaySound *s_xmplaySound; // Songs static XMSONGDATA s_xmSongData[CSoundMediator::NUM_SONGIDS]= { // m_vh m_vb m_pxm m_startPattern; { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x00 }, // SONG_TITLE { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x0a }, // SONG_OPTIONS { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x13 }, // SONG_MEMORYCARD { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x14 }, // SONG_GAMECOMPLETE { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x23 }, // SONG_GAMEOVER { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x25 }, // SONG_PARTY { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x2c }, // SONG_MEMCARD2 { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x2f }, // SONG_MAPSCREEN { MUSIC_SB_TITLE_VH, MUSIC_SB_TITLE_VB, MUSIC_SB_TITLE_PXM, 0x33 }, // SONG_SHOPSCREEN { MUSIC_FMA_VH, MUSIC_FMA_VB, MUSIC_FMA_PXM, 0x00 }, // SONG_FMA { MUSIC_CHAPTER1_VH, MUSIC_CHAPTER1_VB, MUSIC_CHAPTER1_PXM, 0x19 }, // SONG_CHAPTER1_LEVEL1, { MUSIC_CHAPTER1_VH, MUSIC_CHAPTER1_VB, MUSIC_CHAPTER1_PXM, 0x2d }, // SONG_CHAPTER1_LEVEL2, { MUSIC_CHAPTER1_VH, MUSIC_CHAPTER1_VB, MUSIC_CHAPTER1_PXM, 0x00 }, // SONG_CHAPTER1_LEVEL3, { MUSIC_CHAPTER1_VH, MUSIC_CHAPTER1_VB, MUSIC_CHAPTER1_PXM, 0x2c }, // SONG_CHAPTER1_LEVEL4, { MUSIC_CHAPTER1_VH, MUSIC_CHAPTER1_VB, MUSIC_CHAPTER1_PXM, 0x40 }, // SONG_CHAPTER1_BOSS, { MUSIC_CHAPTER2_VH, MUSIC_CHAPTER2_VB, MUSIC_CHAPTER2_PXM, 0x00 }, // SONG_CHAPTER2_LEVEL1, { MUSIC_CHAPTER2_VH, MUSIC_CHAPTER2_VB, MUSIC_CHAPTER2_PXM, 0x16 }, // SONG_CHAPTER2_LEVEL2, { MUSIC_CHAPTER2_VH, MUSIC_CHAPTER2_VB, MUSIC_CHAPTER2_PXM, 0x00 }, // SONG_CHAPTER2_LEVEL3, { MUSIC_CHAPTER2_VH, MUSIC_CHAPTER2_VB, MUSIC_CHAPTER2_PXM, 0x2e }, // SONG_CHAPTER2_LEVEL4, { MUSIC_CHAPTER2_VH, MUSIC_CHAPTER2_VB, MUSIC_CHAPTER2_PXM, 0x3e }, // SONG_CHAPTER2_BOSS, { MUSIC_CHAPTER3_VH, MUSIC_CHAPTER3_VB, MUSIC_CHAPTER3_PXM, 0x18 }, // SONG_CHAPTER3_LEVEL1, { MUSIC_CHAPTER3_VH, MUSIC_CHAPTER3_VB, MUSIC_CHAPTER3_PXM, 0x00 }, // SONG_CHAPTER3_LEVEL2, { MUSIC_CHAPTER3_VH, MUSIC_CHAPTER3_VB, MUSIC_CHAPTER3_PXM, 0x00 }, // SONG_CHAPTER3_LEVEL3, { MUSIC_CHAPTER3_VH, MUSIC_CHAPTER3_VB, MUSIC_CHAPTER3_PXM, 0x0b }, // SONG_CHAPTER3_LEVEL4, { MUSIC_CHAPTER3_VH, MUSIC_CHAPTER3_VB, MUSIC_CHAPTER3_PXM, 0x21 }, // SONG_CHAPTER3_BOSS_ASLEEP, { MUSIC_CHAPTER3_VH, MUSIC_CHAPTER3_VB, MUSIC_CHAPTER3_PXM, 0x22 }, // SONG_CHAPTER3_BOSS_AWAKE, { MUSIC_CHAPTER4_VH, MUSIC_CHAPTER4_VB, MUSIC_CHAPTER4_PXM, 0x1b }, // SONG_CHAPTER4_LEVEL1, { MUSIC_CHAPTER4_VH, MUSIC_CHAPTER4_VB, MUSIC_CHAPTER4_PXM, 0x00 }, // SONG_CHAPTER4_LEVEL2, { MUSIC_CHAPTER4_VH, MUSIC_CHAPTER4_VB, MUSIC_CHAPTER4_PXM, 0x2c }, // SONG_CHAPTER4_LEVEL3, { MUSIC_CHAPTER4_VH, MUSIC_CHAPTER4_VB, MUSIC_CHAPTER4_PXM, 0x00 }, // SONG_CHAPTER4_LEVEL4, { MUSIC_CHAPTER4_VH, MUSIC_CHAPTER4_VB, MUSIC_CHAPTER4_PXM, 0x3c }, // SONG_CHAPTER4_BOSS, { MUSIC_CHAPTER5_VH, MUSIC_CHAPTER5_VB, MUSIC_CHAPTER5_PXM, 0x00 }, // SONG_CHAPTER5_LEVEL1, { MUSIC_CHAPTER5_VH, MUSIC_CHAPTER5_VB, MUSIC_CHAPTER5_PXM, 0x14 }, // SONG_CHAPTER5_LEVEL2, { MUSIC_CHAPTER5_VH, MUSIC_CHAPTER5_VB, MUSIC_CHAPTER5_PXM, 0x00 }, // SONG_CHAPTER5_LEVEL3, { MUSIC_CHAPTER5_VH, MUSIC_CHAPTER5_VB, MUSIC_CHAPTER5_PXM, 0x2a }, // SONG_CHAPTER5_LEVEL4, { MUSIC_CHAPTER5_VH, MUSIC_CHAPTER5_VB, MUSIC_CHAPTER5_PXM, 0x3e }, // SONG_CHAPTER5_BOSS, { MUSIC_CHAPTER6_VH, MUSIC_CHAPTER6_VB, MUSIC_CHAPTER6_PXM, 0x00 }, // SONG_CHAPTER6_ROLLERCOASTER { MUSIC_CHAPTER6_VH, MUSIC_CHAPTER6_VB, MUSIC_CHAPTER6_PXM, 0x00 }, // SONG_CHAPTER6_SNAILRACE { MUSIC_CHAPTER6_VH, MUSIC_CHAPTER6_VB, MUSIC_CHAPTER6_PXM, 0x0c }, // SONG_CHAPTER6_BIGWHEEL { MUSIC_CHAPTER6_VH, MUSIC_CHAPTER6_VB, MUSIC_CHAPTER6_PXM, 0x0c }, // SONG_CHAPTER6_TUNNELOFLOVE { MUSIC_CHAPTER6_VH, MUSIC_CHAPTER6_VB, MUSIC_CHAPTER6_PXM, 0x15 }, // SONG_CHAPTER6_GHOSTTRAIN { MUSIC_CHAPTER6_VH, MUSIC_CHAPTER6_VB, MUSIC_CHAPTER6_PXM, 0x2b }, // SONG_CHAPTER6_BIGTOP }; // SFX banks static XMSFXFILEDATA s_xmSfxData[CSoundMediator::NUM_SFXBANKIDS]= { // m_vh m_vb m_pxm { SFX_INGAME_VH, SFX_INGAME_VB, SFX_INGAME_PXM }, // SFX_INGAME }; // Individual SFX details static SFXDETAILS s_sfxDetails[CSoundMediator::NUM_SFXIDS]= { // m_channelMask m_pattern m_looping { 1, 0, 0 }, // SFX_SPONGEBOB_WALK_1 { 1, 1, 0 }, // SFX_SPONGEBOB_WALK_2 { 1, 2, 0 }, // SFX_SPONGEBOB_SQUEAKY_SHOES_1 { 1, 3, 0 }, // SFX_SPONGEBOB_SQUEAKY_SHOES_2 { 1, 4, 0 }, // SFX_SPONGEBOB_JUMP { 1, 5, 0 }, // SFX_SPONGEBOB_BUTTBOUNCE { 1, 6, 0 }, // SFX_SPONGEBOB_BLINK { 3, 7, 0 }, // SFX_BUBBLE_WAND* { 1, 8, 0 }, // SFX_SPONGEBOB_DEFEATED_JINGLE { 1, 9, 0 }, // SFX_BALLOON_INFLATE { 1, 21, 0 }, // SFX_BALLOON_POP { 1, 10, 0 }, // SFX_GLASSES_ON { 1, 11, 0 }, // SFX_JELLY_LAUNCHER { 1, 12, 0 }, // SFX_SPONGEBOB_KARATE_1 { 1, 13, 0 }, // SFX_SPONGEBOB_KARATE_2 { 1, 14, 0 }, // SFX_SPONGEBOB_ATTACK_IMPACT_WITH_ENEMY_1 { 1, 15, 0 }, // SFX_SPONGEBOB_ATTACK_IMPACT_WITH_ENEMY_2 { 1, 16, 0 }, // SFX_SPONGEBOB_LAND_AFTER_FALL { 1, 17, 0 }, // SFX_SPONGEBOB_NET { 1, 18, 0 }, // SFX_ANEMONE_ATTACK_LEVEL1 { 1, 19, 0 }, // SFX_ANEMONE_ATTACK_LEVEL2 { 1, 20, 0 }, // SFX_ANEMONE_ATTACK_LEVEL3 { 1, 21, 0 }, // SFX_ANEMONE_DEFEATED_LEVEL1 { 1, 21, 0 }, // SFX_ANEMONE_DEFEATED_LEVEL2 { 1, 22, 0 }, // SFX_ANEMONE_DEFEATED_LEVEL3 { 1, 23, 0 }, // SFX_ANEMONE_MOVE { 1, 24, 0 }, // SFX_ANGLER_FISH_MOVE { 1, 25, 0 }, // SFX_BALL_BLOB_MOVE { 1, 26, 0 }, // SFX_BALL_BLOB_ATTACK { 1, 27, 0 }, // SFX_BEANIE_MOVE { 3, 28, 0 }, // SFX_BOOGER_MOVE* { 1, 29, 0 }, // SFX_CLAM_ATTACK { 1, 30, 0 }, // SFX_CLAM_DEFEATED { 1, 31, 0 }, // SFX_CLAM_MOVE { 3, 32, 0 }, // SFX_EYEBALL_SENTRY_ATTACK* { 3, 33, 0 }, // SFX_EYEBALL_SENTRY_MOVE* { 1, 34, 0 }, // SFX_FISH_HOOK_MOVE { 3, 35, 0 }, // SFX_FLAMING_SKULL_MOVE* { 1, 36, 0 }, // SFX_FLAMING_SKULL_DEFEATED { 3, 37, 0 }, // SFX_FLAMING_SKULL_ATTACK* { 1, 38, 0 }, // SFX_GARY_DE_SNAIL { 3, 39, 0 }, // SFX_GHOST* { 1, 40, 0 }, // SFX_FISH_FOLK_MOVE_1 { 1, 41, 0 }, // SFX_FISH_FOLK_MOVE_2 { 1, 42, 0 }, // SFX_CANNING_MACHINE { 3, 43, 0 }, // SFX_LAVA* { 1, 44, 0 }, // SFX_ROLLING_ROCK { 1, 45, 0 }, // SFX_SAW { 3, 46, 0 }, // SFX_WHIRLPOOL_DRAIN* { 3, 47, 0 }, // SFX_WHIRLPOOL_WHIRL* { 1, 48, 0 }, // SFX_HERMIT_CRAB_ATTACK { 1, 49, 0 }, // SFX_HERMIT_CRAB_MOVE { 3, 50, 0 }, // SFX_HAZARD__ACID_DROP* { 3, 51, 0 }, // SFX_HAZARD__ACORN_LAND* { 3, 52, 0 }, // SFX_HAZARD__BLADE_ATTACK* { 3, 53, 0 }, // SFX_HAZARD__BLADE_MOVE* { 1, 54, 0 }, // SFX_HAZARD__ROPE_MOVE { 3, 55, 0 }, // SFX_HAZARD__ROPE_SNAP* { 1, 56, 0 }, // SFX_ANY_OBJECT_FALLING { 3, 57, 0 }, // SFX_HAZARD__FIREBALL_LAND* { 3, 58, 0 }, // SFX_HAZARD__FIREBALL_LAUNCH* { 3, 59, 0 }, // SFX_HAZARD__FALLING_ROCK_FALL* { 3, 60, 0 }, // SFX_HAZARD__FALLING_ROCK_LAND* { 1, 61, 0 }, // SFX_HAZARD__MINE { 1, 62, 0 }, // SFX_SPONGEBOB_SPLASH_INTO_WATER { 1, 63, 0 }, // SFX_SPONGEBOB_DIVING_HELMET { 1, 64, 0 }, // SFX_HAZARD__STALACTITE_LAND { 1, 65, 0 }, // SFX_HAZARD__STALACTITE_RATTLE { 3, 66, 0 }, // SFX_HAZARD__STEAM* { 3, 67, 0 }, // SFX_HAZARD__SWAMP_GAS* { 3, 68, 0 }, // SFX_ITEM__CORAL_BLOWER* { 1, 69, 0 }, // SFX_ITEM__DISGUISE { 1, 70, 0 }, // SFX_ITEM__JAMJAR_AMMO { 3, 71, 0 }, // SFX_ITEM__LEVEL_ITEM* { 1, 72, 0 }, // SFX_ITEM__ANY_OTHER_ITEM { 3, 73, 0 }, // SFX_ITEM__POWER_UP_ITEM* { 3, 74, 0 }, // SFX_ITEM__SKILL_ITEM* { 1, 75, 0 }, // SFX_JELLYFISH_MOVE { 1, 76, 0 }, // SFX_JELLYFISH_DEFEATED { 3, 77, 0 }, // SFX_JELLYFISH_ATTACK* { 1, 78, 0 }, // SFX_NAUTILUS_ATTACK { 1, 79, 0 }, // SFX_NAUTILUS_MOVE { 1, 80, 0 }, // SFX_NINJASTARFISH_ATTACK { 1, 81, 0 }, // SFX_PRICKLY_BUG_ATTACK { 1, 82, 0 }, // SFX_PRICKLY_BUG_DEFEATED { 1, 83, 0 }, // SFX_PRICKLY_BUG_MOVE { 3, 84, 0 }, // SFX_PUFFAFISH_MOVE* { 3, 85, 0 }, // SFX_SKULL_ATTACK* { 1, 86, 0 }, // SFX_SPIDERCRAB_ATTACK { 1, 87, 0 }, // SFX_SPIDERCRAB_MOVE { 1, 88, 0 }, // SFX_SQUIDDART_ATTACK { 3, 89, 0 }, // SFX_SQUIDDART_DEFEATED* { 1, 90, 0 }, // SFX_SQUIDDART_MOVE { 1, 91, 0 }, // SFX_SEASNAKE_ATTACK { 1, 92, 0 }, // SFX_SEASNAKE_MOVE { 1, 93, 0 }, // SFX_TELEPHONE_BOX { 3, 94, 0 }, // SFX_WORLD_OBJECT__BARRIER* { 3, 95, 0 }, // SFX_WORLD_OBJECT__BIG_WHEEL* { 3, 96, 0 }, // SFX_WORLD_OBJECT__GEYSER* { 3, 97, 0 }, // SFX_WORLD_OBJECT__GHOST_TRAIN_DOORS* { 1, 98, 0 }, // SFX_WORLD_OBJECT__DISAPPEARING_PLATFORM { 1, 99, 0 }, // SFX_WORLD_OBJECT__RESPAWNING_PLATFORM { 1, 100, 0 }, // SFX_WORLD_OBJECT__ROTATING_PLATFORM { 1, 101, 0 }, // SFX_WORLD_OBJECT__SEESAW { 1, 102, 0 }, // SFX_WORLD_OBJECT__TRAIN_TRACKS { 1, 103, 0 }, // SFX_WORLD_OBJECT__CURRENTS { 1, 104, 0 }, // SFX_ZOMBIE_FISH_FOLK { 1, 105, 0 }, // SFX_FRONT_END__MOVE_CURSOR { 1, 106, 0 }, // SFX_FRONT_END__SELECT { 1, 107, 0 }, // SFX_FRONT_END__ERROR { 1, 108, 0 }, // SFX_FRONT_END__OK { 3, 109, 0 }, // SFX_KAPOW_V1* { 3, 110, 0 }, // SFX_KAPOW_V2* { 3, 111, 0 }, // SFX_KAPOW_V3* { 1, 112, 0 }, // SFX_SPLAT { 3, 113, 0 }, // SFX_SECRET_AREA* { 1, 114, 0 }, // SFX_LAND_ON_JELLYFISH { 3, 115, 0 }, // SFX_SPLASH* { 3, 116, 0 }, // SFX_BARREL_V1* { 3, 117, 0 }, // SFX_BARREL_V2* { 1, 118, 0 }, // SFX_ACORN_FALL { 1, 119, 0 }, // SFX_ACORN_BOUNCE { 1, 120, 0 }, // SFX_CLAM_SNAP { 1, 121, 0 }, // SFX_CAR_START { 1, 122, 0 }, // CAR_SLOW_DOWN { 1, 123, 0 }, // SFX_SPONGEBOB_OUCH { 3, 124, 0 }, // SFX_DOGFISH_LASER* { 1, 125, 0 }, // SFX_DOGFISH_GROWL { 3, 126, 0 }, // SFX_DOGFISH_STOMP* { 1, 127, 0 }, // SFX_DOGFISH_THUMP { 3, 128, 0 }, // SFX_FLAME* { 3, 129, 0 }, // SFX_BOSS_JELLYFISH_MOVE* { 1, 130, 0 }, // SFX_BOSS_JELLYFISH_PULSATE { 3, 131, 0 }, // SFX_BOSS_JELLYFISH_ELECTRIC_SHOCK* { 1, 132, 0 }, // SFX_BOSS_JELLYFISH___SB_GETS_ELECTROCUTED { 1, 133, 0 }, // SFX_NEW_JELLY_LAUNCHER { 1, 134, 0 }, // SFX_NEW_LIFT { 1, 135, 0 }, // SFX_NEW_RUBBER_RING_BOUNCE { 1, 136, 0 }, // SFX_NEW_HIT_SWITCH { 1, 137, 0 }, // SFX_NEW_BOUNCE_TYRES { 1, 138, 0 }, // SFX_SHARK___CHOMP { 1, 139, 0 }, // SFX_SHARK___SWIM { 1, 140, 0 }, // SFX_SHARK___CREAKING_ATTACK_SOUND { 1, 141, 0 }, // SFX_SIREN { 1, 142, 0 }, // SFX_WORM___CHOMP { 1, 143, 0 }, // SFX_WORM___HISS { 1, 144, 0 }, // SFX_WORM___SWIM { 3, 145, 0 }, // SFX_FLYING_DUTCHMAN* { 1, 146, 0 }, // SFX_BOUNCY_PLATFORM { 1, 147, 0 }, // SFX_ELEVATOR_LOOP { 1, 148, 0 }, // SFX_ELEVATOR_STOP { 1, 149, 0 }, // SFX_PULLEY { 1, 150, 0 }, // SFX_ELECTRIC_FAN { 1, 151, 0 }, // SFX_ROLLING_BARREL { 1, 152, 0 }, // SFX_RETRACTING_PLATFORM { 1, 153, 0 }, // SFX_SINKING_CRATE { 3, 154, 0 }, // SFX_FIRE_CRACKLING* { 3, 155, 0 }, // SFX_OIL_GEYSER* { 3, 156, 0 }, // SFX_FLYIN_DUTCHMAN_WOOSH* { 1, 157, 0 }, // SFX_JELLYFISH_BOUNCE { 1, 158, 0 }, // SFX_TORNADO { 1, 159, 0 }, // SFX_BEEP1 { 1, 160, 0 }, // SFX_BEEP2 { 1, 161, 0 }, // SFX_BEEP3 { 1, 162, 0 }, // SFX_BEEP4 { 1, 163, 0 }, // SFX_BEEP5 { 1, 164, 0 }, // SFX_BEEP6 { 1, 165, 0 }, // SFX_BEEP7 { 1, 166, 0 }, // SFX_BEEP8 { 1, 167, 0 }, // SFX_BEEP9 { 1, 168, 0 }, // SFX_BEEP10 { 1, 169, 0 }, // SFX_BEEP11 { 1, 170, 0 }, // SFX_BEEP12 { 3, 171, 0 }, // SFX_TELEPORT1* { 3, 172, 0 }, // SFX_TELEPORT2* }; // Reverb details static ReverbDetails s_reverbDetails[CSoundMediator::NUM_REVERBTYPES]= { // m_type m_delay m_depth m_feedback { SPU_REV_MODE_OFF, 0, 0, 0 }, // REV_NONE { SPU_REV_MODE_ECHO, 75, 0x3000, 100 }, // REV_ECHOTEST }; /*---------------------------------------------------------------------- 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;ishutdown(); delete s_xmplaySound; s_spuSound->shutdown(); delete s_spuSound; SOUND_DBGMSG("Sound mediator shutdown"); s_initialised=false; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::think(int _frames) { int i; int diff,speed; int *current,*target,*dirty; ASSERT(s_initialised); // Fade to target volume ASSERT(_frames!=0); if(_frames==0)_frames=1; speed=_frames*VOLUME_CHANGE_SPEED; 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++; } // Update of anything that needs it CXAStream::ControlXA(); s_xmplaySound->think(); // Push through any changes in volume if(s_volumeDirty[VOL_FADE]) { s_volumeDirty[VOL_SONG]=true; s_volumeDirty[VOL_SFX]=true; s_volumeDirty[VOL_SPEECH]=true; s_volumeDirty[VOL_FADE]=false; } if (isSpeechPlaying()) { s_volumeDirty[VOL_SONG]=true; s_currentVolume[VOL_FADE]=64; } if(s_volumeDirty[VOL_SONG]) { s_xmplaySound->setMasterSongVolume((s_currentVolume[VOL_SONG]*s_currentVolume[VOL_FADE])>>8); s_volumeDirty[VOL_SONG]=false; } if(s_volumeDirty[VOL_SFX]) { s_xmplaySound->setMasterSfxVolume((s_currentVolume[VOL_SFX]*s_currentVolume[VOL_FADE])>>8); s_volumeDirty[VOL_SFX]=false; } if(s_volumeDirty[VOL_SPEECH]) { // int vol=((s_currentVolume[VOL_SPEECH]*s_currentVolume[VOL_FADE])/*>>8*/)/*<<7*/; int vol=s_currentVolume[VOL_SPEECH]<<8;//*s_currentVolume[VOL_FADE])/*>>8*/)/*<<7*/; if (vol<=CXAStream::MIN_VOLUME) vol=CXAStream::MIN_VOLUME; if (vol>=CXAStream::MAX_VOLUME) vol=CXAStream::MAX_VOLUME; CXAStream::setMasterVolume(vol,vol); s_volumeDirty[VOL_SPEECH]=false; } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::setReverbType(REVERBTYPE _type) { ReverbDetails *rev; rev=&s_reverbDetails[_type]; s_spuSound->setReverbDetails(rev); if(rev->m_type==SPU_REV_MODE_OFF) { s_spuSound->setReverbActive(false); } else { s_spuSound->setReverbActive(true); } } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::setSong(SONGID _songId) { XMSONGDATA *song; song=&s_xmSongData[_songId]; if(s_songSampleId!=NO_SAMPLE&&s_songVh!=song->m_vh) { s_xmplaySound->dumpSampleData(s_songSampleId); s_songSampleId=NO_SAMPLE; } if(s_songSampleId==NO_SAMPLE) { s_songSampleId=s_xmplaySound->loadSampleData(song->m_vh,song->m_vb); } s_songVh=song->m_vh; if(s_songModId!=NO_SONG&&s_songPxm!=song->m_pxm) { s_xmplaySound->dumpModData(s_songModId); s_songModId=NO_SONG; } if(s_songModId==NO_SONG) { s_songModId=s_xmplaySound->loadModData(song->m_pxm); } s_songPxm=song->m_pxm; s_songStartPattern=song->m_startPattern; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::playSong() { ASSERT(s_songSampleId!=NO_SAMPLE); ASSERT(s_songModId!=NO_SONG); ASSERT(s_songPlayingId==NOT_PLAYING); s_songPlayingId=s_xmplaySound->playSong(s_songSampleId,s_songModId,s_songStartPattern); // s_volumeDirty[SONG]=true; // Force a volume update } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::stopSong() { ASSERT(s_songSampleId!=NO_SAMPLE); ASSERT(s_songModId!=NO_SONG); if(s_songPlayingId!=NOT_PLAYING) { s_xmplaySound->stopPlayingId(s_songPlayingId); s_xmplaySound->unlockPlayingId(s_songPlayingId); } s_songPlayingId=NOT_PLAYING; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::dumpSong() { ASSERT(s_songSampleId!=NO_SAMPLE); ASSERT(s_songModId!=NO_SONG); stopSong(); s_xmplaySound->dumpSampleData(s_songSampleId); s_songSampleId=NO_SAMPLE; s_xmplaySound->dumpModData(s_songModId); s_songModId=NO_SONG; s_songVh=(FileEquate)-1; s_songPxm=(FileEquate)-1; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::setSfxBank(SFXBANKID _bankId) { XMSFXFILEDATA *sfx; ASSERT(s_sfxSampleId==NO_SAMPLE); ASSERT(s_sfxModId==NO_SONG); sfx=&s_xmSfxData[_bankId]; s_sfxModId=s_xmplaySound->loadModData(sfx->m_pxm); s_sfxSampleId=s_xmplaySound->loadSampleData(sfx->m_vh,sfx->m_vb); } /*---------------------------------------------------------------------- Function: Purpose: 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: ---------------------------------------------------------------------- */ xmPlayingId CSoundMediator::playSfx(SFXID _sfxId,int _lock=false,int _dontPlayIfSFXAlreadyAudible=false) { if(!s_canPlaySfx) { return NOT_PLAYING; } int sfxChannelMask; xmPlayingId playId; SFXDETAILS *sfx; ASSERT(s_sfxSampleId!=NO_SAMPLE); ASSERT(s_sfxModId!=NO_SONG); // Play! sfx=&s_sfxDetails[_sfxId]; if(_dontPlayIfSFXAlreadyAudible&&s_xmplaySound->isSfxPatternPlaying(sfx->m_pattern)) { return NOT_PLAYING; } 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(!_lock&&playId!=NOT_PLAYING) { s_xmplaySound->unlockPlayingId(playId); // We really don't care about one-shot sfx.. playId=NOT_PLAYING; } } // s_volumeDirty[SFX]=true; // Force a volume update 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(volumevx/2)+CXMPlaySound::PAN_CENTRE; if(panCXMPlaySound::PAN_RIGHT)pan=CXMPlaySound::PAN_RIGHT; s_xmplaySound->setVolume(_playingId,volume); s_xmplaySound->setPanning(_playingId,pan); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::stopAndUnlockSfx(xmPlayingId _playingId) { s_xmplaySound->stopPlayingId(_playingId); s_xmplaySound->unlockPlayingId(_playingId); } /*---------------------------------------------------------------------- Function: Purpose: NB: Will invalidate any locked sfx! Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::stopAllSfx() { s_xmplaySound->stopAndUnlockAllSfx(); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ int CSoundMediator::isSfxStillPlaying(xmPlayingId _playingId) { return s_xmplaySound->isStillPlaying(_playingId); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::playSpeech(SpeechEquate _speech) { stopSpeech(); CXAStream::PlaySpeech(_speech,1); // s_volumeDirty[SPEECH]=true; // Force a volume update } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::stopSpeech() { if(CXAStream::IsPlaying()) CXAStream::Stop(); } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ int CSoundMediator::isSpeechPlaying() { return CXAStream::IsPlaying(); } /*---------------------------------------------------------------------- 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]; } /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ void CSoundMediator::stopAllSound() { s_xmplaySound->stopAndUnlockAllSound(); CXAStream::Stop(); s_songPlayingId=NOT_PLAYING; } /*=========================================================================== end */