ScummVM API documentation
resource.h
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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (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, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22// RSC Resource file management header file
23
24#ifndef SAGA_RESOURCE_H
25#define SAGA_RESOURCE_H
26
27#include "common/array.h"
28#include "common/file.h"
29#include "common/list.h"
30#include "common/macresman.h"
31
32namespace Saga {
33
34#define RSC_TABLEINFO_SIZE 8
35#define RSC_TABLEENTRY_SIZE 8
36
37#define RSC_MIN_FILESIZE (RSC_TABLEINFO_SIZE + RSC_TABLEENTRY_SIZE + 1)
38
39class SagaEngine;
40class ByteArray;
41
42class PatchData {
43private:
45 const char *_fileName;
46 bool _deletePatchFile;
47 bool _patchFileOpened;
48
49public:
50 PatchData(const char *fileName): _fileName(fileName), _deletePatchFile(true), _patchFile(nullptr), _patchFileOpened(false) {
51 }
52 PatchData(Common::SeekableReadStream *patchFile, const char *fileName): _patchFile(patchFile), _fileName(fileName), _deletePatchFile(false), _patchFileOpened(true) {
53 }
54
55 Common::SeekableReadStream *getStream() {
56 if (_patchFileOpened)
57 return _patchFile;
58
59 Common::File *file = new Common::File();
60 _patchFileOpened = true;
61 if (!file->open(_fileName)) {
62 _patchFile = nullptr;
63 delete file;
64 return nullptr;
65 }
66 _patchFile = file;
67 return _patchFile;
68 }
69
70 void closeStream() {
71 if (_deletePatchFile && _patchFileOpened) {
72 delete _patchFile;
73 _patchFile = nullptr;
74 _patchFileOpened = false;
75 }
76 }
77
78 ~PatchData() {
79 if (_deletePatchFile) {
80 delete _patchFile;
81 }
82 }
83};
84
86 size_t offset;
87 size_t size;
88 int diskNum; // -1 = without disk id. -2 = mac res fork
89 PatchData *patchData;
90
91 ResourceData() :
92 offset(0), size(0), patchData(NULL), diskNum(-1) {
93 }
94
96 if (patchData) {
97 delete patchData;
98 patchData = NULL;
99 }
100 }
101};
102
104
106friend class Resource;
107public:
108
110 _fileName(NULL), _fileType(0), _isCompressed(false), _serial(0),
111 _isBigEndian(false),
112 _fileSize(0), _tombstone(false) {
113 }
114
115 virtual ~ResourceContext() { }
116
117 bool isCompressed() const { return _isCompressed; }
118 uint16 fileType() const { return _fileType; }
119 int32 fileSize() const { return _fileSize; }
120 int serial() const { return _serial; }
121 bool isBigEndian() const { return _isBigEndian; }
122 const char * fileName() const { return _fileName; }
123
124 Common::SeekableReadStream *getFile(ResourceData *resourceData) {
125 if (resourceData && resourceData->patchData != NULL) {
126 return resourceData->patchData->getStream();
127 } else {
128 if (!_file && !_tombstone)
130 if (!_file)
131 _tombstone = true;
132
133 return _file.get();
134 }
135 }
136
137 bool validResourceId(uint32 resourceId) const {
138 return (resourceId < _table.size());
139 }
140
141 ResourceData *getResourceData(uint32 resourceId) {
142 if (resourceId >= _table.size()) {
143 error("ResourceContext::getResourceData() wrong resourceId %d", resourceId);
144 }
145 return &_table[resourceId];
146 }
147
148 void closeFile() {
149 _file.reset();
150 }
151
152protected:
153 const char *_fileName;
154 uint16 _fileType;
155 bool _isCompressed;
156 int _serial; // IHNM speech files
157
158 bool _isBigEndian;
159 ResourceDataArray _table;
162 int32 _fileSize;
163 bool _tombstone;
164
165 bool load(SagaEngine *_vm, Resource *resource);
166 bool loadResV1();
167 bool loadResIteAmiga(SagaEngine *_vm, int type, bool isFloppy);
168 bool loadResIteAmigaSound(SagaEngine *_vm, int type);
169
170 virtual bool loadRes(SagaEngine *_vm, int type) = 0;
171 virtual void processPatches(Resource *resource, const GamePatchDescription *patchFiles) { }
172};
173
175
177 int16 sceneIndex;
178 int16 objectCount;
179 int32 objectsStringsResourceID;
180 int32 inventorySpritesID;
181 int32 mainSpritesID;
182 int32 objectsResourceID;
183 int16 actorCount;
184 int32 actorsStringsResourceID;
185 int32 actorsResourceID;
186 int32 protagFaceSpritesID;
187 int32 field_22;
188 int16 field_26;
189 int16 protagStatesCount;
190 int32 protagStatesResourceID;
191 int32 cutawayListResourceID;
192 int32 songTableID;
193
194 MetaResource() {
195 memset(this, 0, sizeof(*this));
196 }
197};
198
199class Resource {
200public:
201 Resource(SagaEngine *vm);
202 virtual ~Resource();
203 bool createContexts();
204 void clearContexts();
205 void loadResource(ResourceContext *context, uint32 resourceId, ByteArray &resourceBuffer);
206
207 virtual uint32 convertResourceId(uint32 resourceId) = 0;
208 virtual void loadGlobalResources(int chapter, int actorsEntrance) = 0;
209
210 ResourceContext *getContext(uint16 fileType, int serial = 0);
211 virtual MetaResource* getMetaResource() = 0;
212protected:
213 SagaEngine *_vm;
214 ResourceContextList _contexts;
215 char _voicesFileName[8][256];
216 char _musicFileName[256];
217 char _soundFileName[256];
218
219 void addContext(const char *fileName, uint16 fileType, bool isCompressed = false, int serial = 0);
220 virtual ResourceContext *createContext() = 0;
221};
222
223// ITE
225protected:
226 bool loadRes(SagaEngine *_vm, int type) override {
227 return loadResV1();
228 }
229 void processPatches(Resource *resource, const GamePatchDescription *patchFiles) override;
230};
231
233public:
234 ResourceContext_RSC_ITE_Amiga(bool isFloppy) : _isFloppy(isFloppy) {}
235
236protected:
237 bool loadRes(SagaEngine *_vm, int type) override {
238 return loadResIteAmiga(_vm, type, _isFloppy);
239 }
240
241 bool _isFloppy;
242};
243
244class Resource_RSC : public Resource {
245public:
246 Resource_RSC(SagaEngine *vm) : Resource(vm) {}
247 uint32 convertResourceId(uint32 resourceId) override {
248 return _vm->isMacResources() ? resourceId - 2 : resourceId;
249 }
250 void loadGlobalResources(int chapter, int actorsEntrance) override {}
251 MetaResource* getMetaResource() override {
252 MetaResource *dummy = 0;
253 return dummy;
254 }
255protected:
256 ResourceContext *createContext() override {
257 if (_vm->getPlatform() == Common::kPlatformAmiga && _vm->getGameId() == GID_ITE) {
258 return new ResourceContext_RSC_ITE_Amiga(_vm->getFeatures() & GF_ITE_FLOPPY);
259 }
260 return new ResourceContext_RSC();
261 }
262};
263
264#ifdef ENABLE_IHNM
265// IHNM
266class ResourceContext_RES: public ResourceContext {
267protected:
268 bool loadRes(SagaEngine *_vm, int type) override {
269 return loadResV1();
270 }
271
272 void processPatches(Resource *resource, const GamePatchDescription *patchFiles) override;
273};
274
275// TODO: move load routines from sndres
276class VoiceResourceContext_RES: public ResourceContext {
277protected:
278 bool loadRes(SagaEngine *_vm, int type) override {
279 return false;
280 }
281public:
282 VoiceResourceContext_RES() : ResourceContext() {
283 _fileType = GAME_VOICEFILE;
284 _isBigEndian = true;
285 }
286};
287
288class Resource_RES : public Resource {
289public:
290 Resource_RES(SagaEngine *vm) : Resource(vm) {}
291 uint32 convertResourceId(uint32 resourceId) override { return resourceId; }
292 void loadGlobalResources(int chapter, int actorsEntrance) override;
293 MetaResource* getMetaResource() override { return &_metaResource; }
294protected:
295 ResourceContext *createContext() override {
296 return new ResourceContext_RES();
297 }
298private:
299 MetaResource _metaResource;
300};
301#endif
302
303} // End of namespace Saga
304
305#endif
size_type size() const
Definition: array.h:316
Definition: file.h:47
virtual bool open(const Path &filename)
static SeekableReadStream * openFileOrDataFork(const Path &fileName, Archive &archive)
void reset(PointerType o=nullptr)
Definition: ptr.h:607
PointerType get() const
Definition: ptr.h:637
Definition: stream.h:745
Definition: saga.h:464
Definition: resource.h:42
Definition: resource.h:244
Definition: resource.h:232
Definition: resource.h:224
Definition: resource.h:105
Definition: resource.h:199
Definition: saga.h:497
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: actor.h:34
Definition: saga.h:295
Definition: resource.h:176
Definition: resource.h:85