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 
33 namespace Sci {
34 
35 class SegManager;
36 class Script;
37 
38 enum infoSelectorFlags {
39  kInfoFlagClone = 0x0001,
40 #ifdef ENABLE_SCI32
41 
45  kInfoFlagViewVisible = 0x0008,
46 
51  kInfoFlagViewInserted = 0x0010,
52 #endif
53  kInfoFlagClass = 0x8000
54 };
55 
56 enum 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 
69 class Object : public Common::Serializable {
70 public:
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 
311 private:
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
344 
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
int funcSelectorPosition(Selector sel) const
Definition: object.h:252
Definition: serializer.h:79
int locateVarSelector(SegManager *segMan, Selector slc) const
Definition: script.h:71
Definition: object.h:69
Definition: console.h:28
Definition: serializer.h:308
size_type size() const
Definition: array.h:315
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: seg_manager.h:48
Selector getFuncSelector(const uint16 index) const
Definition: object.h:242
reg_t getFunction(const uint16 index) const
Definition: object.h:235
Definition: vm_types.h:39