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
30namespace Sci {
31
32struct EngineState;
33class ResourceManager;
34struct SciScriptPatcherEntry;
35
36enum 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
51
52enum 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
58enum : 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
71class Script : public SegmentObj {
72private:
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;
96protected:
97 offsetLookupArrayType _offsetLookupArray; // Table of all elements of currently loaded script, that may get pointed to
98
99private:
100 uint16 _offsetLookupObjectCount;
101 uint16 _offsetLookupStringCount;
102 uint16 _offsetLookupSaidCount;
103
104public:
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
134public:
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;
147
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
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
198
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
273
274#ifdef ENABLE_SCI32
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
302private:
309 const SciSpan<const uint16> getRelocationTableSci0Sci21() const;
310
316 void relocateSci0Sci21(const SegmentId segmentId);
317
318#ifdef ENABLE_SCI32
324 void relocateSci3(const SegmentId segmentId);
325#endif
326
327 bool relocateLocal(SegmentId segment, int location, uint32 offset);
328
329#ifdef ENABLE_SCI32
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
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
iterator begin()
Definition: array.h:375
Definition: serializer.h:80
Definition: span.h:893
Definition: object.h:69
Definition: resource.h:327
Definition: script.h:71
uint32 getRelocationOffset(const uint32 offset) const
uint getLockers() const
SciSpan< const byte > findBlockSCI0(ScriptObjectTypes type, bool findLastBlock=false) const
void initializeLocals(SegManager *segMan)
bool isValidOffset(uint32 offset) const override
const SciSpan< const byte > & getSynonyms() const
Definition: script.h:227
void initializeClass(SegManager *segMan, uint16 species, uint32 position)
void incrementLockers()
Common::Array< reg_t > listAllOutgoingReferences(reg_t object) const override
bool isMarkedAsDeleted() const
Definition: script.h:259
int getCodeBlockOffset()
Definition: script.h:286
void freeAtAddress(SegManager *segMan, reg_t sub_addr) override
Common::Array< reg_t > listAllDeallocatable(SegmentId segId) const override
void markDeleted()
Definition: script.h:252
void syncStringHeap(Common::Serializer &ser)
void setLockers(uint lockers)
uint16 getExportsNr() const
Definition: script.h:221
Object * scriptObjInit(reg_t obj_pos, bool fullObjectInit=true)
uint16 getSynonymsNr() const
Definition: script.h:233
reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const override
uint getExportsOffset() const
Definition: script.h:215
void decrementLockers()
const offsetLookupArrayType * getOffsetArray()
Definition: script.h:291
void initializeObjects(SegManager *segMan, SegmentId segmentId, bool applyScriptPatches)
uint32 validateExportFunc(int pubfunct, bool relocSci3)
SegmentRef dereference(reg_t pointer) override
Common::Array< reg_t > listObjectReferences() const
Definition: script_patches.h:91
Definition: seg_manager.h:48
Definition: console.h:28
Definition: segment.h:147
Definition: segment.h:82
Definition: segment.h:37
Definition: script.h:62
Definition: vm_types.h:39