1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef TSAGE_RESOURCES_H 24 #define TSAGE_RESOURCES_H 25 26 #include "common/scummsys.h" 27 #include "common/array.h" 28 #include "common/file.h" 29 #include "common/list.h" 30 #include "common/str.h" 31 #include "common/str-array.h" 32 #include "common/util.h" 33 #include "graphics/surface.h" 34 35 namespace TsAGE { 36 37 // Magic number used by original game to identify valid memory blocks 38 const uint32 MEMORY_ENTRY_ID = 0xE11DA722; 39 40 const int MEMORY_POOL_SIZE = 1000; 41 42 enum ResourceType { RES_LIBRARY, RES_STRIP, RES_IMAGE, RES_PALETTE, RES_VISAGE, RES_SOUND, RES_MESSAGE, 43 RES_FONT, RES_POINTER, RES_BANK, RES_SND_DRIVER, RES_PRIORITY, RES_CONTROL, RES_WALKRGNS, 44 RES_BITMAP, RES_SAVE, RES_SEQUENCE, 45 // Return to Ringworld specific resource types 46 RT17, RT18, RT19, RT20, RT21, RT22, RT23, RT24, RT25, RT26, RT27, RT28, RT29, RT30, RT31 47 }; 48 49 class MemoryHeader { 50 public: 51 uint32 id; 52 int16 index; 53 int lockCtr; 54 int criticalCtr; 55 uint8 tag; 56 uint32 size; 57 MemoryHeader()58 MemoryHeader() { 59 id = 0; 60 index = 0; 61 lockCtr = 0; 62 criticalCtr = 0; 63 tag = 0; 64 size = 0; 65 } 66 }; 67 68 class SectionEntry { 69 public: 70 ResourceType resType; 71 uint16 resNum; 72 uint32 fileOffset; 73 SectionEntry()74 SectionEntry() { 75 resType = RES_LIBRARY; 76 resNum = 0; 77 fileOffset = 0; 78 } 79 }; 80 81 class ResourceEntry { 82 public: 83 uint16 id; 84 bool isCompressed; 85 uint32 fileOffset; 86 uint32 size; 87 uint32 uncompressedSize; 88 ResourceEntry()89 ResourceEntry() { 90 id = 0; 91 isCompressed = false; 92 fileOffset = 0; 93 size = 0; 94 uncompressedSize = 0; 95 } 96 }; 97 98 typedef Common::List<ResourceEntry> ResourceList; 99 100 class SectionList : public Common::List<SectionEntry> { 101 public: 102 uint32 fileOffset; 103 SectionList()104 SectionList() { 105 fileOffset = 0; 106 } 107 }; 108 109 class MemoryManager { 110 private: 111 MemoryHeader **_memoryPool; 112 public: 113 MemoryManager(); 114 ~MemoryManager(); 115 116 uint16 allocate(uint32 size); 117 byte *allocate2(uint32 size); 118 byte *lock(uint32 handle); 119 int indexOf(const byte *p); 120 void deallocate(const byte *p); deallocate(uint16 handle)121 void deallocate(uint16 handle) { warning("TODO: MemoryManager::deallocate(handle)"); } 122 uint32 getSize(const byte *p); 123 void incLocks(const byte *p); 124 }; 125 126 class BitReader { 127 private: 128 Common::ReadStream &_stream; 129 uint8 _remainder, _bitsLeft; readByte()130 byte readByte() { return _stream.eos() ? 0 : _stream.readByte(); } 131 public: BitReader(Common::ReadStream & s)132 BitReader(Common::ReadStream &s) : _stream(s) { 133 numBits = 9; 134 _remainder = 0; 135 _bitsLeft = 0; 136 } 137 uint16 readToken(); 138 139 int numBits; 140 }; 141 142 class TLib { 143 private: 144 Common::StringArray _resStrings; 145 MemoryManager &_memoryManager; 146 private: 147 Common::SeekableReadStream *_file; 148 Common::String _filename; 149 ResourceList _resources; 150 SectionList _sections; 151 152 void loadSection(uint32 fileOffset); 153 void loadIndex(); 154 public: 155 TLib(MemoryManager &memManager, const Common::String &filename); 156 ~TLib(); 157 getFilename()158 const Common::String &getFilename() { return _filename; } getSections()159 const SectionList &getSections() { return _sections; } 160 byte *getResource(uint16 id, bool suppressErrors = false); 161 byte *getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors = false); 162 uint32 getResourceStart(ResourceType resType, uint16 resNum, uint16 rlbNum, ResourceEntry &entry); 163 bool getPalette(int paletteNum, byte *palData, uint *startNum, uint *numEntries); 164 byte *getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors = false); 165 bool getMessage(int resNum, int lineNum, Common::String &result, bool suppressErrors = false); 166 }; 167 168 class ResourceManager { 169 private: 170 Common::Array<TLib *> _libList; 171 public: 172 ~ResourceManager(); 173 174 void addLib(const Common::String &libName); 175 176 byte *getResource(uint16 id, bool suppressErrors = false); 177 byte *getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors = false); 178 void getPalette(int paletteNum, byte *palData, uint *startNum, uint *numEntries, bool suppressErrors = false); 179 byte *getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors = false); 180 Common::String getMessage(int resNum, int lineNum, bool suppressErrors = false); first()181 TLib &first() { return **_libList.begin(); } 182 183 static bool scanIndex(Common::File &f, ResourceType resType, int rlbNum, int resNum, ResourceEntry &resEntry); 184 static void loadSection(Common::SeekableReadStream *f, ResourceList &resources); 185 }; 186 187 188 } // end of namespace TsAGE 189 190 #endif 191