1858 lines
48 KiB
C++
1858 lines
48 KiB
C++
//============ Copyright (c) Valve Corporation, All rights reserved. ============
|
|
//
|
|
//
|
|
//
|
|
//===============================================================================
|
|
#include "audio_pch.h"
|
|
|
|
#include "snd_dma.h"
|
|
#include "sos_system.h"
|
|
#include "sos_op.h"
|
|
#include "sound.h"
|
|
#include "../../debugoverlay.h"
|
|
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
Color CollectionColor( 245, 245, 245, 255 );
|
|
Color StackColor( 225, 225, 245, 255 );
|
|
|
|
ConVar snd_sos_show_operator_init("snd_sos_show_operator_init", "0", FCVAR_CHEAT );
|
|
ConVar snd_sos_show_operator_start("snd_sos_show_operator_start", "0", FCVAR_CHEAT );
|
|
ConVar snd_sos_show_operator_prestart("snd_sos_show_operator_prestart", "0", FCVAR_CHEAT );
|
|
ConVar snd_sos_show_operator_updates("snd_sos_show_operator_updates", "0", FCVAR_CHEAT );
|
|
ConVar snd_sos_show_operator_shutdown("snd_sos_show_operator_shutdown", "0", FCVAR_CHEAT );
|
|
ConVar snd_sos_show_operator_parse("snd_sos_show_operator_parse", "0", FCVAR_CHEAT );
|
|
|
|
ConVar snd_sos_list_operator_updates("snd_sos_list_operator_updates", "0", FCVAR_CHEAT );
|
|
|
|
ConVar snd_sos_show_operator_entry_filter( "snd_sos_show_operator_entry_filter", "", FCVAR_CHEAT );
|
|
|
|
|
|
extern CScratchPad g_scratchpad;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CSosOperatorStack
|
|
//-----------------------------------------------------------------------------
|
|
CSosOperatorStack::CSosOperatorStack( SosStackType_t SosType, stack_data_t &stackData )
|
|
{
|
|
m_SOSType = SosType;
|
|
m_pMemPool = NULL;
|
|
m_nMemSize = 0;
|
|
m_stopType = SOS_STOP_NONE;
|
|
m_flStopTime = -1.0;
|
|
m_nChannelGuid = stackData.m_nGuid;
|
|
m_flStartTime = stackData.m_flStartTime;
|
|
m_nScriptHash = stackData.m_nSoundScriptHash;
|
|
m_pOperatorsKV = stackData.m_pOperatorsKV;
|
|
|
|
}
|
|
CSosOperatorStack::~CSosOperatorStack()
|
|
{
|
|
g_pSoundOperatorSystem->RemoveChannelFromTracks( m_nChannelGuid );
|
|
|
|
if ( m_pMemPool )
|
|
{
|
|
free( m_pMemPool );
|
|
}
|
|
}
|
|
|
|
void CSosOperatorStack::SetStopType( SOSStopType_t stopType )
|
|
{
|
|
if( stopType != SOS_STOP_NONE )
|
|
{
|
|
m_stopType = stopType;
|
|
}
|
|
}
|
|
void CSosOperatorStack::SetScriptHash( HSOUNDSCRIPTHASH nHash )
|
|
{
|
|
m_nScriptHash = nHash;
|
|
KeyValues *pOperatorsKV = g_pSoundEmitterSystem->GetOperatorKVByHandle( nHash );
|
|
m_pOperatorsKV = pOperatorsKV;
|
|
}
|
|
void CSosOperatorStack::AddToTail( CSosOperator *pOperator, const char *pName )
|
|
{
|
|
int nIndex = m_vStack.AddToTail( pOperator );
|
|
m_vOperatorMap.Insert( pName , nIndex );
|
|
}
|
|
|
|
int CSosOperatorStack::FindOperatorViaOffset( size_t nOffset )
|
|
{
|
|
size_t memOffset = 0;
|
|
int i;
|
|
for( i = 0; i < m_vStack.Count(); i++ )
|
|
{
|
|
CSosOperator *pOp = m_vStack[i];
|
|
if ( pOp )
|
|
{
|
|
memOffset += pOp->GetSize();
|
|
if( memOffset > nOffset )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return i;
|
|
|
|
}
|
|
|
|
CSosOperator *CSosOperatorStack::FindOperator( const char *pName, void **pStructHandle )
|
|
{
|
|
int nOpIndex = m_vOperatorMap.Find( pName );
|
|
size_t memOffset = 0;
|
|
*pStructHandle = m_pMemPool;
|
|
for( int i = 0; i < nOpIndex; i++ )
|
|
{
|
|
CSosOperator *pOp = m_vStack[i];
|
|
if ( pOp )
|
|
{
|
|
memOffset += pOp->GetSize();
|
|
char *pStructMem = ((char *)m_pMemPool) + memOffset;
|
|
*pStructHandle = (void *)pStructMem;
|
|
}
|
|
else
|
|
{
|
|
// error!
|
|
return NULL;
|
|
}
|
|
}
|
|
return m_vStack[nOpIndex];
|
|
|
|
}
|
|
int CSosOperatorStack::FindOperator( const char *pName )
|
|
{
|
|
int nIndex = m_vOperatorMap.Find( pName );
|
|
if ( !m_vStack.IsValidIndex( nIndex ) )
|
|
{
|
|
// error
|
|
return -1;
|
|
}
|
|
return nIndex;
|
|
|
|
}
|
|
int CSosOperatorStack::GetOperatorOffset( int nIndex )
|
|
{
|
|
if ( !m_vStack.IsValidIndex( nIndex ) )
|
|
{
|
|
// error
|
|
return -1;
|
|
}
|
|
|
|
size_t memOffset = 0;
|
|
for ( int i = 0; i < nIndex; i++ )
|
|
{
|
|
CSosOperator *pOp = m_vStack[i];
|
|
if ( pOp )
|
|
{
|
|
memOffset += pOp->GetSize();
|
|
}
|
|
}
|
|
return memOffset;
|
|
}
|
|
|
|
int CSosOperatorStack::GetOperatorOutputOffset( const char *pOperatorName, const char *pOutputName )
|
|
{
|
|
int nOpIndex = FindOperator( pOperatorName );
|
|
if ( ! m_vStack.IsValidIndex( nOpIndex ) )
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Unable to find referenced operator: %s", pOperatorName );
|
|
return -1;
|
|
}
|
|
CSosOperator *pOperator = m_vStack[ nOpIndex ];
|
|
size_t nOpOffset = GetOperatorOffset( nOpIndex );
|
|
size_t nOutputOffset = pOperator->GetOutputOffset( pOutputName );
|
|
|
|
return nOpOffset + nOutputOffset;
|
|
|
|
}
|
|
void CSosOperatorStack::Init( )
|
|
{
|
|
size_t TotalSize = 0;
|
|
for( int i = 0 ; i < m_vStack.Count(); i++ )
|
|
{
|
|
char *pCharMem = ((char *)m_pMemPool) + TotalSize;
|
|
|
|
m_vStack[i]->ResolveInputValues( (void *)pCharMem, m_pMemPool );
|
|
m_vStack[i]->StackInit( (void *)pCharMem, this, i );
|
|
TotalSize += m_vStack[i]->GetSize();
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
void CSosOperatorStack::Shutdown( )
|
|
{
|
|
// if ( snd_sos_show_operator_updates.GetInt() )
|
|
// {
|
|
// Log_Msg( LOG_SND_OPERATORS, StackColor, "Operator Stack: %s\n", m_nName );
|
|
// }
|
|
|
|
size_t TotalSize = 0;
|
|
for( int i = 0 ; i < m_vStack.Count(); i++ )
|
|
{
|
|
char *pCharMem = ((char *)m_pMemPool) + TotalSize;
|
|
|
|
m_vStack[i]->ResolveInputValues( (void *)pCharMem, m_pMemPool );
|
|
m_vStack[i]->StackShutdown( (void *)pCharMem, this, i );
|
|
TotalSize += m_vStack[i]->GetSize();
|
|
}
|
|
}
|
|
|
|
bool CSosOperatorStack::ShouldPrintOperators( ) const
|
|
{
|
|
const char *pFilterString = snd_sos_show_operator_entry_filter.GetString();
|
|
|
|
if( !pFilterString || !pFilterString[0] )
|
|
{
|
|
return true;
|
|
}
|
|
if( V_stristr( g_pSoundEmitterSystem->GetSoundNameForHash( GetScriptHash() ), pFilterString ) )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CSosOperatorStack::ShouldPrintOperatorUpdates( ) const
|
|
{
|
|
if ( !snd_sos_show_operator_updates.GetInt() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return ShouldPrintOperators();
|
|
|
|
}
|
|
void CSosOperatorStack::Execute( channel_t *pChannel, CScratchPad *pScratchPad )
|
|
{
|
|
VPROF ( "CSosOperatorStack::Execute" );
|
|
|
|
if ( ShouldPrintOperatorUpdates( ) || snd_sos_list_operator_updates.GetInt() )
|
|
{
|
|
Color SEColor(255, 255, 145, 255);
|
|
Log_Msg( LOG_SND_OPERATORS, SEColor, "\nUpdate Sound Entry: %s\n", g_pSoundEmitterSystem->GetSoundNameForHash( GetScriptHash() ) );
|
|
Log_Msg( LOG_SND_OPERATORS, StackColor, "Operator Stack: %s\n", m_nName );
|
|
}
|
|
if( !pChannel )
|
|
{
|
|
pChannel = S_FindChannelByGuid( m_nChannelGuid );
|
|
}
|
|
|
|
size_t TotalSize = 0;
|
|
for( int i = 0 ; i < m_vStack.Count(); i++ )
|
|
{
|
|
char *pCharMem = ((char *)m_pMemPool) + TotalSize;
|
|
CSosOperator_t *pStructMem = (CSosOperator_t *)pCharMem;
|
|
|
|
m_vStack[i]->ResolveInputValues( (void *)pCharMem, m_pMemPool );
|
|
if( pStructMem->m_flExecute[0] > 0.0 && !( pStructMem->m_bExecuteOnce && pStructMem->m_bHasExecuted ) )
|
|
{
|
|
m_pCurrentOperatorName = m_vOperatorMap.GetElementName( i );
|
|
m_vStack[i]->Execute( (void *)pCharMem, pChannel, pScratchPad, this, i );
|
|
pStructMem->m_bHasExecuted = true;
|
|
|
|
if( ShouldPrintOperatorUpdates( ) )
|
|
{
|
|
m_vStack[i]->Print( (void *)pCharMem, this, i, 0 );
|
|
}
|
|
// diagnostics
|
|
|
|
}
|
|
else if( ShouldPrintOperatorUpdates( ) )
|
|
{
|
|
m_vStack[i]->Print( (void *)pCharMem, this, i, 1 );
|
|
}
|
|
|
|
TotalSize += m_vStack[i]->GetSize();
|
|
}
|
|
|
|
}
|
|
|
|
void CSosOperatorStack::ExecuteIterator( channel_t *pChannel, CScratchPad *pScratchPad, const void *pStopMemBlock, const char *pOperatorName, int * pnOperatorIndex )
|
|
{
|
|
if ( ShouldPrintOperatorUpdates( ) || snd_sos_list_operator_updates.GetInt() )
|
|
{
|
|
Color SEColor(255, 255, 145, 255);
|
|
Log_Msg( LOG_SND_OPERATORS, SEColor, "\nUpdate Sound Entry: %s\n", g_pSoundEmitterSystem->GetSoundNameForHash( GetScriptHash() ) );
|
|
Log_Msg( LOG_SND_OPERATORS, StackColor, "Operator Stack: %s\n", m_nName );
|
|
}
|
|
|
|
int nIndex = *pnOperatorIndex;
|
|
if ( nIndex < 0 )
|
|
{
|
|
nIndex = FindOperator( pOperatorName );
|
|
if ( nIndex < 0 )
|
|
{
|
|
Log_Warning(LOG_SND_OPERATORS, "Error: Execute iterator unable to find sound operator %s\n", pOperatorName );
|
|
return;
|
|
}
|
|
*pnOperatorIndex = nIndex; // Update the passed operator index
|
|
}
|
|
else
|
|
{
|
|
Assert( nIndex == FindOperator( pOperatorName ) );
|
|
}
|
|
|
|
size_t TotalSize = 0;
|
|
for( int i = 0; i < m_vStack.Count(); i++ )
|
|
{
|
|
char *pCharMem = ((char *)m_pMemPool) + TotalSize;
|
|
CSosOperator_t *pStructMem = (CSosOperator_t *)pCharMem;
|
|
|
|
if ( i >= nIndex )
|
|
{
|
|
m_vStack[i]->ResolveInputValues( (void *)pCharMem, m_pMemPool );
|
|
if( pStructMem->m_flExecute[0] > 0.0 && !( pStructMem->m_bExecuteOnce && pStructMem->m_bHasExecuted ) )
|
|
{
|
|
m_pCurrentOperatorName = m_vOperatorMap.GetElementName( i );;
|
|
m_vStack[i]->Execute( (void *)pCharMem, pChannel, pScratchPad, this, i );
|
|
pStructMem->m_bHasExecuted = true;
|
|
|
|
// diagnostics
|
|
if ( ShouldPrintOperatorUpdates( ) )
|
|
{
|
|
m_vStack[i]->Print( (void *)pCharMem, this, i, 0 );
|
|
}
|
|
}
|
|
else if( ShouldPrintOperatorUpdates( ) )
|
|
{
|
|
const char *pFilterString = snd_sos_show_operator_entry_filter.GetString();
|
|
if( pFilterString && pFilterString[0] &&
|
|
V_stristr( g_pSoundEmitterSystem->GetSoundNameForHash( GetScriptHash() ), pFilterString ) )
|
|
{
|
|
m_vStack[i]->Print( (void *)pCharMem, this, i, 1 );
|
|
}
|
|
}
|
|
if( pCharMem == pStopMemBlock )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
TotalSize += m_vStack[i]->GetSize();
|
|
}
|
|
}
|
|
|
|
void CSosOperatorStack::Copy( CSosOperatorStack *pSrcStack, size_t nMemOffset )
|
|
{
|
|
// copy first so we can alter
|
|
V_memcpy((char *)m_pMemPool + nMemOffset, pSrcStack->m_pMemPool, pSrcStack->m_nMemSize );
|
|
|
|
size_t nTotalOffset = 0;
|
|
|
|
// UGLY, MAKE POINTERS!
|
|
for ( int i = 0; i < pSrcStack->m_vStack.Count(); i++ )
|
|
{
|
|
CSosOperator *pOperator = pSrcStack->m_vStack[i];
|
|
const char *pName = pSrcStack->m_vOperatorMap.GetElementName( i );
|
|
|
|
// same names not allowed?
|
|
int nIndex = m_vOperatorMap.Find( pName );
|
|
if ( m_vOperatorMap.IsValidIndex( nIndex ) )
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Importing operator with same name as existing operator: %s\n", pName );
|
|
}
|
|
|
|
AddToTail( pOperator, pName );
|
|
pOperator->OffsetConnections( (char *)m_pMemPool + nMemOffset + nTotalOffset, nMemOffset );
|
|
|
|
nTotalOffset += pOperator->GetSize();
|
|
}
|
|
}
|
|
|
|
void CSosOperatorStack::Print( int nLevel )
|
|
{
|
|
if( !ShouldPrintOperators() )
|
|
{
|
|
return;
|
|
}
|
|
Log_Msg( LOG_SND_OPERATORS, StackColor, "\n%*sOperator Stack: %s\n%*sSize: %i\n", nLevel, " ", m_nName, nLevel, " ", static_cast<int>( m_nMemSize ) );
|
|
size_t TotalSize = 0;
|
|
for ( int i = 0 ; i < m_vStack.Count(); i++ )
|
|
{
|
|
m_vStack[i]->Print( (void *)((char *)m_pMemPool + TotalSize), this, i, nLevel );
|
|
TotalSize += m_vStack[i]->GetSize();
|
|
}
|
|
}
|
|
|
|
enum sosStackCreationPasses_t
|
|
{
|
|
SND_SOS_MEMORY_ALLOCATION_PASS = 0,
|
|
SND_SOS_MEMORY_INITIALIZATION_PASS,
|
|
SND_SOS_TOTAL_MEMORY_PASSES
|
|
|
|
};
|
|
|
|
void CSosOperatorStack::ParseKV( KeyValues *pOperatorsKV )
|
|
{
|
|
size_t TotalSize = 0;
|
|
KeyValues *pOperator = pOperatorsKV->GetFirstSubKey();
|
|
|
|
CUtlDict < CSosOperator * > testDict;
|
|
|
|
// 2 passes:
|
|
//
|
|
// SND_SOS_MEMORY_ALLOCATION_PASS:
|
|
//
|
|
// Sum up the total memory necessary for this stack by
|
|
// accumulating imported stack sizes and newly declared
|
|
// operator sizes. Then allocate the resulting quantity of memory.
|
|
//
|
|
// SND_SOS_MEMORY_INITIALIZATION_PASS:
|
|
//
|
|
// Copy the existing stack and operator data into the newly
|
|
// allocated block of stack memory. Properly set all parameters
|
|
// via defaults, parsing and updating connection offsets.
|
|
//
|
|
for ( int i = 0; i < SND_SOS_TOTAL_MEMORY_PASSES; i++ )
|
|
{
|
|
while ( pOperator )
|
|
{
|
|
const char *pOpName = pOperator->GetName();
|
|
const char *pOpValue = pOperator->GetString();
|
|
|
|
// if it has subkeys it's an operator, otw it's a parameter
|
|
KeyValues *pParams = pOperator->GetFirstSubKey();
|
|
if ( pParams )
|
|
{
|
|
// do we already have this one and just need to override params?
|
|
int nNewStackIndex = testDict.Find( pOpName );
|
|
int nExistingStackIndex = m_vOperatorMap.Find( pOpName );
|
|
|
|
// is an override of an operator existing in the stack
|
|
if ( m_vOperatorMap.IsValidIndex( nExistingStackIndex ) )
|
|
{
|
|
// only the second time through
|
|
if ( i == SND_SOS_MEMORY_INITIALIZATION_PASS )
|
|
{
|
|
m_pCurrentOperatorName = pOpName;
|
|
void *pStructMem;
|
|
CSosOperator *pNewOp = FindOperator( pOpName, &pStructMem );
|
|
// only overwriting
|
|
pNewOp->ParseKV( this, pStructMem, pOperator );
|
|
}
|
|
}
|
|
else if( !( testDict.IsValidIndex( nNewStackIndex ) && i == SND_SOS_MEMORY_ALLOCATION_PASS ) ) // do nothing if override of new op on first memory accumulating pass
|
|
{
|
|
CSosOperator *pNewOp = NULL;
|
|
const char *pOpType = NULL;
|
|
if( pOperator->FindKey( "operator" ) )
|
|
{
|
|
pOpType = pOperator->GetString( "operator", "" );
|
|
}
|
|
if( pOpType && *pOpType )
|
|
{
|
|
int nElementIndex = g_pSoundOperatorSystem->m_vOperatorCollection.Find( pOpType );
|
|
if ( g_pSoundOperatorSystem->m_vOperatorCollection.IsValidIndex( nElementIndex ) )
|
|
{
|
|
pNewOp = g_pSoundOperatorSystem->m_vOperatorCollection[ nElementIndex ];
|
|
}
|
|
else
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Operator: %s : Unknown sound operator type %s\n", pOpName, pOpType );
|
|
|
|
}
|
|
// is a new operator
|
|
if ( pNewOp )
|
|
{
|
|
if ( i == SND_SOS_MEMORY_ALLOCATION_PASS )
|
|
{
|
|
// new operator
|
|
testDict.Insert( pOperator->GetName(), pNewOp );
|
|
}
|
|
else if ( i == SND_SOS_MEMORY_INITIALIZATION_PASS )
|
|
{
|
|
|
|
// new operator
|
|
m_pCurrentOperatorName = pOpName;
|
|
pNewOp->SetBaseDefaults( (void *)(((char *)m_pMemPool) + TotalSize) );
|
|
pNewOp->SetDefaults( (void *)(((char *)m_pMemPool) + TotalSize) );
|
|
pNewOp->ParseKV( this, (void *)(((char *)m_pMemPool) + TotalSize), pOperator );
|
|
AddToTail( pNewOp, pOperator->GetName() );
|
|
}
|
|
TotalSize += pNewOp->GetSize();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( pOpName && *pOpName )
|
|
{
|
|
if ( !V_stricmp( pOpName, "import_stack" ) )
|
|
{
|
|
if ( pOpValue && *pOpValue )
|
|
{
|
|
CSosOperatorStack *pImportStack = g_pSoundOperatorSystem->m_MasterStackCollection.GetStack( pOpValue );
|
|
|
|
if ( pImportStack )
|
|
{
|
|
if ( i == SND_SOS_MEMORY_INITIALIZATION_PASS )
|
|
{
|
|
Copy( pImportStack, TotalSize );
|
|
}
|
|
TotalSize += pImportStack->GetSize();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pOperator = pOperator->GetNextKey();
|
|
}
|
|
// first time through
|
|
if ( i == SND_SOS_MEMORY_ALLOCATION_PASS )
|
|
{
|
|
if ( TotalSize > 0 )
|
|
{
|
|
m_pMemPool = malloc( TotalSize );
|
|
m_nMemSize = TotalSize;
|
|
}
|
|
TotalSize = 0;
|
|
pOperator = pOperatorsKV->GetFirstSubKey();
|
|
}
|
|
}
|
|
}
|
|
|
|
KeyValues *S_GetStopTracksKV( KeyValues *pOperatorsKV )
|
|
{
|
|
if( !pOperatorsKV )
|
|
{
|
|
if( snd_sos_show_operator_parse.GetInt() )
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Sound Operator System has invalid operator KV\n" );
|
|
}
|
|
return NULL;
|
|
}
|
|
KeyValues *pOperatorDataKV = pOperatorsKV->FindKey( "soundentry_operator_data" );
|
|
if( ! pOperatorDataKV )
|
|
{
|
|
// Log_Warning( LOG_SND_OPERATORS, "Error: Sound Operator System cannot find \"soundentry_operator_data\"\n" );
|
|
return NULL;
|
|
}
|
|
|
|
KeyValues *pTrackDataKV = pOperatorDataKV->FindKey("track_data" );
|
|
if( ! pTrackDataKV )
|
|
{
|
|
return NULL;
|
|
}
|
|
KeyValues *pStopTracksKV = pTrackDataKV->FindKey("stop_tracks_on_start" );
|
|
if( ! pStopTracksKV )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
|
|
KeyValues *pStopTracksList = pStopTracksKV->GetFirstSubKey();
|
|
return pStopTracksList;
|
|
//
|
|
// while ( pStopTracksList )
|
|
// {
|
|
// const char *pStopTracksTypeString = pStopTracksList->GetName();
|
|
//
|
|
// if ( pStopTracksTypeString && *pStopTracksTypeString )
|
|
// {
|
|
// if ( !V_strcmp( pStopTracksTypeString, pListName ) )
|
|
// {
|
|
// return pStopTracksList;
|
|
// }
|
|
//
|
|
// }
|
|
// pStopTracksList = pStopTracksList->GetNextKey();
|
|
// }
|
|
//
|
|
//
|
|
// return NULL;
|
|
}
|
|
|
|
KeyValues *S_GetStopTracksKV( HSOUNDSCRIPTHASH nSoundEntryHash )
|
|
{
|
|
if( nSoundEntryHash != SOUNDEMITTER_INVALID_HASH )
|
|
{
|
|
KeyValues *pOperatorKV = g_pSoundEmitterSystem->GetOperatorKVByHandle( nSoundEntryHash );
|
|
if( pOperatorKV )
|
|
{
|
|
return S_GetStopTracksKV( pOperatorKV );
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
KeyValues *CSosOperatorStack::GetSyncPointsKV( KeyValues *pOperatorsKV, const char *pListName )
|
|
{
|
|
if( !pOperatorsKV )
|
|
{
|
|
if( snd_sos_show_operator_parse.GetInt() )
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Sound Operator System has invalid operator KV\n" );
|
|
}
|
|
return NULL;
|
|
}
|
|
KeyValues *pOperatorDataKV = pOperatorsKV->FindKey( "soundentry_operator_data" );
|
|
if( ! pOperatorDataKV )
|
|
{
|
|
// Log_Warning( LOG_SND_OPERATORS, "Error: Sound Operator System cannot find \"soundentry_operator_data\"\n" );
|
|
return NULL;
|
|
}
|
|
|
|
KeyValues *pTrackDataKV = pOperatorDataKV->FindKey("track_data" );
|
|
if( ! pTrackDataKV )
|
|
{
|
|
return NULL;
|
|
}
|
|
KeyValues *pSyncPointsKV = pTrackDataKV->FindKey("syncpoints" );
|
|
if( ! pSyncPointsKV )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
|
|
KeyValues *pSyncPointList = pSyncPointsKV->GetFirstSubKey();
|
|
while ( pSyncPointList )
|
|
{
|
|
const char *pStackListTypeString = pSyncPointList->GetName();
|
|
|
|
if ( pStackListTypeString && *pStackListTypeString )
|
|
{
|
|
if ( !V_strcmp( pStackListTypeString, pListName ) )
|
|
{
|
|
return pSyncPointList;
|
|
}
|
|
|
|
}
|
|
pSyncPointList = pSyncPointList->GetNextKey();
|
|
}
|
|
|
|
|
|
return NULL;
|
|
}
|
|
|
|
KeyValues *CSosOperatorStack::GetSyncPointsKV( const char *pListName )
|
|
{
|
|
KeyValues *pOperatorsKV = GetOperatorsKV();
|
|
return GetSyncPointsKV( pOperatorsKV, pListName );
|
|
}
|
|
|
|
bool S_GetTrackData( KeyValues *pOperatorsKV, track_data_t &trackData )
|
|
{
|
|
trackData.SetDefaults();
|
|
|
|
if( !pOperatorsKV )
|
|
{
|
|
if( snd_sos_show_operator_parse.GetInt() )
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Sound Operator System has invalid operator KV\n" );
|
|
}
|
|
return false;
|
|
}
|
|
KeyValues *pOperatorDataKV = pOperatorsKV->FindKey( "soundentry_operator_data" );
|
|
if( ! pOperatorDataKV )
|
|
{
|
|
// Log_Warning( LOG_SND_OPERATORS, "Error: Sound Operator System cannot find \"soundentry_operator_data\"\n" );
|
|
return false;
|
|
}
|
|
|
|
KeyValues *pTrackDataKV = pOperatorDataKV->FindKey("track_data" );
|
|
if( ! pTrackDataKV )
|
|
{
|
|
return false;
|
|
}
|
|
const char *pTrackNumber = pTrackDataKV->GetString( "track_name", "-1" );
|
|
trackData.m_pTrackName = pTrackNumber;
|
|
if( pTrackNumber )
|
|
{
|
|
trackData.m_nTrackNumber = V_atoi( pTrackNumber );
|
|
}
|
|
const char *pTrackPriority = pTrackDataKV->GetString( "priority", "-1" );
|
|
if( pTrackPriority )
|
|
{
|
|
trackData.m_nTrackPriority = V_atoi( pTrackPriority );
|
|
}
|
|
const char *pOverridePriority = pTrackDataKV->GetString( "priority_override", "-1" );
|
|
if( pOverridePriority )
|
|
{
|
|
if ( !V_strcasecmp( pOverridePriority, "true" ) )
|
|
{
|
|
trackData.m_bPriorityOverride = true;
|
|
}
|
|
}
|
|
const char *pBlockEqualPriority = pTrackDataKV->GetString( "block_equal_priority", "-1" );
|
|
if( pBlockEqualPriority )
|
|
{
|
|
if ( !V_strcasecmp( pBlockEqualPriority, "true" ) )
|
|
{
|
|
trackData.m_bBlockEqualPriority = true;
|
|
}
|
|
}
|
|
const char *pSyncTrackNumber = pTrackDataKV->GetString( "sync_track_name", "-1" );
|
|
trackData.m_pSyncTrackName = pSyncTrackNumber;
|
|
if( pSyncTrackNumber )
|
|
{
|
|
trackData.m_nSyncTrackNumber = V_atoi( pSyncTrackNumber );
|
|
}
|
|
const char *pStartPoint = pTrackDataKV->GetString( "start_point", "0.0" );
|
|
if( pStartPoint )
|
|
{
|
|
trackData.m_flStartPoint = V_atof( pStartPoint );
|
|
}
|
|
const char *pEndPoint = pTrackDataKV->GetString( "end_point", "0.0" );
|
|
if( pEndPoint )
|
|
{
|
|
trackData.m_flEndPoint = V_atof( pEndPoint );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CSosOperatorStack::GetTrackData( track_data_t &trackData ) const
|
|
{
|
|
KeyValues *pOperatorsKV = GetOperatorsKV();
|
|
S_GetTrackData( pOperatorsKV, trackData );
|
|
}
|
|
|
|
bool S_GetTrackData( HSOUNDSCRIPTHASH nSoundEntryHash, track_data_t &trackData )
|
|
{
|
|
if( nSoundEntryHash != SOUNDEMITTER_INVALID_HASH )
|
|
{
|
|
KeyValues *pOperatorKV = g_pSoundEmitterSystem->GetOperatorKVByHandle( nSoundEntryHash );
|
|
if( pOperatorKV )
|
|
{
|
|
return S_GetTrackData( pOperatorKV, trackData );
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool S_TrackHasPriority( track_data_t &newTrackData, track_data_t &existingTrackData )
|
|
{
|
|
if( !( newTrackData.m_bPriorityOverride && existingTrackData.m_bPriorityOverride ) )
|
|
{
|
|
if( newTrackData.m_bPriorityOverride )
|
|
{
|
|
return true;
|
|
}
|
|
if( existingTrackData.m_bPriorityOverride )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if( existingTrackData.m_bBlockEqualPriority && ( newTrackData.m_nTrackPriority == existingTrackData.m_nTrackPriority ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( newTrackData.m_nTrackPriority >= existingTrackData.m_nTrackPriority )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CSosOperatorStackList
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CSosOperatorStackList::CSosOperatorStackList()
|
|
{
|
|
m_vUpdateStack = NULL;
|
|
// m_vStartStack = NULL;
|
|
m_vStopStack = NULL;
|
|
// m_vCueStack = NULL;
|
|
m_stopType = SOS_STOP_NONE;
|
|
m_flStopTime = -1.0;
|
|
}
|
|
CSosOperatorStackList::~CSosOperatorStackList()
|
|
{
|
|
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->Shutdown();
|
|
// delete m_vCueStack;
|
|
// }
|
|
// if ( m_vStartStack )
|
|
// {
|
|
// m_vStartStack->Shutdown();
|
|
// delete m_vStartStack;
|
|
// }
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->Shutdown();
|
|
delete m_vUpdateStack;
|
|
}
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->Shutdown();
|
|
delete m_vStopStack;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CSosOperatorStackList::Execute( CSosOperatorStack::SosStackType_t SosType, channel_t *pChannel, CScratchPad *pScratchPad )
|
|
{
|
|
switch( SosType )
|
|
{
|
|
case CSosOperatorStack::SOS_UPDATE:
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->SetStopType( m_stopType );
|
|
m_vUpdateStack->Execute( pChannel, pScratchPad );
|
|
SetStopType( m_vUpdateStack->GetStopType( ) );
|
|
}
|
|
break;
|
|
// case CSosOperatorStack::SOS_START:
|
|
// if ( m_vStartStack )
|
|
// {
|
|
// m_vStartStack->Execute( pChannel, pScratchPad );
|
|
// }
|
|
// break;
|
|
case CSosOperatorStack::SOS_STOP:
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->Execute( pChannel, pScratchPad );
|
|
}
|
|
break;
|
|
// case CSosOperatorStack::SOS_CUE:
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->Execute( pChannel, pScratchPad );
|
|
// }
|
|
// break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool CSosOperatorStackList::HasStack( CSosOperatorStack::SosStackType_t SosType )
|
|
{
|
|
switch( SosType )
|
|
{
|
|
case CSosOperatorStack::SOS_UPDATE:
|
|
if ( m_vUpdateStack )
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
// case CSosOperatorStack::SOS_START:
|
|
// if ( m_vStartStack )
|
|
// {
|
|
// return true;
|
|
// }
|
|
// break;
|
|
|
|
case CSosOperatorStack::SOS_STOP:
|
|
if ( m_vStopStack )
|
|
{
|
|
return true;
|
|
}
|
|
break;
|
|
// case CSosOperatorStack::SOS_CUE:
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// return true;
|
|
// }
|
|
// break;
|
|
default:
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void CSosOperatorStackList::Print()
|
|
{
|
|
Log_Msg( LOG_SOUND_OPERATOR_SYSTEM, StackColor, "\nStack List:\n");
|
|
|
|
// Log_Msg( LOG_SOUND_OPERATOR_SYSTEM, StackColor, "\nCUE Operators:\n");
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->Print( 1 );
|
|
// }
|
|
// Log_Msg( LOG_SOUND_OPERATOR_SYSTEM, StackColor, "\nSTART Operators:\n");
|
|
// if ( m_vStartStack )
|
|
// {
|
|
// m_vStartStack->Print( 1 );
|
|
// }
|
|
Log_Msg( LOG_SOUND_OPERATOR_SYSTEM, StackColor, "\nUPDATE Operators:\n");
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->Print( 1 );
|
|
}
|
|
|
|
Log_Msg( LOG_SOUND_OPERATOR_SYSTEM, StackColor, "\nSTOP Operators:\n");
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->Print( 1 );
|
|
}
|
|
}
|
|
CSosOperatorStack *CSosOperatorStackList::GetStack( CSosOperatorStack::SosStackType_t SosType )
|
|
{
|
|
switch( SosType )
|
|
{
|
|
case CSosOperatorStack::SOS_UPDATE:
|
|
return m_vUpdateStack;
|
|
break;
|
|
// case CSosOperatorStack::SOS_START:
|
|
// return m_vStartStack;
|
|
// break;
|
|
case CSosOperatorStack::SOS_STOP:
|
|
return m_vStopStack;
|
|
break;
|
|
// case CSosOperatorStack::SOS_CUE:
|
|
// return m_vCueStack;
|
|
// break;
|
|
default:
|
|
return NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
void CSosOperatorStackList::SetScriptHash( HSOUNDSCRIPTHASH nHash )
|
|
{
|
|
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->SetScriptHash( nHash );
|
|
// }
|
|
// if ( m_vStartStack )
|
|
// {
|
|
// m_vStartStack->SetScriptHash( nHash );
|
|
// }
|
|
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->SetScriptHash( nHash );
|
|
}
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->SetScriptHash( nHash );
|
|
}
|
|
}
|
|
|
|
void CSosOperatorStackList::SetChannelGuid( int nGuid )
|
|
{
|
|
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->SetChannelGuid( nGuid );
|
|
// }
|
|
// if ( m_vStartStack )
|
|
// {
|
|
// m_vStartStack->SetChannelGuid( nGuid );
|
|
// }
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->SetChannelGuid( nGuid );
|
|
}
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->SetChannelGuid( nGuid );
|
|
}
|
|
}
|
|
void CSosOperatorStackList::SetStartTime( float flStartTime )
|
|
{
|
|
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->SetStartTime( flStartTime );
|
|
// }
|
|
// if ( m_vStartStack )
|
|
// {
|
|
// m_vStartStack->SetStartTime( flStartTime );
|
|
// }
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->SetStartTime( flStartTime );
|
|
}
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->SetStartTime( flStartTime );
|
|
}
|
|
}
|
|
void CSosOperatorStackList::SetStopTime( float flStopTime )
|
|
{
|
|
m_flStopTime = flStopTime;
|
|
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->SetStopTime( flStopTime );
|
|
// }
|
|
// if ( m_vStopStack )
|
|
// {
|
|
// m_vStopStack->SetStopTime( flStopTime );
|
|
// }
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->SetStopTime( flStopTime );
|
|
}
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->SetStopTime( flStopTime );
|
|
}
|
|
}
|
|
void CSosOperatorStackList::SetStopType( SOSStopType_t stopType )
|
|
{
|
|
m_stopType = stopType;
|
|
|
|
// if ( m_vCueStack )
|
|
// {
|
|
// m_vCueStack->SetStopType( stopType );
|
|
// }
|
|
// if ( m_vStopStack )
|
|
// {
|
|
// m_vStopStack->SetStopTime( stopTime );
|
|
// }
|
|
if ( m_vUpdateStack )
|
|
{
|
|
m_vUpdateStack->SetStopType( stopType );
|
|
}
|
|
if ( m_vStopStack )
|
|
{
|
|
m_vStopStack->SetStopType( stopType );
|
|
}
|
|
}
|
|
void CSosOperatorStackList::SetStack( CSosOperatorStack *pStack )
|
|
{
|
|
switch ( pStack->GetType() )
|
|
{
|
|
case CSosOperatorStack::SOS_UPDATE:
|
|
m_vUpdateStack = pStack;
|
|
break;
|
|
// case CSosOperatorStack::SOS_START:
|
|
// m_vStartStack = pStack;
|
|
// break;
|
|
case CSosOperatorStack::SOS_STOP:
|
|
m_vStopStack = pStack;
|
|
break;
|
|
// case CSosOperatorStack::SOS_CUE:
|
|
// m_vCueStack = pStack;
|
|
// break;
|
|
default:
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void CSosOperatorStackList::StopStacks( SOSStopType_t stopType )
|
|
{
|
|
if( stopType == SOS_STOP_FORCE )
|
|
{
|
|
SetStopType( SOS_STOP_FORCE );
|
|
}
|
|
else if( ( m_stopType == SOS_STOP_NONE || m_stopType == SOS_STOP_QUEUE ) && ( stopType != SOS_STOP_NONE && stopType != SOS_STOP_QUEUE ) )
|
|
{
|
|
SetStopType( stopType );
|
|
SetStopTime( g_pSoundServices->GetHostTime() );
|
|
|
|
Execute( CSosOperatorStack::SOS_STOP, NULL, &g_scratchpad );
|
|
}
|
|
}
|
|
|
|
void CSosOperatorStackList::ParseKV( stack_data_t &stackData )
|
|
{
|
|
KeyValues *pOperatorsKV = stackData.m_pOperatorsKV;
|
|
|
|
KeyValues *pStackListType = pOperatorsKV->GetFirstSubKey();
|
|
while ( pStackListType )
|
|
{
|
|
CSosOperatorStack::SosStackType_t SosType = CSosOperatorStack::SOS_NONE;
|
|
|
|
const char *pDefaultStack = NULL;
|
|
const char *pStackListTypeString = pStackListType->GetName();
|
|
if ( pStackListTypeString && *pStackListTypeString )
|
|
{
|
|
if ( !V_strcmp( pStackListTypeString, "update_stack" ) )
|
|
{
|
|
SosType = CSosOperatorStack::SOS_UPDATE;
|
|
pDefaultStack = "update_default";
|
|
}
|
|
else if ( !V_strcmp( pStackListTypeString, "start_stack" ) )
|
|
{
|
|
pStackListType = pStackListType->GetNextKey();
|
|
continue;
|
|
// SosType = CSosOperatorStack::SOS_START;
|
|
// pDefaultStack = "start_default";
|
|
}
|
|
else if ( !V_strcmp( pStackListTypeString, "stop_stack" ) )
|
|
{
|
|
SosType = CSosOperatorStack::SOS_STOP;
|
|
pDefaultStack = "stop_default";
|
|
}
|
|
else if ( !V_strcmp( pStackListTypeString, "prestart_stack" ) )
|
|
{
|
|
pStackListType = pStackListType->GetNextKey();
|
|
continue;
|
|
// SosType = CSosOperatorStack::SOS_CUE;
|
|
// pDefaultStack = "cue_default";
|
|
}
|
|
else if ( !V_strcmp( pStackListTypeString, "soundentry_operator_data" ) )
|
|
{
|
|
|
|
pStackListType = pStackListType->GetNextKey();
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Unknown sound operator stack type: %s\n", pStackListTypeString );
|
|
// gets us out to the stack type level
|
|
pStackListType = pStackListType->GetNextKey();
|
|
continue;
|
|
}
|
|
|
|
if ( pDefaultStack && SosType != CSosOperatorStack::SOS_NONE )
|
|
{
|
|
// todo: morasky, default stacks not implemented?
|
|
CSosOperatorStack *pNewStack = new CSosOperatorStack( SosType, stackData );
|
|
pNewStack->SetName( pStackListTypeString );
|
|
SetStack( pNewStack );
|
|
pNewStack->ParseKV( pStackListType );
|
|
}
|
|
}
|
|
pStackListType = pStackListType->GetNextKey();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// S_ParseOperatorsKV
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
CSosOperatorStackList *S_ParseOperatorsKV( stack_data_t &stackData )
|
|
{
|
|
CSosOperatorStackList *pNewStackList = new CSosOperatorStackList();
|
|
pNewStackList->ParseKV( stackData );
|
|
return pNewStackList;
|
|
|
|
}
|
|
|
|
CSosOperatorStack *S_GetStack( CSosOperatorStack::SosStackType_t stackType, stack_data_t &stackData )
|
|
{
|
|
KeyValues *pOperatorsKV = stackData.m_pOperatorsKV;
|
|
|
|
KeyValues *pStackListType = pOperatorsKV->GetFirstSubKey();
|
|
|
|
// morasky: should "GetString" instead of brute force search?
|
|
while ( pStackListType )
|
|
{
|
|
const char *pStackListTypeString = pStackListType->GetName();
|
|
if ( pStackListTypeString && *pStackListTypeString )
|
|
{
|
|
if ( ( V_strcmp( pStackListTypeString, "start_stack" ) && stackType == CSosOperatorStack::SOS_START ) ||
|
|
( V_strcmp( pStackListTypeString, "prestart_stack" ) && stackType == CSosOperatorStack::SOS_CUE ) )
|
|
{
|
|
pStackListType = pStackListType->GetNextKey();
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
CSosOperatorStack *pNewStack = new CSosOperatorStack( stackType, stackData );
|
|
if( pNewStack )
|
|
{
|
|
pNewStack->SetName( pStackListTypeString );
|
|
pNewStack->ParseKV( pStackListType );
|
|
|
|
if( snd_sos_show_operator_init.GetInt() )
|
|
{
|
|
if( stackType == CSosOperatorStack::SOS_START )
|
|
{
|
|
Log_Msg( LOG_SOUND_OPERATOR_SYSTEM, StackColor, "\nSTART Operators:\n");
|
|
}
|
|
else if( stackType == CSosOperatorStack::SOS_CUE )
|
|
{
|
|
Log_Msg( LOG_SOUND_OPERATOR_SYSTEM, StackColor, "\nCUE Operators:\n");
|
|
}
|
|
|
|
pNewStack->Print( 1 );
|
|
}
|
|
}
|
|
return pNewStack;
|
|
}
|
|
}
|
|
pStackListType = pStackListType->GetNextKey();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CSosOperatorStackList *S_InitChannelOperators( stack_data_t &stackData )
|
|
{
|
|
|
|
CSosOperatorStackList *pStackList = NULL;
|
|
|
|
if ( stackData.m_pOperatorsKV != NULL )
|
|
{
|
|
pStackList = S_ParseOperatorsKV( stackData );
|
|
}
|
|
|
|
if ( ! pStackList )
|
|
{
|
|
// Log_Warning( LOG_SND_OPERATORS, "Error: Unable to create operator stack list on channel\n");
|
|
// return;
|
|
}
|
|
else
|
|
{
|
|
if ( snd_sos_show_operator_init.GetInt() )
|
|
{
|
|
pStackList->Print();
|
|
}
|
|
}
|
|
return pStackList;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CSosOperatorStackCollection
|
|
//-----------------------------------------------------------------------------
|
|
CSosOperatorStackCollection::~CSosOperatorStackCollection()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void CSosOperatorStackCollection::Clear()
|
|
{
|
|
for ( unsigned int i = 0; i < m_vUpdateStacks.Count(); i++ )
|
|
{
|
|
delete m_vUpdateStacks[i];
|
|
}
|
|
m_vUpdateStacks.RemoveAll();
|
|
for ( unsigned int i = 0; i < m_vStartStacks.Count(); i++ )
|
|
{
|
|
delete m_vStartStacks[i];
|
|
}
|
|
m_vStartStacks.RemoveAll();
|
|
for ( unsigned int i = 0; i < m_vStopStacks.Count(); i++ )
|
|
{
|
|
delete m_vStopStacks[i];
|
|
}
|
|
m_vStopStacks.RemoveAll();
|
|
for ( unsigned int i = 0; i < m_vCueStacks.Count(); i++ )
|
|
{
|
|
delete m_vCueStacks[i];
|
|
}
|
|
m_vCueStacks.RemoveAll();
|
|
m_vAllStacks.RemoveAll();
|
|
}
|
|
CSosOperatorStack *CSosOperatorStackCollection::GetStack( const char *pStackName )
|
|
{
|
|
int nIndex = m_vAllStacks.Find( pStackName );
|
|
if ( m_vAllStacks.IsValidIndex( nIndex ) )
|
|
{
|
|
return m_vAllStacks[nIndex];
|
|
}
|
|
return NULL;
|
|
}
|
|
CSosOperatorStack *CSosOperatorStackCollection::GetStack( CSosOperatorStack::SosStackType_t SosType, const char *pStackName )
|
|
{
|
|
CSosOperatorStack *pOpStack = GetStack( pStackName );
|
|
if ( pOpStack )
|
|
{
|
|
if ( pOpStack->IsType( SosType ) )
|
|
{
|
|
return pOpStack;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
void CSosOperatorStackCollection::ParseKV( CSosOperatorStack::SosStackType_t SosType, KeyValues *pStackType )
|
|
{
|
|
stack_data_t stackData;
|
|
KeyValues *pStack = pStackType->GetFirstSubKey();
|
|
|
|
while ( pStack )
|
|
{
|
|
const char *pStackName = pStack->GetName();
|
|
CSosOperatorStack *pNewStack = new CSosOperatorStack( SosType, stackData );
|
|
pNewStack->SetName( pStackName );
|
|
|
|
pNewStack->ParseKV( pStack );
|
|
|
|
switch ( SosType )
|
|
{
|
|
case CSosOperatorStack::SOS_UPDATE:
|
|
m_vUpdateStacks.Insert( pStackName, pNewStack );
|
|
m_vAllStacks.Insert( pStackName, pNewStack );
|
|
break;
|
|
case CSosOperatorStack::SOS_START:
|
|
m_vStartStacks.Insert( pStackName, pNewStack );
|
|
m_vAllStacks.Insert( pStackName, pNewStack );
|
|
break;
|
|
case CSosOperatorStack::SOS_STOP:
|
|
m_vStopStacks.Insert( pStackName, pNewStack );
|
|
m_vAllStacks.Insert( pStackName, pNewStack );
|
|
break;
|
|
case CSosOperatorStack::SOS_CUE:
|
|
m_vCueStacks.Insert( pStackName, pNewStack );
|
|
m_vAllStacks.Insert( pStackName, pNewStack );
|
|
break;
|
|
default:
|
|
// BETTER ERROR HERE
|
|
Log_Warning( LOG_SND_OPERATORS, "Error: Unknown sound operator stack type" );
|
|
delete pNewStack;
|
|
break;
|
|
}
|
|
pStack = pStack->GetNextKey();
|
|
}
|
|
}
|
|
void CSosOperatorStackCollection::Print()
|
|
{
|
|
Log_Msg( LOG_SND_OPERATORS, CollectionColor, "\n\nSound Operators Collection:\n");
|
|
|
|
Log_Msg( LOG_SND_OPERATORS, CollectionColor, "\n%*sCue Stacks:\n", 1, " ");
|
|
for ( unsigned int i = 0; i < m_vCueStacks.Count(); i++ )
|
|
{
|
|
m_vCueStacks[i]->Print( 3 );
|
|
}
|
|
Log_Msg( LOG_SND_OPERATORS, CollectionColor, "\n%*sStart Stacks:\n", 1, " " );
|
|
for ( unsigned int i = 0; i < m_vStartStacks.Count(); i++ )
|
|
{
|
|
m_vStartStacks[i]->Print( 3 );
|
|
}
|
|
Log_Msg ( LOG_SND_OPERATORS, CollectionColor, "\n%*sUpdate Stacks:\n", 1, " " );
|
|
for ( unsigned int i = 0; i < m_vUpdateStacks.Count(); i++ )
|
|
{
|
|
m_vUpdateStacks[i]->Print( 3 );
|
|
}
|
|
Log_Msg ( LOG_SND_OPERATORS, CollectionColor, "\n%*sStop Stacks:\n", 1, " " );
|
|
for ( unsigned int i = 0; i < m_vStopStacks.Count(); i++ )
|
|
{
|
|
m_vStopStacks[i]->Print( 3 );
|
|
}
|
|
Log_Msg( LOG_SND_OPERATORS, CollectionColor, "\n");
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
CSosOperatorSystem::CSosOperatorSystem()
|
|
{
|
|
m_bHasInitialized = false;
|
|
}
|
|
|
|
CSosOperatorSystem::~CSosOperatorSystem()
|
|
{
|
|
for( int i = 0; i < m_sosStopChannelQueue.Count(); i++ )
|
|
{
|
|
SosStopQueueData_t *pStopQueue = m_sosStopChannelQueue[i];
|
|
if( pStopQueue )
|
|
{
|
|
delete pStopQueue;
|
|
}
|
|
}
|
|
m_sosStopChannelQueue.RemoveAll();
|
|
|
|
for( int i = 0; i < m_sosStartEntryQueue.Count(); i++ )
|
|
{
|
|
SosStartQueueData_t *pStartQueue = m_sosStartEntryQueue[i];
|
|
if( pStartQueue )
|
|
{
|
|
delete pStartQueue;
|
|
}
|
|
}
|
|
m_sosStartEntryQueue.RemoveAll();
|
|
}
|
|
|
|
#define SOUND_OPERATORS_FILE "scripts/sound_operator_stacks.txt"
|
|
void CSosOperatorSystem::Flush()
|
|
{
|
|
m_MasterStackCollection.Clear();
|
|
m_bHasInitialized = false;
|
|
Init();
|
|
}
|
|
|
|
void CSosOperatorSystem::Init()
|
|
{
|
|
// checking for "restarting sound system"
|
|
|
|
if( m_bHasInitialized )
|
|
{
|
|
return;
|
|
}
|
|
m_bHasInitialized = true;
|
|
|
|
CRC32_t crc;
|
|
CRC32_Init( &crc );
|
|
|
|
KeyValues *pSoundOperatorStacksKV = new KeyValues( SOUND_OPERATORS_FILE );
|
|
if ( g_pFullFileSystem->LoadKeyValues( *pSoundOperatorStacksKV, IFileSystem::TYPE_SOUNDOPERATORS, SOUND_OPERATORS_FILE, "GAME" ) )
|
|
{
|
|
// TODO: Morasky
|
|
// AccumulateFileNameAndTimestampIntoChecksum( &crc, SOUND_OPERATORS_FILE );
|
|
|
|
KeyValues *pStackType = pSoundOperatorStacksKV;
|
|
while ( pStackType )
|
|
{
|
|
CSosOperatorStack::SosStackType_t curStackType = CSosOperatorStack::SOS_NONE;
|
|
const char *pStackTypeString = pStackType->GetName( );
|
|
if ( pStackTypeString && *pStackTypeString )
|
|
{
|
|
if ( !V_strcmp( pStackTypeString, "update_stacks" ) )
|
|
{
|
|
curStackType = CSosOperatorStack::SOS_UPDATE;
|
|
}
|
|
else if ( !V_strcmp( pStackTypeString, "start_stacks" ) )
|
|
{
|
|
curStackType = CSosOperatorStack::SOS_START;
|
|
}
|
|
else if ( !V_strcmp( pStackTypeString, "stop_stacks" ) )
|
|
{
|
|
curStackType = CSosOperatorStack::SOS_STOP;
|
|
}
|
|
else if ( !V_strcmp( pStackTypeString, "prestart_stacks" ) )
|
|
{
|
|
curStackType = CSosOperatorStack::SOS_CUE;
|
|
}
|
|
else
|
|
{
|
|
// BETTER ERROR HERE
|
|
Log_Warning( LOG_SND_OPERATORS, "Unknown sound operator stack arg %s", pStackTypeString );
|
|
continue;
|
|
}
|
|
}
|
|
m_MasterStackCollection.ParseKV( curStackType, pStackType );
|
|
pStackType = pStackType->GetNextKey();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log_Warning( LOG_SND_OPERATORS, "Warning: Unable to load sound operators file '%s'\n", SOUND_OPERATORS_FILE );
|
|
}
|
|
pSoundOperatorStacksKV->deleteThis();
|
|
|
|
CRC32_Final( &crc );
|
|
|
|
if( snd_sos_show_operator_init.GetInt() )
|
|
{
|
|
m_MasterStackCollection.Print();
|
|
}
|
|
|
|
// m_uManifestPlusScriptChecksum = ( unsigned int )crc;
|
|
}
|
|
void CSosOperatorSystem::PrintOperatorList()
|
|
{
|
|
for( unsigned int i = 0; i < m_vOperatorCollection.Count(); i++)
|
|
{
|
|
DevMsg("%s\n", m_vOperatorCollection.GetElementName( i ) );
|
|
}
|
|
}
|
|
void S_PrintOperatorList( void )
|
|
{
|
|
g_pSoundOperatorSystem->PrintOperatorList();
|
|
}
|
|
|
|
ConCommand snd_sos_print_operators( "snd_sos_print_operators", S_PrintOperatorList, "Prints a list of currently available operators", FCVAR_CHEAT );
|
|
|
|
void CSosOperatorSystem::ClearSubSystems()
|
|
{
|
|
m_vTrackDict.RemoveAll();
|
|
m_sosStopChannelQueue.PurgeAndDeleteElements();
|
|
m_sosStartEntryQueue.PurgeAndDeleteElements();
|
|
}
|
|
|
|
void CSosOperatorSystem::QueueStartEntry( StartSoundParams_t &startParams, float flDelay /*= 0.0*/, bool bFromPrestart /* = false */ )
|
|
{
|
|
SosStartQueueData_t *pStartQueue = new SosStartQueueData_t();
|
|
pStartQueue->m_nStartTime = g_pSoundServices->GetHostTime() + flDelay;
|
|
pStartQueue->m_bFromPrestart = bFromPrestart;
|
|
|
|
startParams.Copy( pStartQueue->m_startSoundParams );
|
|
|
|
m_sosStartEntryQueue.AddToTail( pStartQueue );
|
|
}
|
|
|
|
ConVar snd_sos_show_startqueue("snd_sos_show_startqueue", "0", FCVAR_CHEAT );
|
|
void CSosOperatorSystem::StartQueuedEntries()
|
|
{
|
|
for( int i = m_sosStartEntryQueue.Count() -1; i > -1; i-- )
|
|
{
|
|
SosStartQueueData_t *pStartQueue = m_sosStartEntryQueue[i];
|
|
if( snd_sos_show_startqueue.GetInt() )
|
|
{
|
|
Log_Msg( LOG_SND_OPERATORS, "STARTQUEUE: %s time to start of %f\n", g_pSoundEmitterSystem->GetSoundNameForHash( pStartQueue->m_startSoundParams.m_nSoundScriptHash ), pStartQueue->m_nStartTime - g_pSoundServices->GetHostTime() );
|
|
}
|
|
|
|
if( pStartQueue->m_nStartTime <= g_pSoundServices->GetHostTime() )
|
|
{
|
|
if( snd_sos_show_startqueue.GetInt() )
|
|
{
|
|
Log_Msg( LOG_SND_OPERATORS, "STARTQUEUE: %s satisfies time\n", g_pSoundEmitterSystem->GetSoundNameForHash( pStartQueue->m_startSoundParams.m_nSoundScriptHash ) );
|
|
}
|
|
// check if new entry has priority over old
|
|
track_data_t newTrackData;
|
|
track_data_t existingTrackData;
|
|
|
|
bool bHasData = S_GetTrackData( pStartQueue->m_startSoundParams.m_nSoundScriptHash, newTrackData );
|
|
bool bHasData2 = false;
|
|
bool bHasPriority = false;
|
|
|
|
if( bHasData )
|
|
{
|
|
bHasData2 = GetTrackDataOnTrack( newTrackData.m_pTrackName, existingTrackData );
|
|
if( bHasData2 )
|
|
{
|
|
bHasPriority = S_TrackHasPriority( newTrackData, existingTrackData );
|
|
}
|
|
}
|
|
|
|
if( !bHasPriority && bHasData && bHasData2 )
|
|
{
|
|
if( snd_sos_show_startqueue.GetInt() )
|
|
{
|
|
Log_Msg( LOG_SND_OPERATORS, "STARTQUEUE: Not starting %s due to existing priority.\n", g_pSoundEmitterSystem->GetSoundNameForHash( pStartQueue->m_startSoundParams.m_nSoundScriptHash ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( snd_sos_show_startqueue.GetInt() )
|
|
{
|
|
Log_Msg( LOG_SND_OPERATORS, "STARTQUEUE: %s StartSoundEntry\n", g_pSoundEmitterSystem->GetSoundNameForHash( pStartQueue->m_startSoundParams.m_nSoundScriptHash ) );
|
|
}
|
|
S_StartSoundEntry( pStartQueue->m_startSoundParams , -1, pStartQueue->m_bFromPrestart );
|
|
|
|
// if( bHasData )
|
|
// {
|
|
// KeyValues *pStopTracksList = S_GetStopTracksKV( pStartQueue->m_startSoundParams.m_nSoundScriptHash );
|
|
//
|
|
// if( pStopTracksList )
|
|
// {
|
|
// for ( KeyValues *pValue = pStopTracksList->GetFirstValue(); pValue; pValue = pValue->GetNextValue() )
|
|
// {
|
|
// DevMsg("***STOP TRACK: %s", pValue->GetString() );
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
|
|
m_sosStartEntryQueue.Remove( i );
|
|
delete pStartQueue;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSosOperatorSystem::QueueStopChannel( int nChannelGuid, float flDelay /* = 0.0*/ )
|
|
{
|
|
SosStopQueueData_t *pStopQueue = new SosStopQueueData_t;
|
|
pStopQueue->m_nChannelGuid = nChannelGuid;
|
|
pStopQueue->m_nStopTime = g_pSoundServices->GetHostTime() + flDelay;
|
|
|
|
m_sosStopChannelQueue.AddToTail( pStopQueue );
|
|
}
|
|
bool CSosOperatorSystem::IsInStopQueue( int nChannelGuid )
|
|
{
|
|
for( int i = 0; i < m_sosStopChannelQueue.Count(); i++ )
|
|
{
|
|
SosStopQueueData_t *pStopQueue = m_sosStopChannelQueue[i];
|
|
if( nChannelGuid == pStopQueue->m_nChannelGuid )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CSosOperatorSystem::StopQueuedChannels()
|
|
{
|
|
for( int i = m_sosStopChannelQueue.Count() -1; i > -1; i-- )
|
|
{
|
|
SosStopQueueData_t *pStopQueue = m_sosStopChannelQueue[i];
|
|
if( pStopQueue->m_nStopTime <= g_pSoundServices->GetHostTime() )
|
|
{
|
|
S_StopSoundByGuid( pStopQueue->m_nChannelGuid );
|
|
m_sosStopChannelQueue.Remove( i );
|
|
delete pStopQueue;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSosOperatorSystem::SetChannelOnTrack( const char *pTrackName, channel_t *pChannel )
|
|
{
|
|
int nTrackIndex = m_vTrackDict.Find( pTrackName );
|
|
if( m_vTrackDict.IsValidIndex( nTrackIndex ) )
|
|
{
|
|
g_pSoundOperatorSystem->m_vTrackDict[nTrackIndex] = pChannel;
|
|
}
|
|
else
|
|
{
|
|
int nNewIndex = g_pSoundOperatorSystem->m_vTrackDict.Insert( pTrackName );
|
|
g_pSoundOperatorSystem->m_vTrackDict[ nNewIndex ] = pChannel;
|
|
}
|
|
|
|
}
|
|
|
|
channel_t *CSosOperatorSystem::GetChannelOnTrack( const char *pTrackName )
|
|
{
|
|
int nTrackIndex = m_vTrackDict.Find( pTrackName );
|
|
if( m_vTrackDict.IsValidIndex( nTrackIndex ) )
|
|
{
|
|
return g_pSoundOperatorSystem->m_vTrackDict[nTrackIndex];
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
HSOUNDSCRIPTHASH CSosOperatorSystem::GetSoundEntryOnTrack( const char *pTrackName )
|
|
{
|
|
channel_t *pChannel = GetChannelOnTrack( pTrackName );
|
|
if( pChannel && pChannel->sfx )
|
|
{
|
|
return pChannel->m_nSoundScriptHash;
|
|
}
|
|
else
|
|
{
|
|
return SOUNDEMITTER_INVALID_HASH;
|
|
}
|
|
}
|
|
bool CSosOperatorSystem::GetTrackDataOnTrack( const char *pTrackName, track_data_t &trackData )
|
|
{
|
|
HSOUNDSCRIPTHASH nSoundScriptHash = GetSoundEntryOnTrack( pTrackName );
|
|
if( nSoundScriptHash != SOUNDEMITTER_INVALID_HASH )
|
|
{
|
|
S_GetTrackData( nSoundScriptHash, trackData );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CSosOperatorSystem::StopChannelOnTrack( const char *pTrackName, bool bStopAll /* false */, float flStopDelay /* = 0.0 */ )
|
|
{
|
|
int nTrackIndex = m_vTrackDict.Find( pTrackName );
|
|
if( m_vTrackDict.IsValidIndex( nTrackIndex ) )
|
|
{
|
|
channel_t *pPreviousChannelOnTrack = m_vTrackDict[ nTrackIndex ];
|
|
|
|
if( pPreviousChannelOnTrack && pPreviousChannelOnTrack->sfx )
|
|
{
|
|
//DevMsg("***STOPPING: Track: %s, Entry: %s Delay: %f\n", pTrackName, g_pSoundEmitterSystem->GetSoundNameForHash( pPreviousChannelOnTrack->m_nSoundScriptHash ), flStopDelay );
|
|
if( pPreviousChannelOnTrack->m_pStackList )
|
|
{
|
|
CSosOperatorStack *pStack = pPreviousChannelOnTrack->m_pStackList->GetStack( CSosOperatorStack::SOS_UPDATE);
|
|
if( pStack )
|
|
{
|
|
pStack->SetStopType( SOS_STOP_QUEUE );
|
|
}
|
|
}
|
|
g_pSoundOperatorSystem->QueueStopChannel( pPreviousChannelOnTrack->guid, flStopDelay );
|
|
}
|
|
}
|
|
|
|
// remove a queued entry that is on the same track
|
|
if( bStopAll )
|
|
{
|
|
for( int i = m_sosStartEntryQueue.Count() -1; i > -1; i-- )
|
|
{
|
|
SosStartQueueData_t *pStartQueue = m_sosStartEntryQueue[i];
|
|
track_data_t trackData;
|
|
S_GetTrackData( pStartQueue->m_startSoundParams.m_pOperatorsKV, trackData );
|
|
if( trackData.m_nTrackNumber == nTrackIndex )
|
|
{
|
|
m_sosStartEntryQueue.Remove( i );
|
|
delete pStartQueue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSosOperatorSystem::RemoveChannelFromTracks( int nGuid )
|
|
{
|
|
// no negative guids
|
|
if( nGuid < 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
FOR_EACH_DICT( m_vTrackDict, i )
|
|
{
|
|
channel_t *pChannel = m_vTrackDict[ i ];
|
|
if( pChannel )
|
|
{
|
|
if( pChannel->guid == nGuid )
|
|
{
|
|
m_vTrackDict[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void CSosOperatorSystem::RemoveChannelFromTrack( const char *pTrackName, int nGuid )
|
|
{
|
|
// no negative guids
|
|
if( nGuid < 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int nTrackIndex = m_vTrackDict.Find( pTrackName );
|
|
if( m_vTrackDict.IsValidIndex( nTrackIndex ) )
|
|
{
|
|
channel_t *pChannelOnTrack = m_vTrackDict[ nTrackIndex ];
|
|
if( pChannelOnTrack && pChannelOnTrack->guid == nGuid )
|
|
{
|
|
m_vTrackDict[ nTrackIndex ] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
ConVar snd_sos_show_track_list("snd_sos_show_track_list", "0", FCVAR_NONE );
|
|
void CSosOperatorSystem::DEBUG_ShowTrackList( void )
|
|
{
|
|
if( !snd_sos_show_track_list.GetInt() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
FOR_EACH_DICT( m_vTrackDict, i )
|
|
{
|
|
channel_t *pChannel = m_vTrackDict[ i ];
|
|
char chanStr[128];
|
|
sprintf( chanStr, "Channel %i : %s = %s", i, m_vTrackDict.GetElementName( i ), pChannel ? g_pSoundEmitterSystem->GetSoundNameForHash( pChannel->m_nSoundScriptHash ) : "empty" );
|
|
CDebugOverlay::AddScreenTextOverlay( 0.01, 0.2 + (0.012 * (float) i) , 0.5, 200, 200, 200, 255, chanStr );
|
|
}
|
|
}
|
|
|
|
//Returns a valid id into the string table
|
|
bool CSosOperatorSystem::SetOpVarFloat( const char *pString, float flVariable )
|
|
{
|
|
int nIndex = m_sosOpVarFloatMap.Find( pString );
|
|
if ( m_sosOpVarFloatMap.IsValidIndex( nIndex ) )
|
|
{
|
|
m_sosOpVarFloatMap[nIndex] = flVariable;
|
|
return true;
|
|
}
|
|
nIndex = m_sosOpVarFloatMap.Insert( pString );
|
|
|
|
if ( m_sosOpVarFloatMap.IsValidIndex( nIndex ) )
|
|
{
|
|
m_sosOpVarFloatMap[ nIndex ] = flVariable;
|
|
return true;
|
|
}
|
|
|
|
DevWarning( "SOS System Warning: Unable to set or create float variable %s\n", pString );
|
|
return false;
|
|
|
|
// int stringId = m_sosFloatOpvarMap.Find( pString );
|
|
// if ( stringId != m_sosFloatOpvarMap.InvalidIndex() )
|
|
// {
|
|
// // found in pool
|
|
// m_sosFloatOpvarMap[stringId] = flVariable;
|
|
// return true;
|
|
// }
|
|
// stringId = m_sosFloatOpvarMap.AddString( pString );
|
|
// if ( stringId != m_sosFloatOpvarMap.InvalidIndex() )
|
|
// {
|
|
// // found in pool
|
|
// m_sosFloatOpvarMap[stringId] = flVariable;
|
|
// return true;
|
|
// }
|
|
//
|
|
// DevWarning( "SOS System Warning: Unable to set or create float variable %s\n", pString );
|
|
// return false;
|
|
|
|
}
|
|
|
|
// Returns a valid id into the string table
|
|
bool CSosOperatorSystem::GetOpVarFloat( const char *pString, float &flVariable )
|
|
{
|
|
|
|
int nIndex = m_sosOpVarFloatMap.Find( pString );
|
|
if ( !m_sosOpVarFloatMap.IsValidIndex( nIndex ) )
|
|
{
|
|
// error
|
|
return false;
|
|
}
|
|
float flTest = m_sosOpVarFloatMap.Element( nIndex );
|
|
flVariable = flTest;
|
|
return true;
|
|
|
|
|
|
// int stringId = m_sosFloatOpvarMap.Find( pString );
|
|
// if ( stringId != m_sosFloatOpvarMap.InvalidIndex() )
|
|
// {
|
|
// // found in pool
|
|
// flVariable = m_sosFloatOpvarMap[stringId];
|
|
// return true;
|
|
// }
|
|
// return false;
|
|
|
|
}
|
|
|
|
ConVar snd_sos_show_opvar_list("snd_sos_show_opvar_list", "0", FCVAR_NONE );
|
|
void CSosOperatorSystem::DEBUG_ShowOpvarList( void )
|
|
{
|
|
if( !snd_sos_show_opvar_list.GetInt() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
int nCount = m_sosOpVarFloatMap.Count();
|
|
|
|
char opVarStr[128];
|
|
sprintf( opVarStr, "Opvars %i", nCount );
|
|
|
|
CDebugOverlay::AddScreenTextOverlay( 0.01, 0.5, 0.5, 200, 200, 200, 255, opVarStr );
|
|
|
|
|
|
for ( int i = 0 ; i < nCount; i++ )
|
|
{
|
|
if( m_sosOpVarFloatMap.IsValidIndex( i ) )
|
|
{
|
|
float flValue = m_sosOpVarFloatMap[ i ];
|
|
char chanStr[128];
|
|
sprintf( chanStr, "- %s = %f", m_sosOpVarFloatMap.GetElementName( i ), flValue );
|
|
CDebugOverlay::AddScreenTextOverlay( 0.01, 0.512 + (0.012 * (float) i) , 0.5, 200, 200, 200, 255, chanStr );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CSosOperatorSystem::Update()
|
|
{
|
|
m_sosEntryBlockList.Update();
|
|
}
|
|
|
|
|
|
void CSosOperatorSystem::Shutdown()
|
|
{
|
|
|
|
}
|
|
|
|
CSosOperatorSystem *CSosOperatorSystem::GetSoundOperatorSystem()
|
|
{
|
|
static CSosOperatorSystem s_SoundOperatorSystem;
|
|
return &s_SoundOperatorSystem;
|
|
}
|
|
|
|
void S_SOSFlush()
|
|
{
|
|
g_pSoundOperatorSystem->Flush();
|
|
}
|
|
|
|
|
|
ConCommand snd_sos_flush_operators( "snd_sos_flush_operators", S_SOSFlush, "Flush and re-parse the sound operator system", FCVAR_CHEAT );
|
|
|
|
bool S_SOSSetOpvarFloat( const char *pOpVarName, float flValue )
|
|
{
|
|
if( g_pSoundOperatorSystem )
|
|
{
|
|
return g_pSoundOperatorSystem->SetOpVarFloat( pOpVarName,flValue );
|
|
}
|
|
else
|
|
{
|
|
DevMsg("SOS Error: g_pSoundOperatorSystem used via SOSSetOpvarFloat before it's initialized.");
|
|
return false;
|
|
}
|
|
}
|
|
bool S_SOSGetOpvarFloat( const char *pOpVarName, float &flValue )
|
|
{
|
|
if( g_pSoundOperatorSystem )
|
|
{
|
|
return g_pSoundOperatorSystem->GetOpVarFloat( pOpVarName, flValue );
|
|
}
|
|
else
|
|
{
|
|
DevMsg("SOS Error: g_pSoundOperatorSystem used via SOSGetOpvarFloat before it's initialized.");
|
|
return false;
|
|
}
|
|
}
|