|
|
//========= Copyright � 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client handler implementations for instruction players how to play
//
//=============================================================================//
#include "cbase.h"
#include "c_keyvalue_saver.h"
#include "filesystem.h"
#include "ixboxsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// Key Value Saver auto game system instantiation
C_KeyValueSaver g_KeyValueSaver[ MAX_SPLITSCREEN_PLAYERS ]; C_KeyValueSaver &KeyValueSaver() { ASSERT_LOCAL_PLAYER_RESOLVABLE(); return g_KeyValueSaver[ GET_ACTIVE_SPLITSCREEN_SLOT() ]; }
// C_KeyValueSaver
//
bool C_KeyValueSaver::Init( void ) { // Make sure split slot is up to date
for ( int i = 0 ; i < MAX_SPLITSCREEN_PLAYERS; ++i ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( i ); if ( &KeyValueSaver() == this ) { SetSlot( i ); break; } }
ACTIVE_SPLITSCREEN_PLAYER_GUARD( m_nSplitScreenSlot );
if ( !IsGameConsole() ) { ListenForGameEvent( "round_end" ); ListenForGameEvent( "map_transition" ); ListenForGameEvent( "game_newmap" ); }
return true; }
void C_KeyValueSaver::Shutdown( void ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( m_nSplitScreenSlot );
WriteAllDirtyKeyValues();
for ( int i = 0; i < m_KeyValueData.Count(); ++i ) { m_KeyValueData[ i ].pKeyValues->deleteThis(); m_KeyValueData[ i ].pKeyValues = NULL; }
m_KeyValueData.RemoveAll();
// Stop listening for events
StopListeningForAllEvents(); }
void C_KeyValueSaver::Update( float frametime ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( m_nSplitScreenSlot );
if ( IsGameConsole() ) { // On X360 we want to save when they're not connected
if ( !engine->IsInGame() ) { // They aren't in game
WriteAllDirtyKeyValues(); } else { const char *levelName = engine->GetLevelName(); if ( levelName && levelName[0] && engine->IsLevelMainMenuBackground() ) { // The are in game, but it's a background map
WriteAllDirtyKeyValues(); } } } }
void C_KeyValueSaver::FireGameEvent( IGameEvent *event ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( m_nSplitScreenSlot );
const char *name = event->GetName();
if ( !IsGameConsole() ) { if ( Q_strcmp( name, "round_end" ) == 0 || Q_strcmp( name, "map_transition" ) == 0 || Q_strcmp( name, "game_newmap" ) == 0 ) { // Good place to save
WriteAllDirtyKeyValues(); } } }
bool C_KeyValueSaver::InitKeyValues( const char *pchFileName, KeyValueBuilder funcKeyValueBuilder ) { KeyValueSaverData *pKeyValueData = FindKeyValueData( pchFileName ); if ( pKeyValueData ) { // Already got one by this name
return false; }
int nNew = m_KeyValueData.AddToTail(); pKeyValueData = &(m_KeyValueData[ nNew ]); V_strcpy( pKeyValueData->szFileName, pchFileName ); pKeyValueData->bDirtySaveData = false; pKeyValueData->pKeyValues = NULL; pKeyValueData->funcKeyValueBuilder = funcKeyValueBuilder;
return true; }
bool C_KeyValueSaver::WriteDirtyKeyValues( const char *pchFileName, bool bForceWrite /*= false*/ ) { return WriteDirtyKeyValues( FindKeyValueData( pchFileName ), bForceWrite ); }
KeyValues * C_KeyValueSaver::GetKeyValues( const char *pchFileName, bool bForceReread /*= false*/ ) { KeyValueSaverData *pKeyValueData = FindKeyValueData( pchFileName );
if ( pKeyValueData ) { if ( !pKeyValueData->pKeyValues ) { bForceReread = true; }
if ( bForceReread ) { if ( !ReadKeyValues( pKeyValueData ) ) { return NULL; } }
return pKeyValueData->pKeyValues; }
return NULL; }
void C_KeyValueSaver::MarkKeyValuesDirty( const char *pchFileName ) { KeyValueSaverData *pKeyValueData = FindKeyValueData( pchFileName ); if ( !pKeyValueData ) return;
pKeyValueData->bDirtySaveData = true; }
bool C_KeyValueSaver::ReadKeyValues( KeyValueSaverData *pKeyValueData ) { #if !defined( CSTRIKE15 )
#ifdef _GAMECONSOLE
DevMsg( "Read Game Instructor for splitscreen slot %d\n", m_nSplitScreenSlot );
if ( m_nSplitScreenSlot < 0 ) return false;
if ( m_nSplitScreenSlot >= (int) XBX_GetNumGameUsers() ) return false; #endif
char szFilename[_MAX_PATH]; Q_snprintf( szFilename, sizeof( szFilename ), VarArgs( "save/%s", pKeyValueData->szFileName ) ); if ( pKeyValueData->pKeyValues ) { pKeyValueData->pKeyValues->deleteThis(); pKeyValueData->pKeyValues = NULL; }
pKeyValueData->pKeyValues = new KeyValues( "KeyValueSaverData" );
if ( pKeyValueData->pKeyValues->LoadFromFile( g_pFullFileSystem, szFilename, NULL ) ) { return true; } #endif // !CSTRIKE15
// Couldn't read from the file
return false; }
bool C_KeyValueSaver::WriteDirtyKeyValues( KeyValueSaverData *pKeyValueData, bool bForceWrite /*= false*/ ) { if ( engine->IsPlayingDemo() ) return false;
if ( !pKeyValueData ) return false;
if ( !pKeyValueData->bDirtySaveData && !bForceWrite ) return true;
// Always mark as clean state to avoid re-entry on
// subsequent frames when storage device might be
// in a yet-unmounted state.
pKeyValueData->bDirtySaveData = false;
#ifdef _GAMECONSOLE
DevMsg( "Write KeyValueSaver for splitscreen slot %d at time: %.1f\n", m_nSplitScreenSlot, Plat_FloatTime() );
if ( m_nSplitScreenSlot < 0 ) return false;
if ( m_nSplitScreenSlot >= (int) XBX_GetNumGameUsers() ) return false; #endif
// Build key value data to save
if ( pKeyValueData->pKeyValues ) { pKeyValueData->pKeyValues->deleteThis(); pKeyValueData->pKeyValues = NULL; }
pKeyValueData->pKeyValues = new KeyValues( "KeyValueSaverData" );
// Build key values
pKeyValueData->funcKeyValueBuilder( pKeyValueData->pKeyValues );
#if defined( CSTRIKE15 )
// The key values are saved to the title data block in the callback above.
return true; #else
// Save it!
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
pKeyValueData->pKeyValues->RecursiveSaveToFile( buf, 0 );
char szFilename[_MAX_PATH]; Q_snprintf( szFilename, sizeof( szFilename ), VarArgs( "save/%s", pKeyValueData->szFileName ) ); filesystem->CreateDirHierarchy( "save", "MOD" ); bool bWriteSuccess = filesystem->WriteFile( szFilename, "MOD", buf ); return bWriteSuccess; #endif
}
void C_KeyValueSaver::WriteAllDirtyKeyValues( void ) { for ( int i = 0; i < m_KeyValueData.Count(); ++i ) { WriteDirtyKeyValues( &(m_KeyValueData[ i ]) ); } }
KeyValueSaverData * C_KeyValueSaver::FindKeyValueData( const char *pchFileName ) { for ( int i = 0; i < m_KeyValueData.Count(); ++i ) { KeyValueSaverData *pKeyValueData = &(m_KeyValueData[ i ]); if ( V_strcmp( pKeyValueData->szFileName, pchFileName ) == 0 ) { return pKeyValueData; } }
return NULL; }
|