gcsx_load.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* GCSx
  2. ** LOAD.H
  3. **
  4. ** File loading only
  5. */
  6. /*****************************************************************************
  7. ** Copyright (C) 2003-2006 Janson
  8. **
  9. ** This program 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 2 of the License, or
  12. ** (at your option) any later version.
  13. **
  14. ** This program 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 this program; if not, write to the Free Software
  21. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
  22. *****************************************************************************/
  23. #ifndef __GCSx_LOAD_H_
  24. #define __GCSx_LOAD_H_
  25. // Structures used internally
  26. struct BlockHeader {
  27. Uint32 version; // 0 if not read
  28. Uint32 headerSize;
  29. Uint32 contentSize;
  30. Uint32 compression;
  31. };
  32. struct BlockInfo {
  33. // Current info
  34. Uint32 offset; // 0 if never written to file
  35. Uint32 size;
  36. Uint32 type;
  37. class LoadOnly* object; // Our object that can read this block
  38. BlockHeader header; // Header, if not read, version is 0
  39. // New info used when saving to a new file so we don't
  40. // overwrite old info until save is confirmed
  41. Uint32 newOffset;
  42. Uint32 newSize;
  43. BlockHeader newHeader;
  44. };
  45. // Interface for our files that we pass to objects- no seeking except rewind
  46. class FileRead {
  47. private:
  48. class File* filePtr;
  49. int startOffset;
  50. int totalSize;
  51. Uint32 version;
  52. Uint32 compression;
  53. int currentOffset;
  54. int bytesRead;
  55. // For readStr
  56. enum {
  57. COPY_BUFFER_SIZE = 8192,
  58. };
  59. static char copyBuffer[COPY_BUFFER_SIZE + 1];
  60. // ZLIB compression method
  61. z_stream* zlibStream;
  62. int zlibStreamInit;
  63. Byte* zlibBufferIn;
  64. Uint32 zlibOrigSize;
  65. enum { ZLIB_BUFFER_SIZE = 8192 };
  66. void zlibNextBuffer() throw_File;
  67. public:
  68. // Doesn't assume filePtr is seeked properly or anything like that, on ANY read
  69. FileRead(class File* myFilePtr, int offset, int size, Uint32 myVersion, Uint32 myCompression) throw_File;
  70. ~FileRead();
  71. // What version of data?
  72. Uint32 getVersion() const { return version; }
  73. // How large is our data, total? (uncompressed)
  74. int getSize() const;
  75. // Any more data for us? (actually returns total bytes remaining)
  76. int moreData() const;
  77. // Read X more bytes; throws an exception if size is greater than the bytes
  78. // we've been allocated to read
  79. void read(void* ptr, int size) throw_File;
  80. Uint32 readInt() throw_File;
  81. void readIntBulk(Uint32* ptr, int count) throw_File;
  82. Uint16 readInt16() throw_File;
  83. Uint8 readInt8() throw_File;
  84. // NON-REENTRANT
  85. void readStr(std::string& str) throw_File;
  86. void rewind() throw_File;
  87. };
  88. // Interface for objects that just load
  89. class LoadOnly {
  90. public:
  91. // Generic informational functions, so we can also use LoadOnly as
  92. // a generic "GCSx object" supertype
  93. virtual int getId() const = 0;
  94. // Returns BLOCKTYPE_UNUSED if not a directly writable object
  95. virtual int getBlockType() const = 0;
  96. // Load header
  97. // Discard FileRead object when done
  98. virtual void loadHeader(class FileRead* file) = 0;
  99. // Content, by choice of the object, can be cached
  100. // The FileRead pointer will be good any time the object
  101. // wishes to load as long as the object doesn't modify
  102. // itself; object MUST DEALLOCATE this pointer when done
  103. // Object MUST DEALLOCATE even if exception/throw!
  104. virtual void loadContent(class FileRead* file) = 0;
  105. // Typically used internally, and if excepts, should leave uncached entirely
  106. virtual void cacheLoad() = 0; // (ensures not cached)
  107. virtual int isContentCached() const = 0;
  108. // Mark or unmark an object as being used; lock should
  109. // be incremental; return current lock value, > 0 is locked,
  110. // 0 is locked. This should also load from cache. Content
  111. // cannot be returned to cache until unlocked down to 0.
  112. // This is the only required use of lock (to prevent cacheing)
  113. // Other functions do NOT need to check cache- outside sources
  114. // should call markLock appropriately.
  115. virtual int markLock() = 0;
  116. virtual int markUnlock() = 0;
  117. virtual int isLocked() const = 0;
  118. };
  119. // World file storage- All data is stored LITTLE ENDIAN
  120. // Bytes 00-03 GCSx
  121. // Bytes 04-19 Version, 4 int32s major minor bugfix build
  122. // Bytes 20-23 Reserved (may become pointer within file to world info block)
  123. // Bytes 24-27 Reserved
  124. // Bytes 28-31 Number of blocks
  125. // Per block-
  126. // Bytes 00-03 Offset, 0 if no block in this spot
  127. // Bytes 04-07 Overall block size as stored, 0 if no block in this spot
  128. // Bytes 08-11 Block type, 0 if no block or if block is unused and available
  129. // Bytes 12-15 Reserved
  130. // At block offset-
  131. // Bytes 00-03 Block version code
  132. // Bytes 04-07 Size of header data
  133. // Bytes 08-11 Size of (compressed) content data
  134. // Bytes 12-15 Compression type (applies to content only)
  135. // Bytes 16- Header data, followed by content data
  136. class WorldFileLoad {
  137. protected:
  138. Uint32 fileVersion[4];
  139. Uint32 numBlocks;
  140. std::vector<BlockInfo> blocks; // BlockInfo id is index
  141. class File* filePtr;
  142. const std::string* filename;
  143. Uint32 scanNextBlock;
  144. static const char* correctCookie;
  145. static const Uint32 currentVersion[4];
  146. WorldFileLoad();
  147. public:
  148. // Block types
  149. enum {
  150. // Unused blocks can't be claimed, but their position/size
  151. // are still relevant
  152. // Do not change the order/numbering of these!
  153. BLOCKTYPE_UNUSED = 0,
  154. BLOCKTYPE_WORLDINFO = 1,
  155. BLOCKTYPE_TILESET = 2,
  156. BLOCKTYPE_SCENE = 3,
  157. BLOCKTYPE_ANIMGROUP = 4,
  158. BLOCKTYPE_SCRIPT = 5,
  159. BLOCKTYPE_FOLDER = 6,
  160. };
  161. // Compression types
  162. enum {
  163. BLOCKCOMPRESSION_NONE = 0,
  164. BLOCKCOMPRESSION_ZLIB = 1,
  165. };
  166. // Pointer must remain valid
  167. WorldFileLoad(const std::string* openFile, int mode = File::FILE_MODE_READ) throw_File; // Open existing
  168. virtual ~WorldFileLoad(); // Closes the file
  169. // Use this to loop through all in-use blocks, to load
  170. // This initializes or "rewinds" the nextBlock() sequence.
  171. // You may loop through as many times as needed, but cannot claimBlock more
  172. // than once per block
  173. void scanBlocks();
  174. // Returns true if there was a "next" block- returns type and
  175. // a unique ID for the next block; construct object and tell
  176. // the object to load the block by it's ID; This skips unused blocks
  177. int nextBlock(Uint32* getType, Uint32* getID);
  178. // An object uses this to "claim" a block by it's ID; it will
  179. // then have both load functions called; cannot claim an id
  180. // more than once
  181. void claimBlock(Uint32 id, LoadOnly* claimingObject) throw_File;
  182. };
  183. #endif