mirror of
https://github.com/dhewm/dhewm3.git
synced 2025-06-03 10:21:14 +00:00
hello world
This commit is contained in:
commit
fb1609f554
2155 changed files with 1017022 additions and 0 deletions
328
neo/framework/DemoFile.cpp
Normal file
328
neo/framework/DemoFile.cpp
Normal file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../idlib/precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
idCVar idDemoFile::com_logDemos( "com_logDemos", "0", CVAR_SYSTEM | CVAR_BOOL, "Write demo.log with debug information in it" );
|
||||
idCVar idDemoFile::com_compressDemos( "com_compressDemos", "1", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE, "Compression scheme for demo files\n0: None (Fast, large files)\n1: LZW (Fast to compress, Fast to decompress, medium/small files)\n2: LZSS (Slow to compress, Fast to decompress, small files)\n3: Huffman (Fast to compress, Slow to decompress, medium files)\nSee also: The 'CompressDemo' command" );
|
||||
idCVar idDemoFile::com_preloadDemos( "com_preloadDemos", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_ARCHIVE, "Load the whole demo in to RAM before running it" );
|
||||
|
||||
#define DEMO_MAGIC GAME_NAME " RDEMO"
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::idDemoFile
|
||||
================
|
||||
*/
|
||||
idDemoFile::idDemoFile() {
|
||||
f = NULL;
|
||||
fLog = NULL;
|
||||
log = false;
|
||||
fileImage = NULL;
|
||||
compressor = NULL;
|
||||
writing = false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::~idDemoFile
|
||||
================
|
||||
*/
|
||||
idDemoFile::~idDemoFile() {
|
||||
Close();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::AllocCompressor
|
||||
================
|
||||
*/
|
||||
idCompressor *idDemoFile::AllocCompressor( int type ) {
|
||||
switch ( type ) {
|
||||
case 0: return idCompressor::AllocNoCompression();
|
||||
default:
|
||||
case 1: return idCompressor::AllocLZW();
|
||||
case 2: return idCompressor::AllocLZSS();
|
||||
case 3: return idCompressor::AllocHuffman();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::OpenForReading
|
||||
================
|
||||
*/
|
||||
bool idDemoFile::OpenForReading( const char *fileName ) {
|
||||
static const int magicLen = sizeof(DEMO_MAGIC) / sizeof(DEMO_MAGIC[0]);
|
||||
char magicBuffer[magicLen];
|
||||
int compression;
|
||||
int fileLength;
|
||||
|
||||
Close();
|
||||
|
||||
f = fileSystem->OpenFileRead( fileName );
|
||||
if ( !f ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fileLength = f->Length();
|
||||
|
||||
if ( com_preloadDemos.GetBool() ) {
|
||||
fileImage = (byte *)Mem_Alloc( fileLength );
|
||||
f->Read( fileImage, fileLength );
|
||||
fileSystem->CloseFile( f );
|
||||
f = new idFile_Memory( va( "preloaded(%s)", fileName ), (const char *)fileImage, fileLength );
|
||||
}
|
||||
|
||||
if ( com_logDemos.GetBool() ) {
|
||||
fLog = fileSystem->OpenFileWrite( "demoread.log" );
|
||||
}
|
||||
|
||||
writing = false;
|
||||
|
||||
f->Read(magicBuffer, magicLen);
|
||||
if ( memcmp(magicBuffer, DEMO_MAGIC, magicLen) == 0 ) {
|
||||
f->ReadInt( compression );
|
||||
} else {
|
||||
// Ideally we would error out if the magic string isn't there,
|
||||
// but for backwards compatibility we are going to assume it's just an uncompressed demo file
|
||||
compression = 0;
|
||||
f->Rewind();
|
||||
}
|
||||
|
||||
compressor = AllocCompressor( compression );
|
||||
compressor->Init( f, false, 8 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::SetLog
|
||||
================
|
||||
*/
|
||||
void idDemoFile::SetLog(bool b, const char *p) {
|
||||
log = b;
|
||||
if (p) {
|
||||
logStr = p;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::Log
|
||||
================
|
||||
*/
|
||||
void idDemoFile::Log(const char *p) {
|
||||
if ( fLog && p && *p ) {
|
||||
fLog->Write( p, strlen(p) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::OpenForWriting
|
||||
================
|
||||
*/
|
||||
bool idDemoFile::OpenForWriting( const char *fileName ) {
|
||||
Close();
|
||||
|
||||
f = fileSystem->OpenFileWrite( fileName );
|
||||
if ( f == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( com_logDemos.GetBool() ) {
|
||||
fLog = fileSystem->OpenFileWrite( "demowrite.log" );
|
||||
}
|
||||
|
||||
writing = true;
|
||||
|
||||
f->Write(DEMO_MAGIC, sizeof(DEMO_MAGIC));
|
||||
f->WriteInt( com_compressDemos.GetInteger() );
|
||||
f->Flush();
|
||||
|
||||
compressor = AllocCompressor( com_compressDemos.GetInteger() );
|
||||
compressor->Init( f, true, 8 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::Close
|
||||
================
|
||||
*/
|
||||
void idDemoFile::Close() {
|
||||
if ( writing && compressor ) {
|
||||
compressor->FinishCompress();
|
||||
}
|
||||
|
||||
if ( f ) {
|
||||
fileSystem->CloseFile( f );
|
||||
f = NULL;
|
||||
}
|
||||
if ( fLog ) {
|
||||
fileSystem->CloseFile( fLog );
|
||||
fLog = NULL;
|
||||
}
|
||||
if ( fileImage ) {
|
||||
Mem_Free( fileImage );
|
||||
fileImage = NULL;
|
||||
}
|
||||
if ( compressor ) {
|
||||
delete compressor;
|
||||
compressor = NULL;
|
||||
}
|
||||
|
||||
demoStrings.DeleteContents( true );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::ReadHashString
|
||||
================
|
||||
*/
|
||||
const char *idDemoFile::ReadHashString() {
|
||||
int index;
|
||||
|
||||
if ( log && fLog ) {
|
||||
const char *text = va( "%s > Reading hash string\n", logStr.c_str() );
|
||||
fLog->Write( text, strlen( text ) );
|
||||
}
|
||||
|
||||
ReadInt( index );
|
||||
|
||||
if ( index == -1 ) {
|
||||
// read a new string for the table
|
||||
idStr *str = new idStr;
|
||||
|
||||
idStr data;
|
||||
ReadString( data );
|
||||
*str = data;
|
||||
|
||||
demoStrings.Append( str );
|
||||
|
||||
return *str;
|
||||
}
|
||||
|
||||
if ( index < -1 || index >= demoStrings.Num() ) {
|
||||
Close();
|
||||
common->Error( "demo hash index out of range" );
|
||||
}
|
||||
|
||||
return demoStrings[index]->c_str();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::WriteHashString
|
||||
================
|
||||
*/
|
||||
void idDemoFile::WriteHashString( const char *str ) {
|
||||
if ( log && fLog ) {
|
||||
const char *text = va( "%s > Writing hash string\n", logStr.c_str() );
|
||||
fLog->Write( text, strlen( text ) );
|
||||
}
|
||||
// see if it is already in the has table
|
||||
for ( int i = 0 ; i < demoStrings.Num() ; i++ ) {
|
||||
if ( !strcmp( demoStrings[i]->c_str(), str ) ) {
|
||||
WriteInt( i );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add it to our table and the demo table
|
||||
idStr *copy = new idStr( str );
|
||||
//common->Printf( "hash:%i = %s\n", demoStrings.Num(), str );
|
||||
demoStrings.Append( copy );
|
||||
int cmd = -1;
|
||||
WriteInt( cmd );
|
||||
WriteString( str );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::ReadDict
|
||||
================
|
||||
*/
|
||||
void idDemoFile::ReadDict( idDict &dict ) {
|
||||
int i, c;
|
||||
idStr key, val;
|
||||
|
||||
dict.Clear();
|
||||
ReadInt( c );
|
||||
for ( i = 0; i < c; i++ ) {
|
||||
key = ReadHashString();
|
||||
val = ReadHashString();
|
||||
dict.Set( key, val );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::WriteDict
|
||||
================
|
||||
*/
|
||||
void idDemoFile::WriteDict( const idDict &dict ) {
|
||||
int i, c;
|
||||
|
||||
c = dict.GetNumKeyVals();
|
||||
WriteInt( c );
|
||||
for ( i = 0; i < c; i++ ) {
|
||||
WriteHashString( dict.GetKeyVal( i )->GetKey() );
|
||||
WriteHashString( dict.GetKeyVal( i )->GetValue() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::Read
|
||||
================
|
||||
*/
|
||||
int idDemoFile::Read( void *buffer, int len ) {
|
||||
int read = compressor->Read( buffer, len );
|
||||
if ( read == 0 && len >= 4 ) {
|
||||
*(demoSystem_t *)buffer = DS_FINISHED;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idDemoFile::Write
|
||||
================
|
||||
*/
|
||||
int idDemoFile::Write( const void *buffer, int len ) {
|
||||
return compressor->Write( buffer, len );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue