diff options
Diffstat (limited to 'utils/demoinfo/tooldemofile.cpp')
| -rw-r--r-- | utils/demoinfo/tooldemofile.cpp | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/utils/demoinfo/tooldemofile.cpp b/utils/demoinfo/tooldemofile.cpp new file mode 100644 index 0000000..20abf88 --- /dev/null +++ b/utils/demoinfo/tooldemofile.cpp @@ -0,0 +1,295 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include <utlbuffer.h> +#include "tooldemofile.h" +#include "filesystem.h" +#include "demofile/demoformat.h" + +extern IBaseFileSystem *g_pFileSystem; + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CToolDemoFile::CToolDemoFile() +{ + m_hDemoFile = FILESYSTEM_INVALID_HANDLE; +} + +CToolDemoFile::~CToolDemoFile() +{ + if ( IsOpen() ) + { + Close(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CToolDemoFile::ReadSequenceInfo(int &nSeqNrIn, int &nSeqNrOut) +{ + Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ); + + g_pFileSystem->Read( &nSeqNrIn, sizeof(int), m_hDemoFile ); + g_pFileSystem->Read( &nSeqNrOut, sizeof(int), m_hDemoFile ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CToolDemoFile::ReadCmdInfo( democmdinfo_t& info ) +{ + Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ); + g_pFileSystem->Read( &info, sizeof( democmdinfo_t ), m_hDemoFile ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : cmd - +// dt - +// frame - +//----------------------------------------------------------------------------- +void CToolDemoFile::ReadCmdHeader( unsigned char& cmd, int& tick ) +{ + Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ); + + // Read the command + int r = g_pFileSystem->Read ( &cmd, sizeof(byte), m_hDemoFile ); + + if ( r <=0 ) + { + Warning("Missing end tag in demo file.\n"); + cmd = dem_stop; + return; + } + + Assert( cmd >= 1 && cmd <= dem_lastcmd ); + + // Read the timestamp + g_pFileSystem->Read ( &tick, sizeof(int), m_hDemoFile ); + + tick = LittleDWord( tick ); +} + +const char *CToolDemoFile::ReadConsoleCommand() +{ + static char cmdstring[1024]; + + ReadRawData( cmdstring, sizeof(cmdstring) ); + + return cmdstring; +} + +unsigned int CToolDemoFile::GetCurPos() +{ + if ( m_hDemoFile == FILESYSTEM_INVALID_HANDLE ) + return 0; + + return g_pFileSystem->Tell( m_hDemoFile ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : expected_length - +// &demofile - +//----------------------------------------------------------------------------- +int CToolDemoFile::ReadNetworkDataTables( CUtlBuffer *buf ) +{ + Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ); + char data[ 1024 ]; + int length; + + g_pFileSystem->Read( &length, sizeof( int ), m_hDemoFile ); + + while( length > 0 ) + { + int chunk = min( length, 1024 ); + g_pFileSystem->Read( data, chunk, m_hDemoFile ); + length -= chunk; + + if ( buf ) + { + buf->Put( data, chunk ); + } + } + + return length; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : discard - +//----------------------------------------------------------------------------- +int CToolDemoFile::ReadUserCmd( char *buffer, int &size ) +{ + Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ); + + int outgoing_sequence; + + g_pFileSystem->Read( &outgoing_sequence, sizeof( int ), m_hDemoFile ); + + size = ReadRawData( buffer, size ); + + return outgoing_sequence; +} + +//----------------------------------------------------------------------------- +// Purpose: Rewind from the current spot by the time stamp, byte code and frame counter offsets +//----------------------------------------------------------------------------- +void CToolDemoFile::SeekTo( int position ) +{ + Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ); + g_pFileSystem->Seek( m_hDemoFile, position, FILESYSTEM_SEEK_HEAD ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +int CToolDemoFile::ReadRawData( char *buffer, int length ) +{ + Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ); + + int size; + + // read length of data block + g_pFileSystem->Read( &size, sizeof( int ), m_hDemoFile ); + + if ( buffer && (length < size) ) + { + DevMsg("CToolDemoFile::ReadRawData: buffe overflow (%i).\n", size ); + return -1; + } + + if ( buffer ) + { + if ( length < size ) + { + // given buffer is too small + DevMsg("CToolDemoFile::ReadRawData: buffe overflow (%i).\n", size ); + g_pFileSystem->Seek( m_hDemoFile, size, FILESYSTEM_SEEK_CURRENT ); + size = -1; + } + else + { + // read data into buffer + int r = g_pFileSystem->Read( buffer, size, m_hDemoFile ); + if ( r != size ) + { + Warning( "Error reading demo message data.\n"); + return -1; + } + } + } + else + { + // just skip it + g_pFileSystem->Seek( m_hDemoFile, size, FILESYSTEM_SEEK_CURRENT ); + } + + return size; +} + +demoheader_t *CToolDemoFile::ReadDemoHeader() +{ + if ( m_hDemoFile == FILESYSTEM_INVALID_HANDLE ) + return NULL; // file not open + + // goto file start + g_pFileSystem->Seek(m_hDemoFile, 0, FILESYSTEM_SEEK_HEAD); + + Q_memset( &m_DemoHeader, 0, sizeof(m_DemoHeader) ); + + int r = g_pFileSystem->Read( &m_DemoHeader, sizeof(demoheader_t), m_hDemoFile ); + + if ( r != sizeof(demoheader_t) ) + return NULL; // reading failed + + if ( Q_strcmp ( m_DemoHeader.demofilestamp, DEMO_HEADER_ID ) ) + { + Warning( "%s has invalid demo header ID.\n", m_szFileName ); + return NULL; + } + + /* +// The current network protocol version. Changing this makes clients and servers incompatible +#define PROTOCOL_VERSION 7 + + if ( m_DemoHeader.networkprotocol != PROTOCOL_VERSION ) + { + Warning ("ERROR: demo network protocol %i outdated, engine version is %i \n", + m_DemoHeader.networkprotocol, PROTOCOL_VERSION ); + + return NULL; + } + */ + + if ( m_DemoHeader.demoprotocol != DEMO_PROTOCOL ) + { + Warning ("ERROR: demo file protocol %i outdated, engine version is %i \n", + m_DemoHeader.demoprotocol, DEMO_PROTOCOL ); + + return NULL; + } + + return &m_DemoHeader; +} + +bool CToolDemoFile::Open(const char *name, bool bReadOnly) +{ + if ( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ) + { + Warning ("CToolDemoFile::Open: file already open.\n"); + return false; + } + + m_szFileName[0] = 0; // clear name + Q_memset( &m_DemoHeader, 0, sizeof(m_DemoHeader) ); // and demo header + + if ( bReadOnly ) + { + // open existing file for reading only + m_hDemoFile = g_pFileSystem->Open (name, "rb", "GAME" ); + } + else + { + // create new file for writing only + m_hDemoFile = g_pFileSystem->Open (name, "wb", "GAME" ); + } + + if ( m_hDemoFile == FILESYSTEM_INVALID_HANDLE ) + { + Warning ("CToolDemoFile::Open: couldn't open file %s for %s.\n", + name, bReadOnly?"reading":"writing" ); + return false; + } + + Q_strncpy( m_szFileName, name, sizeof(m_szFileName) ); + + return true; +} + +bool CToolDemoFile::IsOpen() +{ + return m_hDemoFile != FILESYSTEM_INVALID_HANDLE; +} + +void CToolDemoFile::Close() +{ + if ( m_hDemoFile != FILESYSTEM_INVALID_HANDLE ) + { + g_pFileSystem->Close(m_hDemoFile); + m_hDemoFile = FILESYSTEM_INVALID_HANDLE; + } +} + +int CToolDemoFile::GetSize() +{ + return g_pFileSystem->Size( m_hDemoFile ); +} + |