/* Patrick 5/6/97 ------------------------------------------------------------- AvP sound management source ----------------------------------------------------------------------------*/ #define DB_LEVEL 1 #include "3dc.h" #include "module.h" #include "inline.h" #include "stratdef.h" #include "gamedef.h" #include "psndplat.h" #define UseLocalAssert Yes #include "ourasert.h" #include "db.h" #include "showcmds.h" #include "avp_userprofile.h" /* Patrick 5/6/97 ------------------------------------------------------------- Internal globals ----------------------------------------------------------------------------*/ int SoundSwitchedOn = 0; static int SoundInitialised = 0; static int GlobalVolume = VOLUME_DEFAULT; extern int DebuggingCommandsActive; int EffectsSoundVolume=VOLUME_DEFAULT; static int MasterVolumeFadeLevel; static enum FADE_STATUS_ID {FADE_STATUS_READY, FADE_STATUS_UP, FADE_STATUS_DOWN, FADE_STATUS_DOWN_FAST} MasterVolumeFadeStatus = FADE_STATUS_READY; static unsigned int Sound_MaxActive_HW = 0; static void HandleFadingLevel(void); /* Patrick 5/6/97 ------------------------------------------------------------- Internal functions ----------------------------------------------------------------------------*/ static int FindFreeActiveSound(unsigned int min, unsigned int max); static int FindLowerPriorityActiveSound(ACTIVESOUNDPRIORITY testPriority, unsigned int min, unsigned int max); /* Patrick 5/6/97 ------------------------------------------------------------- External refernces ----------------------------------------------------------------------------*/ extern int NormalFrameTime; extern int GlobalFrameCounter; /* Patrick 5/6/97 ------------------------------------------------------------- Sound system functions ----------------------------------------------------------------------------*/ void SoundSys_Start(void) { int i; /* if we have already switched on, so do nothing */ if(SoundSwitchedOn) return; /* we are not switched on, but we are initialised, so do nothing */ if(SoundInitialised) return; /* initialise game sounds and active instances*/ for(i=0;i SOUND_MAXACTIVE) { Sound_MaxActive_HW = SOUND_MAXACTIVE; } SoundSys_SwitchOn(); /* cancel any fades */ /* set global volume */ GlobalVolume = VOLUME_DEFAULT; PlatChangeGlobalVolume(VOLUME_DEFAULT); } void SoundSys_End(void) { /* end only if we are initialised, regardless of whether we are switched on */ if(!SoundInitialised) return; /* stop and remove all sounds */ SoundSys_RemoveAll(); /* switch off, and de-initillise */ PlatEndSoundSys(); SoundSys_SwitchOff(); SoundInitialised = 0; /* forces call to Soundsys_Start to re-start sound system */ } void SoundSys_Management(void) { int i; int numActive = 0; int num3dUpdates = 0; if(!SoundSwitchedOn) return; /* go through all the active sounds */ for(i=0;i 0) { if(ActiveSounds[i].soundIndex != SID_NOSOUND) { PrintDebuggingText("%s\n",GameSounds[ActiveSounds[i].soundIndex].wavName); } } } if(WARPSPEED_CHEATMODE || JOHNWOO_CHEATMODE || DebuggingCommandsActive) UpdateSoundFrequencies(); } extern void SoundSys_ResetFadeLevel(void) { MasterVolumeFadeLevel = ONE_FIXED; MasterVolumeFadeStatus = FADE_STATUS_READY; } extern void SoundSys_FadeIn(void) { /* always fade in from silence ? */ MasterVolumeFadeLevel = ONE_FIXED/2; MasterVolumeFadeStatus = FADE_STATUS_UP; } extern void SoundSys_FadeOut(void) { MasterVolumeFadeStatus = FADE_STATUS_DOWN; } extern void SoundSys_FadeOutFast(void) { MasterVolumeFadeStatus = FADE_STATUS_DOWN_FAST; } static void HandleFadingLevel(void) { switch (MasterVolumeFadeStatus) { default: case FADE_STATUS_READY: break; case FADE_STATUS_UP: { MasterVolumeFadeLevel+=NormalFrameTime/2; if (MasterVolumeFadeLevel>ONE_FIXED) { MasterVolumeFadeLevel = ONE_FIXED; MasterVolumeFadeStatus = FADE_STATUS_READY; } break; } case FADE_STATUS_DOWN: { MasterVolumeFadeLevel-=NormalFrameTime/8; if (MasterVolumeFadeLevel<0) { MasterVolumeFadeLevel = 0; MasterVolumeFadeStatus = FADE_STATUS_READY; } break; } case FADE_STATUS_DOWN_FAST: { MasterVolumeFadeLevel-=NormalFrameTime; if (MasterVolumeFadeLevel<0) { MasterVolumeFadeLevel = 0; MasterVolumeFadeStatus = FADE_STATUS_READY; } break; } } } void SoundSys_PauseOn(void) { int i; /* if we're not switched on, should be nothing playing */ if(!SoundSwitchedOn) return; for(i=0;iVOLUME_MAX) newVolume = VOLUME_MAX; if(newVolume=SID_MAXIMUM)) return; if(!(GameSounds[soundNumber].loaded)) return; if(!(GameSounds[soundNumber].activeInstancesVOLUME_MAX) volume=VOLUME_MAX; if(volumePITCH_MAX) pitch=PITCH_MAX; if(pitch=SOUND_MAXACTIVE) return; /* Check there's a sound in this slot */ if(ActiveSounds[activeSoundNumber].soundIndex == SID_NOSOUND) return; /* update game sound instances, and external reference */ soundNo = ActiveSounds[activeSoundNumber].soundIndex; GameSounds[soundNo].activeInstances--; db_assert1((GameSounds[soundNo].activeInstances>=0)&& (GameSounds[soundNo].activeInstances=SOUND_MAXACTIVE) return; /* Check there's a sound in this slot */ if(ActiveSounds[activeSoundNumber].soundIndex == SID_NOSOUND) return; /* validate other argument */ newVolume = volume; if(newVolume>VOLUME_MAX) newVolume = VOLUME_MAX; if(newVolume=SOUND_MAXACTIVE) return; /* Check there's a sound in this slot */ if(ActiveSounds[activeSoundNumber].soundIndex == SID_NOSOUND) return; /* validate other argument */ newPitch = pitch; if(newPitch>PITCH_MAX) newPitch = PITCH_MAX; if(newPitch=SOUND_MAXACTIVE) return; /* Check there's a sound in this slot */ if(ActiveSounds[activeSoundNumber].soundIndex == SID_NOSOUND) return; ActiveSounds[activeSoundNumber].threedeedata.position = *posn; } void Sound_UpdateNew3d(int activeSoundNumber, SOUND3DDATA * s3d) { if(!SoundSwitchedOn) return; /* validate argument */ if(activeSoundNumber<0) return; if(activeSoundNumber>=SOUND_MAXACTIVE) return; /* Check there's a sound in this slot */ if(ActiveSounds[activeSoundNumber].soundIndex == SID_NOSOUND) return; ActiveSounds[activeSoundNumber].threedeedata = *s3d; } unsigned int SoundNumActiveVoices() { int i = Sound_MaxActive_HW; int num_active = 0; while(i-- > 0) { if(ActiveSounds[i].soundIndex != SID_NOSOUND) { num_active++; } } return num_active; } /* Patrick 5/6/97 ------------------------------------------------------------- Internal support functions ----------------------------------------------------------------------------*/ static int FindFreeActiveSound(unsigned int min, unsigned int max) { int i; for(i = min; (i < max); i++) { if(ActiveSounds[i].soundIndex == SID_NOSOUND) return i; } return SOUND_NOACTIVEINDEX; } static int FindLowerPriorityActiveSound(ACTIVESOUNDPRIORITY testPriority, unsigned int min, unsigned int max) { int i; for(i = min; (i < max); i++) { if((ActiveSounds[i].soundIndex != SID_NOSOUND)&& (ActiveSounds[i].priority < testPriority)) return i; } return SOUND_NOACTIVEINDEX; } static SOUNDINDEX GetSoundIndexFromNameAndIndex(const char* name,SOUNDINDEX index); #include "savegame.h" typedef struct sound_save_block { SAVE_BLOCK_HEADER header; int fileNameLength; SOUNDINDEX soundIndex; ACTIVESOUNDPRIORITY priority; int volume; int pitch; unsigned int loop :1; unsigned int threedee :1; unsigned int paused :1; unsigned int marine_ignore :1; unsigned int reverb_off :1; unsigned int externalRef :1; SOUND3DDATA threedeedata; int position; }SOUND_SAVE_BLOCK; //defines for load/save macros #define SAVELOAD_BLOCK block #define SAVELOAD_BEHAV sound void Load_SoundState(int* soundHandle) { SOUND_SAVE_BLOCK* block; const char* name; SOUNDINDEX soundIndex; if(!soundHandle) return; block = (SOUND_SAVE_BLOCK*)GetNextBlockIfOfType(SaveBlock_SoundState); if(!block) return ; name = (const char*)(block+1); //stop the current sound if(*soundHandle == SOUND_NOACTIVEINDEX) { Sound_Stop(*soundHandle); } //check the size if(block->header.size != sizeof(*block) + block->fileNameLength) return; soundIndex = GetSoundIndexFromNameAndIndex(name,block->soundIndex); if(soundIndex==SID_NOSOUND) return; { char playOptions[20]="evpP"; if(block->loop) strcat(playOptions,"l"); if(block->marine_ignore) strcat(playOptions,"m"); if(block->reverb_off) strcat(playOptions,"r"); if(block->priority == ASP_Maximum) strcat(playOptions,"h"); if(block->threedee) { strcat(playOptions,"n"); Sound_Play(soundIndex,playOptions,soundHandle,block->volume,block->pitch,block->position,&block->threedeedata); } else { Sound_Play(soundIndex,playOptions,soundHandle,block->volume,block->pitch,block->position); } } } void Save_SoundState(int* soundHandle) { if(!soundHandle) return; if(*soundHandle == SOUND_NOACTIVEINDEX) { SAVE_BLOCK_HEADER* header; GET_SAVE_BLOCK_POINTER(header); //fill in the header header->size = sizeof(*header); header->type = SaveBlock_SoundState; } else { ACTIVESOUNDSAMPLE* sound = &ActiveSounds[*soundHandle]; SOUND_SAVE_BLOCK* block; const char* name = GameSounds[sound->soundIndex].wavName; int name_length = strlen(name) + 1; block = GetPointerForSaveBlock(sizeof(*block)+name_length); //fill in the header block->header.size = sizeof(*block) + name_length; block->header.type = SaveBlock_SoundState; COPYELEMENT_SAVE(soundIndex) COPYELEMENT_SAVE(priority) COPYELEMENT_SAVE(volume) COPYELEMENT_SAVE(pitch) COPYELEMENT_SAVE(loop) COPYELEMENT_SAVE(threedee) COPYELEMENT_SAVE(paused) COPYELEMENT_SAVE(marine_ignore) COPYELEMENT_SAVE(reverb_off) COPYELEMENT_SAVE(threedeedata) block->externalRef = 1; block->position = 0; block->fileNameLength = name_length; //the volume in the active sound list is scaled differently from the volume used //by Sound_Play block->volume<<=7; block->volume/=VOLUME_PLAT2DSCALE; if(sound->dsBufferP) IDirectSoundBuffer_GetCurrentPosition(sound->dsBufferP,(LPDWORD)&block->position,NULL); else block->position = 0; strcpy((char*)(block+1),name); } } void Load_SoundState_NoRef(SAVE_BLOCK_HEADER* header) { SOUND_SAVE_BLOCK* block = (SOUND_SAVE_BLOCK*) header; const char* name = (const char*)(block+1); SOUNDINDEX soundIndex; //check the size if(block->header.size != sizeof(*block) + block->fileNameLength) return; //only load if the sound doesn't require an external reference if(block->externalRef) return; soundIndex = GetSoundIndexFromNameAndIndex(name,block->soundIndex); if(soundIndex==SID_NOSOUND) return; { char playOptions[20]="vpP"; if(block->marine_ignore) strcat(playOptions,"m"); if(block->reverb_off) strcat(playOptions,"r"); if(block->priority == ASP_Maximum) strcat(playOptions,"h"); if(block->threedee) { strcat(playOptions,"n"); Sound_Play(soundIndex,playOptions,block->volume,block->pitch,block->position,&block->threedeedata); } else { Sound_Play(soundIndex,playOptions,block->volume,block->pitch,block->position); } } } void Save_SoundsWithNoReference() { int i; for(i=0;isoundIndex].wavName; int name_length = strlen(name) + 1; block = GetPointerForSaveBlock(sizeof(*block)+name_length); //fill in the header block->header.size = sizeof(*block) + name_length; block->header.type = SaveBlock_SoundState; COPYELEMENT_SAVE(soundIndex) COPYELEMENT_SAVE(priority) COPYELEMENT_SAVE(volume) COPYELEMENT_SAVE(pitch) COPYELEMENT_SAVE(loop) COPYELEMENT_SAVE(threedee) COPYELEMENT_SAVE(paused) COPYELEMENT_SAVE(marine_ignore) COPYELEMENT_SAVE(reverb_off) COPYELEMENT_SAVE(threedeedata) block->externalRef = 0; block->position = 0; block->fileNameLength = name_length; //the volume in the active sound list is scaled differently from the volume used //by Sound_Play block->volume<<=7; block->volume/=VOLUME_PLAT2DSCALE; if(sound->dsBufferP) IDirectSoundBuffer_GetCurrentPosition(sound->dsBufferP,(LPDWORD)&block->position,NULL); else block->position = 0; strcpy((char*)(block+1),name); } } } } static SOUNDINDEX GetSoundIndexFromNameAndIndex(const char* name,SOUNDINDEX index) { int i; if(index>=0 && index