ScummVM API documentation
object.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 SCI_ENGINE_OBJECT_H
23#define SCI_ENGINE_OBJECT_H
24
25#include "common/array.h"
26#include "common/serializer.h"
27#include "common/textconsole.h"
28
29#include "sci/engine/vm_types.h" // for reg_t
30#include "sci/util.h"
31#include "sci/version.h"
32
33namespace Sci {
34
35class SegManager;
36class Script;
37
38enum infoSelectorFlags {
39 kInfoFlagClone = 0x0001,
40#ifdef ENABLE_SCI32
45 kInfoFlagViewVisible = 0x0008,
46
51 kInfoFlagViewInserted = 0x0010,
52#endif
53 kInfoFlagClass = 0x8000
54};
55
56enum ObjectOffsets {
57 kOffsetHeaderSize = 6,
58 kOffsetHeaderLocalVariables = 0,
59 kOffsetHeaderFunctionArea = 2,
60 kOffsetHeaderSelectorCounter = 4,
61
62 kOffsetSelectorSegment = 0,
63 kOffsetInfoSelectorSci0 = 4,
64 kOffsetNamePointerSci0 = 6,
65 kOffsetInfoSelectorSci11 = 14,
66 kOffsetNamePointerSci11 = 16
67};
68
70public:
71 Object() :
72 _name(NULL_REG),
73 _offset(getSciVersion() < SCI_VERSION_1_1 ? 0 : 5),
74 _isFreed(false),
75 _methodCount(0),
76 _pos(NULL_REG)
77#ifdef ENABLE_SCI32
78 ,
79 _infoSelectorSci3(NULL_REG),
80 _speciesSelectorSci3(NULL_REG),
81 _superClassPosSci3(NULL_REG)
82#endif
83 {}
84
85 Object &operator=(const Object &other) {
86 _name = other._name;
87 _baseObj = other._baseObj;
88 _baseMethod = other._baseMethod;
89 _variables = other._variables;
90 _methodCount = other._methodCount;
91 _isFreed = other._isFreed;
92 _offset = other._offset;
93 _pos = other._pos;
94 _baseVars = other._baseVars;
95
96#ifdef ENABLE_SCI32
97 if (getSciVersion() == SCI_VERSION_3) {
98 _propertyOffsetsSci3 = other._propertyOffsetsSci3;
99 _superClassPosSci3 = other._superClassPosSci3;
100 _speciesSelectorSci3 = other._speciesSelectorSci3;
101 _infoSelectorSci3 = other._infoSelectorSci3;
102 _mustSetViewVisible = other._mustSetViewVisible;
103 }
104#endif
105
106 return *this;
107 }
108
109 reg_t getSpeciesSelector() const {
110#ifdef ENABLE_SCI32
111 if (getSciVersion() == SCI_VERSION_3)
112 return _speciesSelectorSci3;
113 else
114#endif
115 return _variables[_offset];
116 }
117
118 void setSpeciesSelector(reg_t value) {
119#ifdef ENABLE_SCI32
120 if (getSciVersion() == SCI_VERSION_3)
121 _speciesSelectorSci3 = value;
122 else
123#endif
124 _variables[_offset] = value;
125 }
126
127 reg_t getSuperClassSelector() const {
128#ifdef ENABLE_SCI32
129 if (getSciVersion() == SCI_VERSION_3)
130 return _superClassPosSci3;
131 else
132#endif
133 return _variables[_offset + 1];
134 }
135
136 void setSuperClassSelector(reg_t value) {
137#ifdef ENABLE_SCI32
138 if (getSciVersion() == SCI_VERSION_3)
139 _superClassPosSci3 = value;
140 else
141#endif
142 _variables[_offset + 1] = value;
143 }
144
145 reg_t getInfoSelector() const {
146#ifdef ENABLE_SCI32
147 if (getSciVersion() == SCI_VERSION_3)
148 return _infoSelectorSci3;
149 else
150#endif
151 return _variables[_offset + 2];
152 }
153
154 void setInfoSelector(reg_t info) {
155#ifdef ENABLE_SCI32
156 if (getSciVersion() == SCI_VERSION_3)
157 _infoSelectorSci3 = info;
158 else
159#endif
160 _variables[_offset + 2] = info;
161 }
162
163#ifdef ENABLE_SCI32
164 void setInfoSelectorFlag(infoSelectorFlags flag) {
165 if (getSciVersion() == SCI_VERSION_3) {
166 _infoSelectorSci3 |= flag;
167 } else {
168 _variables[_offset + 2] |= flag;
169 }
170 }
171
172 void clearInfoSelectorFlag(infoSelectorFlags flag) {
173 if (getSciVersion() == SCI_VERSION_3) {
174 _infoSelectorSci3 &= ~flag;
175 } else {
176 _variables[_offset + 2] &= ~flag;
177 }
178 }
179
180 bool isInserted() const {
181 return getInfoSelector().toUint16() & kInfoFlagViewInserted;
182 }
183#endif
184
185 reg_t getNameSelector() const {
186 return _name;
187 }
188
189 // No setter for the name selector
190
191 reg_t getPropDictSelector() const {
192#ifdef ENABLE_SCI32
193 if (getSciVersion() == SCI_VERSION_3)
194 // This should never occur, this is called from a SCI1.1 - SCI2.1 only function
195 error("getPropDictSelector called for SCI3");
196 else
197#endif
198 return _variables[2];
199 }
200
201 void setPropDictSelector(reg_t value) {
202#ifdef ENABLE_SCI32
203 if (getSciVersion() == SCI_VERSION_3)
204 // This should never occur, this is called from a SCI1.1 - SCI2.1 only function
205 error("setPropDictSelector called for SCI3");
206 else
207#endif
208 _variables[2] = value;
209 }
210
211 reg_t getClassScriptSelector() const {
212#ifdef ENABLE_SCI32
213 if (getSciVersion() == SCI_VERSION_3)
214 return make_reg(0, _baseObj.getUint16SEAt(6));
215 else
216#endif
217 return _variables[4];
218 }
219
220 void setClassScriptSelector(reg_t value) {
221#ifdef ENABLE_SCI32
222 if (getSciVersion() == SCI_VERSION_3)
223 // This should never occur, this is called from a SCI1.1 - SCI2.1 only function
224 error("setClassScriptSelector called for SCI3");
225 else
226#endif
227 _variables[4] = value;
228 }
229
230 Selector getVarSelector(uint16 i) const { return _baseVars[i]; }
231
235 reg_t getFunction(const uint16 index) const {
236 return make_reg32(_pos.getSegment(), _baseMethod[index * 2 + 1]);
237 }
238
242 Selector getFuncSelector(const uint16 index) const {
243 return _baseMethod[index * 2];
244 }
245
252 int funcSelectorPosition(Selector sel) const {
253 for (uint i = 0; i < _methodCount; i++)
254 if (getFuncSelector(i) == sel)
255 return i;
256
257 return -1;
258 }
259
264 int locateVarSelector(SegManager *segMan, Selector slc) const;
265
266 bool isClass() const { return (getInfoSelector().getOffset() & kInfoFlagClass); }
267 const Object *getClass(SegManager *segMan) const;
268
269 void markAsFreed() { _isFreed = true; }
270 bool isFreed() const { return _isFreed; }
271
272 uint getVarCount() const { return _variables.size(); }
273
274 void init(const Script &owner, reg_t obj_pos, bool initVariables = true);
275
276 reg_t getVariable(uint var) const { return _variables[var]; }
277 reg_t &getVariableRef(uint var) { return _variables[var]; }
278
279 uint16 getMethodCount() const { return _methodCount; }
280 reg_t getPos() const { return _pos; }
281
282 void saveLoadWithSerializer(Common::Serializer &ser) override;
283
284 void cloneFromObject(const Object *obj) {
285 _name = obj ? obj->_name : NULL_REG;
286 _baseObj = obj ? obj->_baseObj : SciSpan<const byte>();
287 _baseMethod = obj ? obj->_baseMethod : Common::Array<uint32>();
288 _baseVars = obj ? obj->_baseVars : Common::Array<uint16>();
289#ifdef ENABLE_SCI32
290 if (getSciVersion() == SCI_VERSION_3) {
291 _mustSetViewVisible = obj ? obj->_mustSetViewVisible : Common::Array<bool>();
292 }
293#endif
294 }
295
296 bool relocateSci0Sci21(SegmentId segment, int location, uint32 heapOffset);
297#ifdef ENABLE_SCI32
298 bool relocateSci3(SegmentId segment, uint32 location, int offset, uint32 scriptSize);
299#endif
300
301 int propertyOffsetToId(SegManager *segMan, int propertyOffset) const;
302
303 void initSpecies(SegManager *segMan, reg_t addr, bool applyScriptPatches);
304 void initSuperClass(SegManager *segMan, reg_t addr, bool applyScriptPatches);
305 bool initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClass = true, bool applyScriptPatches = true);
306
307#ifdef ENABLE_SCI32
308 bool mustSetViewVisible(const int index, const bool fromPropertyOp) const;
309#endif
310
311private:
312#ifdef ENABLE_SCI32
313 void initSelectorsSci3(const SciSpan<const byte> &buf, const bool initVariables);
314#endif
315
319 reg_t _name;
320
324 SciSpan<const byte> _baseObj;
325
330 Common::Array<uint16> _baseVars;
331
336 Common::Array<uint32> _baseMethod;
337
341 Common::Array<reg_t> _variables;
342
343#ifdef ENABLE_SCI32
351 Common::Array<uint32> _propertyOffsetsSci3;
352#endif
353
357 uint16 _methodCount;
358
362 bool _isFreed;
363
368 uint16 _offset;
369
370 reg_t _pos;
371#ifdef ENABLE_SCI32
372 reg_t _superClassPosSci3;
373 reg_t _speciesSelectorSci3;
374 reg_t _infoSelectorSci3;
375 Common::Array<bool> _mustSetViewVisible;
376#endif
377};
378
379
380} // End of namespace Sci
381
382#endif // SCI_ENGINE_OBJECT_H
size_type size() const
Definition: array.h:316
Definition: serializer.h:352
Definition: serializer.h:80
Definition: object.h:69
int funcSelectorPosition(Selector sel) const
Definition: object.h:252
Selector getFuncSelector(const uint16 index) const
Definition: object.h:242
reg_t getFunction(const uint16 index) const
Definition: object.h:235
int locateVarSelector(SegManager *segMan, Selector slc) const
Definition: seg_manager.h:48
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: console.h:28
Definition: vm_types.h:39