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__