ScummVM API documentation
script.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_SCRIPT_H
23 #define SCI_ENGINE_SCRIPT_H
24 
25 #include "common/str.h"
26 #include "sci/util.h"
27 #include "sci/engine/segment.h"
28 #include "sci/engine/script_patches.h"
29 
30 namespace Sci {
31 
32 struct EngineState;
33 class ResourceManager;
34 struct SciScriptPatcherEntry;
35 
36 enum ScriptObjectTypes {
37  SCI_OBJ_TERMINATOR,
38  SCI_OBJ_OBJECT,
39  SCI_OBJ_CODE,
40  SCI_OBJ_SYNONYMS,
41  SCI_OBJ_SAID,
42  SCI_OBJ_STRINGS,
43  SCI_OBJ_CLASS,
44  SCI_OBJ_EXPORTS,
45  SCI_OBJ_POINTERS,
46  SCI_OBJ_PRELOAD_TEXT, /* This is really just a flag. */
47  SCI_OBJ_LOCALVARS
48 };
49 
50 typedef Common::HashMap<uint32, Object> ObjMap;
51 
52 enum ScriptOffsetEntryTypes {
53  SCI_SCR_OFFSET_TYPE_OBJECT = 0, // classes are handled by this type as well
54  SCI_SCR_OFFSET_TYPE_STRING,
55  SCI_SCR_OFFSET_TYPE_SAID
56 };
57 
58 enum : uint {
59  kNoRelocation = 0xFFFFFFFF
60 };
61 
63  uint16 type; // type of entry
64  uint16 id; // id of this type, first item inside script data is 1, second item is 2, etc.
65  uint32 offset; // offset of entry within script resource data
66  uint16 stringSize; // size of string, including terminating [NUL]
67 };
68 
70 
71 class Script : public SegmentObj {
72 private:
73  int _nr;
75  SciSpan<byte> _script;
76  SciSpan<byte> _heap;
78  uint _lockers;
80  SciSpan<const uint16> _exports;
81  uint16 _numExports;
82  SciSpan<const byte> _synonyms;
83  uint16 _numSynonyms;
85  int _codeOffset;
87  int _localsOffset;
88  uint16 _localsCount;
89 
90  bool _markedAsDeleted;
91  SegmentId _localsSegment;
92  LocalVariables *_localsBlock;
93 
94  ObjMap _objects;
96 protected:
97  offsetLookupArrayType _offsetLookupArray; // Table of all elements of currently loaded script, that may get pointed to
98 
99 private:
100  uint16 _offsetLookupObjectCount;
101  uint16 _offsetLookupStringCount;
102  uint16 _offsetLookupSaidCount;
103 
104 public:
105  int getLocalsOffset() const { return _localsOffset; }
106  uint16 getLocalsCount() const { return _localsCount; }
107 
108  uint32 getScriptSize() const { return _script.size(); }
109  uint32 getHeapSize() const { return _heap.size(); }
110  uint32 getBufSize() const { return _buf->size(); }
111  inline uint32 getHeapOffset() const {
112  if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1_LATE) {
113  return _script.size();
114  }
115 
116  return 0;
117  }
118 
119  const byte *getBuf(uint offset = 0) const { return _buf->getUnsafeDataAt(offset); }
120  SciSpan<const byte> getSpan(uint offset) const { return _buf->subspan(offset); }
121 
122  int getScriptNumber() const { return _nr; }
123  SegmentId getLocalsSegment() const { return _localsSegment; }
124  reg_t *getLocalsBegin() { return _localsBlock ? _localsBlock->_locals.begin() : NULL; }
125  void syncLocalsBlock(SegManager *segMan);
126  ObjMap &getObjectMap() { return _objects; }
127  const ObjMap &getObjectMap() const { return _objects; }
128 
129  // speed optimization: inline due to frequent calling
130  bool offsetIsObject(uint32 offset) const {
131  return _buf->getUint16SEAt(offset + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER;
132  }
133 
134 public:
135  Script();
136  ~Script() override;
137 
138  void freeScript(const bool keepLocalsSegment = false);
139  void load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher, bool applyScriptPatches = true);
140 
141  bool isValidOffset(uint32 offset) const override;
142  SegmentRef dereference(reg_t pointer) override;
143  reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const override;
144  void freeAtAddress(SegManager *segMan, reg_t sub_addr) override;
145  Common::Array<reg_t> listAllDeallocatable(SegmentId segId) const override;
146  Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const override;
147 
154  Common::Array<reg_t> listObjectReferences() const;
155 
156  void saveLoadWithSerializer(Common::Serializer &ser) override;
157 
158  Object *getObject(uint32 offset);
159  const Object *getObject(uint32 offset) const;
160 
170  Object *scriptObjInit(reg_t obj_pos, bool fullObjectInit = true);
171 
176  void initializeLocals(SegManager *segMan);
177 
184  void initializeClass(SegManager *segMan, uint16 species, uint32 position);
185 
192  void initializeObjects(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches);
193 
194  // script lock operations
195 
197  void incrementLockers();
198 
200  void decrementLockers();
201 
206  uint getLockers() const;
207 
209  void setLockers(uint lockers);
210 
215  uint getExportsOffset() const { return _exports.sourceByteOffset(); }
216 
221  uint16 getExportsNr() const { return _numExports; }
222 
227  const SciSpan<const byte> &getSynonyms() const { return _synonyms; }
228 
233  uint16 getSynonymsNr() const { return _numSynonyms; }
234 
243  uint32 validateExportFunc(int pubfunct, bool relocSci3);
244 
252  void markDeleted() {
253  _markedAsDeleted = true;
254  }
255 
259  bool isMarkedAsDeleted() const {
260  return _markedAsDeleted;
261  }
262 
267  SciSpan<const byte> findBlockSCI0(ScriptObjectTypes type, bool findLastBlock = false) const;
268 
272  void syncStringHeap(Common::Serializer &ser);
273 
274 #ifdef ENABLE_SCI32
275 
279  int relocateOffsetSci3(uint32 offset) const;
280 #endif
281 
286  int getCodeBlockOffset() { return _codeOffset; }
287 
291  const offsetLookupArrayType *getOffsetArray() { return &_offsetLookupArray; };
292  uint16 getOffsetObjectCount() { return _offsetLookupObjectCount; };
293  uint16 getOffsetStringCount() { return _offsetLookupStringCount; };
294  uint16 getOffsetSaidCount() { return _offsetLookupSaidCount; };
295 
300  uint32 getRelocationOffset(const uint32 offset) const;
301 
302 private:
309  const SciSpan<const uint16> getRelocationTableSci0Sci21() const;
310 
316  void relocateSci0Sci21(const SegmentId segmentId);
317 
318 #ifdef ENABLE_SCI32
319 
324  void relocateSci3(const SegmentId segmentId);
325 #endif
326 
327  bool relocateLocal(SegmentId segment, int location, uint32 offset);
328 
329 #ifdef ENABLE_SCI32
330 
333  SciSpan<const byte> getSci3ObjectsPointer();
334 #endif
335 
342  void initializeObjectsSci0(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches);
343 
350  void initializeObjectsSci11(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches);
351 
352 #ifdef ENABLE_SCI32
353 
358  void initializeObjectsSci3(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches);
359 #endif
360 
361  LocalVariables *allocLocalsSegment(SegManager *segMan);
362 
366  void identifyOffsets();
367 
371  void applySaidWorkarounds();
372 };
373 
374 } // End of namespace Sci
375 
376 #endif // SCI_ENGINE_SCRIPT_H
uint16 getSynonymsNr() const
Definition: script.h:233
Definition: script.h:62
Definition: segment.h:37
iterator begin()
Definition: array.h:374
const SciSpan< const byte > & getSynonyms() const
Definition: script.h:227
uint getExportsOffset() const
Definition: script.h:215
Definition: span.h:892
Definition: serializer.h:79
Definition: resource.h:327
void markDeleted()
Definition: script.h:252
Definition: segment.h:82
Definition: segment.h:147
Definition: script.h:71
Definition: object.h:69
int getCodeBlockOffset()
Definition: script.h:286
uint16 getExportsNr() const
Definition: script.h:221
Definition: console.h:28
Definition: seg_manager.h:48
Definition: script_patches.h:91
const offsetLookupArrayType * getOffsetArray()
Definition: script.h:291
Definition: vm_types.h:39
bool isMarkedAsDeleted() const
Definition: script.h:259