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 SCUMM_RESOURCE_H 24 #define SCUMM_RESOURCE_H 25 26 #include "common/array.h" 27 #include "scumm/scumm.h" // for ResType 28 29 namespace Scumm { 30 31 enum { 32 OF_OWNER_MASK = 0x0F, 33 OF_STATE_MASK = 0xF0, 34 35 OF_STATE_SHL = 4 36 }; 37 38 class ResourceIterator { 39 uint32 _size; 40 uint32 _pos; 41 const byte *_ptr; 42 bool _smallHeader; 43 public: 44 ResourceIterator(const byte *searchin, bool smallHeader); 45 const byte *findNext(uint32 tag); 46 }; 47 48 enum { 49 RES_INVALID_OFFSET = 0xFFFFFFFF 50 }; 51 52 class ScummEngine; 53 54 /** 55 * The mode of a resource type indicates whether the resource can be restored 56 * from the game data files or not. 57 * This affects for example whether the resource is stored in savestates. 58 * 59 * Note that we treat sound resources somewhat differently: On the one hand, 60 * these behave mostly like a kStaticResTypeMode res type. However, when we 61 * create a savestate, we do save *some* information about them: Namely, which 62 * sound resources are loaded in memory at the time the save is made. And when 63 * loading, we invoke ensureResourceLoaded() for each sound resource that was 64 * marked in this way. 65 */ 66 enum ResTypeMode { 67 kDynamicResTypeMode = 0, ///< Resource is generated during runtime and may change 68 kStaticResTypeMode = 1, ///< Resource comes from data files, does not change 69 kSoundResTypeMode = 2 ///< Resource comes from data files, but may change 70 }; 71 72 /** 73 * The 'resource manager' class. Currently doesn't really deserve to be called 74 * a 'class', at least until somebody gets around to OOfying this more. 75 */ 76 class ResourceManager { 77 //friend class ScummDebugger; 78 //friend class ScummEngine; 79 protected: 80 ScummEngine *_vm; 81 82 public: 83 class Resource { 84 public: 85 /** 86 * Pointer to the data contained in this resource 87 */ 88 byte *_address; 89 90 /** 91 * Size of this resource, i.e. of the data contained in it. 92 */ 93 uint32 _size; 94 95 protected: 96 /** 97 * The uppermost bit indicates whether the resources is locked. 98 * The lower 7 bits contain a counter. This counter measures roughly 99 * how old the resource is; it starts out with a count of 1 and can go 100 * as high as 127. When memory falls low resp. when the engine decides 101 * that it should throw out some unused stuff, then it begins by 102 * removing the resources with the highest counter (excluding locked 103 * resources and resources that are known to be in use). 104 */ 105 byte _flags; 106 107 /** 108 * The status of the resource. Currently only one bit is used, which 109 * indicates whether the resource is modified. 110 */ 111 byte _status; 112 113 public: 114 /** 115 * The id of the room (resp. the disk) the resource is contained in. 116 */ 117 byte _roomno; 118 119 /** 120 * The offset (in bytes) where the data for this resources can be found 121 * in the game data file(s), relative to the start of the room the 122 * resource is contained in. 123 * 124 * A value of RES_INVALID_OFFSET indicates a resources that is not contained 125 * in the game data files. 126 */ 127 uint32 _roomoffs; 128 129 public: 130 Resource(); 131 ~Resource(); 132 133 void nuke(); 134 135 inline void setResourceCounter(byte counter); 136 inline byte getResourceCounter() const; 137 138 void lock(); 139 void unlock(); 140 bool isLocked() const; 141 142 // HE specific 143 void setModified(); 144 bool isModified() const; 145 void setOffHeap(); 146 void setOnHeap(); 147 bool isOffHeap() const; 148 }; 149 150 /** 151 * This struct represents a resource type and all resource of that type. 152 */ 153 class ResTypeData : public Common::Array<Resource> { 154 friend class ResourceManager; 155 public: 156 /** 157 * The mode of this res type. 158 */ 159 ResTypeMode _mode; 160 161 /** 162 * The 4-byte tag or chunk type associated to this resource type, if any. 163 * Only applies to resources that are loaded from the game data files. 164 * This value is only used for debugging purposes. 165 */ 166 uint32 _tag; 167 168 public: 169 ResTypeData(); 170 ~ResTypeData(); 171 }; 172 ResTypeData _types[rtLast + 1]; 173 174 protected: 175 uint32 _allocatedSize; 176 uint32 _maxHeapThreshold, _minHeapThreshold; 177 byte _expireCounter; 178 179 public: 180 ResourceManager(ScummEngine *vm); 181 ~ResourceManager(); 182 183 void setHeapThreshold(int min, int max); 184 185 void allocResTypeData(ResType type, uint32 tag, int num, ResTypeMode mode); 186 void freeResources(); 187 188 byte *createResource(ResType type, ResId idx, uint32 size); 189 void nukeResource(ResType type, ResId idx); 190 191 // inline Resource &getRes(ResType type, ResId idx) { return _types[type][idx]; } 192 // inline const Resource &getRes(ResType type, ResId idx) const { return _types[type][idx]; } 193 194 bool isResourceLoaded(ResType type, ResId idx) const; 195 196 void lock(ResType type, ResId idx); 197 void unlock(ResType type, ResId idx); 198 bool isLocked(ResType type, ResId idx) const; 199 200 // HE Specific 201 void setModified(ResType type, ResId idx); 202 bool isModified(ResType type, ResId idx) const; 203 void setOffHeap(ResType type, ResId idx); 204 void setOnHeap(ResType type, ResId idx); 205 206 /** 207 * This method increments the _expireCounter, and if it overflows (which happens 208 * after at most 256 calls), it calls increaseResourceCounter. 209 * It is invoked in the engine's main loop ScummEngine::scummLoop(). 210 */ 211 void increaseExpireCounter(); 212 213 /** 214 * Update the specified resource's counter. 215 */ 216 void setResourceCounter(ResType type, ResId idx, byte counter); 217 218 /** 219 * Increment the counter of all unlocked loaded resources. 220 * The maximal count is 255. 221 * This is called by increaseExpireCounter and expireResources, 222 * but also by ScummEngine::startScene. 223 */ 224 void increaseResourceCounters(); 225 226 void resourceStats(); 227 228 //protected: 229 bool validateResource(const char *str, ResType type, ResId idx) const; 230 protected: 231 void expireResources(uint32 size); 232 }; 233 234 } // End of namespace Scumm 235 236 #endif 237