File_SaveGame.h 9.2 KB

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