ScummVM API documentation
scriptexecutor.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 MACS2_SCRIPTEXECUTOR_H
23 #define MACS2_SCRIPTEXECUTOR_H
24 
25 #include "common/array.h"
26 #include "common/path.h"
27 #include "common/rect.h"
28 #include "common/scummsys.h"
29 #include "common/str-array.h"
30 
31 namespace Common {
32 class MemoryReadStream;
33 }
34 
35 namespace Macs2 {
36 class Macs2Engine;
37 class Character;
38 class GameObject;
39 
40 namespace Script {
41 
43  uint16 a;
44  uint16 b;
45 };
46 // Order of cursors when loading from the file is
47 // { Talk = 0, Look = 1, Touch = 2, Walk = 3};
48 // Cursor mode values from setCursorMode (1008:3ea5) and handleInput.
49 // Each mode indexes into the cursor image array at _PTR_LOOP_1020_075a
50 // (16 bytes per entry: data ptr, size, width, height, hotspot x/y).
51 enum class MouseMode {
52  Talk = 0x13,
53  Look = 0x14,
54  Use = 0x15,
55  Walk = 0x16,
56  UseInventory = 0x17,
57  PanelUse = 0x18, // Used in map mode
58  PanelCursor = 0x19, // Used when action bar is open
59  Disabled = 0x1A // Hidden/disabled cursor
60 };
61 
62 enum class ExecutorState {
63  // We are not executing anything at the moment
64  Idle,
65  // We are in the middle of executing
66  Executing,
67  // Executing but paused until a callback happens
68  WaitingForCallback
69 };
70 
72 enum class OpcodeResult {
74  Continue,
76  FinishScript,
78  WaitForCallback,
83  ReturnFinished
84 };
85 
86 enum class ScriptExecutionState {
87  // We are executing the scene script
88  ExecutingSceneScript,
89 
90  // We are executing the other scripts
91  ExecutingOtherScripts
92 };
93 
108 public:
109  typedef OpcodeResult (ScriptExecutor::*OpcodeHandler)();
110 
111  struct OpcodeEntry {
112  const char *name;
113  OpcodeHandler handler;
114  };
115 
117  void setOpcodeTable(const OpcodeEntry *table, uint size);
119  const char *opcodeName(uint8 opcode) const;
120 
122  static const OpcodeEntry kV1OpcodeTable[];
123  static const uint kV1OpcodeTableSize;
128  static const OpcodeEntry kV2OpcodeTable[];
129  static const uint kV2OpcodeTableSize;
130 
131 private:
132 #ifdef DEMACS2
133 public:
134 #endif
135  OpcodeResult scriptSetVar();
136  OpcodeResult scriptSetVarOr();
137  OpcodeResult scriptIfTrue();
138  OpcodeResult scriptIfFalse();
139  OpcodeResult scriptCompare();
140  OpcodeResult scriptIfInteraction();
141  OpcodeResult scriptEndIf();
142  OpcodeResult scriptElse();
143  OpcodeResult scriptNop09();
144  OpcodeResult scriptPrintStringLeft();
145  OpcodeResult scriptMoveObject();
146  OpcodeResult scriptChangeScene();
147  OpcodeResult scriptShowDialogue();
148  OpcodeResult scriptWalkToPosition();
149  OpcodeResult scriptWaitForWalk();
150  OpcodeResult scriptSkipWord();
151  OpcodeResult scriptClearDialogueChoices();
152  OpcodeResult scriptAddDialogueChoice();
153  OpcodeResult scriptShowDialogueChoice();
154  OpcodeResult scriptDismissPanel();
155  OpcodeResult scriptWalkToAndPickup();
156  OpcodeResult scriptSetPickupFrames();
157  OpcodeResult scriptSetupObject();
158  OpcodeResult scriptSetSkippable();
159  OpcodeResult scriptClearSkippable();
160  OpcodeResult scriptPlayAnimation();
161  OpcodeResult scriptTestPathfinding();
162  OpcodeResult scriptSetYOffset();
163  OpcodeResult scriptSetMotion();
164  OpcodeResult scriptSetOrientation();
165  OpcodeResult scriptMoveToPosition();
166  OpcodeResult scriptAddValues();
167  OpcodeResult scriptSubValues();
168  OpcodeResult scriptLoadSpecialAnim();
169  OpcodeResult scriptSetDirection();
170  OpcodeResult scriptStopAnimation();
171  OpcodeResult scriptOpenInventory();
172  OpcodeResult scriptLoadObjectAnim();
173  OpcodeResult scriptCheckObjectData();
174  OpcodeResult scriptCheckInventory();
175  OpcodeResult scriptSetSnapToTarget();
176  OpcodeResult scriptTestObjectAnimFrame();
177  OpcodeResult scriptPrintStringRight();
178  OpcodeResult scriptSetPaletteDarkness();
179  OpcodeResult scriptSetObjectShading();
180  OpcodeResult scriptSetObjectScaling();
181  OpcodeResult scriptSetHotspotOverride();
182  OpcodeResult scriptSetObjectBounds();
183  OpcodeResult scriptDismissAllPanels();
184  OpcodeResult scriptResetToSceneScript();
185  OpcodeResult scriptLoadOverlayFont();
186  OpcodeResult scriptAddOverlayTextEntry();
187  OpcodeResult scriptClearOverlayText();
188  OpcodeResult scriptFadeToBlack();
189  OpcodeResult scriptLoadPcmSound();
190  OpcodeResult scriptPlayPcmSound();
191  OpcodeResult scriptWaitForSound();
192  OpcodeResult scriptStopPcmSound();
193  OpcodeResult scriptLoadMusicSlot();
194  OpcodeResult scriptPlayMusicSlot();
195  OpcodeResult scriptStopMusicSlot();
196  OpcodeResult scriptWaitForMusic();
197  OpcodeResult scriptFreeMusicSlot();
198  OpcodeResult scriptGetObjectX();
199  OpcodeResult scriptGetObjectY();
200  OpcodeResult scriptGetObjectField8();
201  OpcodeResult scriptGetObjectOrientation();
202  OpcodeResult scriptClearActorInventory();
203  OpcodeResult scriptSetPathfindingRemap();
204  OpcodeResult scriptWaitForAdlib();
205  OpcodeResult scriptSkipUntil14();
206  OpcodeResult scriptChangeAnimation();
207  OpcodeResult scriptFrameWait();
208  OpcodeResult scriptSetPathfinding();
209  OpcodeResult scriptTestSceneAnimFrame();
210  OpcodeResult scriptEndOverlayText();
211  OpcodeResult scriptFadeFromBlack();
212  OpcodeResult scriptFreePcmSound();
213 
215  void scriptSkipOpcodeRemainder(uint8 opcode);
216 
217  // Dialect v2: remapped audio slots (v1 PCM/music-slot opcodes are NOPs here).
218  OpcodeResult scriptNopSkipRemainder();
219  OpcodeResult scriptPlaySfx();
220  OpcodeResult scriptPlaySong();
221  OpcodeResult scriptStopSong();
223  Common::String scriptReadFixedFileName();
224  Common::String scriptParsePascalFileName(const Common::String &raw);
226  Common::Path resolveAudioFilePath(const Common::String &fileName, bool preferSpeech) const;
228  Common::Path resolveMidiFilePath(const Common::String &fileName) const;
234  void tryPlayDialogueSpeech(uint16 stringOffset, const Common::Array<Common::String> &lines);
235 
236  // Dialect v2: extended opcodes 0x4F..0x6D (stubs until backends exist).
237  OpcodeResult scriptSetMainActor();
238  OpcodeResult scriptLoadDeltaAnim();
239  OpcodeResult scriptPlayDeltaAnim();
240  OpcodeResult scriptRemoveDeltaAnim();
241  OpcodeResult scriptSetButtonStep();
242  OpcodeResult scriptTestButtonAnimFrame();
243  OpcodeResult scriptScreenShot();
244  OpcodeResult scriptWaitObjectAnimStep();
245  OpcodeResult scriptWaitSpecialAnimStep();
246  OpcodeResult scriptSetObjectAdjust();
247  OpcodeResult scriptReloadSpecialAnim();
248  OpcodeResult scriptPlayDiskDelta();
249  OpcodeResult scriptSetDiskCache();
250  OpcodeResult scriptSetMidiVolume();
251  OpcodeResult scriptSetWaveVolume();
252  OpcodeResult scriptLoadSpecialAnimSlot();
253  OpcodeResult scriptSetSpecialAnimSlot();
254  OpcodeResult scriptClearSpecialAnimSlot();
255  OpcodeResult scriptSetDeltaRange();
256  OpcodeResult scriptClearDeltaRange();
257  OpcodeResult scriptAddDeltaSfx();
258  OpcodeResult scriptClearDeltaSfxList();
259  OpcodeResult scriptShowActionBar();
260  OpcodeResult scriptHideActionBar();
261  OpcodeResult scriptSetCursorType();
262  OpcodeResult scriptCheckDeltaSpeed();
263  OpcodeResult scriptLoadDistanceMask();
264  OpcodeResult scriptLoadAreaMask();
265  OpcodeResult scriptLoadWalkMask();
266  OpcodeResult scriptLoadShadowMask();
267  OpcodeResult scriptTalkTo();
268 
269  inline void scriptUnimplementedOpcode(const char *source, uint16 opcode) {
270  debug("Unimplemented opcode (%s): %.2x.", source, opcode);
271  }
272 #ifdef DEMACS2
273 private:
274 #endif
275 
276  // Active opcode table
277  const OpcodeEntry *_opcodeTable = nullptr;
278  uint _opcodeTableSize = 0;
279 
280  // State variables from here
281 
282  // Overall state
283  ExecutorState _state = ExecutorState::Idle;
284 
285  // Currently executed script
286  Common::MemoryReadStream *_stream = nullptr;
287 
288  // [1014h] global - current assumption is that this is set when we run
289  // the script for the scene initialization and reset when we run when the
290  // scene is active
291  bool _isSceneInitRun = false;
292 
293  // [1012h] global - current assumption is that this guards script runs that
294  // [1012h] g_wRepeatRunFlag - set during the repeat script pass
295  // that runs after scene init to process object scripts
296  bool _repeatRunFlag = false;
297 
298  // Binary runs init and repeat as separate runScriptExecutor calls inside
299  // scriptChangeScene. Init pass = scene script (isSceneInit) + object scripts.
300  // Repeat pass = second call with RepeatRunFlag=1 only.
301  bool _initPassComplete = false;
302  bool _deferredRepeatAfterInit = false;
303  bool _terminateOuterScriptBeforeRepeat = false;
304 
305  uint16 _executingObjectIndex = 0;
306 
307  ScriptExecutionState _scriptExecutionState = ScriptExecutionState::ExecutingSceneScript;
308 
309  // Returns true if the object is relevant to be executing in the current scene
310  bool isRelevantObject(const GameObject *obj) const;
311 
312  // Handles the next step of execution based on the current state.
313  // Can be run right after a previous step or be called after execution was paused
314  // Needs to update the state to be valid again
315  void step();
316 
317  // Depending on the current state, chooses the next script to run
318  // and adjusts the state
319  // Should return true if a new script was loaded
320  bool loadNextScript();
321 
322  bool _isTimerActive = false;
323  uint32 _timerEndMillis = 0;
324  bool _isFrameWaitActive = false;
325  uint16 _frameWaitTicksRemaining = 0;
326 
327  // We use this array to gather the dialogue choices as they come in
328 
329  Common::String identifyScriptOpcode(uint8 opcode, uint8 opcode2);
330  Common::String identifyHelperOpcode(uint8 opcode, uint16 value);
331 
332  byte readByte();
333  uint16 readUint16();
334 
335  // We use this to keep track of whether we have read all bytes we should have read
336  uint32 _expectedEndLocation = 0;
337  uint8 _lastOpcode = 0;
338  uint32 _lastOpcodeStreamPos = 0;
339 
340  // scriptSkipBlock: skips nested opcode blocks
341  void scriptSkipBlock();
342  // scriptSkipAlternate: alternate skip (for opcode 8)
343  void scriptSkipAlternate();
344 
345  bool loadIndexedResource(Common::Array<uint8> &outData, uint8 resourceIndex, uint16 objectTableOffset = 0x189);
351  bool loadSoundResource(Common::Array<uint8> &outData, uint8 resourceIndex,
352  int &rateHz, int &headerSkip);
353  bool loadMusicResource(Common::Array<uint8> &outData, uint8 resourceIndex);
354 
355  // scriptReadValue: reads a typed value from the script stream
356  void scriptReadValuePair(uint16 &out1, uint16 &out2);
357 
358  // Combines both 16 bit values into a 32 bit value
359  uint32 scriptReadValue32();
360 
361  // Returns only the first of the two 16 bit values
362  uint16 scriptReadValue16();
363 
365  int16 scriptReadCoord16();
366 
368  void skipOptionalVarIndexPadding();
369 
370  // Saves the given value in a script variable
371  void scriptSaveVariableHelper(uint32 value);
372 
373  void scriptPrintString(bool alignRight = false);
374 
375  Common::StringArray _debugBuffer;
376  bool _lastOpcodeTriggeredSkip = false;
377  void beginBuffering();
378  void endBuffering(bool shouldMark = false);
379 
380  // g_wExecutingScriptObjectId [0F92h]: 0 when executing the scene script,
381  // 1..0x200 the object index whose script is running, > 0x200 when the
382  // object iteration in run() is exhausted (or a script terminated the run,
383  // e.g. opcode 0x29). The binary drives the whole script-selection flow off
384  // this single value; there is no separate scene-vs-object state flag.
385  uint16 _executingScriptObjectId = 0;
386  // Binary g_wScriptEndPosition [0xf90] and g_wScriptIsExecuting [0xf88].
387  // End is the active script byte limit (scene+0x520b or object runtime+0x18b);
388  // isExecuting is (position < end), persisted in savegames.
389  uint32 _scriptEndPosition = 0;
390  bool _scriptIsExecuting = false;
391 
392  uint32 effectiveScriptEnd() const;
393  void clampScriptEndToStream();
394 
395 public:
397  ~ScriptExecutor();
398 
399  void syncScriptIsExecutingFlag();
400 
402  static Common::String stripAudioExtension(const Common::String &fileName);
403 
404  void setIdle() { _state = ExecutorState::Idle; }
405 
412  void restoreScriptExecutionAfterLoad(bool isExecuting, uint16 executingObjectId,
413  uint16 scriptPosition, uint16 scriptEndPosition);
414 
416  void prepareScriptStateForSave();
417 
418  Common::Array<uint16> _dialogueChoiceScriptIndices;
419  Common::Array<Common::StringArray> _dialogueChoices;
420 
421  // Binary scriptOpenInventory (1008:c3e6) / handleInput panel-3 close (1008:e8bf):
422  // saved script stream state restored when container inventory closes.
423  uint32 _savedOpenInventoryScriptPos = 0;
424  uint32 _savedOpenInventoryScriptEndPos = 0;
425  uint16 _savedOpenInventoryExecutingObjectId = 0;
426  // Legacy alias used by saveload; kept in sync with _savedOpenInventoryScriptPos.
427  uint32 _secondaryInventoryLocation = 0;
428  bool _hasPendingExternalInventoryResume = false;
429  uint16 _externalInventorySourceObjectID = 0;
430  MouseMode _savedExternalInventoryMouseMode = MouseMode::Use;
431 
432  // Determines if we actually look something up when looking up 9F4D FF 27
433  // in the obstacles/pathfinding map
434  // Should be 1 while we execute a "character stopped walking" script,
435  // otherwise 0
436  bool _pathWalkableResult = false;
437  bool _isRepeatRun = false;
438 
439  // chosen dialogue script index
440  int _chosenDialogueOption = 0;
441  uint16 _dialogueSpeakerObjectID = 0;
442 
443  // 0x2000 bytes / 4 bytes per var = 2048 variables max (indices 1-0x800).
444  // All zeroed on init by memsetBytes in loadResourceFile.
446 
447  // g_wCursorMode (1020:0fe6): the active cursor mode (0x13..0x1A).
448  MouseMode _cursorMode = MouseMode::Walk;
449  MouseMode _cursorModeBeforeWait = MouseMode::Walk;
450  // Set by opcodes 0x0A/0x0D/0x17 while waiting for the player to dismiss text UI.
451  // Binary keeps a clickable cursor for those waits; step() must not force hourglass.
452  bool _waitingForUiClick = false;
453 
454  uint16 _interactedObjectID = 0;
455  // g_wInteractedInventoryItemId [1026h]: inventory item involved in a
456  // use-inventory-item-on-object interaction (0x400 + item object index).
457  uint16 _interactedInventoryItemId = 0;
458  uint16 _walkTargetObjectIndex = 0;
459  // Script click state: set by handleInput when user clicks during script execution.
460  // Saved/restored by scriptOpenInventory across UI interactions.
461  uint16 _scriptClickFlag = 0;
462  uint16 _scriptClickX = 0;
463  uint16 _scriptClickY = 0;
464  uint16 _scriptClickResult = 0;
465  uint16 _savedScriptClickFlag = 0;
466  uint16 _savedScriptClickX = 0;
467  uint16 _savedScriptClickY = 0;
468  uint16 _savedScriptClickResult = 0;
469 
470  // Is set to true in opcode 2C if an object is inside another target object
471  bool _inventoryCheckResult = false;
472  bool _animBlobRangeTestResult = false;
473  bool _soundEnabled = true;
474  // [102Ah] - separate from soundEnabled (sound). Controls whether the
475  // player can fast-forward the current script section via button 8.
476  // Set by opcode 0x1C, cleared by opcode 0x1D.
477  bool _scriptSkippable = false;
478  bool _musicEnabled = true;
479  bool _soundSystemActive = true;
481  bool _textEnabled = true;
482  bool _overlayTextStageActive = false;
483  bool _inventoryActionFlag = false;
484  bool _inventoryCombineFlag = false;
485  Common::Array<uint8> _musicSlots[2];
486  uint16 _activeMusicSlot = 0;
487  uint16 _musicControlMode = 0;
488  // g_wMusicControlStep: per-tick volume fade step for the music fade in gameTick.
489  uint16 _musicControlStep = 0;
490  uint16 _musicControlVolume = 0;
491  // g_wWaitForPcmSound [100Ch] (opcode 0x41), g_wWaitForMusicControl [100Eh]
492  // (opcode 0x47), g_wWaitForAdlibReady [1010h] (opcode 0x4E): wait flags
493  // polled by the gameTick wait cascade (View1::tick).
494  bool _waitForPcmSound = false;
495  bool _waitForMusicControl = false;
496  bool _waitForAdlibReady = false;
497  // Dialect-v2: wait until an object/scene anim sequencePosition reaches a target.
498  bool _waitForObjectAnimStep = false;
499  uint16 _waitObjectAnimObjectId = 0;
500  uint16 _waitObjectAnimSlot = 0;
501  uint16 _waitObjectAnimTargetStep = 0;
502  bool _waitForSpecialAnimStep = false;
503  uint16 _waitSpecialAnimIndex = 0;
504  uint16 _waitSpecialAnimTargetStep = 0;
505  bool _waitForDeltaAnim = false;
506  bool _waitForDeltaSpeed = false;
507  bool _debugPaused = false;
508  bool _pickupInProgress = false;
509  uint16 _pickupActorObjectID = 0;
510  uint16 _pickupTargetObjectID = 0;
511 
512  Macs2::Macs2Engine *_engine;
513 
514  // Button 8 skip from handleInput (1008:e8bf)
515  bool skipToEndOfSkippableSection();
516 
517  // Implements a lookup in the "areas" map
518  uint16 getAreaAtPoint(uint16 x, uint16 y);
519 
520  void setVariableValue(uint16 index, uint16 a, uint16 b);
521 
522  void setVariableValue(uint16 index, uint32 value);
523 
524  Common::Point getCharPosition();
525 
526  // executeOpcodes (1008:db56): the opcode dispatch loop for the current script.
527  OpcodeResult executeOpcodes();
528 
529  // Execute the scene script and any object scripts until execution should stop.
530  // Fresh runs bind Scenes::_currentSceneScript at offset 0; mid-script resumes continue in place.
531  void run(bool firstRun = false);
532 
533  void setScript(Common::MemoryReadStream *stream);
534  void releaseObjectStream();
535 
536  void setCurrentSceneScriptAt(uint32 offset);
537 
538  void tick();
539 
540  void startTimer(uint32 duration);
541  void endTimer();
542  void startFrameWait(uint16 duration);
543  void endFrameWait();
544 
545  // True when script execution is paused on any wait opcode (frame, walk, dialogue, etc.).
546  bool isScriptWaitDeferred() const {
547  return _state == ExecutorState::WaitingForCallback ||
548  _frameWaitTicksRemaining != 0 || _walkTargetObjectIndex != 0 ||
549  _waitForPcmSound || _waitForMusicControl || _waitForAdlibReady ||
550  _waitForObjectAnimStep || _waitForSpecialAnimStep ||
551  _waitForDeltaAnim || _waitForDeltaSpeed;
552  }
553 
554  bool isExecuting() const {
555  return _state != ExecutorState::Idle;
556  }
557 
559  bool isScriptMidExecution() const {
560  return _scriptIsExecuting;
561  }
562 
563  uint32 getScriptPosition() const;
564  // Returns the position of the last executed/executing opcode (for debugger highlight)
565  uint32 getDebugOpcodePosition() const;
566  bool isWaitingForCallback() const {
567  return _state == ExecutorState::WaitingForCallback;
568  }
569  uint32 getScriptEndPosition() const;
570  // Binary g_wExecutingScriptObjectId [0xf92]: 0 = scene script, 1..0x200 = object.
571  // Not _executingObjectIndex (iteration cursor / last scene index after Idle).
572  uint16 getExecutingObjectId() const {
573  return _executingScriptObjectId;
574  }
575  void setExecutingObjectId(uint16 id) {
576  _executingScriptObjectId = id;
577  }
578  uint16 getFrameWaitCounter() const {
579  return _frameWaitTicksRemaining;
580  }
581  void setFrameWaitCounter(uint16 val) {
582  _frameWaitTicksRemaining = val;
583  }
584  bool isFrameWaitActive() const {
585  return _isFrameWaitActive;
586  }
587  bool getRepeatRunFlag() const {
588  return _repeatRunFlag;
589  }
590  void setRepeatRunFlag(bool val) {
591  _repeatRunFlag = val;
592  }
593  uint32 getVariableValue(int index) const;
594 
595  // Plate / walk debugging: log actor position, area, walkability, script waits.
596  void debugLogActorWalkState(const char *context);
597 
598  // Computes the read-only runtime value for a type 0xFF special
599  // (FF:value), inlined in scriptReadValue in the original binary
600  uint32 getSpecialValue(uint16 value);
601 
602  // Returns true if the save/load menu can be opened (no blocking state)
603  bool canOpenSaveMenu() const {
604  return !_isSceneInitRun && !_isFrameWaitActive && !_isTimerActive;
605  }
606 
607  // g_wScriptErrorCode (1020:0f86): non-zero halts opcode dispatch (1008:db56).
608  uint16 _scriptErrorCode = 0;
609  Character *getOrCreateCharacter(uint16 objectID);
610  void saveWalkRuntime(const Character *c, GameObject *o) const;
611  void restoreWalkRuntime(Character *c, const GameObject *o);
612  void clearStoredWalkRuntime(GameObject *o);
613  void seedMoveToPositionState(GameObject *object, Character *c, const Common::Point &target, uint16 targetVerticalOffset);
614  void seedMotionState(GameObject *object, Character *c, uint16 targetVerticalOffset, uint16 verticalOffsetDelta, uint16 motionDistance);
615  void saveOpenInventoryScriptContext();
616  void restoreOpenInventoryScriptContext();
617  void setScriptError(uint16 code);
618  bool hasScriptError() const {
619  return _scriptErrorCode != 0;
620  }
621  void clearScriptError() {
622  _scriptErrorCode = 0;
623  }
624  uint16 getScriptErrorCode() const {
625  return _scriptErrorCode;
626  }
627 
628  // Debug globals PTR_LOOP_1020_06c2 / PTR_LOOP_1020_06c4 (saved on script halt).
629  uint32 _errorScriptPosition = 0;
630  uint16 _errorScriptContext = 0;
631  void recordScriptErrorPosition();
632 
633  // Binary scriptChangeScene (1008:ad6e) synchronous init/repeat script passes.
634  void beginSceneEntryInitPass();
635  void finishSceneEntryRepeatPass(bool terminateOuterScript);
636  void runSceneEntryScriptPasses();
637  void runSceneScriptPass(bool initRun, bool repeatRun);
638 
639  // Binary executeOpcodes (1008:db56): blocking waits save cursor then set 0x1A.
640  void enterBlockingWaitCursor();
641  void clearScriptUiWaitState();
642 
643  // Resets the script to the beginning.
644  // Confirmed: runScriptExecutor (1008:e3e7) sets position=0 on fresh runs
645  // (g_wScriptIsExecuting==0). Mid-execution pauses resume from current position.
646  void rewind();
647 };
648 
649 } // namespace Script
650 } // namespace Macs2
651 
652 #endif
Definition: str.h:59
Definition: gameobjects.h:107
Definition: scriptexecutor.h:111
Definition: path.h:52
Definition: scriptexecutor.h:107
Definition: character.h:33
void debug(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: macs2.h:272
Definition: scriptexecutor.h:42
Definition: algorithm.h:29
Definition: rect.h:144
Definition: memstream.h:43
Definition: actionbar.h:31
bool isScriptMidExecution() const
Definition: scriptexecutor.h:559