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 #ifndef MADE_RESOURCE_H
23 #define MADE_RESOURCE_H
24 
25 #include "made/sound.h"
26 
27 #include "common/endian.h"
28 #include "common/array.h"
29 #include "common/hashmap.h"
30 
31 namespace Common {
32 class File;
33 }
34 
35 namespace Audio {
36 class AudioStream;
37 }
38 
39 namespace Graphics {
40 struct Surface;
41 }
42 
43 namespace Made {
44 
49 #ifndef __DS__
50 const int kMaxResourceCacheSize = 1000 * 1024;
51 #else
52 const int kMaxResourceCacheSize = 400 * 1024;
53 #endif
54 
55 
56 enum ResourceType {
57  kResARCH = MKTAG('A','R','C','H'),
58  kResFREE = MKTAG('F','R','E','E'),
59  kResOMNI = MKTAG('O','M','N','I'),
60  kResFLEX = MKTAG('F','L','E','X'),
61  kResSNDS = MKTAG('S','N','D','S'),
62  kResANIM = MKTAG('A','N','I','M'),
63  kResMENU = MKTAG('M','E','N','U'),
64  kResFONT = MKTAG('F','O','N','T'),
65  kResXMID = MKTAG('X','M','I','D'),
66  kResMIDI = MKTAG('M','I','D','I')
67 };
68 
69 struct ResourceSlot;
70 
71 class Resource {
72 public:
73  ResourceSlot *_slot;
74  virtual ~Resource();
75 };
76 
77 class PictureResource : public Resource {
78 public:
80  ~PictureResource() override;
81  void load(byte *source, int size);
82  Graphics::Surface *getPicture() const { return _picture; }
83  byte *getPalette() const { return _picturePalette; }
84  bool hasPalette() const { return _hasPalette; }
85  int getPaletteColorCount() const { return _paletteColorCount; }
86 protected:
87  Graphics::Surface *_picture;
88  byte *_picturePalette;
89  int _paletteColorCount;
90  bool _hasPalette;
91  void loadRaw(byte *source, int size);
92  void loadChunked(byte *source, int size);
93 };
94 
95 class AnimationResource : public Resource {
96 public:
98  ~AnimationResource() override;
99  void load(byte *source, int size);
100  int getCount() const { return _frames.size(); }
101  Graphics::Surface *getFrame(int index) const {
102  if ((uint)index < _frames.size()) {
103  return _frames[index];
104  } else {
105  warning("getFrame: Tried to obtain invalid frame %i, array has %i frames", index, _frames.size());
106  return _frames[_frames.size() - 1];
107  }
108  }
109  uint16 getFlags() const { return _flags; }
110  int16 getWidth() const { return _width; }
111  int16 getHeight() const { return _height; }
112 protected:
114  uint16 _flags;
115  int16 _width, _height;
116 };
117 
118 class SoundResource : public Resource {
119 public:
120  SoundResource();
121  ~SoundResource() override;
122  virtual void load(byte *source, int size);
123  Audio::AudioStream *getAudioStream(int soundRate, bool loop = false);
124  SoundEnergyArray *getSoundEnergyArray() const { return _soundEnergyArray; }
125  int getSoundSize() const { return _soundSize; }
126 protected:
127  byte *_soundData;
128  int _soundSize;
129  SoundEnergyArray *_soundEnergyArray;
130 };
131 
133 public:
134  SoundResourceV1() {}
135  ~SoundResourceV1() override {}
136  void load(byte *source, int size) override;
137 };
138 
139 class MenuResource : public Resource {
140 public:
141  MenuResource();
142  ~MenuResource() override;
143  void load(byte *source, int size);
144  int getCount() const { return _strings.size(); }
145  const char *getString(uint index) const;
146 protected:
148 };
149 
150 class FontResource : public Resource {
151 public:
152  FontResource();
153  ~FontResource() override;
154  void load(byte *source, int size);
155  int getHeight() const;
156  int getCharWidth(uint c) const;
157  int getTextWidth(const char *text);
158  byte *getChar(uint c) const;
159 protected:
160  byte *_data;
161  int _size;
162  byte *getCharData(uint c) const;
163 };
164 
165 class GenericResource : public Resource {
166 public:
167  GenericResource();
168  ~GenericResource() override;
169  void load(byte *source, int size);
170  byte *getData() const { return _data; }
171  int getSize() const { return _size; }
172 protected:
173  byte *_data;
174  int _size;
175 };
176 
177 struct ResourceSlot {
178  uint32 offs;
179  uint32 size;
180  Resource *res;
181  int refCount;
182  ResourceSlot() : offs(0), size(0), res(NULL), refCount(0) {
183  }
184  ResourceSlot(uint32 roffs, uint32 rsize) : offs(roffs), size(rsize), res(NULL), refCount(0) {
185  }
186 };
187 
189 public:
190  ResourceReader();
191  ~ResourceReader();
192 
193  void open(const char *filename);
194  void openResourceBlocks();
195 
196  PictureResource *getPicture(int index);
197  AnimationResource *getAnimation(int index);
198  SoundResource *getSound(int index);
199  MenuResource *getMenu(int index);
200  FontResource *getFont(int index);
201  GenericResource *getXmidi(int index);
202  GenericResource *getMidi(int index);
203 
204  void freeResource(Resource *resource);
205 
206 protected:
207 
208  Common::File *_fd;
209  Common::File *_fdPics, *_fdSounds, *_fdMusic; // V1
210  bool _isV1;
211 
214  void openResourceBlock(const char *filename, Common::File *blockFile, uint32 resType);
215 
216  ResMap _resSlots;
217  int _cacheCount;
218  int _cacheDataSize;
219 
220  void loadIndex(ResourceSlots *slots);
221 
222  template<class T>
223  T *createResource(uint32 resType, int index) {
224  ResourceSlot *slot = getResourceSlot(resType, index);
225  if (!slot)
226  return NULL;
227  T *res = (T *)getResourceFromCache(slot);
228  if (!res) {
229  byte *buffer;
230  uint32 size;
231 
232  // Read from the correct file for V1 games
233  if (_isV1) {
234  switch (resType) {
235  case kResSNDS:
236  _fd = _fdSounds;
237  break;
238  case kResMIDI:
239  _fd = _fdMusic;
240  break;
241  default:
242  _fd = _fdPics;
243  break;
244  }
245  }
246 
247  if (loadResource(slot, buffer, size)) {
248  res = new T();
249  res->_slot = slot;
250  res->load(buffer, size);
251  addResourceToCache(slot, res);
252  delete[] buffer;
253  }
254  }
255  return res;
256  }
257 
258  bool loadResource(ResourceSlot *slot, byte *&buffer, uint32 &size);
259  ResourceSlot *getResourceSlot(uint32 resType, uint index);
260  Resource *getResourceFromCache(ResourceSlot *slot);
261  void addResourceToCache(ResourceSlot *slot, Resource *res);
262  void tossResourceFromCache(ResourceSlot *slot);
263  void purgeCache();
264 
265 };
266 
267 } // End of namespace Made
268 
269 #endif /* MADE_H */
Definition: resource.h:77
Definition: resource.h:165
Definition: surface.h:67
void warning(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: resource.h:132
Definition: resource.h:177
Definition: file.h:47
Definition: resource.h:71
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: audiostream.h:50
const int kMaxResourceCacheSize
Definition: resource.h:50
Definition: resource.h:118
Definition: resource.h:188
#define MKTAG(a0, a1, a2, a3)
Definition: endian.h:188
Definition: resource.h:139
Definition: console.h:27
Definition: resource.h:150
Definition: resource.h:95
Definition: system.h:38