etqw-sdk/source/game/Sound.cpp

386 lines
8.8 KiB
C++
Raw Permalink Normal View History

2008-05-29 00:00:00 +00:00
// Copyright (C) 2007 Id Software, Inc.
//
#include "precompiled.h"
#pragma hdrstop
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "Sound.h"
/*
===============================================================================
sdSoundBroadcastData
===============================================================================
*/
/*
==============
sdSoundBroadcastData::MakeDefault
==============
*/
void sdSoundBroadcastData::MakeDefault( void ) {
isOn = true;
}
/*
==============
sdSoundBroadcastData::Write
==============
*/
void sdSoundBroadcastData::Write( idFile* file ) const {
file->WriteBool( isOn );
}
/*
==============
sdSoundBroadcastData::Read
==============
*/
void sdSoundBroadcastData::Read( idFile* file ) {
file->ReadBool( isOn );
}
/*
===============================================================================
idSound
===============================================================================
*/
idList< idSoundEmitter* > idSound::s_soundEmitters;
extern const idEventDef EV_TurnOn;
extern const idEventDef EV_TurnOff;
const idEventDefInternal EV_Speaker_Timer( "internal_timer", NULL );
CLASS_DECLARATION( idEntity, idSound )
EVENT( EV_Activate, idSound::Event_Trigger )
EVENT( EV_TurnOn, idSound::Event_On )
EVENT( EV_TurnOff, idSound::Event_Off )
EVENT( EV_Speaker_Timer, idSound::Event_Timer )
END_CLASS
/*
================
idSound::idSound
================
*/
idSound::idSound( void ) {
lastSoundVol = 0.0f;
soundVol = 0.0f;
random = 0.0f;
wait = 0.0f;
timerOn = false;
soundOn = false;
playingUntilTime = 0;
}
/*
================
idSound::OnNewMapLoad
================
*/
void idSound::OnNewMapLoad( void ) {
FreeMapSounds();
}
/*
================
idSound::OnMapClear
================
*/
void idSound::OnMapClear( void ) {
FreeMapSounds();
}
/*
================
idSound::FreeMapSounds
================
*/
void idSound::FreeMapSounds( void ) {
for ( int i = 0; i < s_soundEmitters.Num(); i++ ) {
s_soundEmitters[ i ]->Free( true );
}
s_soundEmitters.Clear();
}
/*
================
idSound::Spawn
================
*/
void idSound::Spawn( void ) {
spawnArgs.GetFloat( "random", "0", random );
spawnArgs.GetFloat( "wait", "0", wait );
if ( ( wait > 0.0f ) && ( random >= wait ) ) {
random = wait - 0.001f;
gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
}
soundVol = 0.0f;
lastSoundVol = 0.0f;
if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) {
timerOn = true;
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
} else {
timerOn = false;
soundOn = true;
}
if ( g_removeStaticEntities.GetBool() && !StartSynced() && !timerOn ) {
if ( refSound.referenceSound != NULL ) {
s_soundEmitters.Alloc() = refSound.referenceSound;
refSound.referenceSound = NULL;
}
PostEventMS( &EV_Remove, 0 );
}
}
/*
================
idSound::Event_Trigger
this will toggle the idle idSound on and off
================
*/
void idSound::Event_Trigger( idEntity *activator ) {
if ( wait > 0.0f ) {
if ( timerOn ) {
timerOn = false;
CancelEvents( &EV_Speaker_Timer );
} else {
timerOn = true;
DoSound( true );
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
} else {
if ( refSound.referenceSound && ( gameLocal.time < playingUntilTime ) ) {
DoSound( false );
} else {
DoSound( true );
}
}
}
/*
================
idSound::Event_Timer
================
*/
void idSound::Event_Timer( void ) {
DoSound( true );
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
/*
================
idSound::Think
================
*/
void idSound::Think( void ) {
}
/*
===============
idSound::UpdateChangableSpawnArgs
===============
*/
void idSound::UpdateChangeableSpawnArgs( const idDict *source ) {
idEntity::UpdateChangeableSpawnArgs( source );
if ( source ) {
FreeSoundEmitter( true );
spawnArgs.Copy( *source );
idSoundEmitter *saveRef = refSound.referenceSound;
gameEdit->ParseSpawnArgsToRefSound( spawnArgs, refSound );
refSound.referenceSound = saveRef;
idVec3 origin;
idMat3 axis;
if ( GetPhysicsToSoundTransform( origin, axis ) ) {
refSound.origin = GetPhysics()->GetOrigin() + origin * axis;
} else {
refSound.origin = GetPhysics()->GetOrigin();
}
spawnArgs.GetFloat( "random", "0", random );
spawnArgs.GetFloat( "wait", "0", wait );
if ( ( wait > 0.0f ) && ( random >= wait ) ) {
random = wait - 0.001f;
gameLocal.Warning( "speaker '%s' at (%s) has random >= wait", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
}
if ( !refSound.waitfortrigger && ( wait > 0.0f ) ) {
timerOn = true;
DoSound( false );
CancelEvents( &EV_Speaker_Timer );
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
} else if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) {
// start it if it isn't already playing, and we aren't waitForTrigger
DoSound( true );
timerOn = false;
}
}
}
/*
===============
idSound::SetSound
===============
*/
void idSound::SetSound( const char *sound, int channel ) {
const idSoundShader *shader = declHolder.declSoundShaderType.LocalFind( sound );
if ( shader != refSound.shader ) {
FreeSoundEmitter( true );
}
gameEdit->ParseSpawnArgsToRefSound( spawnArgs, refSound );
refSound.shader = shader;
// start it if it isn't already playing, and we aren't waitForTrigger
if ( !refSound.waitfortrigger && !(refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying() ) ) {
DoSound( true );
}
}
/*
================
idSound::DoSound
================
*/
void idSound::DoSound( bool play ) {
if ( play ) {
StartSoundShader( refSound.shader, SND_ANY, refSound.parms.soundShaderFlags, &playingUntilTime );
playingUntilTime += gameLocal.time;
soundOn = true;
} else {
StopSound( SND_ANY );
playingUntilTime = 0;
soundOn = false;
}
}
/*
================
idSound::Event_On
================
*/
void idSound::Event_On( void ) {
if ( wait > 0.0f ) {
timerOn = true;
PostEventSec( &EV_Speaker_Timer, wait + gameLocal.random.CRandomFloat() * random );
}
DoSound( true );
}
/*
================
idSound::Event_Off
================
*/
void idSound::Event_Off( void ) {
if ( timerOn ) {
timerOn = false;
CancelEvents( &EV_Speaker_Timer );
}
DoSound( false );
}
/*
===============
idSound::ShowEditingDialog
===============
*/
void idSound::ShowEditingDialog( void ) {
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, va( "selectSpeaker '%s'", name.c_str() ) );
}
/*
================
idSound::ApplyNetworkState
================
*/
void idSound::ApplyNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& newState ) {
if ( mode == NSM_BROADCAST ) {
NET_GET_NEW( sdSoundBroadcastData );
DoSound( newData.isOn );
}
idEntity::ApplyNetworkState( mode, newState );
}
/*
==============
idSound::ReadNetworkState
==============
*/
void idSound::ReadNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, const idBitMsg& msg ) const {
if ( mode == NSM_BROADCAST ) {
NET_GET_STATES( sdSoundBroadcastData );
newData.isOn = msg.ReadBool();
}
idEntity::ReadNetworkState( mode, baseState, newState, msg );
}
/*
==============
idSound::WriteNetworkState
==============
*/
void idSound::WriteNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, idBitMsg& msg ) const {
if ( mode == NSM_BROADCAST ) {
NET_GET_STATES( sdSoundBroadcastData );
newData.isOn = soundOn;
msg.WriteBool( newData.isOn );
}
idEntity::WriteNetworkState( mode, baseState, newState, msg );
}
/*
==============
idSound::CheckNetworkStateChanges
==============
*/
bool idSound::CheckNetworkStateChanges( networkStateMode_t mode, const sdEntityStateNetworkData& baseState ) const {
if ( mode == NSM_BROADCAST ) {
NET_GET_BASE( sdSoundBroadcastData );
if ( baseData.isOn != soundOn ) {
return true;
}
}
return idEntity::CheckNetworkStateChanges( mode, baseState );
}
/*
==============
idSound::CreateNetworkStructure
==============
*/
sdEntityStateNetworkData* idSound::CreateNetworkStructure( networkStateMode_t mode ) const {
if ( mode == NSM_BROADCAST ) {
return new sdSoundBroadcastData();
}
return idEntity::CreateNetworkStructure( mode );
}