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