22 #ifndef MACS2_SCRIPTEXECUTOR_H 23 #define MACS2_SCRIPTEXECUTOR_H 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" 32 class MemoryReadStream;
51 enum class MouseMode {
62 enum class ExecutorState {
72 enum class OpcodeResult {
86 enum class ScriptExecutionState {
113 OpcodeHandler handler;
117 void setOpcodeTable(
const OpcodeEntry *table, uint size);
119 const char *opcodeName(uint8 opcode)
const;
123 static const uint kV1OpcodeTableSize;
129 static const uint kV2OpcodeTableSize;
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();
215 void scriptSkipOpcodeRemainder(uint8 opcode);
218 OpcodeResult scriptNopSkipRemainder();
219 OpcodeResult scriptPlaySfx();
220 OpcodeResult scriptPlaySong();
221 OpcodeResult scriptStopSong();
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();
269 inline void scriptUnimplementedOpcode(
const char *source, uint16 opcode) {
270 debug(
"Unimplemented opcode (%s): %.2x.", source, opcode);
278 uint _opcodeTableSize = 0;
283 ExecutorState _state = ExecutorState::Idle;
291 bool _isSceneInitRun =
false;
296 bool _repeatRunFlag =
false;
301 bool _initPassComplete =
false;
302 bool _deferredRepeatAfterInit =
false;
303 bool _terminateOuterScriptBeforeRepeat =
false;
305 uint16 _executingObjectIndex = 0;
307 ScriptExecutionState _scriptExecutionState = ScriptExecutionState::ExecutingSceneScript;
310 bool isRelevantObject(
const GameObject *obj)
const;
320 bool loadNextScript();
322 bool _isTimerActive =
false;
323 uint32 _timerEndMillis = 0;
324 bool _isFrameWaitActive =
false;
325 uint16 _frameWaitTicksRemaining = 0;
336 uint32 _expectedEndLocation = 0;
337 uint8 _lastOpcode = 0;
338 uint32 _lastOpcodeStreamPos = 0;
341 void scriptSkipBlock();
343 void scriptSkipAlternate();
345 bool loadIndexedResource(
Common::Array<uint8> &outData, uint8 resourceIndex, uint16 objectTableOffset = 0x189);
352 int &rateHz,
int &headerSkip);
356 void scriptReadValuePair(uint16 &out1, uint16 &out2);
359 uint32 scriptReadValue32();
362 uint16 scriptReadValue16();
365 int16 scriptReadCoord16();
368 void skipOptionalVarIndexPadding();
371 void scriptSaveVariableHelper(uint32 value);
373 void scriptPrintString(
bool alignRight =
false);
376 bool _lastOpcodeTriggeredSkip =
false;
377 void beginBuffering();
378 void endBuffering(
bool shouldMark =
false);
385 uint16 _executingScriptObjectId = 0;
389 uint32 _scriptEndPosition = 0;
390 bool _scriptIsExecuting =
false;
392 uint32 effectiveScriptEnd()
const;
393 void clampScriptEndToStream();
399 void syncScriptIsExecutingFlag();
404 void setIdle() { _state = ExecutorState::Idle; }
412 void restoreScriptExecutionAfterLoad(
bool isExecuting, uint16 executingObjectId,
413 uint16 scriptPosition, uint16 scriptEndPosition);
416 void prepareScriptStateForSave();
423 uint32 _savedOpenInventoryScriptPos = 0;
424 uint32 _savedOpenInventoryScriptEndPos = 0;
425 uint16 _savedOpenInventoryExecutingObjectId = 0;
427 uint32 _secondaryInventoryLocation = 0;
428 bool _hasPendingExternalInventoryResume =
false;
429 uint16 _externalInventorySourceObjectID = 0;
430 MouseMode _savedExternalInventoryMouseMode = MouseMode::Use;
436 bool _pathWalkableResult =
false;
437 bool _isRepeatRun =
false;
440 int _chosenDialogueOption = 0;
441 uint16 _dialogueSpeakerObjectID = 0;
448 MouseMode _cursorMode = MouseMode::Walk;
449 MouseMode _cursorModeBeforeWait = MouseMode::Walk;
452 bool _waitingForUiClick =
false;
454 uint16 _interactedObjectID = 0;
457 uint16 _interactedInventoryItemId = 0;
458 uint16 _walkTargetObjectIndex = 0;
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;
471 bool _inventoryCheckResult =
false;
472 bool _animBlobRangeTestResult =
false;
473 bool _soundEnabled =
true;
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;
486 uint16 _activeMusicSlot = 0;
487 uint16 _musicControlMode = 0;
489 uint16 _musicControlStep = 0;
490 uint16 _musicControlVolume = 0;
494 bool _waitForPcmSound =
false;
495 bool _waitForMusicControl =
false;
496 bool _waitForAdlibReady =
false;
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;
515 bool skipToEndOfSkippableSection();
518 uint16 getAreaAtPoint(uint16 x, uint16 y);
520 void setVariableValue(uint16 index, uint16 a, uint16 b);
522 void setVariableValue(uint16 index, uint32 value);
527 OpcodeResult executeOpcodes();
531 void run(
bool firstRun =
false);
534 void releaseObjectStream();
536 void setCurrentSceneScriptAt(uint32 offset);
540 void startTimer(uint32 duration);
542 void startFrameWait(uint16 duration);
546 bool isScriptWaitDeferred()
const {
547 return _state == ExecutorState::WaitingForCallback ||
548 _frameWaitTicksRemaining != 0 || _walkTargetObjectIndex != 0 ||
549 _waitForPcmSound || _waitForMusicControl || _waitForAdlibReady ||
550 _waitForObjectAnimStep || _waitForSpecialAnimStep ||
551 _waitForDeltaAnim || _waitForDeltaSpeed;
554 bool isExecuting()
const {
555 return _state != ExecutorState::Idle;
560 return _scriptIsExecuting;
563 uint32 getScriptPosition()
const;
565 uint32 getDebugOpcodePosition()
const;
566 bool isWaitingForCallback()
const {
567 return _state == ExecutorState::WaitingForCallback;
569 uint32 getScriptEndPosition()
const;
572 uint16 getExecutingObjectId()
const {
573 return _executingScriptObjectId;
575 void setExecutingObjectId(uint16
id) {
576 _executingScriptObjectId = id;
578 uint16 getFrameWaitCounter()
const {
579 return _frameWaitTicksRemaining;
581 void setFrameWaitCounter(uint16 val) {
582 _frameWaitTicksRemaining = val;
584 bool isFrameWaitActive()
const {
585 return _isFrameWaitActive;
587 bool getRepeatRunFlag()
const {
588 return _repeatRunFlag;
590 void setRepeatRunFlag(
bool val) {
591 _repeatRunFlag = val;
593 uint32 getVariableValue(
int index)
const;
596 void debugLogActorWalkState(
const char *context);
600 uint32 getSpecialValue(uint16 value);
603 bool canOpenSaveMenu()
const {
604 return !_isSceneInitRun && !_isFrameWaitActive && !_isTimerActive;
608 uint16 _scriptErrorCode = 0;
609 Character *getOrCreateCharacter(uint16 objectID);
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;
621 void clearScriptError() {
622 _scriptErrorCode = 0;
624 uint16 getScriptErrorCode()
const {
625 return _scriptErrorCode;
629 uint32 _errorScriptPosition = 0;
630 uint16 _errorScriptContext = 0;
631 void recordScriptErrorPosition();
634 void beginSceneEntryInitPass();
635 void finishSceneEntryRepeatPass(
bool terminateOuterScript);
636 void runSceneEntryScriptPasses();
637 void runSceneScriptPass(
bool initRun,
bool repeatRun);
640 void enterBlockingWaitCursor();
641 void clearScriptUiWaitState();
Definition: gameobjects.h:107
Definition: scriptexecutor.h:111
Definition: scriptexecutor.h:107
Definition: character.h:33
void debug(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: scriptexecutor.h:42
Definition: algorithm.h:29
Definition: memstream.h:43
Definition: actionbar.h:31
bool isScriptMidExecution() const
Definition: scriptexecutor.h:559