DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

File_SaveGame.h (9379B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 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.
     23 
     24 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.
     25 
     26 ===========================================================================
     27 */
     28 #ifndef __FILE_SAVEGAME_H__
     29 #define __FILE_SAVEGAME_H__
     30 
     31 #include "zlib/zlib.h"
     32 
     33 // Listing of the types of files within a savegame package
     34 enum saveGameType_t {
     35 	SAVEGAMEFILE_NONE			= 0,
     36 	SAVEGAMEFILE_TEXT			= BIT( 0 ),	// implies that no checksum will be used
     37 	SAVEGAMEFILE_BINARY			= BIT( 1 ),	// implies that a checksum will also be used
     38 	SAVEGAMEFILE_COMPRESSED		= BIT( 2 ),
     39 	SAVEGAMEFILE_PIPELINED		= BIT( 3 ),
     40 	SAVEGAMEFILE_THUMB			= BIT( 4 ),	// for special processing on certain platforms
     41 	SAVEGAMEFILE_BKGRND_IMAGE	= BIT( 5 ),	// for special processing on certain platforms, large background used on PS3
     42 	SAVEGAMEFILE_AUTO_DELETE	= BIT( 6 ),	// to be deleted automatically after completed
     43 	SAVEGAMEFILE_OPTIONAL		= BIT( 7 )	// if this flag is not set and missing, there is an error
     44 };
     45 
     46 /*
     47 ================================================
     48 idFile_SaveGame 
     49 ================================================
     50 */
     51 class idFile_SaveGame : public idFile_Memory {
     52 public:
     53 	idFile_SaveGame() : type( SAVEGAMEFILE_NONE ), error( false ) {}
     54 	idFile_SaveGame( const char * _name ) : idFile_Memory( _name ), type( SAVEGAMEFILE_NONE ), error( false ) {}
     55 	idFile_SaveGame( const char * _name, int type_ ) : idFile_Memory( _name ), type( type_ ), error( false ) {}
     56 
     57 	virtual ~idFile_SaveGame() { }
     58 
     59 	bool operator==( const idFile_SaveGame & other ) const {
     60 		return idStr::Icmp( GetName(), other.GetName() ) == 0;
     61 	}
     62 	bool operator==( const char * _name ) const {
     63 		return idStr::Icmp( GetName(), _name ) == 0;
     64 	}
     65 	void SetNameAndType( const char *_name, int _type ) {
     66 		name = _name;
     67 		type = _type;
     68 	}
     69 public: // TODO_KC_CR for now...
     70 
     71 	int					type;			// helps platform determine what to do with the file (encrypt, checksum, etc.)
     72 	bool				error;			// when loading, this is set if there is a problem
     73 };
     74 
     75 /*
     76 ================================================
     77 idFile_SaveGamePipelined uses threads to pipeline overlap compression and IO
     78 ================================================
     79 */
     80 class idSGFreadThread;
     81 class idSGFwriteThread;
     82 class idSGFdecompressThread;
     83 class idSGFcompressThread;
     84 
     85 struct blockForIO_t {
     86 	byte *		data;
     87 	size_t		bytes;
     88 };
     89 
     90 class idFile_SaveGamePipelined : public idFile {
     91 public:
     92 	// The buffers each hold two blocks of data, so one block can be operated on by
     93 	// the next part of the generate / compress / IO pipeline.  The factor of two
     94 	// size difference between the uncompressed and compressed blocks is unrelated
     95 	// to the fact that there are two blocks in each buffer.
     96 	static const int COMPRESSED_BLOCK_SIZE		= 128 * 1024;
     97 	static const int UNCOMPRESSED_BLOCK_SIZE	= 256 * 1024;
     98 
     99 
    100 							idFile_SaveGamePipelined();
    101 	virtual					~idFile_SaveGamePipelined();
    102 
    103 	bool					OpenForReading( const char * const filename, bool useNativeFile );
    104 	bool					OpenForWriting( const char * const filename, bool useNativeFile );
    105 
    106 	bool					OpenForReading( idFile * file );
    107 	bool					OpenForWriting( idFile * file );
    108 
    109 	// Finish any reading or writing.
    110 	void					Finish();
    111 
    112 	// Abort any reading or writing.
    113 	void					Abort();
    114 
    115 	// Cancel any reading or writing for app termination
    116 	static void				CancelToTerminate() { cancelToTerminate = true; }
    117 
    118 	bool					ReadBuildVersion();
    119 	const char *			GetBuildVersion() const { return buildVersion; }
    120 	
    121 	bool					ReadSaveFormatVersion();
    122 	int						GetSaveFormatVersion() const { return saveFormatVersion; }
    123 	int						GetPointerSize() const;
    124 
    125 	//------------------------
    126 	// idFile Interface
    127 	//------------------------
    128 
    129 	virtual const char *	GetName() const { return name.c_str(); }
    130 	virtual const char *	GetFullPath() const	{ return name.c_str(); }
    131 	virtual int				Read( void * buffer, int len );
    132 	virtual int				Write( const void * buffer, int len );
    133 
    134 	// this file is strictly streaming, you can't seek at all
    135 	virtual int				Length() const  { return compressedLength; }
    136 	virtual void			SetLength( size_t len ) { compressedLength = len; }
    137 	virtual int				Tell() const { assert( 0 ); return 0; }
    138 	virtual int				Seek( long offset, fsOrigin_t origin ) { assert( 0 ); return 0; }
    139 
    140 	virtual ID_TIME_T		Timestamp()	const { return 0; }
    141 
    142 	//------------------------
    143 	// These can be used by a background thread to read/write data
    144 	// when the file was opened with 'useNativeFile' set to false.
    145 	//------------------------
    146 
    147 	enum mode_t {
    148 		CLOSED,
    149 		WRITE,
    150 		READ
    151 	};
    152 
    153 	// Get the file mode: read/write.
    154 	mode_t					GetMode() const { return mode; }
    155 
    156 	// Called by a background thread to get the next block to be written out.
    157 	// This may block until a block has been made available through the pipeline.
    158 	// Pass in NULL to notify the last write failed.
    159 	// Returns false if there are no more blocks.
    160 	bool					NextWriteBlock( blockForIO_t * block );
    161 
    162 	// Called by a background thread to get the next block to read data into and to
    163 	// report the number of bytes written to the previous block.
    164 	// This may block until space is available to place the next block.
    165 	// Pass in NULL to notify the end of the file was reached.
    166 	// Returns false if there are no more blocks.
    167 	bool					NextReadBlock( blockForIO_t * block, size_t lastReadBytes );
    168 
    169 private:
    170 	friend class idSGFreadThread;
    171 	friend class idSGFwriteThread;
    172 	friend class idSGFdecompressThread;
    173 	friend class idSGFcompressThread;
    174 
    175 	idStr					name;		// Name of the file.
    176 	idStr					osPath;		// OS path.
    177 	mode_t					mode;		// Open mode.
    178 	size_t					compressedLength;
    179 
    180 	static const int COMPRESSED_BUFFER_SIZE		= COMPRESSED_BLOCK_SIZE * 2;
    181 	static const int UNCOMPRESSED_BUFFER_SIZE	= UNCOMPRESSED_BLOCK_SIZE * 2;
    182 
    183 	byte					uncompressed[UNCOMPRESSED_BUFFER_SIZE];
    184 	size_t					uncompressedProducedBytes;	// not masked
    185 	size_t					uncompressedConsumedBytes;	// not masked
    186 
    187 	byte					compressed[COMPRESSED_BUFFER_SIZE];
    188 	size_t					compressedProducedBytes;	// not masked
    189 	size_t					compressedConsumedBytes;	// not masked
    190 
    191 	//------------------------
    192 	// These variables are used to pass data between threads in a thread-safe manner.
    193 	//------------------------
    194 
    195 	byte *					dataZlib;
    196 	size_t					bytesZlib;
    197 
    198 	byte *					dataIO;
    199 	size_t					bytesIO;
    200 
    201 	//------------------------
    202 	// These variables are used by CompressBlock() and DecompressBlock().
    203 	//------------------------
    204 
    205 	z_stream				zStream;
    206 	int						zLibFlushType;		// Z_NO_FLUSH or Z_FINISH
    207 	bool					zStreamEndHit;
    208 	int						numChecksums;
    209 
    210 	//------------------------
    211 	// These variables are used by WriteBlock() and ReadBlock().
    212 	//------------------------
    213 
    214 	idFile *				nativeFile;
    215 	bool					nativeFileEndHit;
    216 	bool					finished;
    217 
    218 	//------------------------
    219 	// The background threads and signals for NextWriteBlock() and NextReadBlock().
    220 	//------------------------
    221 
    222 	idSGFreadThread *		readThread;
    223 	idSGFwriteThread *		writeThread;
    224 
    225 	idSGFdecompressThread *	decompressThread;
    226 	idSGFcompressThread *	compressThread;
    227 
    228 	idSysSignal				blockRequested;
    229 	idSysSignal				blockAvailable;
    230 	idSysSignal				blockFinished;
    231 
    232 	idStrStatic< 32 >		buildVersion;		// build version this file was saved with
    233 	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)
    234 	int16					saveFormatVersion;	// version number specific to save games (for maintaining save compatibility across builds)
    235 
    236 	//------------------------
    237 	// These variables are used when we want to abort due to the termination of the application
    238 	//------------------------
    239 	static bool				cancelToTerminate;
    240 
    241 	void					FlushUncompressedBlock();
    242 	void					FlushCompressedBlock();
    243 	void					CompressBlock();
    244 	void					WriteBlock();
    245 
    246 	void					PumpUncompressedBlock();
    247 	void					PumpCompressedBlock();
    248 	void					DecompressBlock();
    249 	void					ReadBlock();
    250 };
    251 
    252 #endif // !__FILE_SAVEGAME_H__