2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition 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 BFG Edition 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 .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# ifndef __FILE_SAVEGAME_H__
# define __FILE_SAVEGAME_H__
2012-11-27 22:23:32 +00:00
# include "../libs/zlib/zlib.h"
2012-11-26 18:58:24 +00:00
// Listing of the types of files within a savegame package
2012-11-28 15:47:07 +00:00
enum saveGameType_t
{
2012-11-26 18:58:24 +00:00
SAVEGAMEFILE_NONE = 0 ,
SAVEGAMEFILE_TEXT = BIT ( 0 ) , // implies that no checksum will be used
SAVEGAMEFILE_BINARY = BIT ( 1 ) , // implies that a checksum will also be used
SAVEGAMEFILE_COMPRESSED = BIT ( 2 ) ,
SAVEGAMEFILE_PIPELINED = BIT ( 3 ) ,
SAVEGAMEFILE_THUMB = BIT ( 4 ) , // for special processing on certain platforms
SAVEGAMEFILE_BKGRND_IMAGE = BIT ( 5 ) , // for special processing on certain platforms, large background used on PS3
SAVEGAMEFILE_AUTO_DELETE = BIT ( 6 ) , // to be deleted automatically after completed
SAVEGAMEFILE_OPTIONAL = BIT ( 7 ) // if this flag is not set and missing, there is an error
} ;
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2012-11-28 15:47:07 +00:00
idFile_SaveGame
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
class idFile_SaveGame : public idFile_Memory
{
2012-11-26 18:58:24 +00:00
public :
idFile_SaveGame ( ) : type ( SAVEGAMEFILE_NONE ) , error ( false ) { }
2012-11-28 15:47:07 +00:00
idFile_SaveGame ( const char * _name ) : idFile_Memory ( _name ) , type ( SAVEGAMEFILE_NONE ) , error ( false ) { }
idFile_SaveGame ( const char * _name , int type_ ) : idFile_Memory ( _name ) , type ( type_ ) , error ( false ) { }
2012-11-26 18:58:24 +00:00
virtual ~ idFile_SaveGame ( ) { }
2012-11-28 15:47:07 +00:00
bool operator = = ( const idFile_SaveGame & other ) const
{
2012-11-26 18:58:24 +00:00
return idStr : : Icmp ( GetName ( ) , other . GetName ( ) ) = = 0 ;
}
2012-11-28 15:47:07 +00:00
bool operator = = ( const char * _name ) const
{
2012-11-26 18:58:24 +00:00
return idStr : : Icmp ( GetName ( ) , _name ) = = 0 ;
}
2012-11-28 15:47:07 +00:00
void SetNameAndType ( const char * _name , int _type )
{
2012-11-26 18:58:24 +00:00
name = _name ;
type = _type ;
}
public : // TODO_KC_CR for now...
int type ; // helps platform determine what to do with the file (encrypt, checksum, etc.)
bool error ; // when loading, this is set if there is a problem
} ;
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
idFile_SaveGamePipelined uses threads to pipeline overlap compression and IO
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
class idSGFreadThread ;
class idSGFwriteThread ;
class idSGFdecompressThread ;
class idSGFcompressThread ;
2012-11-28 15:47:07 +00:00
struct blockForIO_t
{
byte * data ;
2012-11-26 18:58:24 +00:00
size_t bytes ;
} ;
2012-11-28 15:47:07 +00:00
class idFile_SaveGamePipelined : public idFile
{
2012-11-26 18:58:24 +00:00
public :
// The buffers each hold two blocks of data, so one block can be operated on by
// the next part of the generate / compress / IO pipeline. The factor of two
// size difference between the uncompressed and compressed blocks is unrelated
// to the fact that there are two blocks in each buffer.
static const int COMPRESSED_BLOCK_SIZE = 128 * 1024 ;
static const int UNCOMPRESSED_BLOCK_SIZE = 256 * 1024 ;
2012-11-28 15:47:07 +00:00
idFile_SaveGamePipelined ( ) ;
2012-11-26 18:58:24 +00:00
virtual ~ idFile_SaveGamePipelined ( ) ;
2012-11-28 15:47:07 +00:00
bool OpenForReading ( const char * const filename , bool useNativeFile ) ;
bool OpenForWriting ( const char * const filename , bool useNativeFile ) ;
bool OpenForReading ( idFile * file ) ;
bool OpenForWriting ( idFile * file ) ;
2012-11-26 18:58:24 +00:00
// Finish any reading or writing.
void Finish ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Abort any reading or writing.
void Abort ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Cancel any reading or writing for app termination
2012-11-28 15:47:07 +00:00
static void CancelToTerminate ( )
{
cancelToTerminate = true ;
}
2012-11-26 18:58:24 +00:00
bool ReadBuildVersion ( ) ;
2012-11-28 15:47:07 +00:00
const char * GetBuildVersion ( ) const
{
return buildVersion ;
}
2012-11-26 18:58:24 +00:00
bool ReadSaveFormatVersion ( ) ;
2012-11-28 15:47:07 +00:00
int GetSaveFormatVersion ( ) const
{
return saveFormatVersion ;
}
2012-11-26 18:58:24 +00:00
int GetPointerSize ( ) const ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//------------------------
// idFile Interface
//------------------------
2012-11-28 15:47:07 +00:00
virtual const char * GetName ( ) const
{
return name . c_str ( ) ;
}
virtual const char * GetFullPath ( ) const
{
return name . c_str ( ) ;
}
virtual int Read ( void * buffer , int len ) ;
virtual int Write ( const void * buffer , int len ) ;
2012-11-26 18:58:24 +00:00
// this file is strictly streaming, you can't seek at all
2012-11-28 15:47:07 +00:00
virtual int Length ( ) const
{
2012-12-17 11:24:31 +00:00
// RB: 64 bit fix, we don't need support for files bigger than 2 GB
return ( int ) compressedLength ;
// RB end
2012-11-28 15:47:07 +00:00
}
virtual void SetLength ( size_t len )
{
compressedLength = len ;
}
virtual int Tell ( ) const
{
assert ( 0 ) ;
return 0 ;
}
virtual int Seek ( long offset , fsOrigin_t origin )
{
assert ( 0 ) ;
return 0 ;
}
virtual ID_TIME_T Timestamp ( ) const
{
return 0 ;
}
2012-11-26 18:58:24 +00:00
//------------------------
// These can be used by a background thread to read/write data
// when the file was opened with 'useNativeFile' set to false.
//------------------------
2012-11-28 15:47:07 +00:00
enum mode_t
{
2012-11-26 18:58:24 +00:00
CLOSED ,
WRITE ,
READ
} ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Get the file mode: read/write.
2012-11-28 15:47:07 +00:00
mode_t GetMode ( ) const
{
return mode ;
}
2012-11-26 18:58:24 +00:00
// Called by a background thread to get the next block to be written out.
// This may block until a block has been made available through the pipeline.
// Pass in NULL to notify the last write failed.
// Returns false if there are no more blocks.
2012-11-28 15:47:07 +00:00
bool NextWriteBlock ( blockForIO_t * block ) ;
2012-11-26 18:58:24 +00:00
// Called by a background thread to get the next block to read data into and to
// report the number of bytes written to the previous block.
// This may block until space is available to place the next block.
// Pass in NULL to notify the end of the file was reached.
// Returns false if there are no more blocks.
2012-11-28 15:47:07 +00:00
bool NextReadBlock ( blockForIO_t * block , size_t lastReadBytes ) ;
2012-11-26 18:58:24 +00:00
private :
friend class idSGFreadThread ;
friend class idSGFwriteThread ;
friend class idSGFdecompressThread ;
friend class idSGFcompressThread ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStr name ; // Name of the file.
idStr osPath ; // OS path.
mode_t mode ; // Open mode.
size_t compressedLength ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
static const int COMPRESSED_BUFFER_SIZE = COMPRESSED_BLOCK_SIZE * 2 ;
static const int UNCOMPRESSED_BUFFER_SIZE = UNCOMPRESSED_BLOCK_SIZE * 2 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
byte uncompressed [ UNCOMPRESSED_BUFFER_SIZE ] ;
size_t uncompressedProducedBytes ; // not masked
size_t uncompressedConsumedBytes ; // not masked
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
byte compressed [ COMPRESSED_BUFFER_SIZE ] ;
size_t compressedProducedBytes ; // not masked
size_t compressedConsumedBytes ; // not masked
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//------------------------
// These variables are used to pass data between threads in a thread-safe manner.
//------------------------
2012-11-28 15:47:07 +00:00
byte * dataZlib ;
2012-11-26 18:58:24 +00:00
size_t bytesZlib ;
2012-11-28 15:47:07 +00:00
byte * dataIO ;
2012-11-26 18:58:24 +00:00
size_t bytesIO ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//------------------------
// These variables are used by CompressBlock() and DecompressBlock().
//------------------------
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
z_stream zStream ;
int zLibFlushType ; // Z_NO_FLUSH or Z_FINISH
bool zStreamEndHit ;
int numChecksums ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//------------------------
// These variables are used by WriteBlock() and ReadBlock().
//------------------------
2012-11-28 15:47:07 +00:00
idFile * nativeFile ;
2012-11-26 18:58:24 +00:00
bool nativeFileEndHit ;
bool finished ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//------------------------
// The background threads and signals for NextWriteBlock() and NextReadBlock().
//------------------------
2012-11-28 15:47:07 +00:00
idSGFreadThread * readThread ;
idSGFwriteThread * writeThread ;
idSGFdecompressThread * decompressThread ;
idSGFcompressThread * compressThread ;
2012-11-26 18:58:24 +00:00
idSysSignal blockRequested ;
idSysSignal blockAvailable ;
idSysSignal blockFinished ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idStrStatic < 32 > buildVersion ; // build version this file was saved with
int16 pointerSize ; // the number of bytes in a pointer, because different pointer sizes mean different offsets into objects a 64 bit build cannot load games saved from a 32 bit build or vice version (a value of 0 is interpreted as 4 bytes)
int16 saveFormatVersion ; // version number specific to save games (for maintaining save compatibility across builds)
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
//------------------------
// These variables are used when we want to abort due to the termination of the application
//------------------------
static bool cancelToTerminate ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
void FlushUncompressedBlock ( ) ;
void FlushCompressedBlock ( ) ;
void CompressBlock ( ) ;
void WriteBlock ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
void PumpUncompressedBlock ( ) ;
void PumpCompressedBlock ( ) ;
void DecompressBlock ( ) ;
void ReadBlock ( ) ;
} ;
# endif // !__FILE_SAVEGAME_H__