ScummVM API documentation
miniscript.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 MTROPOLIS_MINISCRIPT_H
23#define MTROPOLIS_MINISCRIPT_H
24
25#include "mtropolis/data.h"
26#include "mtropolis/runtime.h"
27
28namespace MTropolis {
29
30class MiniscriptThread;
31struct MiniscriptStackValue;
32struct SIMiniscriptInstructionFactory;
33
34bool miniscriptEvaluateTruth(const DynamicValue &value);
35
37public:
38 virtual ~MiniscriptInstruction();
39
40 virtual MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const = 0;
41};
42
44public:
46
47 virtual uint registerGlobalGUIDIndex(uint32 guid) = 0;
48};
49
51public:
52 struct LocalRef {
53 LocalRef();
54
55 uint32 guid;
56 Common::String name;
58 };
59
60 struct GlobalRef {
61 GlobalRef();
62
63 uint32 guid;
65 };
66
67 explicit MiniscriptReferences(const Common::Array<LocalRef> &localRefs, const Common::Array<GlobalRef> &globalRefs);
68
69 void linkInternalReferences(ObjectLinkingScope *scope);
70 void visitInternalReferences(IStructuralReferenceVisitor *visitor);
71
72 Common::WeakPtr<RuntimeObject> getRefByIndex(uint index) const;
73 Common::WeakPtr<RuntimeObject> getGlobalRefByIndex(uint index) const;
74
75private:
76 Common::Array<LocalRef> _localRefs;
77 Common::Array<GlobalRef> _globalRefs;
78
79};
80
82public:
83
84 struct Attribute {
85 Common::String name;
86 };
87
90
91 const Common::Array<MiniscriptInstruction *> &getInstructions() const;
92 const Common::Array<Attribute> &getAttributes() const;
93
94private:
97 Common::Array<Attribute> _attributes;
98};
99
101public:
102 static bool parse(const Data::MiniscriptProgram &programData, Common::SharedPtr<MiniscriptProgram> &outProgram, Common::SharedPtr<MiniscriptReferences> &outReferences);
103
104 static SIMiniscriptInstructionFactory *resolveOpcode(uint16 opcode);
105
106private:
107 struct InstructionData {
108 InstructionData();
109
110 uint16 opcode;
111 uint16 flags;
112 size_t pdPosition;
113 SIMiniscriptInstructionFactory *instrFactory;
114 Common::Array<uint8> contents;
115 };
116};
117
118namespace MiniscriptInstructions {
120 private:
121 virtual MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
122 };
123
124 class Set : public MiniscriptInstruction {
125 private:
126 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
127 };
128
130 public:
131 explicit Send(const Event &evt, const MessageFlags &messageFlags);
132
133 private:
134 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
135
136 Event _evt;
137 MessageFlags _messageFlags;
138 };
139
141 private:
142 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
143
144 protected:
145 virtual MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const = 0;
146 };
147
149 private:
150 MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
151 };
152
154 private:
155 MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
156 };
157
159 private:
160 MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
161 };
162
164 private:
165 MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
166 };
167
169 private:
170 MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
171 };
172
174 private:
175 MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
176 };
177
179 private:
180 MiniscriptInstructionOutcome arithExecute(MiniscriptThread *thread, double &result, double left, double right) const override;
181 };
182
183 class And : public MiniscriptInstruction {
184 private:
185 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
186 };
187
188 class Or : public MiniscriptInstruction {
189 private:
190 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
191 };
192
193 class Neg : public MiniscriptInstruction {
194 private:
195 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
196 };
197
198 class Not : public MiniscriptInstruction {
199 private:
200 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
201 };
202
204 protected:
205 virtual bool compareFloat(double a, double b) const = 0;
206
207 private:
208 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
209 };
210
212 protected:
213 virtual bool resolve(bool isEqual) const = 0;
214
215 private:
216 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
217 };
218
220 private:
221 bool resolve(bool isEqual) const override { return isEqual; };
222 };
223
225 private:
226 bool resolve(bool isEqual) const override { return !isEqual; };
227 };
228
230 private:
231 bool compareFloat(double a, double b) const override { return a <= b; }
232 };
233
235 private:
236 bool compareFloat(double a, double b) const override { return a < b; }
237 };
238
240 private:
241 bool compareFloat(double a, double b) const override { return a >= b; }
242 };
243
245 private:
246 bool compareFloat(double a, double b) const override { return a > b; }
247 };
248
250 public:
251 enum BuiltinFunctionID {
252 kSin = 1,
253 kCos = 2,
254 kRandom = 3,
255 kSqrt = 4,
256 kTan = 5,
257 kAbs = 6,
258 kSign = 7,
259 kArctangent = 8,
260 kExp = 9,
261 kLn = 10,
262 kLog = 11,
263 kCosH = 12,
264 kSinH = 13,
265 kTanH = 14,
266 kRect2Polar = 15,
267 kPolar2Rect = 16,
268 kTrunc = 17,
269 kRound = 18,
270 kNum2Str = 19,
271 kStr2Num = 20,
272 };
273
274 explicit BuiltinFunc(BuiltinFunctionID bfid);
275
276 private:
277 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
278
279 MiniscriptInstructionOutcome executeFunction(MiniscriptThread *thread, DynamicValue *returnValue) const;
280 MiniscriptInstructionOutcome executeSimpleNumericInstruction(MiniscriptThread *thread, DynamicValue *returnValue) const;
281 MiniscriptInstructionOutcome executeRectToPolar(MiniscriptThread *thread, DynamicValue *returnValue) const;
282 MiniscriptInstructionOutcome executePolarToRect(MiniscriptThread *thread, DynamicValue *returnValue) const;
283 MiniscriptInstructionOutcome executeNum2Str(MiniscriptThread *thread, DynamicValue *returnValue) const;
284 MiniscriptInstructionOutcome executeStr2Num(MiniscriptThread *thread, DynamicValue *returnValue) const;
285
286 BuiltinFunctionID _funcID;
287 };
288
290 private:
291 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
292 };
293
295 private:
296 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
297 };
298
300 private:
301 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
302 };
303
305 };
306
308 public:
309 GetChild(uint32 attribute, bool isLValue, bool isIndexed);
310
311 private:
312 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
313 MiniscriptInstructionOutcome readRValueAttrib(MiniscriptThread *thread, DynamicValue &valueSrcDest, const Common::String &attrib) const;
314 MiniscriptInstructionOutcome readRValueAttribIndexed(MiniscriptThread *thread, DynamicValue &valueSrcDest, const Common::String &attrib, const DynamicValue &index) const;
315
316 uint32 _attribute;
317 bool _isLValue;
318 bool _isIndexed;
319 };
320
322 private:
323 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
324 };
325
327 private:
328 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
329 };
330
332 public:
333 enum DataType {
334 kDataTypeNull,
335 kDataTypeDouble,
336 kDataTypeBool,
337 kDataTypeLocalRef,
338 kDataTypeGlobalRef,
339 kDataTypeLabel,
340 };
341
342 struct Label {
343 uint32 superGroup;
344 uint32 id;
345 };
346
347 PushValue(DataType dataType, const void *value, bool isLValue);
348 ~PushValue();
349
350 private:
351 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
352
353 union ValueUnion {
354 ValueUnion();
355
356 bool b;
357 double f;
358 uint32 ref;
359 Label lbl;
360 };
361
362 DataType _dataType;
363 ValueUnion _value;
364 //bool _isLValue;
365 };
366
368 public:
369 explicit PushGlobal(uint32 globalID, bool isLValue);
370
371 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
372
373 private:
374 enum {
375 kGlobalRefElement = 1,
376 kGlobalRefModifier = 2,
377 kGlobalRefSource = 3,
378 kGlobalRefIncomingData = 4,
379 kGlobalRefMouse = 5,
380 kGlobalRefTicks = 6,
381 kGlobalRefScene = 7,
382 kGlobalRefSharedScene = 8,
383 kGlobalRefSection = 9,
384 kGlobalRefProject = 10,
385 kGlobalRefActiveScene = 11,
386 };
387
388 MiniscriptInstructionOutcome executeFindFilteredParent(MiniscriptThread *thread, DynamicValue &result) const;
389
390 uint32 _globalID;
391 bool _isLValue;
392 };
393
395 public:
396 explicit PushString(const Common::String &str);
397
398 private:
399 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
400
401 Common::String _str;
402 };
403
405 public:
406 Jump(uint32 instrOffset, bool isConditional);
407
408 private:
409 MiniscriptInstructionOutcome execute(MiniscriptThread *thread) const override;
410
411 uint32 _instrOffset;
412 bool _isConditional;
413 };
414} // End of namespace MiniscriptInstructions
415
416
418 DynamicValue value;
419};
420
422public:
424
425 void error(const Common::String &message);
426
427 const Common::SharedPtr<MiniscriptProgram> &getProgram() const;
428 const Common::SharedPtr<MiniscriptReferences> &getRefs() const;
429 Modifier *getModifier() const;
430 const Common::SharedPtr<MessageProperties> &getMessageProperties() const;
431 Runtime *getRuntime() const;
432
433 void pushValue(const DynamicValue &value);
434 void popValues(size_t count);
435 size_t getStackSize() const;
436 MiniscriptStackValue &getStackValueFromTop(size_t offset);
437 MiniscriptInstructionOutcome dereferenceRValue(size_t offset);
438
439 void jumpOffset(size_t offset);
440
441 bool evaluateTruthOfResult(bool &isTrue);
442
443 void createWriteIncomingDataProxy(DynamicValueWriteProxy &proxy);
444
445 void retryInstruction();
446
448 CORO_DEFINE_RETURN_TYPE(void);
449 CORO_DEFINE_PARAMS_1(Common::SharedPtr<MiniscriptThread>, thread);
450 };
451
452private:
453 struct IncomingDataWriteInterface {
454 static MiniscriptInstructionOutcome write(MiniscriptThread *thread, const DynamicValue &dest, void *objectRef, uintptr ptrOrOffset);
455 static MiniscriptInstructionOutcome refAttrib(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, void *objectRef, uintptr ptrOrOffset, const Common::String &attrib);
456 static MiniscriptInstructionOutcome refAttribIndexed(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, void *objectRef, uintptr ptrOrOffset, const Common::String &attrib, const DynamicValue &index);
457 };
458
459 MiniscriptInstructionOutcome runNextInstruction();
460
461 VThreadState resume(MiniscriptThread *thread);
462
463 MiniscriptInstructionOutcome tryLoadVariable(MiniscriptStackValue &stackValue);
464
468
469 Modifier *_modifier;
470 Runtime *_runtime;
472
473 size_t _currentInstruction;
474 bool _failed;
475};
476
477MiniscriptInstructionOutcome miniscriptIgnoreFailure(MiniscriptInstructionOutcome outcome);
478
479} // End of namespace MTropolis
480
481#endif
Definition: array.h:52
Definition: ptr.h:159
Definition: str.h:59
Definition: ptr.h:381
Definition: miniscript.h:36
Definition: miniscript.h:148
Definition: miniscript.h:183
Definition: miniscript.h:234
Definition: miniscript.h:163
Definition: miniscript.h:173
Definition: miniscript.h:404
Definition: miniscript.h:178
Definition: miniscript.h:158
Definition: miniscript.h:193
Definition: miniscript.h:198
Definition: miniscript.h:188
Definition: miniscript.h:168
Definition: miniscript.h:129
Definition: miniscript.h:124
Definition: miniscript.h:153
Definition: miniscript.h:100
Definition: miniscript.h:81
Definition: miniscript.h:50
Definition: miniscript.h:421
Definition: runtime.h:3035
Definition: runtime.h:1307
Definition: runtime.h:1575
Definition: actions.h:25
Definition: data.h:1033
Definition: runtime.h:816
Definition: runtime.h:544
Definition: runtime.h:369
Definition: runtime.h:2118
Definition: runtime.h:488
Definition: miniscript.h:84
Definition: miniscript.h:417