[Scummvm-git-logs] scummvm master -> 2597e69f29a4b603cbfc7d53d034a2a9d3405de4

bgK bastien.bouclet at gmail.com
Sat Jul 22 20:42:16 CEST 2017


This automated email contains information about 21 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
9ac98d0fc9 MOHAWK: Myst: Always update the screen during the gameloop
49f48a5b8d MOHAWK: Myst: Turn the currently active resource into a pointer
3c04ad0227 MOHAWK: Myst: Keep track of the resource being clicked
ee9328323b MOHAWK: Myst: Move frame handling to a separate method
8f59348ec3 MOHAWK: Myst: Start reworking mainloop detection
0b9bfb3d3c MOHAWK: Myst: Remove delayUntilMovieEnds
c5496e3206 MOHAWK: Get rid of VideoHandle
a106dc8dd4 MOHAWK: Remove unused parameters VideoManager
49fa0bdd68 MOHAWK: Myst: Change blocking movies and waits to use the main loop
3dd4da0c37 MOHAWK: Myst: Change the delay opcode to use the main loop
8f0fa86fbc MOHAWK: Myst: Change blocking sounds to use the main loop
9cb6c872b7 MOHAWK: Myst: Decorrelate hotspot handling from event handling
64303abb07 MOHAWK: Myst: Update the screen only once per frame
01480f9a00 MOHAWK: Myst: Fix the quickTest debug command
a2fc282e1c MOHAWK: Myst: Move the sound code to its own class
75040819c6 MOHAWK: Myst: Rewrite the sound code
3e99dd8ccc MOHAWK: Myst: Switch to bounds checked opcode arguments
a99397f126 MOHAWK: Myst: Improve script execution tracing
757459bd49 MOHAWK: Myst: Don't cast function pointers when registering commands
7ac1bd9a57 MOHAWK: Myst: Fix error when checking the rocket sliders solution twice
2597e69f29 MOHAWK: Myst: Fix Selenitic sound receiver buttons not flashing


Commit: 9ac98d0fc90c332c66621554cbc024cd70f38026
    https://github.com/scummvm/scummvm/commit/9ac98d0fc90c332c66621554cbc024cd70f38026
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Always update the screen during the gameloop

Changed paths:
    engines/mohawk/cursors.cpp
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h


diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index ebc5561..cef24e1 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -93,12 +93,10 @@ MystCursorManager::~MystCursorManager() {
 
 void MystCursorManager::showCursor() {
 	CursorMan.showMouse(true);
-	_vm->_needsUpdate = true;
 }
 
 void MystCursorManager::hideCursor() {
 	CursorMan.showMouse(false);
-	_vm->_needsUpdate = true;
 }
 
 void MystCursorManager::setCursor(uint16 id) {
@@ -139,8 +137,6 @@ void MystCursorManager::setCursor(uint16 id) {
 		Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
 		CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
 	}
-
-	_vm->_needsUpdate = true;
 }
 
 void MystCursorManager::setDefaultCursor() {
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 3d45e38..3e1ca0e 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -70,7 +70,6 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
 	_mainCursor = kDefaultMystCursor;
 	_showResourceRects = false;
 	_curCard = 0;
-	_needsUpdate = false;
 	_canSafelySaveLoad = false;
 	_curResource = -1;
 	_hoverResource = nullptr;
@@ -264,13 +263,12 @@ Common::Error MohawkEngine_Myst::run() {
 	Common::Event event;
 	while (!shouldQuit()) {
 		// Update any background videos
-		_needsUpdate = _video->updateMovies();
+		_video->updateMovies();
 		_scriptParser->runPersistentScripts();
 
 		while (pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_MOUSEMOVE: {
-				_needsUpdate = true;
 				bool mouseClicked = _system->getEventManager()->getButtonState() & 1;
 
 				// Keep the same resource when dragging
@@ -349,10 +347,7 @@ Common::Error MohawkEngine_Myst::run() {
 			}
 		}
 
-		if (_needsUpdate) {
-			_system->updateScreen();
-			_needsUpdate = false;
-		}
+		_system->updateScreen();
 
 		// Cut down on CPU usage
 		_system->delayMillis(10);
@@ -643,7 +638,6 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
 		} else {
 			_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
 			_system->updateScreen();
-			_needsUpdate = false;
 		}
 	}
 
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 588880a..d1b74d7 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -193,7 +193,6 @@ public:
 	MystSoundBlock readSoundBlock(Common::ReadStream *stream) const;
 	void applySoundBlock(const MystSoundBlock &block);
 
-	bool _needsUpdate;
 	bool _needsPageDrop;
 	bool _needsShowMap;
 	bool _needsShowDemoMenu;


Commit: 49f48a5b8d7ae0d2d9625baab24f8b72f7a64f66
    https://github.com/scummvm/scummvm/commit/49f48a5b8d7ae0d2d9625baab24f8b72f7a64f66
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Turn the currently active resource into a pointer

Changed paths:
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h


diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 3e1ca0e..dae6ecd 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -71,7 +71,7 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
 	_showResourceRects = false;
 	_curCard = 0;
 	_canSafelySaveLoad = false;
-	_curResource = -1;
+	_activeResource = nullptr;
 	_hoverResource = nullptr;
 
 	_sound = nullptr;
@@ -275,23 +275,20 @@ Common::Error MohawkEngine_Myst::run() {
 				if (!mouseClicked) {
 					checkCurrentResource();
 				}
-				if (_curResource >= 0 && _resources[_curResource]->isEnabled() && mouseClicked) {
-					debug(2, "Sending mouse move event to resource %d", _curResource);
-					_resources[_curResource]->handleMouseDrag();
+				if (_activeResource && _activeResource->isEnabled() && mouseClicked) {
+					_activeResource->handleMouseDrag();
 				}
 				break;
 			}
 			case Common::EVENT_LBUTTONUP:
-				if (_curResource >= 0 && _resources[_curResource]->isEnabled()) {
-					debug(2, "Sending mouse up event to resource %d", _curResource);
-					_resources[_curResource]->handleMouseUp();
+				if (_activeResource && _activeResource->isEnabled()) {
+					_activeResource->handleMouseUp();
 				}
 				checkCurrentResource();
 				break;
 			case Common::EVENT_LBUTTONDOWN:
-				if (_curResource >= 0 && _resources[_curResource]->isEnabled()) {
-					debug(2, "Sending mouse up event to resource %d", _curResource);
-					_resources[_curResource]->handleMouseDown();
+				if (_activeResource && _activeResource->isEnabled()) {
+					_activeResource->handleMouseDown();
 				}
 				break;
 			case Common::EVENT_KEYDOWN:
@@ -643,7 +640,7 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
 
 	// Make sure we have the right cursor showing
 	_hoverResource = nullptr;
-	_curResource = -1;
+	_activeResource = nullptr;
 	checkCurrentResource();
 
 	// Debug: Show resource rects
@@ -661,8 +658,6 @@ void MohawkEngine_Myst::drawResourceRects() {
 }
 
 void MohawkEngine_Myst::checkCurrentResource() {
-	// See what resource we're over
-	bool foundResource = false;
 	const Common::Point &mouse = _system->getEventManager()->getMousePos();
 
 	// Tell previous resource the mouse is no longer hovering it
@@ -671,22 +666,20 @@ void MohawkEngine_Myst::checkCurrentResource() {
 		_hoverResource = nullptr;
 	}
 
-	for (uint16 i = 0; i < _resources.size(); i++)
+	// See what resource we're over
+	_activeResource = nullptr;
+	for (uint16 i = 0; i < _resources.size(); i++) {
 		if (_resources[i]->contains(mouse)) {
 			if (_hoverResource != _resources[i] && _resources[i]->type == kMystAreaHover) {
 				_hoverResource = static_cast<MystAreaHover *>(_resources[i]);
 				_hoverResource->handleMouseEnter();
 			}
 
-			if (!foundResource && _resources[i]->canBecomeActive()) {
-				_curResource = i;
-				foundResource = true;
+			if (!_activeResource && _resources[i]->canBecomeActive()) {
+				_activeResource = _resources[i];
 			}
 		}
-
-	// Set the resource to none if we're not over any
-	if (!foundResource)
-		_curResource = -1;
+	}
 
 	checkCursorHints();
 }
@@ -694,10 +687,7 @@ void MohawkEngine_Myst::checkCurrentResource() {
 MystArea *MohawkEngine_Myst::updateCurrentResource() {
 	checkCurrentResource();
 
-	if (_curResource >= 0)
-		return _resources[_curResource];
-	else
-		return nullptr;
+	return _activeResource;
 }
 
 void MohawkEngine_Myst::loadCard() {
@@ -996,7 +986,7 @@ void MohawkEngine_Myst::checkCursorHints() {
 
 	// Check all the cursor hints to see if we're in a hotspot that contains a hint.
 	for (uint16 i = 0; i < _cursorHints.size(); i++)
-		if (_cursorHints[i].id == _curResource && _resources[_cursorHints[i].id]->isEnabled()) {
+		if (_resources[_cursorHints[i].id] == _activeResource && _activeResource->isEnabled()) {
 			if (_cursorHints[i].cursor == -1) {
 				uint16 var_value = _scriptParser->getVar(_cursorHints[i].variableHint.var);
 
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index d1b74d7..0fcc829 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -263,7 +263,7 @@ private:
 	void loadResources();
 	void drawResourceRects();
 	void checkCurrentResource();
-	int16 _curResource;
+	MystArea *_activeResource;
 	MystAreaHover *_hoverResource;
 
 	Common::Array<MystCursorHint> _cursorHints;


Commit: 3c04ad0227ea1ef48ca16afbe5545306d8cb4312
    https://github.com/scummvm/scummvm/commit/3c04ad0227ea1ef48ca16afbe5545306d8cb4312
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Keep track of the resource being clicked

Changed paths:
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h


diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index dae6ecd..9462663 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -71,8 +71,10 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
 	_showResourceRects = false;
 	_curCard = 0;
 	_canSafelySaveLoad = false;
-	_activeResource = nullptr;
+
 	_hoverResource = nullptr;
+	_activeResource = nullptr;
+	_clickedResource = nullptr;
 
 	_sound = nullptr;
 	_video = nullptr;
@@ -269,26 +271,21 @@ Common::Error MohawkEngine_Myst::run() {
 		while (pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_MOUSEMOVE: {
-				bool mouseClicked = _system->getEventManager()->getButtonState() & 1;
-
-				// Keep the same resource when dragging
-				if (!mouseClicked) {
-					checkCurrentResource();
-				}
-				if (_activeResource && _activeResource->isEnabled() && mouseClicked) {
-					_activeResource->handleMouseDrag();
+				if (_clickedResource && _clickedResource->isEnabled()) {
+					_clickedResource->handleMouseDrag();
 				}
 				break;
 			}
 			case Common::EVENT_LBUTTONUP:
-				if (_activeResource && _activeResource->isEnabled()) {
-					_activeResource->handleMouseUp();
+				if (_clickedResource && _clickedResource->isEnabled()) {
+					_clickedResource->handleMouseUp();
+					_clickedResource = nullptr;
 				}
-				checkCurrentResource();
 				break;
 			case Common::EVENT_LBUTTONDOWN:
 				if (_activeResource && _activeResource->isEnabled()) {
-					_activeResource->handleMouseDown();
+					_clickedResource = _activeResource;
+					_clickedResource->handleMouseDown();
 				}
 				break;
 			case Common::EVENT_KEYDOWN:
@@ -344,6 +341,8 @@ Common::Error MohawkEngine_Myst::run() {
 			}
 		}
 
+		checkCurrentResource();
+
 		_system->updateScreen();
 
 		// Cut down on CPU usage
@@ -641,6 +640,8 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
 	// Make sure we have the right cursor showing
 	_hoverResource = nullptr;
 	_activeResource = nullptr;
+	_clickedResource = nullptr;
+
 	checkCurrentResource();
 
 	// Debug: Show resource rects
@@ -685,8 +686,6 @@ void MohawkEngine_Myst::checkCurrentResource() {
 }
 
 MystArea *MohawkEngine_Myst::updateCurrentResource() {
-	checkCurrentResource();
-
 	return _activeResource;
 }
 
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 0fcc829..00aaff3 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -263,9 +263,16 @@ private:
 	void loadResources();
 	void drawResourceRects();
 	void checkCurrentResource();
-	MystArea *_activeResource;
+
+	/** Area of type kMystAreaHover being hovered by the mouse, if any */
 	MystAreaHover *_hoverResource;
 
+	/** Active area being hovered by the mouse, if any */
+	MystArea *_activeResource;
+
+	/** Active area being clicked on / dragged, if any */
+	MystArea *_clickedResource;
+
 	Common::Array<MystCursorHint> _cursorHints;
 	void loadCursorHints();
 	uint16 _currentCursor;


Commit: ee9328323b7f6fc9796df51d88ed76e3a7ca67dd
    https://github.com/scummvm/scummvm/commit/ee9328323b7f6fc9796df51d88ed76e3a7ca67dd
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Move frame handling to a separate method

Changed paths:
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h


diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 9462663..35b1b68 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -262,14 +262,21 @@ Common::Error MohawkEngine_Myst::run() {
 	// Test Load Function...
 	loadHelp(10000);
 
-	Common::Event event;
 	while (!shouldQuit()) {
-		// Update any background videos
-		_video->updateMovies();
-		_scriptParser->runPersistentScripts();
+		doFrame();
+	}
 
-		while (pollEvent(event)) {
-			switch (event.type) {
+	return Common::kNoError;
+}
+
+void MohawkEngine_Myst::doFrame() {
+	// Update any background videos
+	_video->updateMovies();
+	_scriptParser->runPersistentScripts();
+
+	Common::Event event;
+	while (pollEvent(event)) {
+		switch (event.type) {
 			case Common::EVENT_MOUSEMOVE: {
 				if (_clickedResource && _clickedResource->isEnabled()) {
 					_clickedResource->handleMouseDrag();
@@ -290,66 +297,63 @@ Common::Error MohawkEngine_Myst::run() {
 				break;
 			case Common::EVENT_KEYDOWN:
 				switch (event.kbd.keycode) {
-				case Common::KEYCODE_d:
-					if (event.kbd.flags & Common::KBD_CTRL) {
-						_console->attach();
-						_console->onFrame();
-					}
-					break;
-				case Common::KEYCODE_SPACE:
-					pauseGame();
-					break;
-				case Common::KEYCODE_F5:
-					_needsPageDrop = false;
-					_needsShowMap = false;
-					_needsShowDemoMenu = false;
-					_needsShowCredits = false;
-
-					_canSafelySaveLoad = true;
-					runDialog(*_optionsDialog);
-					if (_optionsDialog->getLoadSlot() >= 0)
-						loadGameState(_optionsDialog->getLoadSlot());
-					_canSafelySaveLoad = false;
-
-					if (_needsPageDrop) {
-						dropPage();
+					case Common::KEYCODE_d:
+						if (event.kbd.flags & Common::KBD_CTRL) {
+							_console->attach();
+							_console->onFrame();
+						}
+						break;
+					case Common::KEYCODE_SPACE:
+						pauseGame();
+						break;
+					case Common::KEYCODE_F5:
 						_needsPageDrop = false;
-					}
-
-					if (_needsShowMap) {
-						_scriptParser->showMap();
 						_needsShowMap = false;
-					}
-
-					if (_needsShowDemoMenu) {
-						changeToStack(kDemoStack, 2002, 0, 0);
 						_needsShowDemoMenu = false;
-					}
-
-					if (_needsShowCredits) {
-						_cursor->hideCursor();
-						changeToStack(kCreditsStack, 10000, 0, 0);
 						_needsShowCredits = false;
-					}
-					break;
-				default:
-					break;
+
+						_canSafelySaveLoad = true;
+						runDialog(*_optionsDialog);
+						if (_optionsDialog->getLoadSlot() >= 0)
+							loadGameState(_optionsDialog->getLoadSlot());
+						_canSafelySaveLoad = false;
+
+						if (_needsPageDrop) {
+							dropPage();
+							_needsPageDrop = false;
+						}
+
+						if (_needsShowMap) {
+							_scriptParser->showMap();
+							_needsShowMap = false;
+						}
+
+						if (_needsShowDemoMenu) {
+							changeToStack(kDemoStack, 2002, 0, 0);
+							_needsShowDemoMenu = false;
+						}
+
+						if (_needsShowCredits) {
+							_cursor->hideCursor();
+							changeToStack(kCreditsStack, 10000, 0, 0);
+							_needsShowCredits = false;
+						}
+						break;
+					default:
+						break;
 				}
 				break;
 			default:
 				break;
-			}
 		}
+	}
 
-		checkCurrentResource();
-
-		_system->updateScreen();
+	checkCurrentResource();
 
-		// Cut down on CPU usage
-		_system->delayMillis(10);
-	}
+	_system->updateScreen();
 
-	return Common::kNoError;
+	// Cut down on CPU usage
+	_system->delayMillis(10);
 }
 
 bool MohawkEngine_Myst::pollEvent(Common::Event &event) {
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 00aaff3..dc07f45 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -190,6 +190,9 @@ public:
 	void pollAndDiscardEvents();
 	bool wait(uint32 duration, bool skippable = false);
 
+	/** Update the game state according to events and update the screen */
+	void doFrame();
+
 	MystSoundBlock readSoundBlock(Common::ReadStream *stream) const;
 	void applySoundBlock(const MystSoundBlock &block);
 


Commit: 8f59348ec33ec7c4357b639e810ff131ab6461e1
    https://github.com/scummvm/scummvm/commit/8f59348ec33ec7c4357b639e810ff131ab6461e1
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Start reworking mainloop detection

Changed paths:
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_scripts.h


diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 35b1b68..7804fb5 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -70,7 +70,6 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
 	_mainCursor = kDefaultMystCursor;
 	_showResourceRects = false;
 	_curCard = 0;
-	_canSafelySaveLoad = false;
 
 	_hoverResource = nullptr;
 	_activeResource = nullptr;
@@ -275,7 +274,7 @@ void MohawkEngine_Myst::doFrame() {
 	_scriptParser->runPersistentScripts();
 
 	Common::Event event;
-	while (pollEvent(event)) {
+	while (_system->getEventManager()->pollEvent(event)) {
 		switch (event.type) {
 			case Common::EVENT_MOUSEMOVE: {
 				if (_clickedResource && _clickedResource->isEnabled()) {
@@ -312,11 +311,9 @@ void MohawkEngine_Myst::doFrame() {
 						_needsShowDemoMenu = false;
 						_needsShowCredits = false;
 
-						_canSafelySaveLoad = true;
 						runDialog(*_optionsDialog);
 						if (_optionsDialog->getLoadSlot() >= 0)
 							loadGameState(_optionsDialog->getLoadSlot());
-						_canSafelySaveLoad = false;
 
 						if (_needsPageDrop) {
 							dropPage();
@@ -356,15 +353,6 @@ void MohawkEngine_Myst::doFrame() {
 	_system->delayMillis(10);
 }
 
-bool MohawkEngine_Myst::pollEvent(Common::Event &event) {
-	// Saving / Loading is allowed from the GMM only when the main event loop is running
-	_canSafelySaveLoad = true;
-	bool eventReturned =  _eventMan->pollEvent(event);
-	_canSafelySaveLoad = false;
-
-	return eventReturned;
-}
-
 bool MohawkEngine_Myst::wait(uint32 duration, bool skippable) {
 	uint32 end = getTotalPlayTime() + duration;
 	bool skipped = false;
@@ -1122,12 +1110,25 @@ bool MohawkEngine_Myst::hasGameSaveSupport() const {
 }
 
 bool MohawkEngine_Myst::canLoadGameStateCurrently() {
-	// No loading in the demo/makingof
-	return _canSafelySaveLoad && hasGameSaveSupport();
+	if (_scriptParser->isScriptRunning()) {
+		return false;
+	}
+
+	if (_clickedResource) {
+		// Can't save while dragging resources
+		return false;
+	}
+
+	if (!hasGameSaveSupport()) {
+		// No loading in the demo/makingof
+		return false;
+	}
+
+	return true;
 }
 
 bool MohawkEngine_Myst::canSaveGameStateCurrently() {
-	if (!_canSafelySaveLoad) {
+	if (!canLoadGameStateCurrently()) {
 		return false;
 	}
 
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index dc07f45..a5a5494 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -246,14 +246,8 @@ private:
 
 	bool _runExitScript;
 
-	/**
-	 * Saving / Loading is only allowed from the main event loop
-	 */
-	bool _canSafelySaveLoad;
 	bool hasGameSaveSupport() const;
 
-	bool pollEvent(Common::Event &event);
-
 	void dropPage();
 
 	void loadCard();
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 267d644..3480650 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -85,6 +85,7 @@ MystScriptParser::MystScriptParser(MohawkEngine_Myst *vm) :
 	_savedCardId = 0;
 	_savedCursorId = 0;
 	_tempVar = 0;
+	_scriptNestingLevel = 0;
 }
 
 MystScriptParser::~MystScriptParser() {
@@ -160,6 +161,7 @@ void MystScriptParser::runScript(MystScript script, MystArea *invokingResource)
 	// Scripted drawing takes more time to simulate older hardware
 	// This way opcodes can't overwrite what the previous ones drew too quickly
 	_vm->_gfx->enableDrawingTimeSimulation(true);
+	_scriptNestingLevel++;
 
 	for (uint16 i = 0; i < script->size(); i++) {
 		MystScriptEntry &entry = (*script)[i];
@@ -173,12 +175,14 @@ void MystScriptParser::runScript(MystScript script, MystArea *invokingResource)
 		runOpcode(entry.opcode, entry.var, entry.argc, entry.argv);
 	}
 
+	_scriptNestingLevel--;
 	_vm->_gfx->enableDrawingTimeSimulation(false);
 }
 
 void MystScriptParser::runOpcode(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	bool ranOpcode = false;
+	_scriptNestingLevel++;
 
+	bool ranOpcode = false;
 	for (uint16 i = 0; i < _opcodes.size(); i++)
 		if (_opcodes[i]->op == op) {
 			(this->*(_opcodes[i]->proc)) (op, var, argc, argv);
@@ -188,6 +192,12 @@ void MystScriptParser::runOpcode(uint16 op, uint16 var, uint16 argc, uint16 *arg
 
 	if (!ranOpcode)
 		warning("Trying to run invalid opcode %d", op);
+
+	_scriptNestingLevel--;
+}
+
+bool MystScriptParser::isScriptRunning() const {
+	return _scriptNestingLevel > 0;
 }
 
 const Common::String MystScriptParser::getOpcodeDesc(uint16 op) {
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index 69052b1..1ec821b 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -69,6 +69,13 @@ public:
 	MystScript readScript(Common::SeekableReadStream *stream, MystScriptType type);
 	void setInvokingResource(MystArea *resource) { _invokingResource = resource; }
 
+	/**
+	 * Is a script is running?
+	 *
+	 * Allows to detect if some inner loop is running instead of the main loop.
+	 */
+	bool isScriptRunning() const;
+
 	virtual void disablePersistentScripts() = 0;
 	virtual void runPersistentScripts() = 0;
 
@@ -167,6 +174,7 @@ protected:
 
 private:
 	MystArea *_invokingResource;
+	int32 _scriptNestingLevel;
 };
 
 template<class T>


Commit: 0b9bfb3d3c71df7c011754a2f7b98e32e023dc3e
    https://github.com/scummvm/scummvm/commit/0b9bfb3d3c71df7c011754a2f7b98e32e023dc3e
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Remove delayUntilMovieEnds

This will break movies called by scripts until event handling is
decorrelated from script calls.

Changed paths:
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/stoneship.cpp
    engines/mohawk/video.cpp
    engines/mohawk/video.h


diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 84a91e2..edd4ecc 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -2981,7 +2981,7 @@ void Myst::o_clockLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	for (uint i = 0; i < ARRAYSIZE(videos); i++) {
 		VideoHandle handle = _vm->_video->findVideoHandle(_vm->wrapMovieFilename(videos[i], kMystStack));
 		if (handle)
-			_vm->_video->delayUntilMovieEnds(handle);
+			_vm->_video->waitUntilMovieEnds(handle);
 	}
 
 	if (_clockMiddleGearMovedAlone)
@@ -3065,7 +3065,7 @@ void Myst::clockReset() {
 	for (uint i = 0; i < ARRAYSIZE(videos); i++) {
 		VideoHandle handle = _vm->_video->findVideoHandle(_vm->wrapMovieFilename(videos[i], kMystStack));
 		if (handle)
-			_vm->_video->delayUntilMovieEnds(handle);
+			_vm->_video->waitUntilMovieEnds(handle);
 	}
 
 	_vm->_sound->replaceSoundMyst(10113);
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 293c0f9..2308738 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -608,7 +608,7 @@ void Stoneship::o_hologramPlayback(uint16 op, uint16 var, uint16 argc, uint16 *a
 		displayMovie->setBounds(Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
 	}
 
-	_vm->_video->delayUntilMovieEnds(displayMovie);
+	_vm->_video->waitUntilMovieEnds(displayMovie);
 }
 
 void Stoneship::o_hologramSelectionStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index eec0e9a..1a7c019 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -203,10 +203,6 @@ void VideoManager::playMovieBlockingCentered(const Common::String &fileName, boo
 	waitUntilMovieEnds(VideoHandle(ptr));
 }
 
-void VideoManager::waitUntilMovieEnds(const VideoEntryPtr &video) {
-	waitUntilMovieEnds(VideoHandle(video));
-}
-
 void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
 	if (!videoHandle)
 		return;
@@ -252,29 +248,6 @@ void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
 	removeEntry(videoHandle._ptr);
 }
 
-void VideoManager::delayUntilMovieEnds(VideoHandle videoHandle) {
-	// FIXME: Why is this separate from waitUntilMovieEnds?
-	// It seems to only cut out the event loop (which is bad).
-
-	if (!videoHandle)
-		return;
-
-	// Sanity check
-	if (videoHandle._ptr->isLooping())
-		error("Called delayUntilMovieEnds() on a looping video");
-
-	while (!videoHandle->endOfVideo() && !_vm->shouldQuit()) {
-		if (updateMovies())
-			_vm->_system->updateScreen();
-
-		// Cut down on CPU usage
-		_vm->_system->delayMillis(10);
-	}
-
-	// Ensure it's removed
-	removeEntry(videoHandle._ptr);
-}
-
 VideoHandle VideoManager::playMovie(const Common::String &fileName) {
 	VideoEntryPtr ptr = open(fileName);
 	if (!ptr)
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index c59c4af..4298298 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -305,13 +305,10 @@ public:
 	void stopVideos();
 	bool isVideoPlaying();
 
-	void waitUntilMovieEnds(const VideoEntryPtr &video);
-
 	// Handle functions
 	VideoHandle findVideoHandle(uint16 id);
 	VideoHandle findVideoHandle(const Common::String &fileName);
 	void waitUntilMovieEnds(VideoHandle handle);
-	void delayUntilMovieEnds(VideoHandle handle);
 	void drawVideoFrame(VideoHandle handle, const Audio::Timestamp &time);
 
 private:


Commit: c5496e32068a24c53b6a9f0e633d4e0321c3c831
    https://github.com/scummvm/scummvm/commit/c5496e32068a24c53b6a9f0e633d4e0321c3c831
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Get rid of VideoHandle

Changed paths:
    engines/mohawk/console.cpp
    engines/mohawk/livingbooks.cpp
    engines/mohawk/myst_areas.cpp
    engines/mohawk/myst_areas.h
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/dni.cpp
    engines/mohawk/myst_stacks/intro.cpp
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/myst.h
    engines/mohawk/myst_stacks/stoneship.cpp
    engines/mohawk/video.cpp
    engines/mohawk/video.h


diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 91be370..cfabbd3 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -272,20 +272,20 @@ bool MystConsole::Cmd_PlayMovie(int argc, const char **argv) {
 		fileName = argv[1];
 	}
 
-	VideoHandle handle = _vm->_video->playMovie(fileName);
-	if (!handle) {
+	VideoEntryPtr video = _vm->_video->playMovie(fileName);
+	if (!video) {
 		debugPrintf("Failed to open movie '%s'\n", fileName.c_str());
 		return true;
 	}
 
 	if (argc == 4) {
-		handle->setX(atoi(argv[2]));
-		handle->setY(atoi(argv[3]));
+		video->setX(atoi(argv[2]));
+		video->setY(atoi(argv[3]));
 	} else if (argc > 4) {
-		handle->setX(atoi(argv[3]));
-		handle->setY(atoi(argv[4]));
+		video->setX(atoi(argv[3]));
+		video->setY(atoi(argv[4]));
 	} else {
-		handle->center();
+		video->center();
 	}
 
 	return false;
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index 340dfd1..95b4722 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -3828,8 +3828,8 @@ LBMovieItem::~LBMovieItem() {
 
 void LBMovieItem::update() {
 	if (_playing) {
-		VideoHandle videoHandle = _vm->_video->findVideoHandle(_resourceId);
-		if (!videoHandle || videoHandle->endOfVideo())
+		VideoEntryPtr video = _vm->_video->findVideo(_resourceId);
+		if (!video || video->endOfVideo())
 			done(true);
 	}
 
@@ -3840,11 +3840,11 @@ bool LBMovieItem::togglePlaying(bool playing, bool restart) {
 	if (playing) {
 		if ((_loaded && _enabled && _globalEnabled) || _phase == kLBPhaseNone) {
 			debug("toggled video for phase %d", _phase);
-			VideoHandle handle = _vm->_video->playMovie(_resourceId);
-			if (!handle)
+			VideoEntryPtr video = _vm->_video->playMovie(_resourceId);
+			if (!video)
 				error("Failed to open tMOV %d", _resourceId);
 
-			handle->moveTo(_rect.left, _rect.top);
+			video->moveTo(_rect.left, _rect.top);
 			return true;
 		}
 	}
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 8514cd5..5bad3e5 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -211,9 +211,9 @@ MystAreaVideo::MystAreaVideo(MohawkEngine_Myst *vm, Common::SeekableReadStream *
 	debugC(kDebugResource, "\tplayRate: %d", _playRate);
 }
 
-VideoHandle MystAreaVideo::playMovie() {
+VideoEntryPtr MystAreaVideo::playMovie() {
 	// Check if the video is already running
-	VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
+	VideoEntryPtr handle = _vm->_video->findVideo(_videoFile);
 
 	// If the video is not running, play it
 	if (!handle) {
@@ -245,15 +245,15 @@ VideoHandle MystAreaVideo::playMovie() {
 
 	if (_playBlocking) {
 		_vm->_video->waitUntilMovieEnds(handle);
-		return VideoHandle();
+		return VideoEntryPtr();
 	}
 
 	return handle;
 }
 
-VideoHandle MystAreaVideo::getMovieHandle() {
+VideoEntryPtr MystAreaVideo::getVideo() {
 	// If the video is already in the manager, just return the handle
-	VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
+	VideoEntryPtr handle = _vm->_video->findVideo(_videoFile);
 	if (!handle) {
 		// If the video has not been loaded yet, do it but don't start playing it
 		handle = _vm->_video->playMovie(_videoFile);
@@ -271,12 +271,12 @@ void MystAreaVideo::handleCardChange() {
 }
 
 bool MystAreaVideo::isPlaying() {
-	VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
+	VideoEntryPtr handle = _vm->_video->findVideo(_videoFile);
 	return handle && !handle->endOfVideo();
 }
 
 void MystAreaVideo::pauseMovie(bool pause) {
-	VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
+	VideoEntryPtr handle = _vm->_video->findVideo(_videoFile);
 	if (handle && !handle->endOfVideo())
 		handle->pause(pause);
 }
diff --git a/engines/mohawk/myst_areas.h b/engines/mohawk/myst_areas.h
index b19a2df..3108a19 100644
--- a/engines/mohawk/myst_areas.h
+++ b/engines/mohawk/myst_areas.h
@@ -107,8 +107,8 @@ class MystAreaVideo : public MystAreaAction {
 public:
 	MystAreaVideo(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystArea *parent);
 
-	VideoHandle playMovie();
-	VideoHandle getMovieHandle();
+	VideoEntryPtr playMovie();
+	VideoEntryPtr getVideo();
 
 	void handleCardChange() override;
 	bool isPlaying();
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index f006a8e..aee3036 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -302,7 +302,7 @@ bool Channelwood::pipeChangeValve(bool open, uint16 mask) {
 void Channelwood::o_bridgeToggle(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Bridge rise / skink video", op);
 
-	VideoHandle bridge = _vm->_video->playMovie(_vm->wrapMovieFilename("bridge", kChannelwoodStack));
+	VideoEntryPtr bridge = _vm->_video->playMovie(_vm->wrapMovieFilename("bridge", kChannelwoodStack));
 	if (!bridge)
 		error("Failed to open 'bridge' movie");
 
@@ -324,7 +324,7 @@ void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
 
 	_vm->_sound->replaceSoundMyst(soundId);
-	VideoHandle pipe = _vm->_video->playMovie(_vm->wrapMovieFilename("pipebrid", kChannelwoodStack));
+	VideoEntryPtr pipe = _vm->_video->playMovie(_vm->wrapMovieFilename("pipebrid", kChannelwoodStack));
 	if (!pipe)
 		error("Failed to open 'pipebrid' movie");
 
@@ -617,32 +617,32 @@ void Channelwood::o_hologramMonitor(uint16 op, uint16 var, uint16 argc, uint16 *
 
 		_vm->_video->stopVideos();
 
-		VideoHandle handle;
+		VideoEntryPtr video;
 
 		switch (button) {
 		case 0:
-			handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monalgh", kChannelwoodStack));
-			if (!handle)
+			video = _vm->_video->playMovie(_vm->wrapMovieFilename("monalgh", kChannelwoodStack));
+			if (!video)
 				error("Failed to open monalgh movie");
-			handle->moveTo(227, 70);
+			video->moveTo(227, 70);
 			break;
 		case 1:
-			handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monamth", kChannelwoodStack));
-			if (!handle)
+			video = _vm->_video->playMovie(_vm->wrapMovieFilename("monamth", kChannelwoodStack));
+			if (!video)
 				error("Failed to open monamth movie");
-			handle->moveTo(227, 70);
+			video->moveTo(227, 70);
 			break;
 		case 2:
-			handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monasirs", kChannelwoodStack));
-			if (!handle)
+			video = _vm->_video->playMovie(_vm->wrapMovieFilename("monasirs", kChannelwoodStack));
+			if (!video)
 				error("Failed to open monasirs movie");
-			handle->moveTo(227, 70);
+			video->moveTo(227, 70);
 			break;
 		case 3:
-			handle = _vm->_video->playMovie(_vm->wrapMovieFilename("monsmsg", kChannelwoodStack));
-			if (!handle)
+			video = _vm->_video->playMovie(_vm->wrapMovieFilename("monsmsg", kChannelwoodStack));
+			if (!video)
 				error("Failed to open monsmsg movie");
-			handle->moveTo(226, 68);
+			video->moveTo(226, 68);
 			break;
 		default:
 			warning("Opcode %d Control Variable Out of Range", op);
diff --git a/engines/mohawk/myst_stacks/dni.cpp b/engines/mohawk/myst_stacks/dni.cpp
index 6ba0b63..8611662 100644
--- a/engines/mohawk/myst_stacks/dni.cpp
+++ b/engines/mohawk/myst_stacks/dni.cpp
@@ -100,7 +100,7 @@ void Dni::o_handPage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	// Used in Card 5014 (Atrus)
 
 	// Find Atrus movie
-	VideoHandle atrus = _vm->_video->findVideoHandle(_video);
+	VideoEntryPtr atrus = _vm->_video->findVideo(_video);
 
 	// Good ending and Atrus asked to give page
 	if (_globals.ending == 1 && atrus && atrus->getTime() > (uint)Audio::Timestamp(0, 6801, 600).msecs()) {
@@ -121,7 +121,7 @@ void Dni::o_handPage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 void Dni::atrusLeft_run() {
 	if (_vm->_system->getMillis() > _atrusLeftTime + 63333) {
 		_video = _vm->wrapMovieFilename("atrus2", kDniStack);
-		VideoHandle atrus = _vm->_video->playMovie(_video);
+		VideoEntryPtr atrus = _vm->_video->playMovie(_video);
 		if (!atrus)
 			error("Failed to open '%s'", _video.c_str());
 
@@ -143,7 +143,7 @@ void Dni::atrusLeft_run() {
 
 void Dni::loopVideo_run() {
 	if (!_vm->_video->isVideoPlaying()) {
-		VideoHandle atrus = _vm->_video->playMovie(_video);
+		VideoEntryPtr atrus = _vm->_video->playMovie(_video);
 		if (!atrus)
 			error("Failed to open '%s'", _video.c_str());
 
@@ -163,7 +163,7 @@ void Dni::atrus_run() {
 		// Atrus asking for page
 		if (!_vm->_video->isVideoPlaying()) {
 			_video = _vm->wrapMovieFilename("atr1page", kDniStack);
-			VideoHandle atrus = _vm->_video->playMovie(_video);
+			VideoEntryPtr atrus = _vm->_video->playMovie(_video);
 			if (!atrus)
 				error("Failed to open '%s'", _video.c_str());
 
@@ -174,7 +174,7 @@ void Dni::atrus_run() {
 	} else if (_globals.ending != 3 && _globals.ending != 4) {
 		if (_globals.heldPage == 13) {
 			_video = _vm->wrapMovieFilename("atr1page", kDniStack);
-			VideoHandle atrus = _vm->_video->playMovie(_video);
+			VideoEntryPtr atrus = _vm->_video->playMovie(_video);
 			if (!atrus)
 				error("Failed to open '%s'", _video.c_str());
 
@@ -190,7 +190,7 @@ void Dni::atrus_run() {
 
 		} else {
 			_video = _vm->wrapMovieFilename("atr1nopg", kDniStack);
-			VideoHandle atrus = _vm->_video->playMovie(_video);
+			VideoEntryPtr atrus = _vm->_video->playMovie(_video);
 			if (!atrus)
 				error("Failed to open '%s'", _video.c_str());
 
@@ -205,12 +205,12 @@ void Dni::atrus_run() {
 			_globals.ending = 3;
 		}
 	} else if (!_vm->_video->isVideoPlaying()) {
-		VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename("atrwrite", kDniStack));
-		if (!handle)
+		VideoEntryPtr atrus = _vm->_video->playMovie(_vm->wrapMovieFilename("atrwrite", kDniStack));
+		if (!atrus)
 			error("Failed to open atrwrite movie");
 
-		handle->moveTo(215, 77);
-		handle->setLooping(true);
+		atrus->moveTo(215, 77);
+		atrus->setLooping(true);
 	}
 }
 
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index e465180..2797ba3 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -96,16 +96,16 @@ void Intro::introMovies_run() {
 	// Play Intro Movies
 	// This is all quite messy...
 
-	VideoHandle handle;
+	VideoEntryPtr video;
 
 	switch (_introStep) {
 	case 0:
 		_introStep = 1;
-		handle = _vm->_video->playMovie(_vm->wrapMovieFilename("broder", kIntroStack));
-		if (!handle)
+		video = _vm->_video->playMovie(_vm->wrapMovieFilename("broder", kIntroStack));
+		if (!video)
 			error("Failed to open broder movie");
 
-		handle->center();
+		video->center();
 		break;
 	case 1:
 		if (!_vm->_video->isVideoPlaying())
@@ -113,11 +113,11 @@ void Intro::introMovies_run() {
 		break;
 	case 2:
 		_introStep = 3;
-		handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cyanlogo", kIntroStack));
-		if (!handle)
+		video = _vm->_video->playMovie(_vm->wrapMovieFilename("cyanlogo", kIntroStack));
+		if (!video)
 			error("Failed to open cyanlogo movie");
 
-		handle->center();
+		video->center();
 		break;
 	case 3:
 		if (!_vm->_video->isVideoPlaying())
@@ -127,11 +127,11 @@ void Intro::introMovies_run() {
 		_introStep = 5;
 
 		if (!(_vm->getFeatures() & GF_DEMO)) { // The demo doesn't have the intro video
-			handle = _vm->_video->playMovie(_vm->wrapMovieFilename("intro", kIntroStack));
-			if (!handle)
+			video = _vm->_video->playMovie(_vm->wrapMovieFilename("intro", kIntroStack));
+			if (!video)
 				error("Failed to open intro movie");
 
-			handle->center();
+			video->center();
 		}
 		break;
 	case 5:
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 6daa5bd..7c5989f 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -319,7 +319,7 @@ void Mechanical::o_snakeBoxTrigger(uint16 op, uint16 var, uint16 argc, uint16 *a
 void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Play Stairs Movement Movie", op);
 
-	VideoHandle staircase = _vm->_video->playMovie(_vm->wrapMovieFilename("hhstairs", kMechanicalStack));
+	VideoEntryPtr staircase = _vm->_video->playMovie(_vm->wrapMovieFilename("hhstairs", kMechanicalStack));
 	if (!staircase)
 		error("Failed to open hhstairs movie");
 
@@ -578,7 +578,7 @@ void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, uint16 argc, uint1
 
 	debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
 
-	VideoHandle window = _vm->_video->playMovie(_vm->wrapMovieFilename("ewindow", kMechanicalStack));
+	VideoEntryPtr window = _vm->_video->playMovie(_vm->wrapMovieFilename("ewindow", kMechanicalStack));
 	if (!window)
 		error("Failed to open ewindow movie");
 
@@ -655,7 +655,7 @@ void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, uint16 argc, uint16 *
 
 	debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
 
-	VideoHandle window = _vm->_video->playMovie(_vm->wrapMovieFilename("hcelev", kMechanicalStack));
+	VideoEntryPtr window = _vm->_video->playMovie(_vm->wrapMovieFilename("hcelev", kMechanicalStack));
 	if (!window)
 		error("Failed to open hcelev movie");
 
@@ -667,7 +667,7 @@ void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, uint16 argc, uint16 *
 void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Set fortress position", op);
 
-	VideoHandle gears = _fortressRotationGears->getMovieHandle();
+	VideoEntryPtr gears = _fortressRotationGears->getVideo();
 	uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
 
 	// Myst ME short movie workaround, explained in o_fortressRotation_init
@@ -801,7 +801,7 @@ void Mechanical::o_elevatorRotation_init(uint16 op, uint16 var, uint16 argc, uin
 }
 
 void Mechanical::fortressRotation_run() {
-	VideoHandle gears = _fortressRotationGears->getMovieHandle();
+	VideoEntryPtr gears = _fortressRotationGears->getVideo();
 
 	double oldRate = gears->getRate().toDouble();
 	uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
@@ -877,7 +877,7 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
 
 	_fortressRotationGears = getInvokingResource<MystAreaVideo>();
 
-	VideoHandle gears = _fortressRotationGears->playMovie();
+	VideoEntryPtr gears = _fortressRotationGears->playMovie();
 	gears->setLooping(true);
 	gears->seek(Audio::Timestamp(0, 1800 * _fortressPosition, 600));
 	gears->setRate(0);
@@ -917,7 +917,7 @@ void Mechanical::fortressSimulation_run() {
 		_vm->_sound->replaceSoundMyst(_fortressSimulationStartSound2);
 
 		// Update movie while the sound is playing
-		VideoHandle startup = _fortressSimulationStartup->playMovie();
+		VideoEntryPtr startup = _fortressSimulationStartup->playMovie();
 		while (_vm->_sound->isPlaying(_fortressSimulationStartSound2)) {
 			if (_vm->_video->updateMovies())
 				_vm->_system->updateScreen();
@@ -937,7 +937,7 @@ void Mechanical::fortressSimulation_run() {
 		_vm->_system->updateScreen();
 
 		_fortressSimulationStartup->pauseMovie(true);
-		VideoHandle holo = _fortressSimulationHolo->playMovie();
+		VideoEntryPtr holo = _fortressSimulationHolo->playMovie();
 		holo->setLooping(true);
 		holo->setRate(0);
 
@@ -949,7 +949,7 @@ void Mechanical::fortressSimulation_run() {
 
 		_fortressSimulationInit = false;
 	} else {
-		VideoHandle holo = _fortressSimulationHolo->getMovieHandle();
+		VideoEntryPtr holo = _fortressSimulationHolo->getVideo();
 
 		double oldRate = holo->getRate().toDouble();
 
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index edd4ecc..2840b7c 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -1139,7 +1139,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
 		_vm->wait(500);
 
 		// Gears rise up
-		VideoHandle gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack));
+		VideoEntryPtr gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack));
 		if (!gears)
 			error("Failed to open gears movie");
 
@@ -1154,7 +1154,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
 		_vm->wait(500);
 
 		// Gears sink down
-		VideoHandle gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack));
+		VideoEntryPtr gears = _vm->_video->playMovie(_vm->wrapMovieFilename("gears", kMystStack));
 		if (!gears)
 			error("Failed to open gears movie");
 
@@ -1202,7 +1202,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		if (_state.imagerActive) {
 			// Mountains disappearing
 			Common::String file = _vm->wrapMovieFilename("vltmntn", kMystStack);
-			VideoHandle mountain = _vm->_video->playMovie(file);
+			VideoEntryPtr mountain = _vm->_video->playMovie(file);
 			if (!mountain)
 				error("Failed to open '%s'", file.c_str());
 
@@ -1213,7 +1213,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		} else {
 			// Mountains appearing
 			Common::String file = _vm->wrapMovieFilename("vltmntn", kMystStack);
-			VideoHandle mountain = _vm->_video->playMovie(file);
+			VideoEntryPtr mountain = _vm->_video->playMovie(file);
 			if (!mountain)
 				error("Failed to open '%s'", file.c_str());
 
@@ -1230,14 +1230,14 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 			_vm->_sound->replaceSoundMyst(argv[1]);
 
 			// Water disappearing
-			VideoHandle water = _imagerMovie->playMovie();
+			VideoEntryPtr water = _imagerMovie->playMovie();
 			water->setBounds(Audio::Timestamp(0, 4204, 600), Audio::Timestamp(0, 6040, 600));
 			water->setLooping(false);
 
 			_state.imagerActive = 0;
 		} else {
 			// Water appearing
-			VideoHandle water = _imagerMovie->playMovie();
+			VideoEntryPtr water = _imagerMovie->playMovie();
 			water->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 1814, 600));
 			_vm->_video->waitUntilMovieEnds(water);
 
@@ -2979,7 +2979,7 @@ void Myst::o_clockLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	// Let movies stop playing
 	for (uint i = 0; i < ARRAYSIZE(videos); i++) {
-		VideoHandle handle = _vm->_video->findVideoHandle(_vm->wrapMovieFilename(videos[i], kMystStack));
+		VideoEntryPtr handle = _vm->_video->findVideo(_vm->wrapMovieFilename(videos[i], kMystStack));
 		if (handle)
 			_vm->_video->waitUntilMovieEnds(handle);
 	}
@@ -3063,7 +3063,7 @@ void Myst::clockReset() {
 
 	// Let movies stop playing
 	for (uint i = 0; i < ARRAYSIZE(videos); i++) {
-		VideoHandle handle = _vm->_video->findVideoHandle(_vm->wrapMovieFilename(videos[i], kMystStack));
+		VideoEntryPtr handle = _vm->_video->findVideo(_vm->wrapMovieFilename(videos[i], kMystStack));
 		if (handle)
 			_vm->_video->waitUntilMovieEnds(handle);
 	}
@@ -3077,7 +3077,7 @@ void Myst::clockReset() {
 		_vm->_sound->replaceSoundMyst(7113);
 
 		// Gear closing movie
-		VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wggat", kMystStack));
+		VideoEntryPtr handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wggat", kMystStack));
 		if (!handle)
 			error("Failed to open cl1wggat movie");
 
@@ -3355,7 +3355,7 @@ void Myst::imager_run() {
 	_imagerRunning = false;
 
 	if (_state.imagerActive && _state.imagerSelection == 67) {
-		VideoHandle water = _imagerMovie->playMovie();
+		VideoEntryPtr water = _imagerMovie->playMovie();
 		water->setBounds(Audio::Timestamp(0, 1814, 600), Audio::Timestamp(0, 4204, 600));
 		water->setLooping(true);
 	}
@@ -3469,7 +3469,7 @@ void Myst::gullsFly1_run() {
 			else
 				x = _vm->_rnd->getRandomNumber(160) + 260;
 
-			VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
+			VideoEntryPtr handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
 			if (!handle)
 				error("Failed to open gulls movie");
 
@@ -3614,7 +3614,7 @@ void Myst::gullsFly2_run() {
 	if (time > _gullsNextTime) {
 		uint16 video = _vm->_rnd->getRandomNumber(3);
 		if (video != 3) {
-			VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
+			VideoEntryPtr handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
 			if (!handle)
 				error("Failed to open gulls movie");
 
@@ -3769,7 +3769,7 @@ void Myst::greenBook_run() {
 		_vm->_sound->stopSound();
 		_vm->_sound->pauseBackgroundMyst();
 
-		VideoHandle book = _vm->_video->playMovie(file);
+		VideoEntryPtr book = _vm->_video->playMovie(file);
 		if (!book)
 			error("Failed to open '%s'", file.c_str());
 
@@ -3783,7 +3783,7 @@ void Myst::greenBook_run() {
 			_tempVar = 0;
 		}
 	} else if (_tempVar == 2 && !_vm->_video->isVideoPlaying()) {
-		VideoHandle book = _vm->_video->playMovie(file);
+		VideoEntryPtr book = _vm->_video->playMovie(file);
 		if (!book)
 			error("Failed to open '%s'", file.c_str());
 
@@ -3812,7 +3812,7 @@ void Myst::gullsFly3_run() {
 		if (video != 3) {
 			uint16 x = _vm->_rnd->getRandomNumber(280) + 135;
 
-			VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
+			VideoEntryPtr handle = _vm->_video->playMovie(_vm->wrapMovieFilename(gulls[video], kMystStack));
 			if (!handle)
 				error("Failed to open gulls movie");
 
@@ -3851,8 +3851,8 @@ void Myst::o_treeEntry_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 void Myst::o_boiler_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Exit boiler card", op);
 
-	_cabinGaugeMovie = VideoHandle();
-	_cabinFireMovie = VideoHandle();
+	_cabinGaugeMovie = VideoEntryPtr();
+	_cabinFireMovie = VideoEntryPtr();
 
 	_cabinGaugeMovieEnabled = false;
 }
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index a44f914..870daa8 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -199,7 +199,7 @@ protected:
 	MystAreaSlider *_rocketSlider5; // 264
 	uint16 _rocketSliderSound; // 294
 	uint16 _rocketLeverPosition; // 296
-	VideoHandle _rocketLinkBook; // 268
+	VideoEntryPtr _rocketLinkBook; // 268
 
 	bool _libraryCombinationBookPagesTurning;
 	int16 _libraryBookPage; // 86
@@ -235,8 +235,8 @@ protected:
 
 	uint16 _clockTurningWheel;
 
-	VideoHandle _clockGearsVideos[3]; // 148 to 156
-	VideoHandle _clockWeightVideo; // 160
+	VideoEntryPtr _clockGearsVideos[3]; // 148 to 156
+	VideoEntryPtr _clockWeightVideo; // 160
 	uint16 _clockGearsPositions[3]; // 164 to 168
 	uint16 _clockWeightPosition; // 172
 	bool _clockMiddleGearMovedAlone; // 176
@@ -261,10 +261,10 @@ protected:
 	uint16 _cabinMatchState; // 60
 	uint32 _matchGoOutTime; // 144
 
-	VideoHandle _cabinFireMovie; // 240
+	VideoEntryPtr _cabinFireMovie; // 240
 
 	bool _cabinGaugeMovieEnabled;
-	VideoHandle _cabinGaugeMovie; // 244
+	VideoEntryPtr _cabinGaugeMovie; // 244
 
 	bool _boilerPressureIncreasing;
 	bool _boilerPressureDecreasing;
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 2308738..cd63da4 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -427,7 +427,7 @@ void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	uint16 startTime = argv[0];
 	uint16 endTime = argv[1];
 
-	VideoHandle book = _vm->_video->playMovie(_vm->wrapMovieFilename("bkroom", kStoneshipStack));
+	VideoEntryPtr book = _vm->_video->playMovie(_vm->wrapMovieFilename("bkroom", kStoneshipStack));
 	if (!book)
 		error("Failed to open bkroom movie");
 
@@ -598,7 +598,7 @@ void Stoneship::o_hologramPlayback(uint16 op, uint16 var, uint16 argc, uint16 *a
 	// uint16 direction = argv[2];
 
 	_hologramDisplay->setBlocking(false);
-	VideoHandle displayMovie = _hologramDisplay->playMovie();
+	VideoEntryPtr displayMovie = _hologramDisplay->playMovie();
 
 	if (_hologramTurnedOn) {
 		if (_hologramDisplayPos)
@@ -629,7 +629,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint
 		// Draw handle movie frame
 		uint16 selectionPos = position * 1500 / 243;
 
-		VideoHandle handleMovie = _hologramSelection->playMovie();
+		VideoEntryPtr handleMovie = _hologramSelection->playMovie();
 		_vm->_video->drawVideoFrame(handleMovie, Audio::Timestamp(0, selectionPos, 600));
 
 		_hologramDisplayPos = position * 1450 / 243 + 350;
@@ -637,7 +637,7 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint
 		// Draw display movie frame
 		if (_hologramTurnedOn) {
 			_hologramDisplay->setBlocking(false);
-			VideoHandle displayMovie = _hologramDisplay->playMovie();
+			VideoEntryPtr displayMovie = _hologramDisplay->playMovie();
 			_vm->_video->drawVideoFrame(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600));
 		}
 	}
@@ -679,7 +679,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 
 	if (_state.chestValveState) {
 		// Valve closing
-		VideoHandle valve = _vm->_video->playMovie(movie);
+		VideoEntryPtr valve = _vm->_video->playMovie(movie);
 		if (!valve)
 			error("Failed to open '%s'", movie.c_str());
 
@@ -688,7 +688,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 		_vm->_video->waitUntilMovieEnds(valve);
 	} else if (_state.chestWaterState) {
 		// Valve opening, spilling water
-		VideoHandle valve = _vm->_video->playMovie(movie);
+		VideoEntryPtr valve = _vm->_video->playMovie(movie);
 		if (!valve)
 			error("Failed to open '%s'", movie.c_str());
 
@@ -711,7 +711,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 		_vm->_sound->resumeBackgroundMyst();
 	} else {
 		// Valve opening
-		VideoHandle valve = _vm->_video->playMovie(movie);
+		VideoEntryPtr valve = _vm->_video->playMovie(movie);
 		if (!valve)
 			error("Failed to open '%s'", movie.c_str());
 
@@ -738,7 +738,7 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	Common::String movie = _vm->wrapMovieFilename("openloc", kStoneshipStack);
 
-	VideoHandle lock = _vm->_video->playMovie(movie);
+	VideoEntryPtr lock = _vm->_video->playMovie(movie);
 	if (!lock)
 		error("Failed to open '%s'", movie.c_str());
 
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index 1a7c019..64f6f23 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -24,6 +24,8 @@
 #include "mohawk/resource.h"
 #include "mohawk/video.h"
 
+#include "mohawk/myst.h"
+
 #include "common/algorithm.h"
 #include "common/debug.h"
 #include "common/events.h"
@@ -138,13 +140,7 @@ void VideoEntry::setVolume(int volume) {
 	_video->setVolume(CLIP(volume, 0, 255));
 }
 
-VideoHandle::VideoHandle(VideoEntryPtr ptr) : _ptr(ptr) {
-}
-
-VideoHandle::VideoHandle(const VideoHandle &handle) : _ptr(handle._ptr) {
-}
-
-VideoManager::VideoManager(MohawkEngine* vm) : _vm(vm) {
+VideoManager::VideoManager(MohawkEngine *vm) : _vm(vm) {
 	// Set dithering enabled, if required
 	_enableDither = (_vm->getGameType() == GType_MYST || _vm->getGameType() == GType_MAKINGOF) && !(_vm->getFeatures() & GF_ME);
 }
@@ -184,7 +180,7 @@ void VideoManager::playMovieBlocking(const Common::String &fileName, uint16 x, u
 	}
 
 	ptr->start();
-	waitUntilMovieEnds(VideoHandle(ptr));
+	waitUntilMovieEnds(ptr);
 }
 
 void VideoManager::playMovieBlockingCentered(const Common::String &fileName, bool clearScreen) {
@@ -200,20 +196,20 @@ void VideoManager::playMovieBlockingCentered(const Common::String &fileName, boo
 
 	ptr->center();
 	ptr->start();
-	waitUntilMovieEnds(VideoHandle(ptr));
+	waitUntilMovieEnds(ptr);
 }
 
-void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
-	if (!videoHandle)
+void VideoManager::waitUntilMovieEnds(const VideoEntryPtr &video) {
+	if (!video)
 		return;
 
 	// Sanity check
-	if (videoHandle._ptr->isLooping())
+	if (video->isLooping())
 		error("Called waitUntilMovieEnds() on a looping video");
 
 	bool continuePlaying = true;
 
-	while (!videoHandle->endOfVideo() && !_vm->shouldQuit() && continuePlaying) {
+	while (!video->endOfVideo() && !_vm->shouldQuit() && continuePlaying) {
 		if (updateMovies())
 			_vm->_system->updateScreen();
 
@@ -245,25 +241,25 @@ void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
 	}
 
 	// Ensure it's removed
-	removeEntry(videoHandle._ptr);
+	removeEntry(video);
 }
 
-VideoHandle VideoManager::playMovie(const Common::String &fileName) {
+VideoEntryPtr VideoManager::playMovie(const Common::String &fileName) {
 	VideoEntryPtr ptr = open(fileName);
 	if (!ptr)
-		return VideoHandle();
+		return VideoEntryPtr();
 
 	ptr->start();
-	return VideoHandle(ptr);
+	return ptr;
 }
 
-VideoHandle VideoManager::playMovie(uint16 id) {
+VideoEntryPtr VideoManager::playMovie(uint16 id) {
 	VideoEntryPtr ptr = open(id);
 	if (!ptr)
-		return VideoHandle();
+		return VideoEntryPtr();
 
 	ptr->start();
-	return VideoHandle(ptr);
+	return ptr;
 }
 
 bool VideoManager::updateMovies() {
@@ -376,9 +372,9 @@ bool VideoManager::drawNextFrame(VideoEntryPtr videoEntry) {
 
 VideoEntryPtr VideoManager::open(uint16 id) {
 	// If this video is already playing, return that handle
-	VideoHandle oldHandle = findVideoHandle(id);
-	if (oldHandle._ptr)
-		return oldHandle._ptr;
+	VideoEntryPtr oldVideo = findVideo(id);
+	if (oldVideo)
+		return oldVideo;
 
 	// Otherwise, create a new entry
 	Video::QuickTimeDecoder *video = new Video::QuickTimeDecoder();
@@ -399,9 +395,9 @@ VideoEntryPtr VideoManager::open(uint16 id) {
 
 VideoEntryPtr VideoManager::open(const Common::String &fileName) {
 	// If this video is already playing, return that entry
-	VideoHandle oldHandle = findVideoHandle(fileName);
-	if (oldHandle._ptr)
-		return oldHandle._ptr;
+	VideoEntryPtr oldVideo = findVideo(fileName);
+	if (oldVideo)
+		return oldVideo;
 
 	// Otherwise, create a new entry
 	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName);
@@ -427,26 +423,26 @@ VideoEntryPtr VideoManager::open(const Common::String &fileName) {
 	return entry;
 }
 
-VideoHandle VideoManager::findVideoHandle(uint16 id) {
+VideoEntryPtr VideoManager::findVideo(uint16 id) {
 	if (id == 0)
-		return VideoHandle();
+		return VideoEntryPtr();
 
 	for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
 		if ((*it)->getID() == id)
-			return VideoHandle(*it);
+			return *it;
 
-	return VideoHandle();
+	return VideoEntryPtr();
 }
 
-VideoHandle VideoManager::findVideoHandle(const Common::String &fileName) {
+VideoEntryPtr VideoManager::findVideo(const Common::String &fileName) {
 	if (fileName.empty())
-		return VideoHandle();
+		return VideoEntryPtr();
 
 	for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
 		if ((*it)->getFileName().equalsIgnoreCase(fileName))
-			return VideoHandle(*it);
+			return *it;
 
-	return VideoHandle();
+	return VideoEntryPtr();
 }
 
 bool VideoManager::isVideoPlaying() {
@@ -457,11 +453,11 @@ bool VideoManager::isVideoPlaying() {
 	return false;
 }
 
-void VideoManager::drawVideoFrame(VideoHandle handle, const Audio::Timestamp &time) {
-	assert(handle);
-	handle->seek(time);
-	drawNextFrame(handle._ptr);
-	handle->stop();
+void VideoManager::drawVideoFrame(const VideoEntryPtr &video, const Audio::Timestamp &time) {
+	assert(video);
+	video->seek(time);
+	drawNextFrame(video);
+	video->stop();
 }
 
 VideoManager::VideoList::iterator VideoManager::findEntry(VideoEntryPtr ptr) {
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index 4298298..d8b3add 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -234,71 +234,16 @@ private:
 
 typedef Common::SharedPtr<VideoEntry> VideoEntryPtr;
 
-/**
- * A handle for manipulating a video
- */
-class VideoHandle {
-	// The private members should be able to be manipulated by VideoManager
-	friend class VideoManager;
-
-public:
-	/**
-	 * Default constructor
-	 */
-	VideoHandle() {}
-
-	/**
-	 * Copy constructor
-	 */
-	VideoHandle(const VideoHandle &handle);
-
-	/**
-	 * Is this handle pointing to a valid video entry?
-	 */
-	bool isValid() const { return _ptr && _ptr->isOpen(); }
-
-	/**
-	 * Convenience implicit cast to bool
-	 */
-	operator bool() const { return isValid(); }
-
-	/**
-	 * Simple equality operator
-	 */
-	bool operator==(const VideoHandle &other) const { return _ptr.get() == other._ptr.get(); }
-
-	/**
-	 * Simple inequality operator
-	 */
-	bool operator!=(const VideoHandle &other) const { return !(*this == other); }
-
-	/**
-	 * Convenience operator-> override to give direct access to the VideoEntry
-	 */
-	VideoEntryPtr operator->() const { return _ptr; }
-
-private:
-	/**
-	 * Constructor for internal VideoManager use
-	 */
-	explicit VideoHandle(VideoEntryPtr ptr);
-
-	/**
-	 * The video entry this is associated with
-	 */
-	VideoEntryPtr _ptr;
-};
-
 class VideoManager {
 public:
 	VideoManager(MohawkEngine *vm);
-	~VideoManager();
+	virtual ~VideoManager();
 
 	// Generic movie functions
 	void playMovieBlocking(const Common::String &filename, uint16 x = 0, uint16 y = 0, bool clearScreen = false);
 	void playMovieBlockingCentered(const Common::String &filename, bool clearScreen = true);
-	VideoHandle playMovie(const Common::String &filename);
-	VideoHandle playMovie(uint16 id);
+	VideoEntryPtr playMovie(const Common::String &filename);
+	VideoEntryPtr playMovie(uint16 id);
 	bool updateMovies();
 	void pauseVideos();
 	void resumeVideos();
@@ -306,12 +251,12 @@ public:
 	bool isVideoPlaying();
 
 	// Handle functions
-	VideoHandle findVideoHandle(uint16 id);
-	VideoHandle findVideoHandle(const Common::String &fileName);
-	void waitUntilMovieEnds(VideoHandle handle);
-	void drawVideoFrame(VideoHandle handle, const Audio::Timestamp &time);
+	VideoEntryPtr findVideo(uint16 id);
+	VideoEntryPtr findVideo(const Common::String &fileName);
+	void waitUntilMovieEnds(const VideoEntryPtr &video);
+	void drawVideoFrame(const VideoEntryPtr &video, const Audio::Timestamp &time);
 
-private:
+protected:
 	MohawkEngine *_vm;
 
 	// Keep tabs on any videos playing


Commit: a106dc8dd4a055821743ed5bf01a27171e093cd0
    https://github.com/scummvm/scummvm/commit/a106dc8dd4a055821743ed5bf01a27171e093cd0
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Remove unused parameters VideoManager

Changed paths:
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/video.cpp
    engines/mohawk/video.h


diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 8d2e660..99cb5c4 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -484,7 +484,7 @@ void Selenitic::mazeRunnerPlayVideo(uint16 video, uint16 pos) {
 
 	if (!file.empty()) {
 		const Common::Rect &dest = _mazeRunnerWindow->getRect();
-		_vm->_video->playMovieBlocking(file, dest.left, dest.top, false);
+		_vm->_video->playMovieBlocking(file, dest.left, dest.top);
 	}
 }
 
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index 64f6f23..6148472 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -166,33 +166,25 @@ void VideoManager::stopVideos() {
 	_videos.clear();
 }
 
-void VideoManager::playMovieBlocking(const Common::String &fileName, uint16 x, uint16 y, bool clearScreen) {
+void VideoManager::playMovieBlocking(const Common::String &fileName, uint16 x, uint16 y) {
 	VideoEntryPtr ptr = open(fileName);
 	if (!ptr)
 		return;
 
 	ptr->moveTo(x, y);
-
-	// Clear screen if requested
-	if (clearScreen) {
-		_vm->_system->fillScreen(_vm->_system->getScreenFormat().RGBToColor(0, 0, 0));
-		_vm->_system->updateScreen();
-	}
-
 	ptr->start();
+
 	waitUntilMovieEnds(ptr);
 }
 
-void VideoManager::playMovieBlockingCentered(const Common::String &fileName, bool clearScreen) {
+void VideoManager::playMovieBlockingCentered(const Common::String &fileName) {
 	VideoEntryPtr ptr = open(fileName);
 	if (!ptr)
 		return;
 
-	// Clear screen if requested
-	if (clearScreen) {
-		_vm->_system->fillScreen(_vm->_system->getScreenFormat().RGBToColor(0, 0, 0));
-		_vm->_system->updateScreen();
-	}
+	// Clear screen
+	_vm->_system->fillScreen(_vm->_system->getScreenFormat().RGBToColor(0, 0, 0));
+	_vm->_system->updateScreen();
 
 	ptr->center();
 	ptr->start();
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index d8b3add..20da429 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -240,8 +240,8 @@ public:
 	virtual ~VideoManager();
 
 	// Generic movie functions
-	void playMovieBlocking(const Common::String &filename, uint16 x = 0, uint16 y = 0, bool clearScreen = false);
-	void playMovieBlockingCentered(const Common::String &filename, bool clearScreen = true);
+	void playMovieBlocking(const Common::String &filename, uint16 x, uint16 y);
+	void playMovieBlockingCentered(const Common::String &filename);
 	VideoEntryPtr playMovie(const Common::String &filename);
 	VideoEntryPtr playMovie(uint16 id);
 	bool updateMovies();


Commit: 49fa0bdd689514fda992bffb39e06ccd37df85c4
    https://github.com/scummvm/scummvm/commit/49fa0bdd689514fda992bffb39e06ccd37df85c4
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Change blocking movies and waits to use the main loop

Changed paths:
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/myst_areas.cpp
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/myst_stacks/stoneship.cpp
    engines/mohawk/video.cpp
    engines/mohawk/video.h


diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 7804fb5..f965756 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -84,6 +84,8 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
 	_optionsDialog = nullptr;
 
 	_prevStack = nullptr;
+
+	_escapePressed = false;
 }
 
 MohawkEngine_Myst::~MohawkEngine_Myst() {
@@ -220,6 +222,52 @@ Common::String MohawkEngine_Myst::wrapMovieFilename(const Common::String &movieN
 	return Common::String("qtw/") + prefix + movieName + ".mov";
 }
 
+
+void MohawkEngine_Myst::playMovieBlocking(const Common::String &fileName, uint16 x, uint16 y) {
+	VideoEntryPtr video = _video->playMovie(fileName);
+	if (!video) {
+		error("Failed to open the '%s' movie", fileName.c_str());
+	}
+
+	video->moveTo(x, y);
+
+	waitUntilMovieEnds(video);
+}
+
+void MohawkEngine_Myst::playMovieBlockingCentered(const Common::String &fileName) {
+	VideoEntryPtr video = _video->playMovie(fileName);
+	if (!video) {
+		error("Failed to open the '%s' movie", fileName.c_str());
+	}
+
+	// Clear screen
+	_system->fillScreen(_system->getScreenFormat().RGBToColor(0, 0, 0));
+
+	video->center();
+	waitUntilMovieEnds(video);
+}
+
+void MohawkEngine_Myst::waitUntilMovieEnds(const VideoEntryPtr &video) {
+	assert(video);
+
+	// Sanity check
+	if (video->isLooping())
+		error("Called waitUntilMovieEnds() on a looping video");
+
+	while (!video->endOfVideo() && !shouldQuit()) {
+		doFrame();
+
+		// Allow skipping
+		if (_escapePressed) {
+			_escapePressed = false;
+			break;
+		}
+	}
+
+	// Ensure it's removed
+	_video->removeEntry(video);
+}
+
 Common::Error MohawkEngine_Myst::run() {
 	MohawkEngine::run();
 
@@ -336,6 +384,18 @@ void MohawkEngine_Myst::doFrame() {
 							_needsShowCredits = false;
 						}
 						break;
+					case Common::KEYCODE_ESCAPE:
+						_escapePressed = true;
+						break;
+					default:
+						break;
+				}
+				break;
+			case Common::EVENT_KEYUP:
+				switch (event.kbd.keycode) {
+					case Common::KEYCODE_ESCAPE:
+						_escapePressed = false;
+						break;
 					default:
 						break;
 				}
@@ -355,36 +415,17 @@ void MohawkEngine_Myst::doFrame() {
 
 bool MohawkEngine_Myst::wait(uint32 duration, bool skippable) {
 	uint32 end = getTotalPlayTime() + duration;
-	bool skipped = false;
 
-	while (getTotalPlayTime() < end && !skipped && !shouldQuit()) {
-		Common::Event event;
-		while (_system->getEventManager()->pollEvent(event)) {
-			switch (event.type) {
-			case Common::EVENT_LBUTTONUP:
-				skipped = skippable;
-				break;
-			case Common::EVENT_KEYDOWN:
-				switch (event.kbd.keycode) {
-				case Common::KEYCODE_SPACE:
-					pauseGame();
-					break;
-				case Common::KEYCODE_ESCAPE:
-					skipped = skippable;
-					break;
-				default:
-					break;
-			}
-			default:
-				break;
-			}
-		}
+	while (getTotalPlayTime() < end && !shouldQuit()) {
+		doFrame();
 
-		// Cut down on CPU usage
-		_system->delayMillis(10);
+		if (_escapePressed && skippable) {
+			_escapePressed = false;
+			return true; // Return true if skipped
+		}
 	}
 
-	return skipped;
+	return false;
 }
 
 void MohawkEngine_Myst::pollAndDiscardEvents() {
@@ -539,8 +580,9 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
 			break;
 		}
 
-		if (flyby)
-			_video->playMovieBlockingCentered(wrapMovieFilename(flyby, kMasterpieceOnly));
+		if (flyby) {
+			playMovieBlockingCentered(wrapMovieFilename(flyby, kMasterpieceOnly));
+		}
 	}
 
 	changeToCard(card, kTransitionCopy);
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index a5a5494..e3fa5a9 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -27,6 +27,7 @@
 #include "mohawk/mohawk.h"
 #include "mohawk/resource_cache.h"
 #include "mohawk/myst_scripts.h"
+#include "mohawk/video.h"
 
 #include "common/events.h"
 #include "common/random.h"
@@ -225,6 +226,10 @@ public:
 	void setCacheState(bool state) { _cache.enabled = state; }
 	bool getCacheState() { return _cache.enabled; }
 
+	void playMovieBlocking(const Common::String &filename, uint16 x, uint16 y);
+	void playMovieBlockingCentered(const Common::String &filename);
+	void waitUntilMovieEnds(const VideoEntryPtr &video);
+
 	GUI::Debugger *getDebugger() override { return _console; }
 
 	bool canLoadGameStateCurrently() override;
@@ -270,6 +275,9 @@ private:
 	/** Active area being clicked on / dragged, if any */
 	MystArea *_clickedResource;
 
+	// Input
+	bool _escapePressed;
+
 	Common::Array<MystCursorHint> _cursorHints;
 	void loadCursorHints();
 	uint16 _currentCursor;
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 5bad3e5..568a95d 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -244,7 +244,7 @@ VideoEntryPtr MystAreaVideo::playMovie() {
 	}
 
 	if (_playBlocking) {
-		_vm->_video->waitUntilMovieEnds(handle);
+		_vm->waitUntilMovieEnds(handle);
 		return VideoEntryPtr();
 	}
 
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index aee3036..7e91dbb 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -314,7 +314,7 @@ void Channelwood::o_bridgeToggle(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	else
 		bridge->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3050, 600));
 
-	_vm->_video->waitUntilMovieEnds(bridge);
+	_vm->waitUntilMovieEnds(bridge);
 }
 
 void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -336,7 +336,7 @@ void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	else
 		pipe->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3040, 600));
 
-	_vm->_video->waitUntilMovieEnds(pipe);
+	_vm->waitUntilMovieEnds(pipe);
 	_vm->_sound->resumeBackgroundMyst();
 }
 
@@ -667,16 +667,16 @@ void Channelwood::o_hologramTemple(uint16 op, uint16 var, uint16 argc, uint16 *a
 	// Used on Card 3333 (Temple Hologram)
 	switch (_state.holoprojectorSelection) {
 	case 0:
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("holoalgh", kChannelwoodStack), 139, 64);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("holoalgh", kChannelwoodStack), 139, 64);
 		break;
 	case 1:
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("holoamth", kChannelwoodStack), 127, 73);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("holoamth", kChannelwoodStack), 127, 73);
 		break;
 	case 2:
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("holoasir", kChannelwoodStack), 139, 64);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("holoasir", kChannelwoodStack), 139, 64);
 		break;
 	case 3:
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("holosmsg", kChannelwoodStack), 127, 45);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("holosmsg", kChannelwoodStack), 127, 45);
 		break;
 	default:
 		warning("Opcode %d Control Variable Out of Range", op);
@@ -748,7 +748,7 @@ void Channelwood::o_elevatorMovies(uint16 op, uint16 var, uint16 argc, uint16 *a
 	}
 
 	_vm->_sound->pauseBackgroundMyst();
-	_vm->_video->playMovieBlocking(movie, x, y);
+	_vm->playMovieBlocking(movie, x, y);
 	_vm->_sound->resumeBackgroundMyst();
 }
 
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 7c5989f..351379b 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -331,7 +331,7 @@ void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, uint16 argc, ui
 		staircase->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 840, 600));
 	}
 
-	_vm->_video->waitUntilMovieEnds(staircase);
+	_vm->waitUntilMovieEnds(staircase);
 }
 
 void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -584,7 +584,7 @@ void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, uint16 argc, uint1
 
 	window->moveTo(253, 0);
 	window->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
-	_vm->_video->waitUntilMovieEnds(window);
+	_vm->waitUntilMovieEnds(window);
 }
 
 void Mechanical::o_elevatorGoMiddle(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -661,7 +661,7 @@ void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, uint16 argc, uint16 *
 
 	window->moveTo(206, 38);
 	window->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
-	_vm->_video->waitUntilMovieEnds(window);
+	_vm->waitUntilMovieEnds(window);
 }
 
 void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -681,7 +681,7 @@ void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, uint16 arg
 void Mechanical::o_mystStaircaseMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Myst book staircase video", op);
 
-	_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("sstairs", kMechanicalStack), 199, 108);
+	_vm->playMovieBlocking(_vm->wrapMovieFilename("sstairs", kMechanicalStack), 199, 108);
 }
 
 void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -925,7 +925,7 @@ void Mechanical::fortressSimulation_run() {
 			_vm->_system->delayMillis(10);
 		}
 		_vm->_sound->replaceBackgroundMyst(_fortressSimulationStartSound1, 65535);
-		_vm->_video->waitUntilMovieEnds(startup);
+		_vm->waitUntilMovieEnds(startup);
 		_vm->_sound->stopBackgroundMyst();
 		_vm->_sound->replaceSoundMyst(_fortressSimulationStartSound2);
 
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 2840b7c..6979ce5 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -887,9 +887,9 @@ void Myst::o_fireplaceRotation(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	debugC(kDebugScript, "\tmovieNum: %d", movieNum);
 
 	if (movieNum)
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("fpout", kMystStack), 167, 4);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("fpout", kMystStack), 167, 4);
 	else
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("fpin", kMystStack), 167, 4);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("fpin", kMystStack), 167, 4);
 }
 
 void Myst::o_courtyardBoxesCheckSolution(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -1145,7 +1145,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
 
 		gears->moveTo(305, 33);
 		gears->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 650, 600));
-		_vm->_video->waitUntilMovieEnds(gears);
+		_vm->waitUntilMovieEnds(gears);
 
 		_state.clockTowerBridgeOpen = 1;
 		_vm->redrawArea(12);
@@ -1160,7 +1160,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
 
 		gears->moveTo(305, 33);
 		gears->setBounds(Audio::Timestamp(0, 700, 600), Audio::Timestamp(0, 1300, 600));
-		_vm->_video->waitUntilMovieEnds(gears);
+		_vm->waitUntilMovieEnds(gears);
 
 		_state.clockTowerBridgeOpen = 0;
 		_vm->redrawArea(12);
@@ -1239,7 +1239,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 			// Water appearing
 			VideoEntryPtr water = _imagerMovie->playMovie();
 			water->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 1814, 600));
-			_vm->_video->waitUntilMovieEnds(water);
+			_vm->waitUntilMovieEnds(water);
 
 			// Water looping
 			water = _imagerMovie->playMovie();
@@ -1340,10 +1340,10 @@ void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, uint16 argc, uint16 *
 
 	switch (argv[0]) {
 	case 0:
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("libdown", kMystStack), 216, 78);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("libdown", kMystStack), 216, 78);
 		break;
 	case 1:
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("libup", kMystStack), 216, 78);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("libup", kMystStack), 216, 78);
 		break;
 	default:
 		break;
@@ -2279,7 +2279,7 @@ void Myst::rocketCheckSolution() {
 
 		_rocketLinkBook->moveTo(224, 41);
 		_rocketLinkBook->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 660, 600));
-		_vm->_video->waitUntilMovieEnds(_rocketLinkBook);
+		_vm->waitUntilMovieEnds(_rocketLinkBook);
 
 		// Book looping closed
 		_rocketLinkBook = _vm->_video->playMovie(movieFile);
@@ -2981,7 +2981,7 @@ void Myst::o_clockLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	for (uint i = 0; i < ARRAYSIZE(videos); i++) {
 		VideoEntryPtr handle = _vm->_video->findVideo(_vm->wrapMovieFilename(videos[i], kMystStack));
 		if (handle)
-			_vm->_video->waitUntilMovieEnds(handle);
+			_vm->waitUntilMovieEnds(handle);
 	}
 
 	if (_clockMiddleGearMovedAlone)
@@ -3013,7 +3013,7 @@ void Myst::clockGearsCheckSolution() {
 		_clockWeightVideo->setBounds(
 				Audio::Timestamp(0, _clockWeightPosition, 600),
 				Audio::Timestamp(0, 2214, 600));
-		_vm->_video->waitUntilMovieEnds(_clockWeightVideo);
+		_vm->waitUntilMovieEnds(_clockWeightVideo);
 		_clockWeightPosition = 2214;
 
 		_vm->_sound->replaceSoundMyst(6113);
@@ -3021,7 +3021,7 @@ void Myst::clockGearsCheckSolution() {
 		_vm->_sound->replaceSoundMyst(7113);
 
 		// Gear opening video
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("cl1wggat", kMystStack), 195, 225);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("cl1wggat", kMystStack), 195, 225);
 		_state.gearsOpen = 1;
 		_vm->redrawArea(40);
 
@@ -3065,7 +3065,7 @@ void Myst::clockReset() {
 	for (uint i = 0; i < ARRAYSIZE(videos); i++) {
 		VideoEntryPtr handle = _vm->_video->findVideo(_vm->wrapMovieFilename(videos[i], kMystStack));
 		if (handle)
-			_vm->_video->waitUntilMovieEnds(handle);
+			_vm->waitUntilMovieEnds(handle);
 	}
 
 	_vm->_sound->replaceSoundMyst(10113);
@@ -3084,7 +3084,7 @@ void Myst::clockReset() {
 		handle->moveTo(195, 225);
 		handle->seek(handle->getDuration());
 		handle->setRate(-1);
-		_vm->_video->waitUntilMovieEnds(handle);
+		_vm->waitUntilMovieEnds(handle);
 
 		// Redraw gear
 		_state.gearsOpen = 0;
diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 99cb5c4..22cb856 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -484,7 +484,7 @@ void Selenitic::mazeRunnerPlayVideo(uint16 video, uint16 pos) {
 
 	if (!file.empty()) {
 		const Common::Rect &dest = _mazeRunnerWindow->getRect();
-		_vm->_video->playMovieBlocking(file, dest.left, dest.top);
+		_vm->playMovieBlocking(file, dest.left, dest.top);
 	}
 }
 
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index cd63da4..5fbb664 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -433,7 +433,7 @@ void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, uint16 argc, uint16 *arg
 
 	book->moveTo(159, 99);
 	book->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
-	_vm->_video->waitUntilMovieEnds(book);
+	_vm->waitUntilMovieEnds(book);
 }
 
 void Stoneship::o_drawerOpenSirius(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -608,7 +608,7 @@ void Stoneship::o_hologramPlayback(uint16 op, uint16 var, uint16 argc, uint16 *a
 		displayMovie->setBounds(Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
 	}
 
-	_vm->_video->waitUntilMovieEnds(displayMovie);
+	_vm->waitUntilMovieEnds(displayMovie);
 }
 
 void Stoneship::o_hologramSelectionStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -685,7 +685,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 
 		valve->moveTo(97, 267);
 		valve->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 350, 600));
-		_vm->_video->waitUntilMovieEnds(valve);
+		_vm->waitUntilMovieEnds(valve);
 	} else if (_state.chestWaterState) {
 		// Valve opening, spilling water
 		VideoEntryPtr valve = _vm->_video->playMovie(movie);
@@ -694,7 +694,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 
 		valve->moveTo(97, 267);
 		valve->setBounds(Audio::Timestamp(0, 350, 600), Audio::Timestamp(0, 650, 600));
-		_vm->_video->waitUntilMovieEnds(valve);
+		_vm->waitUntilMovieEnds(valve);
 
 		_vm->_sound->playSound(3132);
 
@@ -705,7 +705,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 
 			valve->moveTo(97, 267);
 			valve->setBounds(Audio::Timestamp(0, 650, 600), Audio::Timestamp(0, 750, 600));
-			_vm->_video->waitUntilMovieEnds(valve);
+			_vm->waitUntilMovieEnds(valve);
 		}
 
 		_vm->_sound->resumeBackgroundMyst();
@@ -718,7 +718,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 		valve->moveTo(97, 267);
 		valve->seek(Audio::Timestamp(0, 350, 600));
 		valve->setRate(-1);
-		_vm->_video->waitUntilMovieEnds(valve);
+		_vm->waitUntilMovieEnds(valve);
 	}
 }
 
@@ -744,7 +744,7 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	lock->moveTo(187, 71);
 	lock->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 750, 600));
-	_vm->_video->waitUntilMovieEnds(lock);
+	_vm->waitUntilMovieEnds(lock);
 
 	_vm->_sound->playSound(2143);
 
@@ -754,7 +754,7 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	lock->moveTo(187, 71);
 	lock->setBounds(Audio::Timestamp(0, 750, 600), Audio::Timestamp(0, 10000, 600));
-	_vm->_video->waitUntilMovieEnds(lock);
+	_vm->waitUntilMovieEnds(lock);
 
 	if (_state.pumpState != 4)
 		_vm->_sound->playSound(4143);
@@ -773,19 +773,19 @@ void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	switch (movieId) {
 	case 0:
 		// Card 2251
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("tunaup", kStoneshipStack), 149, 161);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("tunaup", kStoneshipStack), 149, 161);
 		break;
 	case 1:
 		// Card 2247
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("tunadown", kStoneshipStack), 218, 150);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("tunadown", kStoneshipStack), 218, 150);
 		break;
 	case 2:
 		// Card 2289
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("tuncup", kStoneshipStack), 259, 161);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("tuncup", kStoneshipStack), 259, 161);
 		break;
 	case 3:
 		// Card 2285
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("tuncdown", kStoneshipStack), 166, 150);
+		_vm->playMovieBlocking(_vm->wrapMovieFilename("tuncdown", kStoneshipStack), 166, 150);
 		break;
 	default:
 		warning("Opcode 120 MovieId Out Of Range");
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index 6148472..4aff5b5 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -166,76 +166,6 @@ void VideoManager::stopVideos() {
 	_videos.clear();
 }
 
-void VideoManager::playMovieBlocking(const Common::String &fileName, uint16 x, uint16 y) {
-	VideoEntryPtr ptr = open(fileName);
-	if (!ptr)
-		return;
-
-	ptr->moveTo(x, y);
-	ptr->start();
-
-	waitUntilMovieEnds(ptr);
-}
-
-void VideoManager::playMovieBlockingCentered(const Common::String &fileName) {
-	VideoEntryPtr ptr = open(fileName);
-	if (!ptr)
-		return;
-
-	// Clear screen
-	_vm->_system->fillScreen(_vm->_system->getScreenFormat().RGBToColor(0, 0, 0));
-	_vm->_system->updateScreen();
-
-	ptr->center();
-	ptr->start();
-	waitUntilMovieEnds(ptr);
-}
-
-void VideoManager::waitUntilMovieEnds(const VideoEntryPtr &video) {
-	if (!video)
-		return;
-
-	// Sanity check
-	if (video->isLooping())
-		error("Called waitUntilMovieEnds() on a looping video");
-
-	bool continuePlaying = true;
-
-	while (!video->endOfVideo() && !_vm->shouldQuit() && continuePlaying) {
-		if (updateMovies())
-			_vm->_system->updateScreen();
-
-		Common::Event event;
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
-			switch (event.type) {
-			case Common::EVENT_RTL:
-			case Common::EVENT_QUIT:
-				continuePlaying = false;
-				break;
-			case Common::EVENT_KEYDOWN:
-				switch (event.kbd.keycode) {
-				case Common::KEYCODE_SPACE:
-					_vm->pauseGame();
-					break;
-				case Common::KEYCODE_ESCAPE:
-					continuePlaying = false;
-					break;
-				default:
-					break;
-			}
-			default:
-				break;
-			}
-		}
-
-		// Cut down on CPU usage
-		_vm->_system->delayMillis(10);
-	}
-
-	// Ensure it's removed
-	removeEntry(video);
-}
-
 VideoEntryPtr VideoManager::playMovie(const Common::String &fileName) {
 	VideoEntryPtr ptr = open(fileName);
 	if (!ptr)
@@ -456,8 +386,8 @@ VideoManager::VideoList::iterator VideoManager::findEntry(VideoEntryPtr ptr) {
 	return Common::find(_videos.begin(), _videos.end(), ptr);
 }
 
-void VideoManager::removeEntry(VideoEntryPtr ptr) {
-	VideoManager::VideoList::iterator it = findEntry(ptr);
+void VideoManager::removeEntry(const VideoEntryPtr &video) {
+	VideoManager::VideoList::iterator it = findEntry(video);
 	if (it != _videos.end())
 		_videos.erase(it);
 }
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index 20da429..07dc128 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -240,8 +240,6 @@ public:
 	virtual ~VideoManager();
 
 	// Generic movie functions
-	void playMovieBlocking(const Common::String &filename, uint16 x, uint16 y);
-	void playMovieBlockingCentered(const Common::String &filename);
 	VideoEntryPtr playMovie(const Common::String &filename);
 	VideoEntryPtr playMovie(uint16 id);
 	bool updateMovies();
@@ -253,8 +251,8 @@ public:
 	// Handle functions
 	VideoEntryPtr findVideo(uint16 id);
 	VideoEntryPtr findVideo(const Common::String &fileName);
-	void waitUntilMovieEnds(const VideoEntryPtr &video);
 	void drawVideoFrame(const VideoEntryPtr &video, const Audio::Timestamp &time);
+	void removeEntry(const VideoEntryPtr &video);
 
 protected:
 	MohawkEngine *_vm;
@@ -268,7 +266,6 @@ protected:
 	VideoEntryPtr open(const Common::String &fileName);
 
 	VideoList::iterator findEntry(VideoEntryPtr ptr);
-	void removeEntry(VideoEntryPtr ptr);
 
 	bool drawNextFrame(VideoEntryPtr videoEntry);
 


Commit: 3dd4da0c37e5c853e837b5b4af3ebff1536432f8
    https://github.com/scummvm/scummvm/commit/3dd4da0c37e5c853e837b5b4af3ebff1536432f8
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Change the delay opcode to use the main loop

Changed paths:
    engines/mohawk/myst_scripts.cpp


diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 3480650..ed92375 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -831,7 +831,7 @@ void MystScriptParser::o_delay(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	debugC(kDebugScript, "\tTime: %d", time);
 
-	_vm->_system->delayMillis(time);
+	_vm->wait(time);
 }
 
 void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {


Commit: 8f0fa86fbc88e324bdc5c8f4034056104a51003b
    https://github.com/scummvm/scummvm/commit/8f0fa86fbc88e324bdc5c8f4034056104a51003b
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Change blocking sounds to use the main loop

Changed paths:
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/sound.cpp
    engines/mohawk/sound.h


diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index f965756..3237c94 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -268,6 +268,14 @@ void MohawkEngine_Myst::waitUntilMovieEnds(const VideoEntryPtr &video) {
 	_video->removeEntry(video);
 }
 
+void MohawkEngine_Myst::playSoundBlocking(uint16 id, byte volume) {
+	_sound->playSound(id, volume);
+
+	while (_sound->isPlaying() && !shouldQuit()) {
+		doFrame();
+	}
+}
+
 Common::Error MohawkEngine_Myst::run() {
 	MohawkEngine::run();
 
@@ -478,7 +486,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
 	_sound->stopBackgroundMyst();
 	_video->stopVideos();
 	if (linkSrcSound)
-		_sound->playSoundBlocking(linkSrcSound);
+		playSoundBlocking(linkSrcSound);
 
 	// Delete the previous stack and move the current stack to the previous one
 	// There's probably a better way to do this, but the script classes shouldn't
@@ -588,7 +596,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
 	changeToCard(card, kTransitionCopy);
 
 	if (linkDstSound)
-		_sound->playSoundBlocking(linkDstSound);
+		playSoundBlocking(linkDstSound);
 }
 
 uint16 MohawkEngine_Myst::getCardBackgroundId() {
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index e3fa5a9..edcc76f 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -29,6 +29,8 @@
 #include "mohawk/myst_scripts.h"
 #include "mohawk/video.h"
 
+#include "audio/mixer.h"
+
 #include "common/events.h"
 #include "common/random.h"
 
@@ -230,6 +232,8 @@ public:
 	void playMovieBlockingCentered(const Common::String &filename);
 	void waitUntilMovieEnds(const VideoEntryPtr &video);
 
+	void playSoundBlocking(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume);
+
 	GUI::Debugger *getDebugger() override { return _console; }
 
 	bool canLoadGameStateCurrently() override;
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index ed92375..59d7362 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -650,7 +650,7 @@ void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, u
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
 
 	_vm->_sound->stopSound();
-	_vm->_sound->playSoundBlocking(soundId);
+	_vm->playSoundBlocking(soundId);
 }
 
 void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 351379b..3bbf749 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -611,7 +611,7 @@ void Mechanical::elevatorGoMiddle_run() {
 			}
 
 			// Blip
-			_vm->_sound->playSoundBlocking(14120);
+			_vm->playSoundBlocking(14120);
 
 			// Restore button
 			if (_elevatorInCabin) {
@@ -626,11 +626,11 @@ void Mechanical::elevatorGoMiddle_run() {
 
 				// Elevator going to middle animation
 				_vm->_cursor->hideCursor();
-				_vm->_sound->playSoundBlocking(11120);
+				_vm->playSoundBlocking(11120);
 				_vm->_gfx->copyImageToBackBuffer(6118, Common::Rect(544, 333));
 				_vm->_sound->replaceSoundMyst(12120);
 				_vm->_gfx->runTransition(kTransitionSlideToLeft, Common::Rect(177, 0, 370, 333), 25, 0);
-				_vm->_sound->playSoundBlocking(13120);
+				_vm->playSoundBlocking(13120);
 				_vm->_sound->replaceSoundMyst(8120);
 				_vm->_gfx->copyImageToBackBuffer(6327, Common::Rect(544, 333));
 				_vm->wait(500);
@@ -866,7 +866,7 @@ void Mechanical::fortressRotation_run() {
 			gears->seek(Audio::Timestamp(0, 1800 * (_fortressPosition % 2), 600));
 		}
 
-		_vm->_sound->playSoundBlocking(_fortressRotationSounds[_fortressPosition]);
+		_vm->playSoundBlocking(_fortressRotationSounds[_fortressPosition]);
 
 		_gearsWereRunning = false;
 	}
@@ -1023,7 +1023,7 @@ void Mechanical::fortressSimulation_run() {
 			// END HACK
 
 			holo->seek(Audio::Timestamp(0, 1800 * simulationPosition, 600));
-			_vm->_sound->playSoundBlocking(	_fortressRotationSounds[simulationPosition]);
+			_vm->playSoundBlocking(	_fortressRotationSounds[simulationPosition]);
 
 			_gearsWereRunning = false;
 		}
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 6979ce5..ff2415c 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -902,12 +902,12 @@ void Myst::o_courtyardBoxesCheckSolution(uint16 op, uint16 var, uint16 argc, uin
 	if (_state.courtyardImageBoxes == 50 && !_state.shipFloating) {
 		_vm->_cursor->hideCursor();
 		_state.shipFloating = 1;
-		_vm->_sound->playSoundBlocking(soundId);
+		_vm->playSoundBlocking(soundId);
 		_vm->_cursor->showCursor();
 	} else if (_state.courtyardImageBoxes != 50 && _state.shipFloating) {
 		_vm->_cursor->hideCursor();
 		_state.shipFloating = 0;
-		_vm->_sound->playSoundBlocking(soundId);
+		_vm->playSoundBlocking(soundId);
 		_vm->_cursor->showCursor();
 	}
 }
@@ -1097,7 +1097,7 @@ void Myst::o_bookGivePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	}
 
 	_vm->_cursor->hideCursor();
-	_vm->_sound->playSoundBlocking(soundIdAddPage);
+	_vm->playSoundBlocking(soundIdAddPage);
 	_vm->setMainCursor(kDefaultMystCursor);
 
 	// Add page to book
@@ -1269,11 +1269,11 @@ void Myst::o_imagerEraseButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		return;
 	} else if (_imagerValidationStep < 7) {
 		// Too early
-		_vm->_sound->playSoundBlocking(_imagerSound[2]);
+		_vm->playSoundBlocking(_imagerSound[2]);
 		_imagerValidationStep = 0;
 		return;
 	} else if (_imagerValidationStep < 11) {
-		_vm->_sound->playSoundBlocking(_imagerSound[3]);
+		_vm->playSoundBlocking(_imagerSound[3]);
 
 		// Erase selected video from imager
 		switch (_state.imagerSelection) {
@@ -3375,12 +3375,12 @@ void Myst::libraryBookcaseTransform_run(void) {
 		if (_state.libraryBookcaseDoor) {
 			_vm->_gfx->copyImageSectionToBackBuffer(11179, Common::Rect(0, 0, 106, 81), Common::Rect(0, 72, 106, 153));
 			_vm->_gfx->runTransition(kTransitionBottomToTop, Common::Rect(0, 72, 106, 153), 5, 10);
-			_vm->_sound->playSoundBlocking(7348);
+			_vm->playSoundBlocking(7348);
 			_vm->_sound->replaceBackgroundMyst(4348, 16384);
 		} else {
 			_vm->_gfx->copyImageSectionToBackBuffer(11178, Common::Rect(0, 0, 107, 67), Common::Rect(437, 84, 544, 151));
 			_vm->_gfx->copyBackBufferToScreen(Common::Rect(437, 84, 544, 151));
-			_vm->_sound->playSoundBlocking(7348);
+			_vm->playSoundBlocking(7348);
 			_vm->_sound->replaceBackgroundMyst(4334, 16384);
 		}
 
diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp
index 2a54696..5907c5b 100644
--- a/engines/mohawk/sound.cpp
+++ b/engines/mohawk/sound.cpp
@@ -293,31 +293,6 @@ Audio::SoundHandle *Sound::replaceSoundMyst(uint16 id, byte volume, bool loop) {
 	return playSound(id, volume, loop);
 }
 
-void Sound::playSoundBlocking(uint16 id, byte volume) {
-	Audio::SoundHandle *handle = playSound(id, volume);
-
-	while (_vm->_mixer->isSoundHandleActive(*handle) && !_vm->shouldQuit()) {
-		Common::Event event;
-		while (_vm->_system->getEventManager()->pollEvent(event)) {
-			switch (event.type) {
-				case Common::EVENT_KEYDOWN:
-					switch (event.kbd.keycode) {
-						case Common::KEYCODE_SPACE:
-							_vm->pauseGame();
-							break;
-						default:
-							break;
-					}
-				default:
-					break;
-			}
-		}
-
-		// Cut down on CPU usage
-		_vm->_system->delayMillis(10);
-	}
-}
-
 void Sound::playMidi(uint16 id) {
 	uint32 idTag;
 	if (!(_vm->getFeatures() & GF_HASMIDI)) {
diff --git a/engines/mohawk/sound.h b/engines/mohawk/sound.h
index 2b4b1ce..7dcc125 100644
--- a/engines/mohawk/sound.h
+++ b/engines/mohawk/sound.h
@@ -108,7 +108,6 @@ public:
 
 	// Generic sound functions
 	Audio::SoundHandle *playSound(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false, CueList *cueList = NULL);
-	void playSoundBlocking(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume);
 	void playMidi(uint16 id);
 	void stopMidi();
 	void stopSound();


Commit: 9cb6c872b7ffb2a852a81c19369dcae4f8b6c8ed
    https://github.com/scummvm/scummvm/commit/9cb6c872b7ffb2a852a81c19369dcae4f8b6c8ed
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Decorrelate hotspot handling from event handling

This makes sure doFrame can be called from anywhere, including scripts.

Changed paths:
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/myst_stacks/myst.cpp


diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 3237c94..295abeb 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -85,7 +85,10 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
 
 	_prevStack = nullptr;
 
+	_mouseClicked = false;
+	_mouseMoved = false;
 	_escapePressed = false;
+	_interactive = true;
 }
 
 MohawkEngine_Myst::~MohawkEngine_Myst() {
@@ -248,7 +251,7 @@ void MohawkEngine_Myst::playMovieBlockingCentered(const Common::String &fileName
 }
 
 void MohawkEngine_Myst::waitUntilMovieEnds(const VideoEntryPtr &video) {
-	assert(video);
+	_interactive = false;
 
 	// Sanity check
 	if (video->isLooping())
@@ -266,14 +269,17 @@ void MohawkEngine_Myst::waitUntilMovieEnds(const VideoEntryPtr &video) {
 
 	// Ensure it's removed
 	_video->removeEntry(video);
+	_interactive = true;
 }
 
 void MohawkEngine_Myst::playSoundBlocking(uint16 id, byte volume) {
+	_interactive = false;
 	_sound->playSound(id, volume);
 
 	while (_sound->isPlaying() && !shouldQuit()) {
 		doFrame();
 	}
+	_interactive = true;
 }
 
 Common::Error MohawkEngine_Myst::run() {
@@ -332,23 +338,14 @@ void MohawkEngine_Myst::doFrame() {
 	Common::Event event;
 	while (_system->getEventManager()->pollEvent(event)) {
 		switch (event.type) {
-			case Common::EVENT_MOUSEMOVE: {
-				if (_clickedResource && _clickedResource->isEnabled()) {
-					_clickedResource->handleMouseDrag();
-				}
+			case Common::EVENT_MOUSEMOVE:
+				_mouseMoved = true;
 				break;
-			}
 			case Common::EVENT_LBUTTONUP:
-				if (_clickedResource && _clickedResource->isEnabled()) {
-					_clickedResource->handleMouseUp();
-					_clickedResource = nullptr;
-				}
+				_mouseClicked = false;
 				break;
 			case Common::EVENT_LBUTTONDOWN:
-				if (_activeResource && _activeResource->isEnabled()) {
-					_clickedResource = _activeResource;
-					_clickedResource->handleMouseDown();
-				}
+				_mouseClicked = true;
 				break;
 			case Common::EVENT_KEYDOWN:
 				switch (event.kbd.keycode) {
@@ -413,7 +410,10 @@ void MohawkEngine_Myst::doFrame() {
 		}
 	}
 
-	checkCurrentResource();
+	if (!_scriptParser->isScriptRunning() && _interactive) {
+		updateActiveResource();
+		checkCurrentResource();
+	}
 
 	_system->updateScreen();
 
@@ -462,7 +462,9 @@ void MohawkEngine_Myst::pauseEngineIntern(bool pause) {
 		_video->pauseVideos();
 	} else {
 		_video->resumeVideos();
-		_system->updateScreen();
+
+		// We may have missed events while paused
+		_mouseClicked = (_eventMan->getButtonState() & 1) != 0;
 	}
 }
 
@@ -638,6 +640,9 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
 	_cache.clear();
 	_gfx->clearCache();
 
+	_mouseClicked = false;
+	_mouseMoved = false;
+	_escapePressed = false;
 	_curCard = card;
 
 	// Load a bunch of stuff
@@ -679,13 +684,6 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
 		}
 	}
 
-	// Make sure we have the right cursor showing
-	_hoverResource = nullptr;
-	_activeResource = nullptr;
-	_clickedResource = nullptr;
-
-	checkCurrentResource();
-
 	// Debug: Show resource rects
 	if (_showResourceRects)
 		drawResourceRects();
@@ -700,6 +698,18 @@ void MohawkEngine_Myst::drawResourceRects() {
 	_system->updateScreen();
 }
 
+void MohawkEngine_Myst::updateActiveResource() {
+	const Common::Point &mouse = _system->getEventManager()->getMousePos();
+
+	_activeResource = nullptr;
+	for (uint16 i = 0; i < _resources.size(); i++) {
+		if (_resources[i]->contains(mouse) && _resources[i]->canBecomeActive()) {
+			_activeResource = _resources[i];
+			break;
+		}
+	}
+}
+
 void MohawkEngine_Myst::checkCurrentResource() {
 	const Common::Point &mouse = _system->getEventManager()->getMousePos();
 
@@ -709,26 +719,45 @@ void MohawkEngine_Myst::checkCurrentResource() {
 		_hoverResource = nullptr;
 	}
 
-	// See what resource we're over
-	_activeResource = nullptr;
 	for (uint16 i = 0; i < _resources.size(); i++) {
-		if (_resources[i]->contains(mouse)) {
-			if (_hoverResource != _resources[i] && _resources[i]->type == kMystAreaHover) {
-				_hoverResource = static_cast<MystAreaHover *>(_resources[i]);
-				_hoverResource->handleMouseEnter();
-			}
+		if (_resources[i]->contains(mouse) && _resources[i]->type == kMystAreaHover
+			&& _hoverResource != _resources[i]) {
+			_hoverResource = static_cast<MystAreaHover *>(_resources[i]);
+			_hoverResource->handleMouseEnter();
+		}
+	}
 
-			if (!_activeResource && _resources[i]->canBecomeActive()) {
-				_activeResource = _resources[i];
-			}
+	if (!_mouseClicked && _clickedResource) {
+		if (_clickedResource->isEnabled()) {
+			_clickedResource->handleMouseUp();
+		}
+		_clickedResource = nullptr;
+	}
+
+	if (_mouseMoved && _clickedResource) {
+		if (_clickedResource->isEnabled()) {
+			_clickedResource->handleMouseDrag();
 		}
 	}
 
+	if (_mouseClicked && !_clickedResource) {
+		if (_activeResource && _activeResource->isEnabled()) {
+			_clickedResource = _activeResource;
+			_clickedResource->handleMouseDown();
+		}
+	}
+
+	_mouseMoved = false;
+
 	checkCursorHints();
 }
 
-MystArea *MohawkEngine_Myst::updateCurrentResource() {
-	return _activeResource;
+MystArea *MohawkEngine_Myst::forceUpdateClickedResource() {
+	updateActiveResource();
+
+	_clickedResource = _activeResource;
+
+	return _clickedResource;
 }
 
 void MohawkEngine_Myst::loadCard() {
@@ -891,6 +920,9 @@ void MohawkEngine_Myst::unloadCard() {
 	_view.conditionalImages.clear();
 	_view.soundBlock.soundList.clear();
 	_view.scriptResources.clear();
+	_hoverResource = nullptr;
+	_activeResource = nullptr;
+	_clickedResource = nullptr;
 }
 
 void MohawkEngine_Myst::runInitScript() {
@@ -1160,7 +1192,7 @@ bool MohawkEngine_Myst::hasGameSaveSupport() const {
 }
 
 bool MohawkEngine_Myst::canLoadGameStateCurrently() {
-	if (_scriptParser->isScriptRunning()) {
+	if (_scriptParser->isScriptRunning() || !_interactive) {
 		return false;
 	}
 
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index edcc76f..ae34394 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -189,7 +189,7 @@ public:
 	void setMainCursor(uint16 cursor);
 	uint16 getMainCursor() { return _mainCursor; }
 	void checkCursorHints();
-	MystArea *updateCurrentResource();
+	MystArea *forceUpdateClickedResource();
 	void pollAndDiscardEvents();
 	bool wait(uint32 duration, bool skippable = false);
 
@@ -280,7 +280,10 @@ private:
 	MystArea *_clickedResource;
 
 	// Input
+	bool _mouseClicked;
+	bool _mouseMoved;
 	bool _escapePressed;
+	bool _interactive; // Is the game currently interactive
 
 	Common::Array<MystCursorHint> _cursorHints;
 	void loadCursorHints();
@@ -288,6 +291,8 @@ private:
 	uint16 _mainCursor; // Also defines the current page being held (white, blue, red, or none)
 
 	void pauseEngineIntern(bool) override;
+
+	void updateActiveResource();
 };
 
 template<class T>
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index ff2415c..8e130c8 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -2345,7 +2345,7 @@ void Myst::o_rocketPianoMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_vm->_gfx->copyImageSectionToScreen(key->getSubImage(0).wdib, src, dest);
 
 	if (piano.contains(mouse)) {
-		MystArea *resource = _vm->updateCurrentResource();
+		MystArea *resource = _vm->forceUpdateClickedResource();
 		if (resource && resource->type == kMystAreaDrag) {
 			// Press new key
 			key = static_cast<MystAreaDrag *>(resource);
@@ -2372,8 +2372,6 @@ void Myst::o_rocketPianoMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 			_vm->_sound->resumeBackgroundMyst();
 		}
 	}
-
-	_vm->_system->updateScreen();
 }
 
 void Myst::o_rocketPianoStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {


Commit: 64303abb07c058a92ebe1ab8d91dc0c85b1ec432
    https://github.com/scummvm/scummvm/commit/64303abb07c058a92ebe1ab8d91dc0c85b1ec432
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Update the screen only once per frame

Change all inner loops to call the same frame function.

Remove the draw delay code. Now that we have proper frame pacing it is
not necessary anymore to wait before drawing to make sure the previous
frame stayed on the screen long enough.

Fixes #9915, #9922, #9923.

Changed paths:
    engines/mohawk/console.cpp
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/myst_areas.cpp
    engines/mohawk/myst_graphics.cpp
    engines/mohawk/myst_graphics.h
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/credits.cpp
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/stoneship.cpp
    engines/mohawk/riven.cpp


diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index cfabbd3..374e2a5 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -194,7 +194,6 @@ bool MystConsole::Cmd_DrawImage(int argc, const char **argv) {
 		rect = Common::Rect((uint16)atoi(argv[2]), (uint16)atoi(argv[3]), (uint16)atoi(argv[4]), (uint16)atoi(argv[5]));
 
 	_vm->_gfx->copyImageToScreen((uint16)atoi(argv[1]), rect);
-	_vm->_system->updateScreen();
 	return false;
 }
 
@@ -348,9 +347,7 @@ bool MystConsole::Cmd_QuickTest(int argc, const char **argv) {
 			debug("Loading card %d", ids[j]);
 			_vm->changeToCard(ids[j], kTransitionCopy);
 
-			_vm->_video->updateMovies();
-			_vm->_scriptParser->runPersistentScripts();
-			_vm->_system->updateScreen();
+			_vm->doFrame();
 
 			int16 resIndex = _vm->_rnd->getRandomNumber(_vm->_resources.size()) - 1;
 			if (resIndex >= 0 && _vm->_resources[resIndex]->isEnabled()) {
@@ -358,9 +355,7 @@ bool MystConsole::Cmd_QuickTest(int argc, const char **argv) {
 				_vm->_resources[resIndex]->handleMouseUp();
 			}
 
-			_vm->_video->updateMovies();
-			_vm->_scriptParser->runPersistentScripts();
-			_vm->_system->updateScreen();
+			_vm->doFrame();
 
 			if (_vm->getCurStack() != i) {
 				// Clicking may have linked us to another age
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 295abeb..24778fe 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -251,6 +251,9 @@ void MohawkEngine_Myst::playMovieBlockingCentered(const Common::String &fileName
 }
 
 void MohawkEngine_Myst::waitUntilMovieEnds(const VideoEntryPtr &video) {
+	if (!video)
+		return;
+
 	_interactive = false;
 
 	// Sanity check
@@ -333,7 +336,11 @@ Common::Error MohawkEngine_Myst::run() {
 void MohawkEngine_Myst::doFrame() {
 	// Update any background videos
 	_video->updateMovies();
-	_scriptParser->runPersistentScripts();
+	if (!_scriptParser->isScriptRunning() && _interactive) {
+		_interactive = false;
+		_scriptParser->runPersistentScripts();
+		_interactive = true;
+	}
 
 	Common::Event event;
 	while (_system->getEventManager()->pollEvent(event)) {
@@ -422,39 +429,22 @@ void MohawkEngine_Myst::doFrame() {
 }
 
 bool MohawkEngine_Myst::wait(uint32 duration, bool skippable) {
+	_interactive = false;
 	uint32 end = getTotalPlayTime() + duration;
 
-	while (getTotalPlayTime() < end && !shouldQuit()) {
+	do {
 		doFrame();
 
 		if (_escapePressed && skippable) {
 			_escapePressed = false;
 			return true; // Return true if skipped
 		}
-	}
+	} while (getTotalPlayTime() < end && !shouldQuit());
 
+	_interactive = true;
 	return false;
 }
 
-void MohawkEngine_Myst::pollAndDiscardEvents() {
-	// Poll the events to update the mouse cursor position
-	Common::Event event;
-	while (_system->getEventManager()->pollEvent(event)) {
-		switch (event.type) {
-			case Common::EVENT_KEYDOWN:
-				switch (event.kbd.keycode) {
-					case Common::KEYCODE_SPACE:
-						pauseGame();
-						break;
-					default:
-						break;
-				}
-			default:
-				break;
-		}
-	}
-}
-
 void MohawkEngine_Myst::pauseEngineIntern(bool pause) {
 	MohawkEngine::pauseEngineIntern(pause);
 
@@ -482,8 +472,6 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
 	else
 		_gfx->clearScreenPalette();
 
-	_system->updateScreen();
-
 	_sound->stopSound();
 	_sound->stopBackgroundMyst();
 	_video->stopVideos();
@@ -680,7 +668,6 @@ void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
 			_gfx->runTransition(transition, Common::Rect(544, 333), 10, 0);
 		} else {
 			_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
-			_system->updateScreen();
 		}
 	}
 
@@ -694,8 +681,6 @@ void MohawkEngine_Myst::drawResourceRects() {
 		_resources[i]->getRect().debugPrint(0);
 		_resources[i]->drawBoundingRect();
 	}
-
-	_system->updateScreen();
 }
 
 void MohawkEngine_Myst::updateActiveResource() {
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index ae34394..a411b64 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -190,7 +190,6 @@ public:
 	uint16 getMainCursor() { return _mainCursor; }
 	void checkCursorHints();
 	MystArea *forceUpdateClickedResource();
-	void pollAndDiscardEvents();
 	bool wait(uint32 duration, bool skippable = false);
 
 	/** Update the game state according to events and update the screen */
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 568a95d..5e6b39d 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -443,7 +443,6 @@ void MystAreaImageSwitch::drawConditionalDataToScreen(uint16 state, bool update)
 		// Draw to screen
 		if (update) {
 			_vm->_gfx->copyImageSectionToScreen(imageToDraw, _subImages[subImageId].rect, _rect);
-			_vm->_system->updateScreen();
 		} else {
 			_vm->_gfx->copyImageSectionToBackBuffer(imageToDraw, _subImages[subImageId].rect, _rect);
 		}
@@ -777,7 +776,6 @@ MystVideoInfo::~MystVideoInfo() {
 void MystVideoInfo::drawFrame(uint16 frame) {
 	_currentFrame = _firstFrame + frame;
 	_vm->_gfx->copyImageToScreen(_currentFrame, _frameRect);
-	_vm->_system->updateScreen();
 }
 
 bool MystVideoInfo::pullLeverV() {
@@ -808,7 +806,7 @@ void MystVideoInfo::releaseLeverV() {
 	// Release lever
 	for (int i = step; i >= 0; i--) {
 		drawFrame(i);
-		_vm->_system->delayMillis(10);
+		_vm->doFrame();
 	}
 }
 
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
index 333da40..0aceb1d 100644
--- a/engines/mohawk/myst_graphics.cpp
+++ b/engines/mohawk/myst_graphics.cpp
@@ -55,9 +55,6 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
 	// Initialize our buffer
 	_backBuffer = new Graphics::Surface();
 	_backBuffer->create(_vm->_system->getWidth(), _vm->_system->getHeight(), _pixelFormat);
-
-	_nextAllowedDrawTime = _vm->_system->getMillis();
-	_enableDrawingTimeSimulation = 0;
 }
 
 MystGraphics::~MystGraphics() {
@@ -156,8 +153,6 @@ void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Comm
 	debug(3, "\twidth: %d", width);
 	debug(3, "\theight: %d", height);
 
-	simulatePreviousDrawDelay(dest);
-
 	_vm->_system->copyRectToScreen(surface->getBasePtr(src.left, top), surface->pitch, dest.left, dest.top, width, height);
 }
 
@@ -222,16 +217,11 @@ void MystGraphics::copyImageToBackBuffer(uint16 image, Common::Rect dest) {
 void MystGraphics::copyBackBufferToScreen(Common::Rect r) {
 	r.clip(_viewport);
 
-	simulatePreviousDrawDelay(r);
-
 	_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(r.left, r.top), _backBuffer->pitch, r.left, r.top, r.width(), r.height());
 }
 
 void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16 steps, uint16 delay) {
 
-	// Transitions are barely visible without adding delays between the draw calls
-	enableDrawingTimeSimulation(true);
-
 	switch (type) {
 	case kTransitionLeftToRight:	{
 			debugC(kDebugView, "Left to Right");
@@ -242,18 +232,14 @@ void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16
 				area.left = rect.left + step * i;
 				area.right = area.left + step;
 
-				_vm->_system->delayMillis(delay);
-				_vm->pollAndDiscardEvents();
-
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
+				_vm->wait(delay);
 			}
 			if (area.right < rect.right) {
 				area.left = area.right;
 				area.right = rect.right;
 
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
 			}
 		}
 		break;
@@ -266,18 +252,14 @@ void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16
 				area.right = rect.right - step * i;
 				area.left = area.right - step;
 
-				_vm->_system->delayMillis(delay);
-				_vm->pollAndDiscardEvents();
-
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
+				_vm->wait(delay);
 			}
 			if (area.left > rect.left) {
 				area.right = area.left;
 				area.left = rect.left;
 
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
 			}
 		}
 		break;
@@ -293,11 +275,8 @@ void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16
 			debugC(kDebugView, "Dissolve");
 
 			for (int16 step = 0; step < 8; step++) {
-				// Only one eighth of the rect pixels are updated by a draw step,
-				// delay by one eighth of the regular time
-				simulatePreviousDrawDelay(Common::Rect(rect.width() / 8, rect.height()));
-
 				transitionDissolve(rect, step);
+				_vm->doFrame();
 			}
 		}
 		break;
@@ -310,18 +289,14 @@ void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16
 				area.top = rect.top + step * i;
 				area.bottom = area.top + step;
 
-				_vm->_system->delayMillis(delay);
-				_vm->pollAndDiscardEvents();
-
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
+				_vm->wait(delay);
 			}
 			if (area.bottom < rect.bottom) {
 				area.top = area.bottom;
 				area.bottom = rect.bottom;
 
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
 			}
 		}
 		break;
@@ -334,18 +309,14 @@ void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16
 				area.bottom = rect.bottom - step * i;
 				area.top = area.bottom - step;
 
-				_vm->_system->delayMillis(delay);
-				_vm->pollAndDiscardEvents();
-
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
+				_vm->wait(delay);
 			}
 			if (area.top > rect.top) {
 				area.bottom = area.top;
 				area.top = rect.top;
 
 				copyBackBufferToScreen(area);
-				_vm->_system->updateScreen();
 			}
 		}
 		break;
@@ -371,13 +342,10 @@ void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16
 		break;
 	case kTransitionCopy:
 		copyBackBufferToScreen(rect);
-		_vm->_system->updateScreen();
 		break;
 	default:
 		error("Unknown transition %d", type);
 	}
-
-	enableDrawingTimeSimulation(false);
 }
 
 void MystGraphics::transitionDissolve(Common::Rect rect, uint step) {
@@ -460,8 +428,6 @@ void MystGraphics::transitionDissolve(Common::Rect rect, uint step) {
 	}
 
 	_vm->_system->unlockScreen();
-	_vm->pollAndDiscardEvents();
-	_vm->_system->updateScreen();
 }
 
 void MystGraphics::transitionSlideToLeft(Common::Rect rect, uint16 steps, uint16 delay) {
@@ -475,18 +441,13 @@ void MystGraphics::transitionSlideToLeft(Common::Rect rect, uint16 steps, uint16
 		dstRect.right = dstRect.left + step * stepWidth;
 		srcRect.left = srcRect.right - step * stepWidth;
 
-		_vm->_system->delayMillis(delay);
-
-		simulatePreviousDrawDelay(dstRect);
 		_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(dstRect.left, dstRect.top),
 				_backBuffer->pitch, srcRect.left, srcRect.top, srcRect.width(), srcRect.height());
-		_vm->pollAndDiscardEvents();
-		_vm->_system->updateScreen();
+		_vm->wait(delay);
 	}
 
 	if (dstRect.right != rect.right) {
 		copyBackBufferToScreen(rect);
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -501,18 +462,13 @@ void MystGraphics::transitionSlideToRight(Common::Rect rect, uint16 steps, uint1
 		dstRect.left = dstRect.right - step * stepWidth;
 		srcRect.right = srcRect.left + step * stepWidth;
 
-		_vm->_system->delayMillis(delay);
-
-		simulatePreviousDrawDelay(dstRect);
 		_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(dstRect.left, dstRect.top),
 				_backBuffer->pitch, srcRect.left, srcRect.top, srcRect.width(), srcRect.height());
-		_vm->pollAndDiscardEvents();
-		_vm->_system->updateScreen();
+		_vm->wait(delay);
 	}
 
 	if (dstRect.left != rect.left) {
 		copyBackBufferToScreen(rect);
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -527,19 +483,14 @@ void MystGraphics::transitionSlideToTop(Common::Rect rect, uint16 steps, uint16
 		dstRect.bottom = dstRect.top + step * stepWidth;
 		srcRect.top = srcRect.bottom - step * stepWidth;
 
-		_vm->_system->delayMillis(delay);
-
-		simulatePreviousDrawDelay(dstRect);
 		_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(dstRect.left, dstRect.top),
 				_backBuffer->pitch, srcRect.left, srcRect.top, srcRect.width(), srcRect.height());
-		_vm->pollAndDiscardEvents();
-		_vm->_system->updateScreen();
+		_vm->wait(delay);
 	}
 
 
 	if (dstRect.bottom < rect.bottom) {
 		copyBackBufferToScreen(rect);
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -554,19 +505,14 @@ void MystGraphics::transitionSlideToBottom(Common::Rect rect, uint16 steps, uint
 		dstRect.top = dstRect.bottom - step * stepWidth;
 		srcRect.bottom = srcRect.top + step * stepWidth;
 
-		_vm->_system->delayMillis(delay);
-
-		simulatePreviousDrawDelay(dstRect);
 		_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(dstRect.left, dstRect.top),
 				_backBuffer->pitch, srcRect.left, srcRect.top, srcRect.width(), srcRect.height());
-		_vm->pollAndDiscardEvents();
-		_vm->_system->updateScreen();
+		_vm->wait(delay);
 	}
 
 
 	if (dstRect.top > rect.top) {
 		copyBackBufferToScreen(rect);
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -581,15 +527,12 @@ void MystGraphics::transitionPartialToRight(Common::Rect rect, uint32 width, uin
 		dstRect.right = dstRect.left + step * stepWidth;
 		srcRect.left = srcRect.right - step * stepWidth;
 
-		simulatePreviousDrawDelay(dstRect);
 		_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(dstRect.left, dstRect.top),
 				_backBuffer->pitch, srcRect.left, srcRect.top, srcRect.width(), srcRect.height());
-		_vm->pollAndDiscardEvents();
-		_vm->_system->updateScreen();
+		_vm->doFrame();
 	}
 
 	copyBackBufferToScreen(rect);
-	_vm->_system->updateScreen();
 }
 
 void MystGraphics::transitionPartialToLeft(Common::Rect rect, uint32 width, uint32 steps) {
@@ -603,15 +546,12 @@ void MystGraphics::transitionPartialToLeft(Common::Rect rect, uint32 width, uint
 		dstRect.left = dstRect.right - step * stepWidth;
 		srcRect.right = srcRect.left + step * stepWidth;
 
-		simulatePreviousDrawDelay(dstRect);
 		_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(dstRect.left, dstRect.top),
 				_backBuffer->pitch, srcRect.left, srcRect.top, srcRect.width(), srcRect.height());
-		_vm->pollAndDiscardEvents();
-		_vm->_system->updateScreen();
+		_vm->doFrame();
 	}
 
 	copyBackBufferToScreen(rect);
-	_vm->_system->updateScreen();
 }
 
 void MystGraphics::drawRect(Common::Rect rect, RectState state) {
@@ -637,36 +577,6 @@ void MystGraphics::drawLine(const Common::Point &p1, const Common::Point &p2, ui
 	_backBuffer->drawLine(p1.x, p1.y, p2.x, p2.y, color);
 }
 
-void MystGraphics::enableDrawingTimeSimulation(bool enable) {
-	if (enable)
-		_enableDrawingTimeSimulation++;
-	else
-		_enableDrawingTimeSimulation--;
-
-	if (_enableDrawingTimeSimulation < 0)
-		_enableDrawingTimeSimulation = 0;
-}
-
-void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
-	uint32 time = 0;
-
-	if (_enableDrawingTimeSimulation) {
-		time = _vm->_system->getMillis();
-
-		// Do not draw anything new too quickly after the previous draw call
-		// so that images stay at least a little while on screen
-		// This is enabled only for scripted draw calls
-		if (time < _nextAllowedDrawTime) {
-			debugC(kDebugView, "Delaying draw call by %d ms", _nextAllowedDrawTime - time);
-			_vm->_system->delayMillis(_nextAllowedDrawTime - time);
-		}
-	}
-
-	// Next draw call allowed at DELAY + AERA * COEFF milliseconds from now
-	time = _vm->_system->getMillis();
-	_nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
-}
-
 void MystGraphics::fadeToBlack() {
 	// This is only for the demo
 	assert(!(_vm->getFeatures() & GF_ME));
@@ -681,7 +591,7 @@ void MystGraphics::fadeToBlack() {
 			*dst++ = *src++ * i / 64;
 
 		_vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
-		_vm->_system->updateScreen();
+		_vm->doFrame();
 	}
 }
 
@@ -701,12 +611,11 @@ void MystGraphics::fadeFromBlack() {
 			*dst++ = *src++ * i / 64;
 
 		_vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
-		_vm->_system->updateScreen();
+		_vm->doFrame();
 	}
 
 	// Set the full palette
 	_vm->_system->getPaletteManager()->setPalette(_palette, 0, 256);
-	_vm->_system->updateScreen();
 }
 
 void MystGraphics::clearScreenPalette() {
diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h
index cd09a53..173e023 100644
--- a/engines/mohawk/myst_graphics.h
+++ b/engines/mohawk/myst_graphics.h
@@ -72,12 +72,6 @@ private:
 	Common::Rect _viewport;
 	byte _palette[256 * 3];
 
-	int _enableDrawingTimeSimulation;
-	uint32 _nextAllowedDrawTime;
-	static const uint _constantDrawDelay = 10; // ms
-	static const uint _proportionalDrawDelay = 500; // pixels per ms
-
-	void simulatePreviousDrawDelay(const Common::Rect &dest);
 	void transitionDissolve(Common::Rect rect, uint step);
 	void transitionSlideToLeft(Common::Rect rect, uint16 steps, uint16 delay);
 	void transitionSlideToRight(Common::Rect rect, uint16 steps, uint16 delay);
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 59d7362..f3e44bc 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -158,9 +158,6 @@ void MystScriptParser::setupCommonOpcodes() {
 void MystScriptParser::runScript(MystScript script, MystArea *invokingResource) {
 	debugC(kDebugScript, "Script Size: %d", script->size());
 
-	// Scripted drawing takes more time to simulate older hardware
-	// This way opcodes can't overwrite what the previous ones drew too quickly
-	_vm->_gfx->enableDrawingTimeSimulation(true);
 	_scriptNestingLevel++;
 
 	for (uint16 i = 0; i < script->size(); i++) {
@@ -176,7 +173,6 @@ void MystScriptParser::runScript(MystScript script, MystArea *invokingResource)
 	}
 
 	_scriptNestingLevel--;
-	_vm->_gfx->enableDrawingTimeSimulation(false);
 }
 
 void MystScriptParser::runOpcode(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -412,7 +408,6 @@ void MystScriptParser::o_redrawCard(uint16 op, uint16 var, uint16 argc, uint16 *
 	_vm->drawCardBackground();
 	_vm->drawResourceImages();
 	_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
-	_vm->_system->updateScreen();
 }
 
 void MystScriptParser::o_goToDest(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -671,7 +666,6 @@ void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, uint16 ar
 	debugC(kDebugScript, "\trect.bottom: %d", rect.bottom);
 
 	_vm->_gfx->copyBackBufferToScreen(rect);
-	_vm->_system->updateScreen();
 }
 
 void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -772,7 +766,6 @@ void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, uint16 argc, u
 	debugC(kDebugScript, "\tdstRect.bottom: %d", dstRect.bottom);
 
 	_vm->_gfx->copyImageSectionToScreen(imageId, srcRect, dstRect);
-	_vm->_system->updateScreen();
 }
 
 void MystScriptParser::o_changeCard(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -797,7 +790,7 @@ void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, uint16 argc,
 		debugC(kDebugScript, "\tcardId: %d", cardId);
 
 		_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
-		_vm->_system->updateScreen();
+		_vm->wait(200);
 
 		_vm->changeToCard(cardId, transition);
 }
@@ -915,7 +908,7 @@ void MystScriptParser::o_soundWaitStop(uint16 op, uint16 var, uint16 argc, uint1
 	debugC(kDebugScript, "Opcode %d: Wait for foreground sound to finish", op);
 
 	while (_vm->_sound->isPlaying())
-		_vm->_system->delayMillis(10);
+		_vm->doFrame();
 }
 
 void MystScriptParser::o_quit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 7e91dbb..b8cdb59 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -350,7 +350,7 @@ void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, uint16 a
 	debugC(kDebugScript, "\tcardId: %d", cardId);
 
 	_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
-	_vm->_system->updateScreen();
+	_vm->wait(200);
 
 	_vm->changeToCard(cardId, kTransitionPartToLeft);
 
@@ -368,8 +368,7 @@ void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, uint16 argc, uint1
 	for (uint i = 0; i < 2; i++)
 		for (uint16 imageId = 3601; imageId >= 3595; imageId--) {
 			_vm->_gfx->copyImageToScreen(imageId, rect);
-			_vm->pollAndDiscardEvents();
-			_vm->_system->updateScreen();
+			_vm->doFrame();
 		}
 
 	pipeChangeValve(true, 0x80);
@@ -448,14 +447,14 @@ void Channelwood::o_leverEndMoveWithSound(uint16 op, uint16 var, uint16 argc, ui
 
 void Channelwood::o_leverElev3StartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_vm->_gfx->copyImageToScreen(3970, Common::Rect(544, 333));
-	_vm->_system->updateScreen();
+	_vm->doFrame();
 	o_leverStartMove(op, var, argc, argv);
 }
 
 void Channelwood::o_leverElev3EndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	o_leverEndMove(op, var, argc, argv);
 	_vm->_gfx->copyImageToScreen(3265, Common::Rect(544, 333));
-	_vm->_system->updateScreen();
+	_vm->doFrame();
 	_vm->_sound->replaceSoundMyst(5265);
 }
 
@@ -700,8 +699,7 @@ void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, uint16 argc, uint
 	for (uint i = 0; i < 2; i++)
 		for (uint16 imageId = 3595; imageId <= 3601; imageId++) {
 			_vm->_gfx->copyImageToScreen(imageId, rect);
-			_vm->pollAndDiscardEvents();
-			_vm->_system->updateScreen();
+			_vm->doFrame();
 		}
 
 	pipeChangeValve(false, 0x80);
diff --git a/engines/mohawk/myst_stacks/credits.cpp b/engines/mohawk/myst_stacks/credits.cpp
index c382263..b295255 100644
--- a/engines/mohawk/myst_stacks/credits.cpp
+++ b/engines/mohawk/myst_stacks/credits.cpp
@@ -74,7 +74,6 @@ void Credits::runPersistentScripts() {
 		// Draw next image
 		_vm->drawCardBackground();
 		_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
-		_vm->_system->updateScreen();
 
 		_startTime = _vm->_system->getMillis();
 	}
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 3bbf749..5f49e69 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -381,7 +381,7 @@ void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, uint16 argc, uint
 	// Release lever
 	for (int i = step; i >= 0; i--) {
 		lever->drawFrame(i);
-		_vm->_system->delayMillis(10);
+		_vm->doFrame();
 	}
 
 	// Stop persistent script
@@ -449,7 +449,7 @@ void Mechanical::o_fortressRotationSpeedStop(uint16 op, uint16 var, uint16 argc,
 	// Release lever
 	for (int i = _fortressRotationSpeed; i >= 0; i--) {
 		lever->drawFrame(i);
-		_vm->_system->delayMillis(10);
+		_vm->doFrame();
 	}
 
 	_fortressRotationSpeed = 0;
@@ -528,7 +528,7 @@ void Mechanical::o_fortressSimulationSpeedStop(uint16 op, uint16 var, uint16 arg
 	// Release lever
 	for (int i = _fortressSimulationSpeed; i >= 0; i--) {
 		lever->drawFrame(i);
-		_vm->_system->delayMillis(10);
+		_vm->doFrame();
 	}
 
 	_fortressSimulationSpeed = 0;
@@ -607,7 +607,6 @@ void Mechanical::elevatorGoMiddle_run() {
 			// Draw button pressed
 			if (_elevatorInCabin) {
 				_vm->_gfx->copyImageSectionToScreen(6332, Common::Rect(0, 35, 51, 63), Common::Rect(10, 137, 61, 165));
-				_vm->_system->updateScreen();
 			}
 
 			// Blip
@@ -616,7 +615,6 @@ void Mechanical::elevatorGoMiddle_run() {
 			// Restore button
 			if (_elevatorInCabin) {
 				_vm->_gfx->copyBackBufferToScreen(Common::Rect(10, 137, 61, 165));
-				_vm->_system->updateScreen();
 			 }
 		} else {
 			_elevatorTooLate = true;
@@ -690,7 +688,7 @@ void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, uint16 argc, uint1
 	// Wait while the elevator times out
 	while (_elevatorGoingMiddle) {
 		runPersistentScripts();
-		_vm->_system->delayMillis(10);
+		_vm->doFrame();
 	}
 }
 
@@ -914,16 +912,9 @@ void Mechanical::fortressSimulation_run() {
 		// Init sequence
 		_vm->_sound->replaceBackgroundMyst(_fortressSimulationStartSound1, 65535);
 		_vm->wait(5000, true);
-		_vm->_sound->replaceSoundMyst(_fortressSimulationStartSound2);
 
-		// Update movie while the sound is playing
 		VideoEntryPtr startup = _fortressSimulationStartup->playMovie();
-		while (_vm->_sound->isPlaying(_fortressSimulationStartSound2)) {
-			if (_vm->_video->updateMovies())
-				_vm->_system->updateScreen();
-
-			_vm->_system->delayMillis(10);
-		}
+		_vm->playSoundBlocking(_fortressSimulationStartSound2);
 		_vm->_sound->replaceBackgroundMyst(_fortressSimulationStartSound1, 65535);
 		_vm->waitUntilMovieEnds(startup);
 		_vm->_sound->stopBackgroundMyst();
@@ -934,7 +925,6 @@ void Mechanical::fortressSimulation_run() {
 		Common::Rect dst = Common::Rect(187, 3, 363, 179);
 		_vm->_gfx->copyImageSectionToBackBuffer(6046, src, dst);
 		_vm->_gfx->copyBackBufferToScreen(dst);
-		_vm->_system->updateScreen();
 
 		_fortressSimulationStartup->pauseMovie(true);
 		VideoEntryPtr holo = _fortressSimulationHolo->playMovie();
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 8e130c8..d5e3fe2 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -828,8 +828,6 @@ void Myst::o_libraryBookPageTurnLeft(uint16 op, uint16 var, uint16 argc, uint16
 			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
 		else
 			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
-
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -846,8 +844,6 @@ void Myst::o_libraryBookPageTurnRight(uint16 op, uint16 var, uint16 argc, uint16
 			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
 		else
 			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
-
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -865,16 +861,14 @@ void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, uint16 argc, uint16 *a
 		// Unset button
 		for (uint i = 4795; i >= 4779; i--) {
 			_vm->_gfx->copyImageToScreen(i, getInvokingResource<MystArea>()->getRect());
-			_vm->pollAndDiscardEvents();
-			_vm->_system->updateScreen();
+			_vm->doFrame();
 		}
 		_fireplaceLines[var - 17] &= ~bitmask;
 	} else {
 		// Set button
 		for (uint i = 4779; i <= 4795; i++) {
 			_vm->_gfx->copyImageToScreen(i, getInvokingResource<MystArea>()->getRect());
-			_vm->pollAndDiscardEvents();
-			_vm->_system->updateScreen();
+			_vm->doFrame();
 		}
 		_fireplaceLines[var - 17] |= bitmask;
 	}
@@ -1178,12 +1172,11 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	Common::Rect src = Common::Rect(0, 0, 32, 75);
 	Common::Rect dest = Common::Rect(261, 257, 293, 332);
 	_vm->_gfx->copyImageSectionToScreen(4699, src, dest);
-	_vm->_system->updateScreen();
 
 	_vm->wait(200);
 
 	_vm->_gfx->copyBackBufferToScreen(dest);
-	_vm->_system->updateScreen();
+	_vm->doFrame();
 
 	_vm->_cursor->hideCursor();
 
@@ -2316,7 +2309,6 @@ void Myst::o_rocketPianoStart(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	// Draw pressed piano key
 	_vm->_gfx->copyImageSectionToScreen(key->getSubImage(1).wdib, src, dest);
-	_vm->_system->updateScreen();
 
 	// Play note
 	_rocketPianoSound = 0;
@@ -2386,7 +2378,6 @@ void Myst::o_rocketPianoStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 
 	// Draw unpressed piano key
 	_vm->_gfx->copyImageSectionToScreen(key->getSubImage(0).wdib, src, dest);
-	_vm->_system->updateScreen();
 
 	_vm->_sound->stopSound();
 	_vm->_sound->resumeBackgroundMyst();
@@ -2469,7 +2460,6 @@ void Myst::o_treePressureReleaseStart(uint16 op, uint16 var, uint16 argc, uint16
 	Common::Rect src = Common::Rect(0, 0, 49, 86);
 	Common::Rect dest = Common::Rect(78, 46, 127, 132);
 	_vm->_gfx->copyImageSectionToScreen(4631, src, dest);
-	_vm->_system->updateScreen();
 
 	_tempVar = _state.cabinValvePosition;
 
@@ -2485,7 +2475,6 @@ void Myst::o_treePressureReleaseStop(uint16 op, uint16 var, uint16 argc, uint16
 
 	Common::Rect rect = Common::Rect(78, 46, 127, 132);
 	_vm->_gfx->copyBackBufferToScreen(rect);
-	_vm->_system->updateScreen();
 
 	_state.cabinValvePosition = _tempVar;
 	_treeMinPosition = 0;
@@ -2789,8 +2778,6 @@ void Myst::libraryCombinationBookTurnLeft() {
 			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
 		else
 			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
-
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -2815,8 +2802,6 @@ void Myst::libraryCombinationBookTurnRight() {
 			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
 		else
 			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
-
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -3166,7 +3151,6 @@ void Myst::towerRotationMap_run() {
 
 		// Draw to screen
 		_vm->_gfx->copyBackBufferToScreen(Common::Rect(106, 42, 459, 273));
-		_vm->_system->updateScreen();
 	}
 
 	uint32 time = _vm->_system->getMillis();
@@ -3305,7 +3289,6 @@ void Myst::towerRotationMapDrawLine(const Common::Point &center, const Common::P
 	// Draw line
 	_vm->_gfx->drawLine(center, end, color);
 	_vm->_gfx->copyBackBufferToScreen(rect);
-	_vm->_system->updateScreen();
 }
 
 void Myst::towerRotationMapRotate() {
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 5fbb664..26c38f2 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -481,7 +481,6 @@ void Stoneship::o_telescopeMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
 
     // Draw lighthouse
     telescopeLighthouseDraw();
-    _vm->_system->updateScreen();
 }
 
 void Stoneship::o_telescopeStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -890,7 +889,6 @@ void Stoneship::batteryGauge_run() {
 		_vm->drawCardBackground();
 		_vm->drawResourceImages();
 		_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
-		_vm->_system->updateScreen();
 	}
 }
 
@@ -920,7 +918,6 @@ void Stoneship::tunnel_run() {
 			// Draw tunnel black
 			if (_tunnelImagesCount) {
 				_vm->_gfx->copyImageToScreen(_tunnelImages[1], Common::Rect(544, 333));
-				_vm->_system->updateScreen();
 			}
 
 			_vm->_sound->replaceSoundMyst(_tunnelAlarmSound);
@@ -928,7 +925,6 @@ void Stoneship::tunnel_run() {
 			// Draw tunnel dark
 			if (_tunnelImagesCount) {
 				_vm->_gfx->copyImageToScreen(_tunnelImages[0], Common::Rect(544, 333));
-				_vm->_system->updateScreen();
 			}
 		}
 	}
@@ -969,7 +965,6 @@ void Stoneship::telescope_run() {
 		_telescopeLighthouseState = !_telescopeLighthouseState;
 
 		telescopeLighthouseDraw();
-		_vm->_system->updateScreen();
 	}
 }
 
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 495f399..d3f9e61 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -164,7 +164,6 @@ Common::Error MohawkEngine_Riven::run() {
 	// Start at main cursor
 	_cursor->setCursor(kRivenMainCursor);
 	_cursor->showCursor();
-	_system->updateScreen();
 
 	// Let's begin, shall we?
 	if (getFeatures() & GF_DEMO) {
@@ -283,7 +282,6 @@ void MohawkEngine_Riven::pauseEngineIntern(bool pause) {
 		_video->pauseVideos();
 	} else {
 		_video->resumeVideos();
-		_system->updateScreen();
 	}
 }
 


Commit: 01480f9a00bdc237477f6867c9b6404ec160c3f5
    https://github.com/scummvm/scummvm/commit/01480f9a00bdc237477f6867c9b6404ec160c3f5
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Fix the quickTest debug command

Changed paths:
    engines/mohawk/console.cpp


diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 374e2a5..5b810c5 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -334,6 +334,8 @@ bool MystConsole::Cmd_Resources(int argc, const char **argv) {
 }
 
 bool MystConsole::Cmd_QuickTest(int argc, const char **argv) {
+	_vm->pauseEngine(false);
+
 	// Go through all the ages, all the views and click random stuff
 	for (uint i = 0; i < ARRAYSIZE(mystStackNames); i++) {
 		if (i == 2 || i == 5 || i == 9 || i == 10) continue;
@@ -364,6 +366,7 @@ bool MystConsole::Cmd_QuickTest(int argc, const char **argv) {
 		}
 	}
 
+	_vm->pauseEngine(true);
 	return true;
 }
 


Commit: a2fc282e1c872a725f58b5d87d783191f1fe3987
    https://github.com/scummvm/scummvm/commit/a2fc282e1c872a725f58b5d87d783191f1fe3987
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Move the sound code to its own class

Changed paths:
  A engines/mohawk/myst_sound.cpp
  A engines/mohawk/myst_sound.h
    engines/mohawk/console.cpp
    engines/mohawk/module.mk
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/myst_areas.cpp
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/preview.cpp
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/myst_stacks/stoneship.cpp
    engines/mohawk/riven_sound.cpp
    engines/mohawk/sound.cpp
    engines/mohawk/sound.h


diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 5b810c5..a25023c 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -22,6 +22,7 @@
 
 #include "mohawk/console.h"
 #include "mohawk/livingbooks.h"
+#include "mohawk/resource.h"
 #include "mohawk/sound.h"
 #include "mohawk/video.h"
 
@@ -37,6 +38,7 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_scripts.h"
+#include "mohawk/myst_sound.h"
 #endif
 
 #ifdef ENABLE_RIVEN
diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk
index de0f205..e20638f 100644
--- a/engines/mohawk/module.mk
+++ b/engines/mohawk/module.mk
@@ -34,6 +34,7 @@ MODULE_OBJS += \
 	myst_areas.o \
 	myst_graphics.o \
 	myst_scripts.o \
+	myst_sound.o \
 	myst_state.o \
 	resource_cache.o \
 	myst_stacks/channelwood.o \
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 24778fe..8d96780 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -31,11 +31,11 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_scripts.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/myst_state.h"
 #include "mohawk/dialogs.h"
 #include "mohawk/resource.h"
 #include "mohawk/resource_cache.h"
-#include "mohawk/sound.h"
 #include "mohawk/video.h"
 
 // The stacks
@@ -290,7 +290,7 @@ Common::Error MohawkEngine_Myst::run() {
 
 	_gfx = new MystGraphics(this);
 	_video = new VideoManager(this);
-	_sound = new Sound(this);
+	_sound = new MystSound(this);
 	_console = new MystConsole(this);
 	_gameState = new MystGameState(this, _saveFileMan);
 	_optionsDialog = new MystOptionsDialog(this);
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index a411b64..39d96bb 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -43,6 +43,7 @@ class MystScriptParser;
 class MystConsole;
 class MystGameState;
 class MystOptionsDialog;
+class MystSound;
 class MystArea;
 class MystAreaImageSwitch;
 class MystAreaHover;
@@ -206,7 +207,7 @@ public:
 	bool _showResourceRects;
 
 	VideoManager *_video;
-	Sound *_sound;
+	MystSound *_sound;
 	MystGraphics *_gfx;
 	MystGameState *_gameState;
 	MystScriptParser *_scriptParser;
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 5e6b39d..3bb6eb8 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -23,7 +23,7 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_scripts.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 
 #include "common/events.h"
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index f3e44bc..9141f9f 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -25,7 +25,7 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_scripts.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 
 #include "common/system.h"
diff --git a/engines/mohawk/myst_sound.cpp b/engines/mohawk/myst_sound.cpp
new file mode 100644
index 0000000..f8cdc04
--- /dev/null
+++ b/engines/mohawk/myst_sound.cpp
@@ -0,0 +1,239 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mohawk/myst_sound.h"
+
+#include "mohawk/myst.h"
+#include "mohawk/resource.h"
+
+#include "common/debug.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/wave.h"
+
+namespace Mohawk {
+
+MystSound::MystSound(MohawkEngine_Myst *vm) :
+		_vm(vm) {
+	_mystBackgroundSound.type = kFreeHandle;
+}
+
+MystSound::~MystSound() {
+	stopSound();
+	stopBackgroundMyst();
+}
+
+Audio::RewindableAudioStream *MystSound::makeAudioStream(uint16 id, CueList *cueList) {
+	if (_vm->getFeatures() & GF_ME)
+		return Audio::makeWAVStream(_vm->getResource(ID_MSND, convertMystID(id)), DisposeAfterUse::YES);
+	else
+		return makeMohawkWaveStream(_vm->getResource(ID_MSND, id), cueList);
+}
+
+Audio::SoundHandle *MystSound::playSound(uint16 id, byte volume, bool loop, CueList *cueList) {
+	debug (0, "Playing sound %d", id);
+
+	Audio::RewindableAudioStream *rewindStream = makeAudioStream(id, cueList);
+
+	if (rewindStream) {
+		SndHandle *handle = getHandle();
+		handle->type = kUsedHandle;
+		handle->id = id;
+		handle->samplesPerSecond = rewindStream->getRate();
+
+		// Set the stream to loop here if it's requested
+		Audio::AudioStream *audStream = rewindStream;
+		if (loop)
+			audStream = Audio::makeLoopingAudioStream(rewindStream, 0);
+
+		_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle->handle, audStream, -1, volume);
+		return &handle->handle;
+	}
+
+	return nullptr;
+}
+
+Audio::SoundHandle *MystSound::replaceSoundMyst(uint16 id, byte volume, bool loop) {
+	debug (0, "Replacing sound %d", id);
+
+	// The original engine also forces looping for those sounds
+	switch (id) {
+	case 2205:
+	case 2207:
+	case 5378:
+	case 7220:
+	case 9119: 	// Elevator engine sound in mechanical age is looping.
+	case 9120:
+	case 9327:
+		loop = true;
+		break;
+	}
+
+	stopSound();
+	return playSound(id, volume, loop);
+}
+
+SndHandle *MystSound::getHandle() {
+	for (uint32 i = 0; i < _handles.size(); i++) {
+		if (_handles[i].type == kFreeHandle)
+			return &_handles[i];
+
+		if (!_vm->_mixer->isSoundHandleActive(_handles[i].handle)) {
+			_handles[i].type = kFreeHandle;
+			_handles[i].id = 0;
+			return &_handles[i];
+		}
+	}
+
+	// Let's add a new sound handle!
+	SndHandle handle;
+	handle.handle = Audio::SoundHandle();
+	handle.type = kFreeHandle;
+	handle.id = 0;
+	_handles.push_back(handle);
+
+	return &_handles[_handles.size() - 1];
+}
+
+void MystSound::stopSound() {
+	for (uint32 i = 0; i < _handles.size(); i++)
+		if (_handles[i].type == kUsedHandle) {
+			_vm->_mixer->stopHandle(_handles[i].handle);
+			_handles[i].type = kFreeHandle;
+			_handles[i].id = 0;
+		}
+}
+
+void MystSound::stopSound(uint16 id) {
+	for (uint32 i = 0; i < _handles.size(); i++)
+		if (_handles[i].type == kUsedHandle && _handles[i].id == id) {
+			_vm->_mixer->stopHandle(_handles[i].handle);
+			_handles[i].type = kFreeHandle;
+			_handles[i].id = 0;
+		}
+}
+
+bool MystSound::isPlaying(uint16 id) {
+	for (uint32 i = 0; i < _handles.size(); i++)
+		if (_handles[i].type == kUsedHandle && _handles[i].id == id)
+			return _vm->_mixer->isSoundHandleActive(_handles[i].handle);
+
+	return false;
+}
+
+bool MystSound::isPlaying() {
+	for (uint32 i = 0; i < _handles.size(); i++)
+		if (_handles[i].type == kUsedHandle)
+			if (_vm->_mixer->isSoundHandleActive(_handles[i].handle))
+				return true;
+
+	return false;
+}
+
+uint MystSound::getNumSamplesPlayed(uint16 id) {
+	for (uint32 i = 0; i < _handles.size(); i++)
+		if (_handles[i].type == kUsedHandle && _handles[i].id == id) {
+			return (_vm->_mixer->getSoundElapsedTime(_handles[i].handle) * _handles[i].samplesPerSecond) / 1000;
+		}
+
+	return 0;
+}
+
+uint16 MystSound::convertMystID(uint16 id) {
+	// Myst ME is a bit more efficient with sound storage than Myst
+	// Myst has lots of sounds repeated. To overcome this, Myst ME
+	// has MJMP resources which provide a link to the actual MSND
+	// resource we're looking for. This saves a lot of space from
+	// repeated data.
+	if (_vm->hasResource(ID_MJMP, id)) {
+		Common::SeekableReadStream *mjmpStream = _vm->getResource(ID_MJMP, id);
+		id = mjmpStream->readUint16LE();
+		delete mjmpStream;
+	}
+
+	return id;
+}
+
+void MystSound::replaceBackgroundMyst(uint16 id, uint16 volume) {
+	debug(0, "Replacing background sound with %d", id);
+
+	// TODO: The original engine does fading
+
+	Common::String name = _vm->getResourceName(ID_MSND, convertMystID(id));
+
+	// Only the first eight characters need to be the same to have a match
+	Common::String prefix;
+	if (name.size() >= 8)
+		prefix = Common::String(name.c_str(), name.c_str() + 8);
+	else
+		prefix = name;
+
+	// Check if sound is already playing
+	if (_mystBackgroundSound.type == kUsedHandle && _vm->_mixer->isSoundHandleActive(_mystBackgroundSound.handle)
+			&& _vm->getResourceName(ID_MSND, convertMystID(_mystBackgroundSound.id)).hasPrefix(prefix)) {
+		// The sound is already playing, just change the volume
+		changeBackgroundVolumeMyst(volume);
+		return;
+	}
+
+	// Stop old background sound
+	stopBackgroundMyst();
+
+	// Play new sound
+	Audio::RewindableAudioStream *rewindStream = makeAudioStream(id);
+
+	if (rewindStream) {
+		_mystBackgroundSound.type = kUsedHandle;
+		_mystBackgroundSound.id = id;
+		_mystBackgroundSound.samplesPerSecond = rewindStream->getRate();
+
+		// Set the stream to loop
+		Audio::AudioStream *audStream = Audio::makeLoopingAudioStream(rewindStream, 0);
+
+		_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mystBackgroundSound.handle, audStream, -1, volume >> 8);
+	}
+}
+
+void MystSound::stopBackgroundMyst() {
+	if (_mystBackgroundSound.type == kUsedHandle) {
+		_vm->_mixer->stopHandle(_mystBackgroundSound.handle);
+		_mystBackgroundSound.type = kFreeHandle;
+		_mystBackgroundSound.id = 0;
+	}
+}
+
+void MystSound::pauseBackgroundMyst() {
+	if (_mystBackgroundSound.type == kUsedHandle)
+		_vm->_mixer->pauseHandle(_mystBackgroundSound.handle, true);
+}
+
+void MystSound::resumeBackgroundMyst() {
+	if (_mystBackgroundSound.type == kUsedHandle)
+		_vm->_mixer->pauseHandle(_mystBackgroundSound.handle, false);
+}
+
+void MystSound::changeBackgroundVolumeMyst(uint16 vol) {
+	if (_mystBackgroundSound.type == kUsedHandle)
+		_vm->_mixer->setChannelVolume(_mystBackgroundSound.handle, vol >> 8);
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/myst_sound.h b/engines/mohawk/myst_sound.h
new file mode 100644
index 0000000..d5cd541
--- /dev/null
+++ b/engines/mohawk/myst_sound.h
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MOHAWK_MYST_SOUND_H
+#define MOHAWK_MYST_SOUND_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+
+#include "audio/mixer.h"
+
+#include "mohawk/sound.h"
+
+namespace Audio {
+class RewindableAudioStream;
+}
+
+namespace Mohawk {
+
+class MohawkEngine_Myst;
+
+class MystSound {
+public:
+	MystSound(MohawkEngine_Myst *vm);
+	~MystSound();
+
+	// Generic sound functions
+	Audio::SoundHandle *playSound(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false, CueList *cueList = NULL);
+	void stopSound();
+	void stopSound(uint16 id);
+	bool isPlaying(uint16 id);
+	bool isPlaying();
+	uint getNumSamplesPlayed(uint16 id);
+
+	// Myst-specific sound functions
+	Audio::SoundHandle *replaceSoundMyst(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false);
+	void replaceBackgroundMyst(uint16 id, uint16 volume = 0xFFFF);
+	void pauseBackgroundMyst();
+	void resumeBackgroundMyst();
+	void stopBackgroundMyst();
+	void changeBackgroundVolumeMyst(uint16 vol);
+
+private:
+	MohawkEngine_Myst *_vm;
+
+	Common::Array<SndHandle> _handles;
+	SndHandle *getHandle();
+	Audio::RewindableAudioStream *makeAudioStream(uint16 id, CueList *cueList = NULL);
+	uint16 convertMystID(uint16 id);
+
+	// Myst-specific
+	SndHandle _mystBackgroundSound;
+};
+
+} // End of namespace Mohawk
+
+#endif
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index b8cdb59..fbe6b60 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -25,7 +25,7 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_state.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 #include "mohawk/myst_stacks/channelwood.h"
 
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 5f49e69..09a876e 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -25,7 +25,7 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_state.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 #include "mohawk/myst_stacks/mechanical.h"
 
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index d5e3fe2..f98fee0 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -25,7 +25,7 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_state.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 #include "mohawk/myst_stacks/myst.h"
 
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index 4245875..aa36ef7 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -24,7 +24,7 @@
 #include "mohawk/myst.h"
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 #include "mohawk/myst_stacks/preview.h"
 
diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 22cb856..47e7a56 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -25,7 +25,7 @@
 #include "mohawk/graphics.h"
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_state.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 #include "mohawk/myst_stacks/selenitic.h"
 
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 26c38f2..2062bb9 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -25,7 +25,7 @@
 #include "mohawk/myst_areas.h"
 #include "mohawk/myst_graphics.h"
 #include "mohawk/myst_state.h"
-#include "mohawk/sound.h"
+#include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 #include "mohawk/myst_stacks/stoneship.h"
 
diff --git a/engines/mohawk/riven_sound.cpp b/engines/mohawk/riven_sound.cpp
index efbcdfb..2305494 100644
--- a/engines/mohawk/riven_sound.cpp
+++ b/engines/mohawk/riven_sound.cpp
@@ -28,6 +28,7 @@
 #include "mohawk/riven_sound.h"
 #include "mohawk/riven.h"
 #include "mohawk/riven_card.h"
+#include "mohawk/resource.h"
 #include "mohawk/sound.h"
 
 namespace Mohawk {
diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp
index 5907c5b..81d83fc 100644
--- a/engines/mohawk/sound.cpp
+++ b/engines/mohawk/sound.cpp
@@ -21,9 +21,6 @@
  */
 
 #include "common/debug.h"
-#include "common/events.h"
-#include "common/system.h"
-#include "common/textconsole.h"
 
 #include "audio/mididrv.h"
 #include "audio/midiparser.h"
@@ -33,7 +30,9 @@
 #include "audio/decoders/raw.h"
 #include "audio/decoders/wave.h"
 
+#include "mohawk/mohawk.h"
 #include "mohawk/sound.h"
+#include "mohawk/resource.h"
 
 namespace Mohawk {
 
@@ -185,13 +184,11 @@ Sound::Sound(MohawkEngine* vm) : _vm(vm) {
 	_midiDriver = NULL;
 	_midiParser = NULL;
 	_midiData = NULL;
-	_mystBackgroundSound.type = kFreeHandle;
 	initMidi();
 }
 
 Sound::~Sound() {
 	stopSound();
-	stopBackgroundMyst();
 
 	if (_midiParser) {
 		_midiParser->unloadMusic();
@@ -225,12 +222,6 @@ Audio::RewindableAudioStream *Sound::makeAudioStream(uint16 id, CueList *cueList
 	Audio::RewindableAudioStream *audStream = NULL;
 
 	switch (_vm->getGameType()) {
-	case GType_MYST:
-		if (_vm->getFeatures() & GF_ME)
-			audStream = Audio::makeWAVStream(_vm->getResource(ID_MSND, convertMystID(id)), DisposeAfterUse::YES);
-		else
-			audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id), cueList);
-		break;
 	case GType_ZOOMBINI:
 		audStream = makeMohawkWaveStream(_vm->getResource(ID_SND, id));
 		break;
@@ -273,26 +264,6 @@ Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop, CueList
 	return NULL;
 }
 
-Audio::SoundHandle *Sound::replaceSoundMyst(uint16 id, byte volume, bool loop) {
-	debug (0, "Replacing sound %d", id);
-
-	// The original engine also forces looping for those sounds
-	switch (id) {
-	case 2205:
-	case 2207:
-	case 5378:
-	case 7220:
-	case 9119: 	// Elevator engine sound in mechanical age is looping.
-	case 9120:
-	case 9327:
-		loop = true;
-		break;
-	}
-
-	stopSound();
-	return playSound(id, volume, loop);
-}
-
 void Sound::playMidi(uint16 id) {
 	uint32 idTag;
 	if (!(_vm->getFeatures() & GF_HASMIDI)) {
@@ -430,82 +401,4 @@ uint Sound::getNumSamplesPlayed(uint16 id) {
 	return 0;
 }
 
-uint16 Sound::convertMystID(uint16 id) {
-	// Myst ME is a bit more efficient with sound storage than Myst
-	// Myst has lots of sounds repeated. To overcome this, Myst ME
-	// has MJMP resources which provide a link to the actual MSND
-	// resource we're looking for. This saves a lot of space from
-	// repeated data.
-	if (_vm->hasResource(ID_MJMP, id)) {
-		Common::SeekableReadStream *mjmpStream = _vm->getResource(ID_MJMP, id);
-		id = mjmpStream->readUint16LE();
-		delete mjmpStream;
-	}
-
-	return id;
-}
-
-void Sound::replaceBackgroundMyst(uint16 id, uint16 volume) {
-	debug(0, "Replacing background sound with %d", id);
-
-	// TODO: The original engine does fading
-
-	Common::String name = _vm->getResourceName(ID_MSND, convertMystID(id));
-
-	// Only the first eight characters need to be the same to have a match
-	Common::String prefix;
-	if (name.size() >= 8)
-		prefix = Common::String(name.c_str(), name.c_str() + 8);
-	else
-		prefix = name;
-
-	// Check if sound is already playing
-	if (_mystBackgroundSound.type == kUsedHandle && _vm->_mixer->isSoundHandleActive(_mystBackgroundSound.handle)
-			&& _vm->getResourceName(ID_MSND, convertMystID(_mystBackgroundSound.id)).hasPrefix(prefix)) {
-		// The sound is already playing, just change the volume
-		changeBackgroundVolumeMyst(volume);
-		return;
-	}
-
-	// Stop old background sound
-	stopBackgroundMyst();
-
-	// Play new sound
-	Audio::RewindableAudioStream *rewindStream = makeAudioStream(id);
-
-	if (rewindStream) {
-		_mystBackgroundSound.type = kUsedHandle;
-		_mystBackgroundSound.id = id;
-		_mystBackgroundSound.samplesPerSecond = rewindStream->getRate();
-
-		// Set the stream to loop
-		Audio::AudioStream *audStream = Audio::makeLoopingAudioStream(rewindStream, 0);
-
-		_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mystBackgroundSound.handle, audStream, -1, volume >> 8);
-	}
-}
-
-void Sound::stopBackgroundMyst() {
-	if (_mystBackgroundSound.type == kUsedHandle) {
-		_vm->_mixer->stopHandle(_mystBackgroundSound.handle);
-		_mystBackgroundSound.type = kFreeHandle;
-		_mystBackgroundSound.id = 0;
-	}
-}
-
-void Sound::pauseBackgroundMyst() {
-	if (_mystBackgroundSound.type == kUsedHandle)
-		_vm->_mixer->pauseHandle(_mystBackgroundSound.handle, true);
-}
-
-void Sound::resumeBackgroundMyst() {
-	if (_mystBackgroundSound.type == kUsedHandle)
-		_vm->_mixer->pauseHandle(_mystBackgroundSound.handle, false);
-}
-
-void Sound::changeBackgroundVolumeMyst(uint16 vol) {
-	if (_mystBackgroundSound.type == kUsedHandle)
-		_vm->_mixer->setChannelVolume(_mystBackgroundSound.handle, vol >> 8);
-}
-
 } // End of namespace Mohawk
diff --git a/engines/mohawk/sound.h b/engines/mohawk/sound.h
index 7dcc125..11fd004 100644
--- a/engines/mohawk/sound.h
+++ b/engines/mohawk/sound.h
@@ -23,14 +23,13 @@
 #ifndef MOHAWK_SOUND_H
 #define MOHAWK_SOUND_H
 
+#include "common/array.h"
 #include "common/scummsys.h"
 #include "common/str.h"
+#include "common/stream.h"
 
 #include "audio/mixer.h"
 
-#include "mohawk/mohawk.h"
-#include "mohawk/resource.h"
-
 class MidiDriver;
 class MidiParser;
 
@@ -116,14 +115,6 @@ public:
 	bool isPlaying();
 	uint getNumSamplesPlayed(uint16 id);
 
-	// Myst-specific sound functions
-	Audio::SoundHandle *replaceSoundMyst(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false);
-	void replaceBackgroundMyst(uint16 id, uint16 volume = 0xFFFF);
-	void pauseBackgroundMyst();
-	void resumeBackgroundMyst();
-	void stopBackgroundMyst();
-	void changeBackgroundVolumeMyst(uint16 vol);
-
 private:
 	MohawkEngine *_vm;
 	MidiDriver *_midiDriver;
@@ -137,9 +128,6 @@ private:
 	SndHandle *getHandle();
 	Audio::RewindableAudioStream *makeAudioStream(uint16 id, CueList *cueList = NULL);
 	uint16 convertMystID(uint16 id);
-
-	// Myst-specific
-	SndHandle _mystBackgroundSound;
 };
 
 } // End of namespace Mohawk


Commit: 75040819c6642c304962d02ba646e04242cd4755
    https://github.com/scummvm/scummvm/commit/75040819c6642c304962d02ba646e04242cd4755
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Rewrite the sound code

It now more closely matches the original. Effect sounds are now stopped
when resuming background sounds.

Fixes #9574, Fixes #9920.

Changed paths:
    engines/mohawk/console.cpp
    engines/mohawk/detection_tables.h
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/myst_areas.cpp
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_sound.cpp
    engines/mohawk/myst_sound.h
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/preview.cpp
    engines/mohawk/myst_stacks/preview.h
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/myst_stacks/stoneship.cpp


diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index a25023c..877c1ac 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -81,7 +81,7 @@ bool MystConsole::Cmd_ChangeCard(int argc, const char **argv) {
 		return true;
 	}
 
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 	_vm->changeToCard((uint16)atoi(argv[1]), kTransitionCopy);
 
 	return false;
@@ -169,7 +169,7 @@ bool MystConsole::Cmd_ChangeStack(int argc, const char **argv) {
 
 	// We need to stop any playing sound when we change the stack
 	// as the next card could continue playing it if it.
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 
 	uint16 card = 0;
 	if (argc == 3)
@@ -234,7 +234,7 @@ bool MystConsole::Cmd_PlaySound(int argc, const char **argv) {
 		return true;
 	}
 
-	_vm->_sound->replaceSoundMyst((uint16)atoi(argv[1]));
+	_vm->_sound->playEffect((uint16) atoi(argv[1]));
 
 	return false;
 }
@@ -242,7 +242,7 @@ bool MystConsole::Cmd_PlaySound(int argc, const char **argv) {
 bool MystConsole::Cmd_StopSound(int argc, const char **argv) {
 	debugPrintf("Stopping Sound\n");
 
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 
 	return true;
 }
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index ba55701..ec72a63 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -24,10 +24,10 @@ namespace Mohawk {
 
 #define GAMEOPTION_PLAY_MYST_FLYBY         GUIO_GAMEOPTIONS1
 
-#define GUI_OPTIONS_MYST                   GUIO3(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOMIDI)
-#define GUI_OPTIONS_MYST_ME                GUIO4(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOMIDI, GAMEOPTION_PLAY_MYST_FLYBY)
+#define GUI_OPTIONS_MYST                   GUIO4(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOMIDI)
+#define GUI_OPTIONS_MYST_ME                GUIO5(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_PLAY_MYST_FLYBY)
 #define GUI_OPTIONS_MYST_DEMO              GUIO4(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOMIDI, GUIO_NOLAUNCHLOAD)
-#define GUI_OPTIONS_MYST_MAKING_OF         GUIO4(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOMIDI, GUIO_NOLAUNCHLOAD)
+#define GUI_OPTIONS_MYST_MAKING_OF         GUIO5(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_NOLAUNCHLOAD)
 
 #define GUI_OPTIONS_RIVEN                  GUIO4(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOMIDI)
 #define GUI_OPTIONS_RIVEN_DEMO             GUIO5(GUIO_NOASPECT, GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_NOLAUNCHLOAD)
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 8d96780..9ce38b9 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -275,11 +275,11 @@ void MohawkEngine_Myst::waitUntilMovieEnds(const VideoEntryPtr &video) {
 	_interactive = true;
 }
 
-void MohawkEngine_Myst::playSoundBlocking(uint16 id, byte volume) {
+void MohawkEngine_Myst::playSoundBlocking(uint16 id) {
 	_interactive = false;
-	_sound->playSound(id, volume);
+	_sound->playEffect(id);
 
-	while (_sound->isPlaying() && !shouldQuit()) {
+	while (_sound->isEffectPlaying() && !shouldQuit()) {
 		doFrame();
 	}
 	_interactive = true;
@@ -472,8 +472,8 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
 	else
 		_gfx->clearScreenPalette();
 
-	_sound->stopSound();
-	_sound->stopBackgroundMyst();
+	_sound->stopEffect();
+	_sound->stopBackground();
 	_video->stopVideos();
 	if (linkSrcSound)
 		playSoundBlocking(linkSrcSound);
@@ -1220,7 +1220,7 @@ void MohawkEngine_Myst::dropPage() {
 	bool redPage = page - 7 < 6;
 
 	// Play drop page sound
-	_sound->replaceSoundMyst(800);
+	_sound->playEffect(800);
 
 	// Drop page
 	_gameState->_globals.heldPage = 0;
@@ -1317,13 +1317,13 @@ void MohawkEngine_Myst::applySoundBlock(const MystSoundBlock &block) {
 		debug(2, "Continuing with current sound");
 	else if (soundAction == kMystSoundActionChangeVolume) {
 		debug(2, "Continuing with current sound, changing volume");
-		_sound->changeBackgroundVolumeMyst(soundActionVolume);
+		_sound->changeBackgroundVolume(soundActionVolume);
 	} else if (soundAction == kMystSoundActionStop) {
 		debug(2, "Stopping sound");
-		_sound->stopBackgroundMyst();
+		_sound->stopBackground();
 	} else if (soundAction > 0) {
 		debug(2, "Playing new sound %d", soundAction);
-		_sound->replaceBackgroundMyst(soundAction, soundActionVolume);
+		_sound->playBackground(soundAction, soundActionVolume);
 	} else {
 		error("Unknown sound action %d", soundAction);
 	}
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 39d96bb..f9823e5 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -232,7 +232,7 @@ public:
 	void playMovieBlockingCentered(const Common::String &filename);
 	void waitUntilMovieEnds(const VideoEntryPtr &video);
 
-	void playSoundBlocking(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume);
+	void playSoundBlocking(uint16 id);
 
 	GUI::Debugger *getDebugger() override { return _console; }
 
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index 3bb6eb8..61b0d87 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -640,7 +640,7 @@ void MystAreaSlider::updatePosition(const Common::Point &mouse) {
 	}
 
 	if (positionChanged && _dragSound)
-		_vm->_sound->replaceSoundMyst(_dragSound);
+		_vm->_sound->playEffect(_dragSound);
 }
 
 MystAreaDrag::MystAreaDrag(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystArea *parent) :
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 9141f9f..30d2c15 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -630,12 +630,12 @@ void MystScriptParser::o_playSound(uint16 op, uint16 var, uint16 argc, uint16 *a
 	debugC(kDebugScript, "Opcode %d: playSound", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
 
-	_vm->_sound->replaceSoundMyst(soundId);
+	_vm->_sound->playEffect(soundId);
 }
 
 void MystScriptParser::o_stopSoundBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: stopSoundBackground", op);
-	_vm->_sound->stopBackgroundMyst();
+	_vm->_sound->stopBackground();
 }
 
 void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -644,7 +644,7 @@ void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, u
 	debugC(kDebugScript, "Opcode %d: playSoundBlocking", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
 
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 	_vm->playSoundBlocking(soundId);
 }
 
@@ -729,13 +729,13 @@ void MystScriptParser::o_soundPlaySwitch(uint16 op, uint16 var, uint16 argc, uin
 		debugC(kDebugScript, "\tsoundId: %d", soundId);
 
 		if (soundId)
-			_vm->_sound->replaceSoundMyst(soundId);
+			_vm->_sound->playEffect(soundId);
 	}
 }
 
 void MystScriptParser::o_soundResumeBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: soundResumeBackground", op);
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 }
 
 void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -838,7 +838,7 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
 	debugC(kDebugScript, "\tSource Stack Link Sound: %d", soundIdLinkSrc);
 	debugC(kDebugScript, "\tDestination Stack Link Sound: %d", soundIdLinkDst);
 
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 
 	if (_vm->getFeatures() & GF_DEMO) {
 		// No need to have a table for just this data...
@@ -865,7 +865,7 @@ void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, u
 	debugC(kDebugScript, "\tanimated update data size: %d", dataSize);
 
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 	_vm->changeToCard(cardId, kNoTransition);
 
@@ -884,7 +884,7 @@ void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, uint1
 	debugC(kDebugScript, "\tanimated update data size: %d", dataSize);
 
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 	animatedUpdate(dataSize, &argv[3], delayBetweenSteps);
 }
@@ -907,7 +907,7 @@ void MystScriptParser::o_soundWaitStop(uint16 op, uint16 var, uint16 argc, uint1
 	// Used when Button is pushed...
 	debugC(kDebugScript, "Opcode %d: Wait for foreground sound to finish", op);
 
-	while (_vm->_sound->isPlaying())
+	while (_vm->_sound->isEffectPlaying())
 		_vm->doFrame();
 }
 
diff --git a/engines/mohawk/myst_sound.cpp b/engines/mohawk/myst_sound.cpp
index f8cdc04..a0a167d 100644
--- a/engines/mohawk/myst_sound.cpp
+++ b/engines/mohawk/myst_sound.cpp
@@ -24,6 +24,7 @@
 
 #include "mohawk/myst.h"
 #include "mohawk/resource.h"
+#include "mohawk/sound.h"
 
 #include "common/debug.h"
 
@@ -33,13 +34,15 @@
 namespace Mohawk {
 
 MystSound::MystSound(MohawkEngine_Myst *vm) :
-		_vm(vm) {
-	_mystBackgroundSound.type = kFreeHandle;
+		_vm(vm),
+		_effectId(0),
+		_speechSamplesPerSecond(0),
+		_backgroundId(0) {
 }
 
 MystSound::~MystSound() {
-	stopSound();
-	stopBackgroundMyst();
+	stopEffect();
+	stopBackground();
 }
 
 Audio::RewindableAudioStream *MystSound::makeAudioStream(uint16 id, CueList *cueList) {
@@ -49,111 +52,56 @@ Audio::RewindableAudioStream *MystSound::makeAudioStream(uint16 id, CueList *cue
 		return makeMohawkWaveStream(_vm->getResource(ID_MSND, id), cueList);
 }
 
-Audio::SoundHandle *MystSound::playSound(uint16 id, byte volume, bool loop, CueList *cueList) {
-	debug (0, "Playing sound %d", id);
-
-	Audio::RewindableAudioStream *rewindStream = makeAudioStream(id, cueList);
-
-	if (rewindStream) {
-		SndHandle *handle = getHandle();
-		handle->type = kUsedHandle;
-		handle->id = id;
-		handle->samplesPerSecond = rewindStream->getRate();
-
-		// Set the stream to loop here if it's requested
-		Audio::AudioStream *audStream = rewindStream;
-		if (loop)
-			audStream = Audio::makeLoopingAudioStream(rewindStream, 0);
-
-		_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle->handle, audStream, -1, volume);
-		return &handle->handle;
-	}
-
-	return nullptr;
-}
-
-Audio::SoundHandle *MystSound::replaceSoundMyst(uint16 id, byte volume, bool loop) {
+void MystSound::playEffect(uint16 id, bool loop) {
 	debug (0, "Replacing sound %d", id);
 
 	// The original engine also forces looping for those sounds
 	switch (id) {
-	case 2205:
-	case 2207:
-	case 5378:
-	case 7220:
-	case 9119: 	// Elevator engine sound in mechanical age is looping.
-	case 9120:
-	case 9327:
-		loop = true;
-		break;
+		case 2205:
+		case 2207:
+		case 5378:
+		case 7220:
+		case 9119: 	// Elevator engine sound in mechanical age is looping.
+		case 9120:
+		case 9327:
+			loop = true;
+			break;
+		default:
+			break;
 	}
 
-	stopSound();
-	return playSound(id, volume, loop);
-}
-
-SndHandle *MystSound::getHandle() {
-	for (uint32 i = 0; i < _handles.size(); i++) {
-		if (_handles[i].type == kFreeHandle)
-			return &_handles[i];
+	stopEffect();
 
-		if (!_vm->_mixer->isSoundHandleActive(_handles[i].handle)) {
-			_handles[i].type = kFreeHandle;
-			_handles[i].id = 0;
-			return &_handles[i];
-		}
+	Audio::RewindableAudioStream *rewindStream = makeAudioStream(id);
+	if (!rewindStream) {
+		warning("Unable to open sound '%d'", id);
+		return;
 	}
 
-	// Let's add a new sound handle!
-	SndHandle handle;
-	handle.handle = Audio::SoundHandle();
-	handle.type = kFreeHandle;
-	handle.id = 0;
-	_handles.push_back(handle);
+	_effectId = id;
 
-	return &_handles[_handles.size() - 1];
-}
-
-void MystSound::stopSound() {
-	for (uint32 i = 0; i < _handles.size(); i++)
-		if (_handles[i].type == kUsedHandle) {
-			_vm->_mixer->stopHandle(_handles[i].handle);
-			_handles[i].type = kFreeHandle;
-			_handles[i].id = 0;
-		}
-}
+	// Set the stream to loop here if it's requested
+	Audio::AudioStream *audStream = rewindStream;
+	if (loop)
+		audStream = Audio::makeLoopingAudioStream(rewindStream, 0);
 
-void MystSound::stopSound(uint16 id) {
-	for (uint32 i = 0; i < _handles.size(); i++)
-		if (_handles[i].type == kUsedHandle && _handles[i].id == id) {
-			_vm->_mixer->stopHandle(_handles[i].handle);
-			_handles[i].type = kFreeHandle;
-			_handles[i].id = 0;
-		}
+	_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectHandle, audStream);
 }
 
-bool MystSound::isPlaying(uint16 id) {
-	for (uint32 i = 0; i < _handles.size(); i++)
-		if (_handles[i].type == kUsedHandle && _handles[i].id == id)
-			return _vm->_mixer->isSoundHandleActive(_handles[i].handle);
-
-	return false;
+void MystSound::stopEffect() {
+	_vm->_mixer->stopHandle(_effectHandle);
+	_effectId = 0;
+	_effectHandle = Audio::SoundHandle();
 }
 
-bool MystSound::isPlaying() {
-	for (uint32 i = 0; i < _handles.size(); i++)
-		if (_handles[i].type == kUsedHandle)
-			if (_vm->_mixer->isSoundHandleActive(_handles[i].handle))
-				return true;
-
-	return false;
+bool MystSound::isEffectPlaying() {
+	return _vm->_mixer->isSoundHandleActive(_effectHandle);
 }
 
-uint MystSound::getNumSamplesPlayed(uint16 id) {
-	for (uint32 i = 0; i < _handles.size(); i++)
-		if (_handles[i].type == kUsedHandle && _handles[i].id == id) {
-			return (_vm->_mixer->getSoundElapsedTime(_handles[i].handle) * _handles[i].samplesPerSecond) / 1000;
-		}
+uint MystSound::getSpeechNumSamplesPlayed() {
+	if (isSpeechPlaying()) {
+		return (_vm->_mixer->getSoundElapsedTime(_speechHandle) * _speechSamplesPerSecond) / 1000;
+	}
 
 	return 0;
 }
@@ -173,10 +121,10 @@ uint16 MystSound::convertMystID(uint16 id) {
 	return id;
 }
 
-void MystSound::replaceBackgroundMyst(uint16 id, uint16 volume) {
+void MystSound::playBackground(uint16 id, uint16 volume) {
 	debug(0, "Replacing background sound with %d", id);
 
-	// TODO: The original engine does fading
+	stopEffect();
 
 	Common::String name = _vm->getResourceName(ID_MSND, convertMystID(id));
 
@@ -188,52 +136,69 @@ void MystSound::replaceBackgroundMyst(uint16 id, uint16 volume) {
 		prefix = name;
 
 	// Check if sound is already playing
-	if (_mystBackgroundSound.type == kUsedHandle && _vm->_mixer->isSoundHandleActive(_mystBackgroundSound.handle)
-			&& _vm->getResourceName(ID_MSND, convertMystID(_mystBackgroundSound.id)).hasPrefix(prefix)) {
+	if (_vm->_mixer->isSoundHandleActive(_backgroundHandle)
+			&& _vm->getResourceName(ID_MSND, convertMystID(_backgroundId)).hasPrefix(prefix)) {
 		// The sound is already playing, just change the volume
-		changeBackgroundVolumeMyst(volume);
+		changeBackgroundVolume(volume);
 		return;
 	}
 
 	// Stop old background sound
-	stopBackgroundMyst();
+	stopBackground();
 
 	// Play new sound
 	Audio::RewindableAudioStream *rewindStream = makeAudioStream(id);
 
 	if (rewindStream) {
-		_mystBackgroundSound.type = kUsedHandle;
-		_mystBackgroundSound.id = id;
-		_mystBackgroundSound.samplesPerSecond = rewindStream->getRate();
+		_backgroundId = id;
 
 		// Set the stream to loop
 		Audio::AudioStream *audStream = Audio::makeLoopingAudioStream(rewindStream, 0);
 
-		_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mystBackgroundSound.handle, audStream, -1, volume >> 8);
+		_vm->_mixer->playStream(Audio::Mixer::kMusicSoundType, &_backgroundHandle, audStream, -1, volume >> 8);
 	}
 }
 
-void MystSound::stopBackgroundMyst() {
-	if (_mystBackgroundSound.type == kUsedHandle) {
-		_vm->_mixer->stopHandle(_mystBackgroundSound.handle);
-		_mystBackgroundSound.type = kFreeHandle;
-		_mystBackgroundSound.id = 0;
-	}
+void MystSound::stopBackground() {
+	_vm->_mixer->stopHandle(_backgroundHandle);
+	_backgroundId = 0;
+	_backgroundHandle = Audio::SoundHandle();
+}
+
+void MystSound::pauseBackground() {
+	_vm->_mixer->pauseHandle(_backgroundHandle, true);
+}
+
+void MystSound::resumeBackground() {
+	stopEffect();
+	_vm->_mixer->pauseHandle(_backgroundHandle, false);
 }
 
-void MystSound::pauseBackgroundMyst() {
-	if (_mystBackgroundSound.type == kUsedHandle)
-		_vm->_mixer->pauseHandle(_mystBackgroundSound.handle, true);
+void MystSound::changeBackgroundVolume(uint16 volume) {
+	_vm->_mixer->setChannelVolume(_backgroundHandle, volume >> 8);
+}
+
+void MystSound::playSpeech(uint16 id, CueList *cueList) {
+	debug (0, "Playing speech %d", id);
+
+	Audio::RewindableAudioStream *rewindStream = makeAudioStream(id, cueList);
+	if (!rewindStream) {
+		warning("Unable to open sound '%d'", id);
+		return;
+	}
+
+	_speechSamplesPerSecond = rewindStream->getRate();
+	_vm->_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, rewindStream);
 }
 
-void MystSound::resumeBackgroundMyst() {
-	if (_mystBackgroundSound.type == kUsedHandle)
-		_vm->_mixer->pauseHandle(_mystBackgroundSound.handle, false);
+bool MystSound::isSpeechPlaying() {
+	return _vm->_mixer->isSoundHandleActive(_speechHandle);
 }
 
-void MystSound::changeBackgroundVolumeMyst(uint16 vol) {
-	if (_mystBackgroundSound.type == kUsedHandle)
-		_vm->_mixer->setChannelVolume(_mystBackgroundSound.handle, vol >> 8);
+void MystSound::stopSpeech() {
+	_vm->_mixer->stopHandle(_speechHandle);
+	_speechHandle = Audio::SoundHandle();
+	_speechSamplesPerSecond = 0;
 }
 
 } // End of namespace Mohawk
diff --git a/engines/mohawk/myst_sound.h b/engines/mohawk/myst_sound.h
index d5cd541..71df23d 100644
--- a/engines/mohawk/myst_sound.h
+++ b/engines/mohawk/myst_sound.h
@@ -28,14 +28,13 @@
 
 #include "audio/mixer.h"
 
-#include "mohawk/sound.h"
-
 namespace Audio {
 class RewindableAudioStream;
 }
 
 namespace Mohawk {
 
+struct CueList;
 class MohawkEngine_Myst;
 
 class MystSound {
@@ -43,32 +42,38 @@ public:
 	MystSound(MohawkEngine_Myst *vm);
 	~MystSound();
 
-	// Generic sound functions
-	Audio::SoundHandle *playSound(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false, CueList *cueList = NULL);
-	void stopSound();
-	void stopSound(uint16 id);
-	bool isPlaying(uint16 id);
-	bool isPlaying();
-	uint getNumSamplesPlayed(uint16 id);
-
-	// Myst-specific sound functions
-	Audio::SoundHandle *replaceSoundMyst(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false);
-	void replaceBackgroundMyst(uint16 id, uint16 volume = 0xFFFF);
-	void pauseBackgroundMyst();
-	void resumeBackgroundMyst();
-	void stopBackgroundMyst();
-	void changeBackgroundVolumeMyst(uint16 vol);
+	// Effect channel
+	void playEffect(uint16 id, bool loop = false);
+	void stopEffect();
+	bool isEffectPlaying();
+
+	// Background channel
+	void playBackground(uint16 id, uint16 volume = 0xFFFF);
+	void pauseBackground();
+	void resumeBackground();
+	void stopBackground();
+	void changeBackgroundVolume(uint16 volume);
+
+	// Speech channel
+	void playSpeech(uint16 id, CueList *cueList = nullptr);
+	bool isSpeechPlaying();
+	uint getSpeechNumSamplesPlayed();
+	void stopSpeech();
 
 private:
 	MohawkEngine_Myst *_vm;
 
-	Common::Array<SndHandle> _handles;
-	SndHandle *getHandle();
-	Audio::RewindableAudioStream *makeAudioStream(uint16 id, CueList *cueList = NULL);
+	Audio::RewindableAudioStream *makeAudioStream(uint16 id, CueList *cueList = nullptr);
 	uint16 convertMystID(uint16 id);
 
-	// Myst-specific
-	SndHandle _mystBackgroundSound;
+	Audio::SoundHandle _effectHandle;
+	int _speechSamplesPerSecond;
+	uint16 _effectId;
+
+	Audio::SoundHandle _backgroundHandle;
+	uint16 _backgroundId;
+
+	Audio::SoundHandle _speechHandle;
 };
 
 } // End of namespace Mohawk
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index fbe6b60..a6e3e56 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -323,7 +323,7 @@ void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	uint16 soundId = argv[0];
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
 
-	_vm->_sound->replaceSoundMyst(soundId);
+	_vm->_sound->playEffect(soundId);
 	VideoEntryPtr pipe = _vm->_video->playMovie(_vm->wrapMovieFilename("pipebrid", kChannelwoodStack));
 	if (!pipe)
 		error("Failed to open 'pipebrid' movie");
@@ -337,7 +337,7 @@ void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		pipe->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3040, 600));
 
 	_vm->waitUntilMovieEnds(pipe);
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 }
 
 void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -356,7 +356,7 @@ void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, uint16 a
 
 	if (argc == 3) {
 		uint16 volume = argv[2];
-		_vm->_sound->changeBackgroundVolumeMyst(volume);
+		_vm->_sound->changeBackgroundVolume(volume);
 	}
 }
 
@@ -408,7 +408,7 @@ void Channelwood::o_leverMoveFail(uint16 op, uint16 var, uint16 argc, uint16 *ar
 			_leverPulled = true;
 			uint16 soundId = lever->getList2(0);
 			if (soundId)
-				_vm->_sound->replaceSoundMyst(soundId);
+				_vm->_sound->playEffect(soundId);
 		}
 	} else {
 		_leverPulled = false;
@@ -426,13 +426,13 @@ void Channelwood::o_leverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *arg
 
 	uint16 soundId = lever->getList3(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 	_vm->checkCursorHints();
 }
 
 void Channelwood::o_leverEndMoveResumeBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 	o_leverEndMove(op, var, argc, argv);
 }
 
@@ -442,7 +442,7 @@ void Channelwood::o_leverEndMoveWithSound(uint16 op, uint16 var, uint16 argc, ui
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = lever->getList3(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 }
 
 void Channelwood::o_leverElev3StartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -455,7 +455,7 @@ void Channelwood::o_leverElev3EndMove(uint16 op, uint16 var, uint16 argc, uint16
 	o_leverEndMove(op, var, argc, argv);
 	_vm->_gfx->copyImageToScreen(3265, Common::Rect(544, 333));
 	_vm->doFrame();
-	_vm->_sound->replaceSoundMyst(5265);
+	_vm->_sound->playEffect(5265);
 }
 
 void Channelwood::o_pumpLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -465,10 +465,10 @@ void Channelwood::o_pumpLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *ar
 
 	if (lever->pullLeverV()) {
 		uint16 soundId = lever->getList2(0);
-		_vm->_sound->replaceBackgroundMyst(soundId, 38400);
+		_vm->_sound->playBackground(soundId, 38400);
 	} else {
 		uint16 soundId = lever->getList2(1);
-		_vm->_sound->replaceBackgroundMyst(soundId, 36864);
+		_vm->_sound->playBackground(soundId, 36864);
 	}
 }
 
@@ -478,7 +478,7 @@ void Channelwood::o_pumpLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = lever->getList3(0);
 	if (soundId)
-		_vm->_sound->replaceBackgroundMyst(soundId, 36864);
+		_vm->_sound->playBackground(soundId, 36864);
 }
 
 void Channelwood::o_stairsDoorToggle(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -519,7 +519,7 @@ void Channelwood::o_valveHandleMoveStart1(uint16 op, uint16 var, uint16 argc, ui
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = handle->getList1(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
 	o_valveHandleMove1(op, var, argc, argv);
@@ -539,7 +539,7 @@ void Channelwood::o_valveHandleMoveStop(uint16 op, uint16 var, uint16 argc, uint
 	// Play release sound
 	uint16 soundId = handle->getList3(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 	// Redraw valve
 	_vm->redrawArea(_valveVar);
@@ -570,7 +570,7 @@ void Channelwood::o_valveHandleMoveStart2(uint16 op, uint16 var, uint16 argc, ui
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = handle->getList1(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
 	o_valveHandleMove2(op, var, argc, argv);
@@ -598,7 +598,7 @@ void Channelwood::o_valveHandleMoveStart3(uint16 op, uint16 var, uint16 argc, ui
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = handle->getList1(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
 	o_valveHandleMove3(op, var, argc, argv);
@@ -661,7 +661,7 @@ void Channelwood::o_drawerOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 void Channelwood::o_hologramTemple(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Temple hologram", op);
 
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	// Used on Card 3333 (Temple Hologram)
 	switch (_state.holoprojectorSelection) {
@@ -682,7 +682,7 @@ void Channelwood::o_hologramTemple(uint16 op, uint16 var, uint16 argc, uint16 *a
 		break;
 	}
 
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 }
 
 void Channelwood::o_executeMouseUp(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -745,9 +745,9 @@ void Channelwood::o_elevatorMovies(uint16 op, uint16 var, uint16 argc, uint16 *a
 		error("Unknown elevator state %d in o_elevatorMovies", elevator);
 	}
 
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 	_vm->playMovieBlocking(movie, x, y);
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 }
 
 void Channelwood::o_soundReplace(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -755,8 +755,8 @@ void Channelwood::o_soundReplace(uint16 op, uint16 var, uint16 argc, uint16 *arg
 
 	uint16 soundId = argv[0];
 
-	if (!_vm->_sound->isPlaying()) {
-		_vm->_sound->replaceSoundMyst(soundId);
+	if (!_vm->_sound->isEffectPlaying()) {
+		_vm->_sound->playEffect(soundId);
 	}
 }
 
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 09a876e..5a1b5e0 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -283,7 +283,7 @@ void Mechanical::o_birdCrankStart(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
 
 	uint16 crankSoundId = crank->getList2(0);
-	_vm->_sound->replaceSoundMyst(crankSoundId, Audio::Mixer::kMaxChannelVolume, true);
+	_vm->_sound->playEffect(crankSoundId, true);
 
 	_birdSingEndTime = 0;
 	_birdCrankStartTime = _vm->_system->getMillis();
@@ -301,7 +301,7 @@ void Mechanical::o_birdCrankStop(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	crankMovie->pauseMovie(true);
 
 	uint16 crankSoundId = crank->getList2(1);
-	_vm->_sound->replaceSoundMyst(crankSoundId);
+	_vm->_sound->playEffect(crankSoundId);
 
 	_birdSingEndTime = 2 * _vm->_system->getMillis() - _birdCrankStartTime;
 	_birdSinging = true;
@@ -343,7 +343,7 @@ void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, uint16 argc, uin
 	_elevatorRotationLeverMoving = true;
 	_elevatorRotationSpeed = 0;
 
-	_vm->_sound->stopBackgroundMyst();
+	_vm->_sound->stopBackground();
 
 	_vm->_cursor->setCursor(700);
 }
@@ -407,7 +407,7 @@ void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, uint16 argc, uint
 		// Increment position
 		_state.elevatorRotation = (_state.elevatorRotation + 1) % 10;
 
-		_vm->_sound->replaceSoundMyst(_elevatorRotationSoundId);
+		_vm->_sound->playEffect(_elevatorRotationSoundId);
 		_vm->redrawArea(11);
 	}
 
@@ -626,17 +626,17 @@ void Mechanical::elevatorGoMiddle_run() {
 				_vm->_cursor->hideCursor();
 				_vm->playSoundBlocking(11120);
 				_vm->_gfx->copyImageToBackBuffer(6118, Common::Rect(544, 333));
-				_vm->_sound->replaceSoundMyst(12120);
+				_vm->_sound->playEffect(12120);
 				_vm->_gfx->runTransition(kTransitionSlideToLeft, Common::Rect(177, 0, 370, 333), 25, 0);
 				_vm->playSoundBlocking(13120);
-				_vm->_sound->replaceSoundMyst(8120);
+				_vm->_sound->playEffect(8120);
 				_vm->_gfx->copyImageToBackBuffer(6327, Common::Rect(544, 333));
 				_vm->wait(500);
-				_vm->_sound->replaceSoundMyst(9120);
+				_vm->_sound->playEffect(9120);
 				static uint16 moviePos[2] = { 3540, 5380 };
 				o_elevatorWindowMovie(121, 0, 2, moviePos);
 				_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
-				_vm->_sound->replaceSoundMyst(10120);
+				_vm->_sound->playEffect(10120);
 				_vm->_cursor->showCursor();
 
 				_elevatorPosition = 1;
@@ -754,7 +754,7 @@ void Mechanical::birdSing_run() {
 	uint32 time = _vm->_system->getMillis();
 	if (_birdSingEndTime < time) {
 		_bird->pauseMovie(true);
-		_vm->_sound->stopSound();
+		_vm->_sound->stopEffect();
 		_birdSinging = false;
 	}
 }
@@ -784,7 +784,7 @@ void Mechanical::elevatorRotation_run() {
 
 		_state.elevatorRotation = (_state.elevatorRotation + 1) % 10;
 
-		_vm->_sound->replaceSoundMyst(_elevatorRotationSoundId);
+		_vm->_sound->playEffect(_elevatorRotationSoundId);
 		_vm->redrawArea(11);
 		_vm->wait(100);
 	}
@@ -910,15 +910,15 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
 void Mechanical::fortressSimulation_run() {
 	if (_fortressSimulationInit) {
 		// Init sequence
-		_vm->_sound->replaceBackgroundMyst(_fortressSimulationStartSound1, 65535);
+		_vm->_sound->playBackground(_fortressSimulationStartSound1, 65535);
 		_vm->wait(5000, true);
 
 		VideoEntryPtr startup = _fortressSimulationStartup->playMovie();
 		_vm->playSoundBlocking(_fortressSimulationStartSound2);
-		_vm->_sound->replaceBackgroundMyst(_fortressSimulationStartSound1, 65535);
+		_vm->_sound->playBackground(_fortressSimulationStartSound1, 65535);
 		_vm->waitUntilMovieEnds(startup);
-		_vm->_sound->stopBackgroundMyst();
-		_vm->_sound->replaceSoundMyst(_fortressSimulationStartSound2);
+		_vm->_sound->stopBackground();
+		_vm->_sound->playEffect(_fortressSimulationStartSound2);
 
 
 		Common::Rect src = Common::Rect(0, 0, 176, 176);
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index f98fee0..71747fa 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -825,9 +825,9 @@ void Myst::o_libraryBookPageTurnLeft(uint16 op, uint16 var, uint16 argc, uint16
 		_vm->_gfx->copyImageToScreen(_libraryBookBaseImage + _libraryBookPage, rect);
 
 		if (_vm->_rnd->getRandomBit())
-			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
+			_vm->_sound->playEffect(_libraryBookSound1);
 		else
-			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
+			_vm->_sound->playEffect(_libraryBookSound2);
 	}
 }
 
@@ -841,9 +841,9 @@ void Myst::o_libraryBookPageTurnRight(uint16 op, uint16 var, uint16 argc, uint16
 		_vm->_gfx->copyImageToScreen(_libraryBookBaseImage + _libraryBookPage, rect);
 
 		if (_vm->_rnd->getRandomBit())
-			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
+			_vm->_sound->playEffect(_libraryBookSound1);
 		else
-			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
+			_vm->_sound->playEffect(_libraryBookSound2);
 	}
 }
 
@@ -918,7 +918,7 @@ void Myst::o_towerRotationStart(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	towerRotationMapComputeAngle();
 	towerRotationMapDrawLine(center, end);
 
-	_vm->_sound->replaceSoundMyst(5378, Audio::Mixer::kMaxChannelVolume, true);
+	_vm->_sound->playEffect(5378, true);
 }
 
 void Myst::o_towerRotationEnd(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -943,7 +943,7 @@ void Myst::o_towerRotationEnd(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		_state.towerRotationAngle = 152;
 	}
 
-	_vm->_sound->replaceSoundMyst(6378);
+	_vm->_sound->playEffect(6378);
 
 	_towerRotationBlinkLabel = true;
 	_towerRotationBlinkLabelCount = 0;
@@ -998,7 +998,7 @@ void Myst::o_dockVaultOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 		else
 			_dockVaultState = 1;
 
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 		_vm->redrawArea(41, false);
 		animatedUpdate(directionalUpdateDataSize, &argv[3], delay);
 	}
@@ -1025,7 +1025,7 @@ void Myst::o_dockVaultClose(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 		if (_dockVaultState == 1 || _dockVaultState == 2)
 			_dockVaultState = 0;
 
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 		_vm->redrawArea(41, false);
 		animatedUpdate(directionalUpdateDataSize, &argv[3], delay);
 	}
@@ -1129,7 +1129,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
 						&& _state.clockTowerMinutePosition == 40;
 
 	if (!_state.clockTowerBridgeOpen && correctTime) {
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 		_vm->wait(500);
 
 		// Gears rise up
@@ -1144,7 +1144,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
 		_state.clockTowerBridgeOpen = 1;
 		_vm->redrawArea(12);
 	} else if (_state.clockTowerBridgeOpen && !correctTime) {
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 		_vm->wait(500);
 
 		// Gears sink down
@@ -1167,7 +1167,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	uint16 video = getVar(51);
 
 	// Press button
-	_vm->_sound->replaceSoundMyst(4698);
+	_vm->_sound->playEffect(4698);
 
 	Common::Rect src = Common::Rect(0, 0, 32, 75);
 	Common::Rect dest = Common::Rect(261, 257, 293, 332);
@@ -1183,7 +1183,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	// Play selected video
 	if (!_state.imagerActive && video != 3)
-		_vm->_sound->replaceSoundMyst(argv[0]);
+		_vm->_sound->playEffect(argv[0]);
 
 	switch (video) {
 	case 0: // Nothing
@@ -1220,7 +1220,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		_imagerMovie->setBlocking(false);
 
 		if (_state.imagerActive) {
-			_vm->_sound->replaceSoundMyst(argv[1]);
+			_vm->_sound->playEffect(argv[1]);
 
 			// Water disappearing
 			VideoEntryPtr water = _imagerMovie->playMovie();
@@ -1301,11 +1301,11 @@ void Myst::imagerValidation_run() {
 		_imagerRedButton->drawConditionalDataToScreen(1);
 
 		if (_imagerValidationStep < 6)
-			_vm->_sound->replaceSoundMyst(_imagerSound[0]);
+			_vm->_sound->playEffect(_imagerSound[0]);
 		else if (_imagerValidationStep < 10)
-			_vm->_sound->replaceSoundMyst(_imagerSound[1]);
+			_vm->_sound->playEffect(_imagerSound[1]);
 		else if (_imagerValidationStep == 10)
-			_vm->_sound->replaceSoundMyst(_imagerSound[2]);
+			_vm->_sound->playEffect(_imagerSound[2]);
 
 		_imagerValidationStep++;
 
@@ -1328,8 +1328,8 @@ void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, uint16 argc, uint16 *
 	_treeStopped = true;
 
 	_vm->_cursor->hideCursor();
-	_vm->_sound->stopSound();
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->stopEffect();
+	_vm->_sound->pauseBackground();
 
 	switch (argv[0]) {
 	case 0:
@@ -1342,7 +1342,7 @@ void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, uint16 argc, uint16 *
 		break;
 	}
 
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 	_vm->_cursor->showCursor();
 	_treeStopped = false;
 }
@@ -1366,17 +1366,17 @@ void Myst::o_generatorButtonPressed(uint16 op, uint16 var, uint16 argc, uint16 *
 		_state.generatorVoltage -= value;
 
 		if (_state.generatorVoltage)
-			_vm->_sound->replaceSoundMyst(8297);
+			_vm->_sound->playEffect(8297);
 		else {
-			_vm->_sound->replaceSoundMyst(9297);
-			_vm->_sound->stopBackgroundMyst();
+			_vm->_sound->playEffect(9297);
+			_vm->_sound->stopBackground();
 		}
 	} else {
 		if (_generatorVoltage)
-			_vm->_sound->replaceSoundMyst(6297);
+			_vm->_sound->playEffect(6297);
 		else {
-			_vm->_sound->replaceSoundMyst(7297);
-			_vm->_sound->replaceBackgroundMyst(4297);
+			_vm->_sound->playBackground(4297);
+			_vm->_sound->playEffect(7297);
 		}
 
 		_state.generatorButtons |= mask;
@@ -1482,13 +1482,13 @@ void Myst::o_cabinSafeHandleMove(uint16 op, uint16 var, uint16 argc, uint16 *arg
 		if (_tempVar == 0) {
 			uint16 soundId = handle->getList2(0);
 			if (soundId)
-				_vm->_sound->replaceSoundMyst(soundId);
+				_vm->_sound->playEffect(soundId);
 		}
 		// Combination is right
 		if (_state.cabinSafeCombination == 724) {
 			uint16 soundId = handle->getList2(1);
 			if (soundId)
-				_vm->_sound->replaceSoundMyst(soundId);
+				_vm->_sound->playEffect(soundId);
 
 			_vm->changeToCard(4103, kNoTransition);
 
@@ -1513,7 +1513,7 @@ void Myst::o_cabinSafeHandleEndMove(uint16 op, uint16 var, uint16 argc, uint16 *
 void Myst::o_observatoryMonthChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Observatory month change start", op);
 
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	if (op == 129 || op == 131) {
 		// Increase
@@ -1561,7 +1561,7 @@ void Myst::observatoryIncrementMonth(int16 increment) {
 		_state.observatoryMonthSlider = _observatoryMonthSlider->_pos.y;
 	}
 
-	_vm->_sound->replaceSoundMyst(8500);
+	_vm->_sound->playEffect(8500);
 }
 
 void Myst::observatoryMonthChange_run() {
@@ -1572,7 +1572,7 @@ void Myst::observatoryMonthChange_run() {
 void Myst::o_observatoryDayChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Observatory day change start", op);
 
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	if (op == 129 || op == 131) {
 		// Increase
@@ -1621,7 +1621,7 @@ void Myst::observatoryIncrementDay(int16 increment) {
 		_state.observatoryDaySlider = _observatoryDaySlider->_pos.y;
 	}
 
-	_vm->_sound->replaceSoundMyst(8500);
+	_vm->_sound->playEffect(8500);
 }
 
 void Myst::observatoryDayChange_run() {
@@ -1632,7 +1632,7 @@ void Myst::observatoryDayChange_run() {
 void Myst::o_observatoryYearChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Observatory year change start", op);
 
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	if (op == 196) {
 		// Increase
@@ -1675,7 +1675,7 @@ void Myst::observatoryIncrementYear(int16 increment) {
 		_state.observatoryYearSlider = _observatoryYearSlider->_pos.y;
 	}
 
-	_vm->_sound->replaceSoundMyst(8500);
+	_vm->_sound->playEffect(8500);
 }
 
 void Myst::observatoryYearChange_run() {
@@ -1686,7 +1686,7 @@ void Myst::observatoryYearChange_run() {
 void Myst::o_observatoryTimeChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Observatory time change start", op);
 
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	if (op == 192) {
 		// Increase
@@ -1734,7 +1734,7 @@ void Myst::observatoryIncrementTime(int16 increment) {
 		_state.observatoryTimeSlider = _observatoryTimeSlider->_pos.y;
 	}
 
-	_vm->_sound->replaceSoundMyst(8500);
+	_vm->_sound->playEffect(8500);
 }
 
 void Myst::observatoryTimeChange_run() {
@@ -1751,7 +1751,7 @@ void Myst::o_observatoryGoButton(uint16 op, uint16 var, uint16 argc, uint16 *arg
 			|| _state.observatoryYearTarget != _state.observatoryYearSetting
 			|| _state.observatoryTimeTarget != _state.observatoryTimeSetting) {
 		uint16 soundId = argv[0];
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 		int16 distance = _state.observatoryYearTarget - _state.observatoryYearSetting;
 		uint32 end = _vm->_system->getMillis() + 32 * ABS(distance) / 50 + 800;
@@ -1764,7 +1764,7 @@ void Myst::o_observatoryGoButton(uint16 op, uint16 var, uint16 argc, uint16 *arg
 			_vm->redrawResource(_observatoryVisualizer);
 		}
 
-		_vm->_sound->resumeBackgroundMyst();
+		_vm->_sound->resumeBackground();
 
 		// Redraw visualizer
 		observatorySetTargetToSetting();
@@ -1832,11 +1832,11 @@ void Myst::o_circuitBreakerMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
 				if (_state.generatorVoltage > 59 || _state.generatorBreakers != 1) {
 					uint16 soundId = breaker->getList2(1);
 					if (soundId)
-						_vm->_sound->replaceSoundMyst(soundId);
+						_vm->_sound->playEffect(soundId);
 				} else {
 					uint16 soundId = breaker->getList2(0);
 					if (soundId)
-						_vm->_sound->replaceSoundMyst(soundId);
+						_vm->_sound->playEffect(soundId);
 
 					// Reset breaker state
 					_state.generatorBreakers = 0;
@@ -1846,11 +1846,11 @@ void Myst::o_circuitBreakerMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
 				if (_state.generatorVoltage > 59 || _state.generatorBreakers != 2) {
 					uint16 soundId = breaker->getList2(1);
 					if (soundId)
-						_vm->_sound->replaceSoundMyst(soundId);
+						_vm->_sound->playEffect(soundId);
 				} else {
 					uint16 soundId = breaker->getList2(0);
 					if (soundId)
-						_vm->_sound->replaceSoundMyst(soundId);
+						_vm->_sound->playEffect(soundId);
 
 					// Reset breaker state
 					_state.generatorBreakers = 0;
@@ -1873,7 +1873,7 @@ void Myst::o_boilerIncreasePressureStart(uint16 op, uint16 var, uint16 argc, uin
 
 	_treeStopped = true;
 	if (_state.cabinValvePosition < 25)
-		_vm->_sound->stopBackgroundMyst();
+		_vm->_sound->stopBackground();
 
 	_boilerPressureIncreasing = true;
 }
@@ -1892,7 +1892,7 @@ void Myst::o_boilerLightPilot(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		_matchGoOutTime = _vm->_system->getMillis();
 
 		if (_state.cabinValvePosition > 0)
-			_vm->_sound->replaceBackgroundMyst(8098, 49152);
+			_vm->_sound->playBackground(8098, 49152);
 
 		if (_state.cabinValvePosition > 12) {
 			// Compute the speed of the gauge to synchronize it with the next tree move
@@ -1949,7 +1949,7 @@ void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
 
 	if (_state.cabinPilotLightLit == 1) {
 		if (_state.cabinValvePosition > 0)
-			_vm->_sound->replaceBackgroundMyst(8098, 49152);
+			_vm->_sound->playBackground(8098, 49152);
 
 		if (_cabinGaugeMovie && !_cabinGaugeMovie->endOfVideo()) {
 			uint16 delay = treeNextMoveDelay(_state.cabinValvePosition);
@@ -1958,12 +1958,12 @@ void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
 		}
 
 	} else if (_state.cabinValvePosition > 0)
-		_vm->_sound->replaceBackgroundMyst(4098, _state.cabinValvePosition << 10);
+		_vm->_sound->playBackground(4098, _state.cabinValvePosition << 10);
 }
 
 void Myst::boilerPressureIncrease_run() {
 	// Allow increasing pressure if sound has stopped
-	if (!_vm->_sound->isPlaying(5098) && _state.cabinValvePosition < 25) {
+	if (!_vm->_sound->isEffectPlaying() && _state.cabinValvePosition < 25) {
 		_state.cabinValvePosition++;
 		if (_state.cabinValvePosition == 1) {
 			// Set fire to high
@@ -1973,13 +1973,13 @@ void Myst::boilerPressureIncrease_run() {
 			_vm->redrawArea(305);
 		} else if (_state.cabinValvePosition == 25) {
 			if (_state.cabinPilotLightLit == 1)
-				_vm->_sound->replaceBackgroundMyst(8098, 49152);
+				_vm->_sound->playBackground(8098, 49152);
 			else
-				_vm->_sound->replaceBackgroundMyst(4098, 25600);
+				_vm->_sound->playBackground(4098, 25600);
 		}
 
 		// Pressure increasing sound
-		_vm->_sound->replaceSoundMyst(5098);
+		_vm->_sound->playEffect(5098);
 
 		// Redraw wheel
 		_vm->redrawArea(99);
@@ -1988,7 +1988,7 @@ void Myst::boilerPressureIncrease_run() {
 
 void Myst::boilerPressureDecrease_run() {
 	// Allow decreasing pressure if sound has stopped
-	if (!_vm->_sound->isPlaying(5098) && _state.cabinValvePosition > 0) {
+	if (!_vm->_sound->isEffectPlaying() && _state.cabinValvePosition > 0) {
 		_state.cabinValvePosition--;
 		if (_state.cabinValvePosition == 0) {
 			// Set fire to low
@@ -1999,7 +1999,7 @@ void Myst::boilerPressureDecrease_run() {
 		}
 
 		// Pressure increasing sound
-		_vm->_sound->replaceSoundMyst(5098);
+		_vm->_sound->playEffect(5098);
 
 		// Redraw wheel
 		_vm->redrawArea(99);
@@ -2010,7 +2010,7 @@ void Myst::o_boilerDecreasePressureStart(uint16 op, uint16 var, uint16 argc, uin
 	debugC(kDebugScript, "Opcode %d: Boiler decrease pressure start", op);
 
 	_treeStopped = true;
-	_vm->_sound->stopBackgroundMyst();
+	_vm->_sound->stopBackground();
 
 	_boilerPressureDecreasing = true;
 }
@@ -2024,7 +2024,7 @@ void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
 
 	if (_state.cabinPilotLightLit == 1) {
 		if (_state.cabinValvePosition > 0)
-			_vm->_sound->replaceBackgroundMyst(8098, 49152);
+			_vm->_sound->playBackground(8098, 49152);
 
 		if (_cabinGaugeMovie && !_cabinGaugeMovie->endOfVideo()) {
 			uint16 delay = treeNextMoveDelay(_state.cabinValvePosition);
@@ -2034,7 +2034,7 @@ void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
 
 	} else {
 		if (_state.cabinValvePosition > 0)
-			_vm->_sound->replaceBackgroundMyst(4098, _state.cabinValvePosition << 10);
+			_vm->_sound->playBackground(4098, _state.cabinValvePosition << 10);
 	}
 }
 
@@ -2055,11 +2055,11 @@ void Myst::o_basementIncreasePressureStop(uint16 op, uint16 var, uint16 argc, ui
 
 void Myst::basementPressureIncrease_run() {
 	// Allow increasing pressure if sound has stopped
-	if (!_vm->_sound->isPlaying(4642) && _state.cabinValvePosition < 25) {
+	if (!_vm->_sound->isEffectPlaying() && _state.cabinValvePosition < 25) {
 		_state.cabinValvePosition++;
 
 		// Pressure increasing sound
-		_vm->_sound->replaceSoundMyst(4642);
+		_vm->_sound->playEffect(4642);
 
 		// Redraw wheel
 		_vm->redrawArea(99);
@@ -2068,11 +2068,11 @@ void Myst::basementPressureIncrease_run() {
 
 void Myst::basementPressureDecrease_run() {
 	// Allow decreasing pressure if sound has stopped
-	if (!_vm->_sound->isPlaying(4642) && _state.cabinValvePosition > 0) {
+	if (!_vm->_sound->isEffectPlaying() && _state.cabinValvePosition > 0) {
 		_state.cabinValvePosition--;
 
 		// Pressure decreasing sound
-		_vm->_sound->replaceSoundMyst(4642);
+		_vm->_sound->playEffect(4642);
 
 		// Redraw wheel
 		_vm->redrawArea(99);
@@ -2117,18 +2117,18 @@ void Myst::tree_run() {
 				// Tree movement
 				if (goingDown) {
 					_state.treePosition--;
-					_vm->_sound->replaceSoundMyst(2);
+					_vm->_sound->playEffect(2);
 				} else {
 					_state.treePosition++;
-					_vm->_sound->replaceSoundMyst(1);
+					_vm->_sound->playEffect(1);
 				}
 
 				// Stop background music if going up from book room
 				if (_vm->getCurCard() == 4630) {
 					if (_state.treePosition > 0)
-						_vm->_sound->stopBackgroundMyst();
+						_vm->_sound->stopBackground();
 					else
-						_vm->_sound->replaceBackgroundMyst(4630, 24576);
+						_vm->_sound->playBackground(4630, 24576);
 				}
 
 				// Redraw tree
@@ -2168,7 +2168,7 @@ void Myst::o_rocketSoundSliderStartMove(uint16 op, uint16 var, uint16 argc, uint
 
 	_rocketSliderSound = 0;
 	_vm->_cursor->setCursor(700);
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 	rocketSliderMove();
 }
 
@@ -2184,7 +2184,7 @@ void Myst::o_rocketSoundSliderEndMove(uint16 op, uint16 var, uint16 argc, uint16
 	_vm->checkCursorHints();
 
 	if (_state.generatorVoltage == 59 && !_state.generatorBreakers && _rocketSliderSound)
-		_vm->_sound->stopSound();
+		_vm->_sound->stopEffect();
 
 	if (getInvokingResource<MystArea>() == _rocketSlider1)
 		_state.rocketSliderPosition[0] = _rocketSlider1->_pos.y;
@@ -2197,7 +2197,7 @@ void Myst::o_rocketSoundSliderEndMove(uint16 op, uint16 var, uint16 argc, uint16
 	else if (getInvokingResource<MystArea>() == _rocketSlider5)
 		_state.rocketSliderPosition[4] = _rocketSlider5->_pos.y;
 
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 }
 
 void Myst::rocketSliderMove() {
@@ -2207,7 +2207,7 @@ void Myst::rocketSliderMove() {
 		uint16 soundId = rocketSliderGetSound(slider->_pos.y);
 		if (soundId != _rocketSliderSound) {
 			_rocketSliderSound = soundId;
-			_vm->_sound->replaceSoundMyst(soundId, Audio::Mixer::kMaxChannelVolume, true);
+			_vm->_sound->playEffect(soundId, true);
 		}
 	}
 }
@@ -2223,41 +2223,41 @@ void Myst::rocketCheckSolution() {
 	bool solved = true;
 
 	soundId = rocketSliderGetSound(_rocketSlider1->_pos.y);
-	_vm->_sound->replaceSoundMyst(soundId);
+	_vm->_sound->playEffect(soundId);
 	_rocketSlider1->drawConditionalDataToScreen(2);
 	_vm->wait(250);
 	if (soundId != 9558)
 		solved = false;
 
 	soundId = rocketSliderGetSound(_rocketSlider2->_pos.y);
-	_vm->_sound->replaceSoundMyst(soundId);
+	_vm->_sound->playEffect(soundId);
 	_rocketSlider2->drawConditionalDataToScreen(2);
 	_vm->wait(250);
 	if (soundId != 9546)
 		solved = false;
 
 	soundId = rocketSliderGetSound(_rocketSlider3->_pos.y);
-	_vm->_sound->replaceSoundMyst(soundId);
+	_vm->_sound->playEffect(soundId);
 	_rocketSlider3->drawConditionalDataToScreen(2);
 	_vm->wait(250);
 	if (soundId != 9543)
 		solved = false;
 
 	soundId = rocketSliderGetSound(_rocketSlider4->_pos.y);
-	_vm->_sound->replaceSoundMyst(soundId);
+	_vm->_sound->playEffect(soundId);
 	_rocketSlider4->drawConditionalDataToScreen(2);
 	_vm->wait(250);
 	if (soundId != 9553)
 		solved = false;
 
 	soundId = rocketSliderGetSound(_rocketSlider5->_pos.y);
-	_vm->_sound->replaceSoundMyst(soundId);
+	_vm->_sound->playEffect(soundId);
 	_rocketSlider5->drawConditionalDataToScreen(2);
 	_vm->wait(250);
 	if (soundId != 9560)
 		solved = false;
 
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 
 	if (solved) {
 		// Reset lever position
@@ -2313,9 +2313,9 @@ void Myst::o_rocketPianoStart(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	// Play note
 	_rocketPianoSound = 0;
 	if (_state.generatorVoltage == 59 && !_state.generatorBreakers) {
-		_vm->_sound->pauseBackgroundMyst();
+		_vm->_sound->pauseBackground();
 		_rocketPianoSound = key->getList1(0);
-		_vm->_sound->replaceSoundMyst(_rocketPianoSound, Audio::Mixer::kMaxChannelVolume, true);
+		_vm->_sound->playEffect(_rocketPianoSound, true);
 	}
 }
 
@@ -2355,13 +2355,13 @@ void Myst::o_rocketPianoMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 				uint16 soundId = key->getList1(0);
 				if (soundId != _rocketPianoSound) {
 					_rocketPianoSound = soundId;
-					_vm->_sound->replaceSoundMyst(soundId, Audio::Mixer::kMaxChannelVolume, true);
+					_vm->_sound->playEffect(soundId, true);
 				}
 			}
 		} else {
 			// Not pressing a key anymore
-			_vm->_sound->stopSound();
-			_vm->_sound->resumeBackgroundMyst();
+			_vm->_sound->stopEffect();
+			_vm->_sound->resumeBackground();
 		}
 	}
 }
@@ -2379,8 +2379,8 @@ void Myst::o_rocketPianoStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	// Draw unpressed piano key
 	_vm->_gfx->copyImageSectionToScreen(key->getSubImage(0).wdib, src, dest);
 
-	_vm->_sound->stopSound();
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->stopEffect();
+	_vm->_sound->resumeBackground();
 }
 
 void Myst::o_rocketLeverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -2422,7 +2422,7 @@ void Myst::o_rocketLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 		uint16 soundId = lever->getList2(0);
 
 		if (soundId)
-			_vm->_sound->replaceSoundMyst(soundId);
+			_vm->_sound->playEffect(soundId);
 
 		// If rocket correctly powered
 		if (_state.generatorVoltage == 59 && !_state.generatorBreakers)
@@ -2484,7 +2484,7 @@ void Myst::o_observatoryMonthSliderStartMove(uint16 op, uint16 var, uint16 argc,
 	debugC(kDebugScript, "Opcode %d: Month slider start move", op);
 
 	_vm->_cursor->setCursor(700);
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	observatoryUpdateMonth();
 }
@@ -2493,7 +2493,7 @@ void Myst::o_observatoryMonthSliderEndMove(uint16 op, uint16 var, uint16 argc, u
 	debugC(kDebugScript, "Opcode %d: Month slider end move", op);
 
 	_vm->checkCursorHints();
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 
 	observatoryUpdateMonth();
 }
@@ -2504,7 +2504,7 @@ void Myst::observatoryUpdateMonth() {
 	if (month != _state.observatoryMonthSetting) {
 		_state.observatoryMonthSetting = month;
 		_state.observatoryMonthSlider = _observatoryMonthSlider->_pos.y;
-		_vm->_sound->replaceSoundMyst(8500);
+		_vm->_sound->playEffect(8500);
 
 		// Redraw digits
 		_vm->redrawArea(73);
@@ -2515,7 +2515,7 @@ void Myst::o_observatoryDaySliderStartMove(uint16 op, uint16 var, uint16 argc, u
 	debugC(kDebugScript, "Opcode %d: Day slider start move", op);
 
 	_vm->_cursor->setCursor(700);
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	observatoryUpdateDay();
 }
@@ -2524,7 +2524,7 @@ void Myst::o_observatoryDaySliderEndMove(uint16 op, uint16 var, uint16 argc, uin
 	debugC(kDebugScript, "Opcode %d: Day slider end move", op);
 
 	_vm->checkCursorHints();
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 
 	observatoryUpdateDay();
 }
@@ -2535,7 +2535,7 @@ void Myst::observatoryUpdateDay() {
 	if (day != _state.observatoryDaySetting) {
 		_state.observatoryDaySetting = day;
 		_state.observatoryDaySlider = _observatoryDaySlider->_pos.y;
-		_vm->_sound->replaceSoundMyst(8500);
+		_vm->_sound->playEffect(8500);
 
 		// Redraw digits
 		_vm->redrawArea(75);
@@ -2547,7 +2547,7 @@ void Myst::o_observatoryYearSliderStartMove(uint16 op, uint16 var, uint16 argc,
 	debugC(kDebugScript, "Opcode %d: Year slider start move", op);
 
 	_vm->_cursor->setCursor(700);
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	observatoryUpdateYear();
 }
@@ -2556,7 +2556,7 @@ void Myst::o_observatoryYearSliderEndMove(uint16 op, uint16 var, uint16 argc, ui
 	debugC(kDebugScript, "Opcode %d: Year slider end move", op);
 
 	_vm->checkCursorHints();
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 
 	observatoryUpdateYear();
 }
@@ -2567,7 +2567,7 @@ void Myst::observatoryUpdateYear() {
 	if (year != _state.observatoryYearSetting) {
 		_state.observatoryYearSetting = year;
 		_state.observatoryYearSlider = _observatoryYearSlider->_pos.y;
-		_vm->_sound->replaceSoundMyst(8500);
+		_vm->_sound->playEffect(8500);
 
 		// Redraw digits
 		_vm->redrawArea(79);
@@ -2581,7 +2581,7 @@ void Myst::o_observatoryTimeSliderStartMove(uint16 op, uint16 var, uint16 argc,
 	debugC(kDebugScript, "Opcode %d: Time slider start move", op);
 
 	_vm->_cursor->setCursor(700);
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	observatoryUpdateTime();
 }
@@ -2590,7 +2590,7 @@ void Myst::o_observatoryTimeSliderEndMove(uint16 op, uint16 var, uint16 argc, ui
 	debugC(kDebugScript, "Opcode %d: Time slider end move", op);
 
 	_vm->checkCursorHints();
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 
 	observatoryUpdateTime();
 }
@@ -2601,7 +2601,7 @@ void Myst::observatoryUpdateTime() {
 	if (time != _state.observatoryTimeSetting) {
 		_state.observatoryTimeSetting = time;
 		_state.observatoryTimeSlider = _observatoryTimeSlider->_pos.y;
-		_vm->_sound->replaceSoundMyst(8500);
+		_vm->_sound->playEffect(8500);
 
 		// Redraw digits
 		_vm->redrawArea(80);
@@ -2622,7 +2622,7 @@ void Myst::o_libraryCombinationBookStop(uint16 op, uint16 var, uint16 argc, uint
 
 void Myst::o_cabinMatchLight(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	if (!_cabinMatchState) {
-		_vm->_sound->replaceSoundMyst(4103);
+		_vm->_sound->playEffect(4103);
 
 		// Match is lit
 		_cabinMatchState = 1;
@@ -2662,7 +2662,7 @@ void Myst::matchBurn_run() {
 void Myst::o_courtyardBoxEnter(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Mouse enters courtyard box", op);
 	_tempVar = 1;
-	_vm->_sound->playSound(_courtyardBoxSound);
+	_vm->_sound->playEffect(_courtyardBoxSound);
 	_vm->redrawArea(var);
 }
 
@@ -2714,7 +2714,7 @@ void Myst::clockWheelStartTurn(uint16 wheel) {
 	uint16 soundId = resource->getList1(0);
 
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 	// Turn wheel one step
 	if (wheel == 1)
@@ -2775,9 +2775,9 @@ void Myst::libraryCombinationBookTurnLeft() {
 		_vm->_gfx->copyImageToScreen(_libraryBookBaseImage + _libraryBookPage, rect);
 
 		if (_vm->_rnd->getRandomBit())
-			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
+			_vm->_sound->playEffect(_libraryBookSound1);
 		else
-			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
+			_vm->_sound->playEffect(_libraryBookSound2);
 	}
 }
 
@@ -2799,9 +2799,9 @@ void Myst::libraryCombinationBookTurnRight() {
 		_vm->_gfx->copyImageToScreen(_libraryBookBaseImage + _libraryBookPage, rect);
 
 		if (_vm->_rnd->getRandomBit())
-			_vm->_sound->replaceSoundMyst(_libraryBookSound1);
+			_vm->_sound->playEffect(_libraryBookSound1);
 		else
-			_vm->_sound->replaceSoundMyst(_libraryBookSound2);
+			_vm->_sound->playEffect(_libraryBookSound2);
 	}
 }
 
@@ -2834,7 +2834,7 @@ void Myst::o_observatoryChangeSettingStop(uint16 op, uint16 var, uint16 argc, ui
 		_vm->redrawResource(_observatoryCurrentSlider);
 		_observatoryCurrentSlider = nullptr;
 	}
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 }
 
 void Myst::o_dockVaultForceClose(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -2850,12 +2850,12 @@ void Myst::o_dockVaultForceClose(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	if (_dockVaultState) {
 		// Open switch
 		_state.dockMarkerSwitch = 1;
-		_vm->_sound->replaceSoundMyst(4143);
+		_vm->_sound->playEffect(4143);
 		_vm->redrawArea(4);
 
 		// Close vault
 		_dockVaultState = 0;
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 		_vm->redrawArea(41, false);
 		animatedUpdate(directionalUpdateDataSize, &argv[3], delay);
 	}
@@ -2885,7 +2885,7 @@ void Myst::o_clockLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 		if (lever->pullLeverV()) {
 			// Start videos for first step
 			if (_clockWeightPosition < 2214) {
-				_vm->_sound->replaceSoundMyst(5113);
+				_vm->_sound->playEffect(5113);
 				clockGearForwardOneStep(1);
 
 				// Left lever
@@ -2947,7 +2947,7 @@ void Myst::clockWeightDownOneStep() {
 void Myst::clockGears_run() {
 	if (!_vm->_video->isVideoPlaying() && _clockWeightPosition < 2214) {
 		_clockMiddleGearMovedAlone = true;
-		_vm->_sound->replaceSoundMyst(5113);
+		_vm->_sound->playEffect(5113);
 		clockGearForwardOneStep(1);
 		clockWeightDownOneStep();
 	}
@@ -2968,7 +2968,7 @@ void Myst::o_clockLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	}
 
 	if (_clockMiddleGearMovedAlone)
-		_vm->_sound->replaceSoundMyst(8113);
+		_vm->_sound->playEffect(8113);
 
 	// Release lever
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -2987,7 +2987,7 @@ void Myst::clockGearsCheckSolution() {
 			&& !_state.gearsOpen) {
 
 		// Make weight go down
-		_vm->_sound->replaceSoundMyst(9113);
+		_vm->_sound->playEffect(9113);
 		_clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack));
 		if (!_clockWeightVideo)
 			error("Failed to open cl1wlfch movie");
@@ -2999,16 +2999,16 @@ void Myst::clockGearsCheckSolution() {
 		_vm->waitUntilMovieEnds(_clockWeightVideo);
 		_clockWeightPosition = 2214;
 
-		_vm->_sound->replaceSoundMyst(6113);
+		_vm->_sound->playEffect(6113);
 		_vm->wait(1000);
-		_vm->_sound->replaceSoundMyst(7113);
+		_vm->_sound->playEffect(7113);
 
 		// Gear opening video
 		_vm->playMovieBlocking(_vm->wrapMovieFilename("cl1wggat", kMystStack), 195, 225);
 		_state.gearsOpen = 1;
 		_vm->redrawArea(40);
 
-		_vm->_sound->replaceBackgroundMyst(4113, 16384);
+		_vm->_sound->playBackground(4113, 16384);
 	}
 }
 
@@ -3035,8 +3035,8 @@ void Myst::clockReset() {
 
 	_vm->_cursor->hideCursor();
 
-	_vm->_sound->stopBackgroundMyst();
-	_vm->_sound->replaceSoundMyst(5113);
+	_vm->_sound->stopBackground();
+	_vm->_sound->playEffect(5113);
 
 	// Play reset videos
 	clockResetWeight();
@@ -3051,13 +3051,13 @@ void Myst::clockReset() {
 			_vm->waitUntilMovieEnds(handle);
 	}
 
-	_vm->_sound->replaceSoundMyst(10113);
+	_vm->_sound->playEffect(10113);
 
 	// Close gear
 	if (_state.gearsOpen) {
-		_vm->_sound->replaceSoundMyst(6113);
+		_vm->_sound->playEffect(6113);
 		_vm->wait(1000);
-		_vm->_sound->replaceSoundMyst(7113);
+		_vm->_sound->playEffect(7113);
 
 		// Gear closing movie
 		VideoEntryPtr handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wggat", kMystStack));
@@ -3078,7 +3078,7 @@ void Myst::clockReset() {
 }
 
 void Myst::clockResetWeight() {
-	_vm->_sound->replaceSoundMyst(9113);
+	_vm->_sound->playEffect(9113);
 
 	_clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack));
 	if (!_clockWeightVideo)
@@ -3145,7 +3145,7 @@ void Myst::o_courtyardBox_init(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 void Myst::towerRotationMap_run() {
 	if (!_towerRotationMapInitialized) {
 		_towerRotationMapInitialized = true;
-		_vm->_sound->replaceSoundMyst(4378);
+		_vm->_sound->playEffect(4378);
 
 		towerRotationDrawBuildings();
 
@@ -3159,7 +3159,7 @@ void Myst::towerRotationMap_run() {
 			towerRotationMapRotate();
 			_startTime = time + 100;
 		} else if (_towerRotationBlinkLabel
-				&& _vm->_sound->isPlaying(6378)) {
+				&& _vm->_sound->isEffectPlaying()) {
 			// Blink tower rotation label while sound is playing
 			_towerRotationBlinkLabelCount = (_towerRotationBlinkLabelCount + 1) % 14;
 
@@ -3350,19 +3350,19 @@ void Myst::libraryBookcaseTransform_run(void) {
 		_vm->_cursor->hideCursor();
 
 		// Play transform sound and video
-		_vm->_sound->replaceSoundMyst(_libraryBookcaseSoundId);
+		_vm->_sound->playEffect(_libraryBookcaseSoundId);
 		_libraryBookcaseMovie->playMovie();
 
 		if (_state.libraryBookcaseDoor) {
 			_vm->_gfx->copyImageSectionToBackBuffer(11179, Common::Rect(0, 0, 106, 81), Common::Rect(0, 72, 106, 153));
 			_vm->_gfx->runTransition(kTransitionBottomToTop, Common::Rect(0, 72, 106, 153), 5, 10);
 			_vm->playSoundBlocking(7348);
-			_vm->_sound->replaceBackgroundMyst(4348, 16384);
+			_vm->_sound->playBackground(4348, 16384);
 		} else {
 			_vm->_gfx->copyImageSectionToBackBuffer(11178, Common::Rect(0, 0, 107, 67), Common::Rect(437, 84, 544, 151));
 			_vm->_gfx->copyBackBufferToScreen(Common::Rect(437, 84, 544, 151));
 			_vm->playSoundBlocking(7348);
-			_vm->_sound->replaceBackgroundMyst(4334, 16384);
+			_vm->_sound->playBackground(4334, 16384);
 		}
 
 		_vm->_cursor->showCursor();
@@ -3529,33 +3529,33 @@ void Myst::observatory_run() {
 
 		// Make sliders "initialize"
 		if (observatoryIsDDMMYYYY2400()) {
-			_vm->_sound->replaceSoundMyst(8500);
+			_vm->_sound->playEffect(8500);
 			_observatoryDaySlider->drawConditionalDataToScreen(2);
 			_vm->wait(200);
 			_vm->redrawResource(_observatoryDaySlider);
 
-			_vm->_sound->replaceSoundMyst(8500);
+			_vm->_sound->playEffect(8500);
 			_observatoryMonthSlider->drawConditionalDataToScreen(2);
 			_vm->wait(200);
 			_vm->redrawResource(_observatoryMonthSlider);
 		} else {
-			_vm->_sound->replaceSoundMyst(8500);
+			_vm->_sound->playEffect(8500);
 			_observatoryMonthSlider->drawConditionalDataToScreen(2);
 			_vm->wait(200);
 			_vm->redrawResource(_observatoryMonthSlider);
 
-			_vm->_sound->replaceSoundMyst(8500);
+			_vm->_sound->playEffect(8500);
 			_observatoryDaySlider->drawConditionalDataToScreen(2);
 			_vm->wait(200);
 			_vm->redrawResource(_observatoryDaySlider);
 		}
 
-		_vm->_sound->replaceSoundMyst(8500);
+		_vm->_sound->playEffect(8500);
 		_observatoryYearSlider->drawConditionalDataToScreen(2);
 		_vm->wait(200);
 		_vm->redrawResource(_observatoryYearSlider);
 
-		_vm->_sound->replaceSoundMyst(8500);
+		_vm->_sound->playEffect(8500);
 		_observatoryTimeSlider->drawConditionalDataToScreen(2);
 		_vm->wait(200);
 		_vm->redrawResource(_observatoryTimeSlider);
@@ -3747,8 +3747,8 @@ void Myst::greenBook_run() {
 	}
 
 	if (_tempVar == 1) {
-		_vm->_sound->stopSound();
-		_vm->_sound->pauseBackgroundMyst();
+		_vm->_sound->stopEffect();
+		_vm->_sound->pauseBackground();
 
 		VideoEntryPtr book = _vm->_video->playMovie(file);
 		if (!book)
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index aa36ef7..3a2524d 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -87,9 +87,7 @@ void Preview::o_fadeToBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 void Preview::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Fade from black", op);
 
-	// FIXME: This glitches when enabled. The backbuffer is drawn to screen,
-	// and then the fading occurs, causing the background to appear for one frame.
-	// _vm->_gfx->fadeFromBlack();
+	_vm->_gfx->fadeFromBlack();
 }
 
 void Preview::o_stayHere(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -103,18 +101,18 @@ void Preview::o_stayHere(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 void Preview::o_speechStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Speech stop", op);
 
-	_vm->_sound->stopSound(3001);
+	_vm->_sound->stopSpeech();
 	_speechRunning = false;
 	_globals.currentAge = 2;
 }
 
 void Preview::speechUpdateCue() {
 	// This is a callback in the original, handling audio events.
-	if (!_vm->_sound->isPlaying(3001)) {
+	if (!_vm->_sound->isSpeechPlaying()) {
 		return;
 	}
 
-	uint samples = _vm->_sound->getNumSamplesPlayed(3001);
+	uint samples = _vm->_sound->getSpeechNumSamplesPlayed();
 	for (int16 i = 0; i < _cueList.pointCount; i++) {
 		if (_cueList.points[i].sampleFrame > samples)
 			return;
@@ -134,7 +132,7 @@ void Preview::speech_run() {
 	switch (_speechStep) {
 	case 0: // Start Voice Over... which controls book opening
 		_currentCue = 0;
-		_vm->_sound->playSound(3001, Audio::Mixer::kMaxChannelVolume, false, &_cueList);
+			_vm->_sound->playSpeech(3001, &_cueList);
 
 		_speechStep++;
 		break;
diff --git a/engines/mohawk/myst_stacks/preview.h b/engines/mohawk/myst_stacks/preview.h
index 9d833b3..7a818a1 100644
--- a/engines/mohawk/myst_stacks/preview.h
+++ b/engines/mohawk/myst_stacks/preview.h
@@ -23,9 +23,11 @@
 #ifndef MYST_SCRIPTS_PREVIEW_H
 #define MYST_SCRIPTS_PREVIEW_H
 
+#include "mohawk/sound.h"
+#include "mohawk/myst_stacks/myst.h"
+
 #include "common/scummsys.h"
 #include "common/util.h"
-#include "mohawk/myst_stacks/myst.h"
 
 namespace Mohawk {
 
diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 47e7a56..774efcd 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -561,7 +561,7 @@ void Selenitic::mazeRunnerPlaySoundHelp() {
 		soundId =  2191;
 
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 	_mazeRunnerLight->drawConditionalDataToScreen(0);
 }
@@ -603,17 +603,17 @@ void Selenitic::o_soundReceiverSigma(uint16 op, uint16 var, uint16 argc, uint16
 		}
 
 		_soundReceiverPosition = &_state.soundReceiverPositions[source];
-		_vm->_sound->stopBackgroundMyst();
-		_vm->_sound->replaceSoundMyst(2287);
+		_vm->_sound->stopBackground();
+		_vm->_sound->playEffect(2287);
 		soundReceiverDrawView();
 		uint16 soundId = soundReceiverCurrentSound(source, *_soundReceiverPosition);
-		_vm->_sound->replaceBackgroundMyst(soundId);
+		_vm->_sound->playBackground(soundId);
 		_vm->wait(1000);
 	}
 
 	_soundReceiverPosition = oldPosition;
 	_soundReceiverSigmaPressed = true;
-	_vm->_sound->stopBackgroundMyst();
+	_vm->_sound->stopBackground();
 
 	_soundReceiverSources[_state.soundReceiverCurrentSource]->drawConditionalDataToScreen(1);
 
@@ -652,7 +652,7 @@ void Selenitic::soundReceiverLeftRight(uint direction) {
 	else
 		_soundReceiverLeftButton->drawConditionalDataToScreen(1);
 
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 
 	_soundReceiverDirection = direction;
 	_soundReceiverSpeed = 1;
@@ -717,11 +717,11 @@ void Selenitic::o_soundReceiverSource(uint16 op, uint16 var, uint16 argc, uint16
 		_soundReceiverPosition = &_state.soundReceiverPositions[pressedButton];
 		_soundReceiverCurrentSource = _soundReceiverSources[pressedButton];
 
-		_vm->_sound->stopSound();
+		_vm->_sound->stopEffect();
 
 		uint16 soundId = argv[0];
-		_vm->_sound->stopBackgroundMyst();
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->stopBackground();
+		_vm->_sound->playEffect(soundId);
 
 		_soundReceiverCurrentSource->drawConditionalDataToScreen(1);
 
@@ -738,11 +738,11 @@ void Selenitic::o_mazeRunnerDoorButton(uint16 op, uint16 var, uint16 argc, uint1
 
 	if (_mazeRunnerPosition == 288) {
 		_vm->changeToCard(cardIdEntry, kNoTransition);
-		_vm->_sound->replaceSoundMyst(cardIdEntry);
+		_vm->_sound->playEffect(cardIdEntry);
 		animatedUpdate(argv[2], &argv[3], 10);
 	} else if (_mazeRunnerPosition == 289) {
 		_vm->changeToCard(cardIdExit, kNoTransition);
-		_vm->_sound->replaceSoundMyst(cardIdExit);
+		_vm->_sound->playEffect(cardIdExit);
 		animatedUpdate(argv[2], &argv[3], 10);
 	}
 }
@@ -803,7 +803,7 @@ void Selenitic::o_soundLockMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	uint16 soundId = soundLockCurrentSound(slider->_pos.y, true);
 	if (_soundLockSoundId != soundId) {
 		_soundLockSoundId = soundId;
-		_vm->_sound->replaceSoundMyst(soundId, Audio::Mixer::kMaxChannelVolume, true);
+		_vm->_sound->playEffect(soundId, true);
 	}
 }
 
@@ -813,10 +813,10 @@ void Selenitic::o_soundLockStartMove(uint16 op, uint16 var, uint16 argc, uint16
 	MystAreaSlider *slider = soundLockSliderFromVar(var);
 
 	_vm->_cursor->setCursor(700);
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	_soundLockSoundId = soundLockCurrentSound(slider->_pos.y, true);
-	_vm->_sound->replaceSoundMyst(_soundLockSoundId, Audio::Mixer::kMaxChannelVolume, true);
+	_vm->_sound->playEffect(_soundLockSoundId, true);
 }
 
 void Selenitic::o_soundLockEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -861,21 +861,21 @@ void Selenitic::o_soundLockEndMove(uint16 op, uint16 var, uint16 argc, uint16 *a
 
 	uint16 soundId = slider->getList3(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 }
 
 void Selenitic::soundLockCheckSolution(MystAreaSlider *slider, uint16 value, uint16 solution, bool &solved) {
 	slider->drawConditionalDataToScreen(2);
-	_vm->_sound->replaceSoundMyst(soundLockCurrentSound(value / 12, false));
+	_vm->_sound->playEffect(soundLockCurrentSound(value / 12, false));
 	_vm->wait(1500);
 
 	if (value / 12 != solution)
 		solved = false;
 
 	slider->drawConditionalDataToScreen(1);
-	_vm->_sound->stopSound();
+	_vm->_sound->stopEffect();
 }
 
 void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -883,8 +883,8 @@ void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *ar
 
 	bool solved = true;
 
-	_vm->_sound->pauseBackgroundMyst();
-	_vm->_sound->replaceSoundMyst(1147);
+	_vm->_sound->pauseBackground();
+	_vm->_sound->playEffect(1147);
 	_soundLockButton->drawConditionalDataToScreen(1);
 	_vm->_cursor->hideCursor();
 
@@ -894,8 +894,8 @@ void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	soundLockCheckSolution(_soundLockSlider4, _state.soundLockSliderPositions[3], 6, solved);
 	soundLockCheckSolution(_soundLockSlider5, _state.soundLockSliderPositions[4], 7, solved);
 
-	_vm->_sound->replaceSoundMyst(1148);
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->playEffect(1148);
+	_vm->_sound->resumeBackground();
 
 	if (solved) {
 		_soundLockButton->drawConditionalDataToScreen(2);
@@ -906,7 +906,7 @@ void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *ar
 		_vm->changeToCard(cardIdClosed, kTransitionDissolve);
 
 		_vm->changeToCard(cardIdOpen, kNoTransition);
-		_vm->_sound->replaceSoundMyst(argv[2]);
+		_vm->_sound->playEffect(argv[2]);
 
 		animatedUpdate(argv[4], &argv[5], argv[3]);
 	} else {
@@ -982,7 +982,7 @@ void Selenitic::soundReceiverIncreaseSpeed() {
 
 void Selenitic::soundReceiverUpdateSound() {
 	uint16 soundId = soundReceiverCurrentSound(_state.soundReceiverCurrentSource, *_soundReceiverPosition);
-	_vm->_sound->replaceBackgroundMyst(soundId);
+	_vm->_sound->playBackground(soundId);
 }
 
 uint16 Selenitic::soundReceiverCurrentSound(uint16 source, uint16 position) {
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 2062bb9..706bd72 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -494,7 +494,7 @@ void Stoneship::o_generatorStart(uint16 op, uint16 var, uint16 argc, uint16 *arg
 
 	uint16 soundId = handle->getList1(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 
 	if (_state.generatorDuration)
 		_state.generatorDuration -= _vm->_system->getMillis() - _state.generatorDepletionTime;
@@ -510,7 +510,7 @@ void Stoneship::o_generatorStart(uint16 op, uint16 var, uint16 argc, uint16 *arg
 
 	soundId = handle->getList2(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId, Audio::Mixer::kMaxChannelVolume, true);
+		_vm->_sound->playEffect(soundId, true);
 }
 
 void Stoneship::o_generatorStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -537,7 +537,7 @@ void Stoneship::o_generatorStop(uint16 op, uint16 var, uint16 argc, uint16 *argv
 
 	uint16 soundId = handle->getList3(0);
 	if (soundId)
-		_vm->_sound->replaceSoundMyst(soundId);
+		_vm->_sound->playEffect(soundId);
 }
 
 void Stoneship::chargeBattery_run() {
@@ -674,7 +674,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 
 	Common::String movie = _vm->wrapMovieFilename("ligspig", kStoneshipStack);
 
-	_vm->_sound->playSound(2132);
+	_vm->_sound->playEffect(2132);
 
 	if (_state.chestValveState) {
 		// Valve closing
@@ -695,7 +695,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 		valve->setBounds(Audio::Timestamp(0, 350, 600), Audio::Timestamp(0, 650, 600));
 		_vm->waitUntilMovieEnds(valve);
 
-		_vm->_sound->playSound(3132);
+		_vm->_sound->playEffect(3132);
 
 		for (uint i = 0; i < 25; i++) {
 			valve = _vm->_video->playMovie(movie);
@@ -707,7 +707,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 			_vm->waitUntilMovieEnds(valve);
 		}
 
-		_vm->_sound->resumeBackgroundMyst();
+		_vm->_sound->resumeBackground();
 	} else {
 		// Valve opening
 		VideoEntryPtr valve = _vm->_video->playMovie(movie);
@@ -745,7 +745,7 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	lock->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 750, 600));
 	_vm->waitUntilMovieEnds(lock);
 
-	_vm->_sound->playSound(2143);
+	_vm->_sound->playEffect(2143);
 
 	lock = _vm->_video->playMovie(movie);
 	if (!lock)
@@ -756,7 +756,7 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	_vm->waitUntilMovieEnds(lock);
 
 	if (_state.pumpState != 4)
-		_vm->_sound->playSound(4143);
+		_vm->_sound->playEffect(4143);
 }
 
 void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -767,7 +767,7 @@ void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	debugC(kDebugScript, "\tmovieId: %d", movieId);
 
 	_vm->_cursor->hideCursor();
-	_vm->_sound->pauseBackgroundMyst();
+	_vm->_sound->pauseBackground();
 
 	switch (movieId) {
 	case 0:
@@ -791,14 +791,14 @@ void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, uint16 argc, uint16 *ar
 		break;
 	}
 
-	_vm->_sound->resumeBackgroundMyst();
+	_vm->_sound->resumeBackground();
 	_vm->_cursor->showCursor();
 }
 
 void Stoneship::o_cloudOrbEnter(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Cloud orb enter", op);
 
-	_vm->_sound->replaceSoundMyst(_cloudOrbSound, Audio::Mixer::kMaxChannelVolume, true);
+	_vm->_sound->playEffect(_cloudOrbSound, true);
 	_cloudOrbMovie->playMovie();
 }
 
@@ -806,7 +806,7 @@ void Stoneship::o_cloudOrbLeave(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	debugC(kDebugScript, "Opcode %d: Cloud orb leave", op);
 
 	_cloudOrbMovie->pauseMovie(true);
-	_vm->_sound->replaceSoundMyst(_cloudOrbStopSound);
+	_vm->_sound->playEffect(_cloudOrbStopSound);
 	_vm->_gfx->runTransition(kTransitionTopToBottom, getInvokingResource<MystArea>()->getRect(), 4, 0);
 }
 
@@ -920,7 +920,7 @@ void Stoneship::tunnel_run() {
 				_vm->_gfx->copyImageToScreen(_tunnelImages[1], Common::Rect(544, 333));
 			}
 
-			_vm->_sound->replaceSoundMyst(_tunnelAlarmSound);
+			_vm->_sound->playEffect(_tunnelAlarmSound);
 
 			// Draw tunnel dark
 			if (_tunnelImagesCount) {


Commit: 3e99dd8ccc0cda437ed19dcd3048f1e8eaa6c532
    https://github.com/scummvm/scummvm/commit/3e99dd8ccc0cda437ed19dcd3048f1e8eaa6c532
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Switch to bounds checked opcode arguments

Changed paths:
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_scripts.h
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/channelwood.h
    engines/mohawk/myst_stacks/credits.cpp
    engines/mohawk/myst_stacks/credits.h
    engines/mohawk/myst_stacks/demo.cpp
    engines/mohawk/myst_stacks/demo.h
    engines/mohawk/myst_stacks/dni.cpp
    engines/mohawk/myst_stacks/dni.h
    engines/mohawk/myst_stacks/intro.cpp
    engines/mohawk/myst_stacks/intro.h
    engines/mohawk/myst_stacks/makingof.h
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/mechanical.h
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/myst.h
    engines/mohawk/myst_stacks/preview.cpp
    engines/mohawk/myst_stacks/preview.h
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/myst_stacks/selenitic.h
    engines/mohawk/myst_stacks/slides.cpp
    engines/mohawk/myst_stacks/slides.h
    engines/mohawk/myst_stacks/stoneship.cpp
    engines/mohawk/myst_stacks/stoneship.h


diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 30d2c15..f3caee6 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -37,16 +37,10 @@ namespace Mohawk {
 MystScriptEntry::MystScriptEntry() {
 	type = kMystScriptNone;
 	var = 0;
-	argc = 0;
-	argv = nullptr;
 	resourceId = 0;
 	u1 = 0;
 }
 
-MystScriptEntry::~MystScriptEntry() {
-	delete[] argv;
-}
-
 const uint8 MystScriptParser::_stackMap[11] = {
 	kSeleniticStack,
 	kStoneshipStack,
@@ -169,19 +163,19 @@ void MystScriptParser::runScript(MystScript script, MystArea *invokingResource)
 		else
 			_invokingResource = _vm->_resources[entry.resourceId];
 
-		runOpcode(entry.opcode, entry.var, entry.argc, entry.argv);
+		runOpcode(entry.opcode, entry.var, entry.args);
 	}
 
 	_scriptNestingLevel--;
 }
 
-void MystScriptParser::runOpcode(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::runOpcode(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_scriptNestingLevel++;
 
 	bool ranOpcode = false;
 	for (uint16 i = 0; i < _opcodes.size(); i++)
 		if (_opcodes[i]->op == op) {
-			(this->*(_opcodes[i]->proc)) (op, var, argc, argv);
+			(this->*(_opcodes[i]->proc)) (op, var, args);
 			ranOpcode = true;
 			break;
 		}
@@ -223,13 +217,11 @@ MystScript MystScriptParser::readScript(Common::SeekableReadStream *stream, Myst
 
 		entry.opcode = stream->readUint16LE();
 		entry.var = stream->readUint16LE();
-		entry.argc = stream->readUint16LE();
+		uint16 argumentCount = stream->readUint16LE();
 
-		if (entry.argc > 0) {
-			entry.argv = new uint16[entry.argc];
-			for (uint16 j = 0; j < entry.argc; j++)
-				entry.argv[j] = stream->readUint16LE();
-		}
+		entry.args.resize(argumentCount);
+		for (uint16 j = 0; j < entry.args.size(); j++)
+			entry.args[j] = stream->readUint16LE();
 
 		// u1 exists only in EXIT scripts
 		if (type == kMystScriptExit)
@@ -266,13 +258,13 @@ bool MystScriptParser::setVarValue(uint16 var, uint16 value) {
 	return false;
 }
 
-void MystScriptParser::animatedUpdate(uint16 argc, uint16 *argv, uint16 delay) {
+void MystScriptParser::animatedUpdate(const ArgumentsArray &args, uint16 delay) {
 	uint16 argsRead = 0;
 
-	while (argsRead < argc) {
-		Common::Rect rect = Common::Rect(argv[argsRead], argv[argsRead + 1], argv[argsRead + 2], argv[argsRead + 3]);
-		TransitionType kind = static_cast<TransitionType>(argv[argsRead + 4]);
-		uint16 steps = argv[argsRead + 5];
+	while (argsRead < args.size()) {
+		Common::Rect rect = Common::Rect(args[argsRead], args[argsRead + 1], args[argsRead + 2], args[argsRead + 3]);
+		TransitionType kind = static_cast<TransitionType>(args[argsRead + 4]);
+		uint16 steps = args[argsRead + 5];
 
 		debugC(kDebugScript, "\trect.left: %d", rect.left);
 		debugC(kDebugScript, "\trect.top: %d", rect.top);
@@ -288,82 +280,82 @@ void MystScriptParser::animatedUpdate(uint16 argc, uint16 *argv, uint16 delay) {
 	}
 }
 
-void MystScriptParser::unknown(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::unknown(uint16 op, uint16 var, const ArgumentsArray &args) {
 	warning("Unimplemented opcode 0x%02x (%d)", op, op);
 	warning("\tUses var %d", var);
-	warning("\tArg count = %d", argc);
+	warning("\tArg count = %d", args.size());
 
-	if (argc) {
+	if (!args.empty()) {
 		Common::String str;
-		str += Common::String::format("%d", argv[0]);
+		str += Common::String::format("%d", args[0]);
 
-		for (uint16 i = 1; i < argc; i++)
-			str += Common::String::format(", %d", argv[i]);
+		for (uint16 i = 1; i < args.size(); i++)
+			str += Common::String::format(", %d", args[i]);
 
 		warning("\tArgs: %s\n", str.c_str());
 	}
 }
 
-void MystScriptParser::NOP(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::NOP(uint16 op, uint16 var, const ArgumentsArray &args) {
 }
 
-void MystScriptParser::o_toggleVar(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_toggleVar(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Toggle var %d", op, var);
 
 	toggleVar(var);
 	_vm->redrawArea(var);
 }
 
-void MystScriptParser::o_setVar(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	debugC(kDebugScript, "Opcode %d: Set var %d: %d", op, var, argv[0]);
+void MystScriptParser::o_setVar(uint16 op, uint16 var, const ArgumentsArray &args) {
+	debugC(kDebugScript, "Opcode %d: Set var %d: %d", op, var, args[0]);
 
-	if (setVarValue(var, argv[0]))
+	if (setVarValue(var, args[0]))
 		_vm->redrawArea(var);
 }
 
-void MystScriptParser::o_changeCardSwitch4(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCardSwitch4(uint16 op, uint16 var, const ArgumentsArray &args) {
 	uint16 value = getVar(var);
 
 	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
 
 	if (value)
-		_vm->changeToCard(argv[value -1 ], kTransitionDissolve);
+		_vm->changeToCard(args[value -1 ], kTransitionDissolve);
 	else if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionDissolve);
 	else
 		warning("Missing invokingResource in altDest call");
 }
 
-void MystScriptParser::o_changeCardSwitchLtR(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCardSwitchLtR(uint16 op, uint16 var, const ArgumentsArray &args) {
 	uint16 value = getVar(var);
 
 	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
 
 	if (value)
-		_vm->changeToCard(argv[value -1 ], kTransitionLeftToRight);
+		_vm->changeToCard(args[value -1 ], kTransitionLeftToRight);
 	else if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionLeftToRight);
 	else
 		warning("Missing invokingResource in altDest call");
 }
 
-void MystScriptParser::o_changeCardSwitchRtL(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCardSwitchRtL(uint16 op, uint16 var, const ArgumentsArray &args) {
 	uint16 value = getVar(var);
 
 	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
 
 	if (value)
-		_vm->changeToCard(argv[value -1 ], kTransitionRightToLeft);
+		_vm->changeToCard(args[value -1 ], kTransitionRightToLeft);
 	else if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionRightToLeft);
 	else
 		warning("Missing invokingResource in altDest call");
 }
 
-void MystScriptParser::o_takePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_takePage(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// In most game releases, the first opcode argument is the new mouse cursor.
 	// However, in the original v1.0 English release this opcode takes no argument.
-	uint16 cursorId; // = argv[0];
+	uint16 cursorId; // = args[0];
 	switch (var) {
 		case 41: // Vault white page
 			cursorId = kWhitePageCursor;
@@ -402,7 +394,7 @@ void MystScriptParser::o_takePage(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	}
 }
 
-void MystScriptParser::o_redrawCard(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_redrawCard(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Redraw card", op);
 
 	_vm->drawCardBackground();
@@ -410,7 +402,7 @@ void MystScriptParser::o_redrawCard(uint16 op, uint16 var, uint16 argc, uint16 *
 	_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
 }
 
-void MystScriptParser::o_goToDest(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_goToDest(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
 
 	if (_invokingResource != nullptr)
@@ -419,7 +411,7 @@ void MystScriptParser::o_goToDest(uint16 op, uint16 var, uint16 argc, uint16 *ar
 		warning("Opcode %d: Missing invokingResource", op);
 }
 
-void MystScriptParser::o_goToDestForward(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_goToDestForward(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
 
 	if (_invokingResource != nullptr)
@@ -428,7 +420,7 @@ void MystScriptParser::o_goToDestForward(uint16 op, uint16 var, uint16 argc, uin
 		warning("Opcode %d: Missing invokingResource", op);
 }
 
-void MystScriptParser::o_goToDestLeft(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_goToDestLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
 
 	if (_invokingResource != nullptr)
@@ -437,7 +429,7 @@ void MystScriptParser::o_goToDestLeft(uint16 op, uint16 var, uint16 argc, uint16
 		warning("Opcode %d: Missing invokingResource", op);
 }
 
-void MystScriptParser::o_goToDestRight(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_goToDestRight(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
 
 	if (_invokingResource != nullptr)
@@ -446,7 +438,7 @@ void MystScriptParser::o_goToDestRight(uint16 op, uint16 var, uint16 argc, uint1
 		warning("Opcode %d: Missing invokingResource", op);
 }
 
-void MystScriptParser::o_goToDestUp(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_goToDestUp(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
 
 	if (_invokingResource != nullptr)
@@ -455,7 +447,7 @@ void MystScriptParser::o_goToDestUp(uint16 op, uint16 var, uint16 argc, uint16 *
 		warning("Opcode %d: Missing invokingResource", op);
 }
 
-void MystScriptParser::o_triggerMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_triggerMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Trigger Type 6 Resource Movie..", op);
 	// The original has code to pause the background music before playing the movie,
 	// if the movie has a sound track, as well as code to resume it afterwards. But since
@@ -463,8 +455,8 @@ void MystScriptParser::o_triggerMovie(uint16 op, uint16 var, uint16 argc, uint16
 	// if the movie actually has a sound track. The code is never executed.
 
 	int16 direction = 1;
-	if (argc == 1)
-		direction = argv[0];
+	if (args.size() == 1)
+		direction = args[0];
 
 	debugC(kDebugScript, "\tDirection: %d", direction);
 
@@ -474,54 +466,54 @@ void MystScriptParser::o_triggerMovie(uint16 op, uint16 var, uint16 argc, uint16
 	resource->playMovie();
 }
 
-void MystScriptParser::o_toggleVarNoRedraw(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_toggleVarNoRedraw(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: toggleVarNoRedraw", op);
 
 	toggleVar(var);
 }
 
-void MystScriptParser::o_drawAreaState(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	debugC(kDebugScript, "Opcode %d: drawAreaState, state: %d", op, argv[0]);
+void MystScriptParser::o_drawAreaState(uint16 op, uint16 var, const ArgumentsArray &args) {
+	debugC(kDebugScript, "Opcode %d: drawAreaState, state: %d", op, args[0]);
 	debugC(kDebugScript, "\tVar: %d", var);
 
 	MystAreaImageSwitch *parent = static_cast<MystAreaImageSwitch *>(getInvokingResource<MystArea>()->_parent);
-	parent->drawConditionalDataToScreen(argv[0]);
+	parent->drawConditionalDataToScreen(args[0]);
 }
 
-void MystScriptParser::o_redrawAreaForVar(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_redrawAreaForVar(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: redraw area", op);
 	debugC(kDebugScript, "\tvar: %d", var);
 
 	_vm->redrawArea(var);
 }
 
-void MystScriptParser::o_changeCardDirectional(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCardDirectional(uint16 op, uint16 var, const ArgumentsArray &args) {
 
 	// Used by Channelwood Card 3262 (In Elevator)
 	debugC(kDebugScript, "Opcode %d: Change Card with optional directional update", op);
 
-	uint16 cardId = argv[0];
-	uint16 directionalUpdateDataSize = argv[1];
+	uint16 cardId = args[0];
+	uint16 directionalUpdateDataSize = args[1];
 
 	debugC(kDebugScript, "\tcardId: %d", cardId);
 	debugC(kDebugScript, "\tdirectonal update data size: %d", directionalUpdateDataSize);
 
 	_vm->changeToCard(cardId, kNoTransition);
 
-	animatedUpdate(directionalUpdateDataSize, &argv[2], 0);
+	animatedUpdate(ArgumentsArray(args.begin() + 2, directionalUpdateDataSize), 0);
 }
 
 // NOTE: Opcode 17 and 18 form a pair, where Opcode 17 jumps to a card,
 // but with the current cardId stored.
 // Opcode 18 then "pops" this stored CardId and returns to that card.
 
-void MystScriptParser::o_changeCardPush(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCardPush(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Jump to Card Id, Storing Current Card Id", op);
 
 	_savedCardId = _vm->getCurCard();
 
-	uint16 cardId = argv[0];
-	TransitionType transition = static_cast<TransitionType>(argv[1]);
+	uint16 cardId = args[0];
+	TransitionType transition = static_cast<TransitionType>(args[1]);
 
 	debugC(kDebugScript, "\tCurrent CardId: %d", _savedCardId);
 	debugC(kDebugScript, "\tJump to CardId: %d", cardId);
@@ -529,7 +521,7 @@ void MystScriptParser::o_changeCardPush(uint16 op, uint16 var, uint16 argc, uint
 	_vm->changeToCard(cardId, transition);
 }
 
-void MystScriptParser::o_changeCardPop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCardPop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Return To Stored Card Id", op);
 	debugC(kDebugScript, "\tCardId: %d", _savedCardId);
 
@@ -538,94 +530,82 @@ void MystScriptParser::o_changeCardPop(uint16 op, uint16 var, uint16 argc, uint1
 		return;
 	}
 
-	TransitionType transition = static_cast<TransitionType>(argv[0]);
+	TransitionType transition = static_cast<TransitionType>(args[0]);
 
 	_vm->changeToCard(_savedCardId, transition);
 }
 
-void MystScriptParser::o_enableAreas(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_enableAreas(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Enable Hotspots", op);
 
-	uint16 count = argv[0];
+	uint16 count = args[0];
 
-	if (argc == count + 1) {
-		for (uint16 i = 0; i < count; i++) {
-			debugC(kDebugScript, "Enable hotspot index %d", argv[i + 1]);
+	for (uint16 i = 0; i < count; i++) {
+		debugC(kDebugScript, "Enable hotspot index %d", args[i + 1]);
 
-			MystArea *resource = nullptr;
-			if (argv[i + 1] == 0xFFFF)
-				resource = _invokingResource;
-			else
-				resource = _vm->_resources[argv[i + 1]];
+		MystArea *resource = nullptr;
+		if (args[i + 1] == 0xFFFF)
+			resource = _invokingResource;
+		else
+			resource = _vm->_resources[args[i + 1]];
 
-			if (resource)
-				resource->setEnabled(true);
-			else
-				warning("Unknown Resource in enableAreas script Opcode");
-		}
-	} else {
-		error("Invalid arguments for opcode %d", op);
+		if (resource)
+			resource->setEnabled(true);
+		else
+			warning("Unknown Resource in enableAreas script Opcode");
 	}
 }
 
-void MystScriptParser::o_disableAreas(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_disableAreas(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Disable Hotspots", op);
 
-	uint16 count = argv[0];
+	uint16 count = args[0];
 
-	if (argc == count + 1) {
-		for (uint16 i = 0; i < count; i++) {
-			debugC(kDebugScript, "Disable hotspot index %d", argv[i + 1]);
+	for (uint16 i = 0; i < count; i++) {
+		debugC(kDebugScript, "Disable hotspot index %d", args[i + 1]);
 
-			MystArea *resource = nullptr;
-			if (argv[i + 1] == 0xFFFF)
-				resource = _invokingResource;
-			else
-				resource = _vm->_resources[argv[i + 1]];
+		MystArea *resource = nullptr;
+		if (args[i + 1] == 0xFFFF)
+			resource = _invokingResource;
+		else
+			resource = _vm->_resources[args[i + 1]];
 
-			if (resource)
-				resource->setEnabled(false);
-			else
-				warning("Unknown Resource in disableAreas script Opcode");
-		}
-	} else {
-		error("Invalid arguments for opcode %d", op);
+		if (resource)
+			resource->setEnabled(false);
+		else
+			warning("Unknown Resource in disableAreas script Opcode");
 	}
 }
 
-void MystScriptParser::o_directionalUpdate(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_directionalUpdate(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Transition / Directional update", op);
 
-	animatedUpdate(argc, argv, 0);
+	animatedUpdate(args, 0);
 }
 
-void MystScriptParser::o_toggleAreasActivation(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_toggleAreasActivation(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Toggle areas activation", op);
 
-	uint16 count = argv[0];
+	uint16 count = args[0];
 
-	if (argc == count + 1) {
-		for (uint16 i = 0; i < count; i++) {
-			debugC(kDebugScript, "Enable/Disable hotspot index %d", argv[i + 1]);
+	for (uint16 i = 0; i < count; i++) {
+		debugC(kDebugScript, "Enable/Disable hotspot index %d", args[i + 1]);
 
-			MystArea *resource = nullptr;
-			if (argv[i + 1] == 0xFFFF)
-				resource = _invokingResource;
-			else
-				resource = _vm->_resources[argv[i + 1]];
+		MystArea *resource = nullptr;
+		if (args[i + 1] == 0xFFFF)
+			resource = _invokingResource;
+		else
+			resource = _vm->_resources[args[i + 1]];
 
-			if (resource)
-				resource->setEnabled(!resource->isEnabled());
-			else
-				warning("Unknown Resource in toggleAreasActivation script Opcode");
-		}
-	} else {
-		error("Invalid arguments for opcode %d", op);
+		if (resource)
+			resource->setEnabled(!resource->isEnabled());
+		else
+			warning("Unknown Resource in toggleAreasActivation script Opcode");
 	}
 }
 
-void MystScriptParser::o_playSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 soundId = argv[0];
+void MystScriptParser::o_playSound(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 soundId = args[0];
 
 	debugC(kDebugScript, "Opcode %d: playSound", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
@@ -633,13 +613,13 @@ void MystScriptParser::o_playSound(uint16 op, uint16 var, uint16 argc, uint16 *a
 	_vm->_sound->playEffect(soundId);
 }
 
-void MystScriptParser::o_stopSoundBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_stopSoundBackground(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: stopSoundBackground", op);
 	_vm->_sound->stopBackground();
 }
 
-void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 soundId = argv[0];
+void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 soundId = args[0];
 
 	debugC(kDebugScript, "Opcode %d: playSoundBlocking", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
@@ -648,16 +628,16 @@ void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, u
 	_vm->playSoundBlocking(soundId);
 }
 
-void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Copy back buffer to screen", op);
 
 	Common::Rect rect;
-	if (argv[0] == 0xFFFF) {
+	if (args[0] == 0xFFFF) {
 		// Used in Stoneship Card 2111 (Compass Rose)
 		// Used in Mechanical Card 6267 (Code Lock)
 		rect = _invokingResource->getRect();
 	} else {
-		rect = Common::Rect(argv[0], argv[1], argv[2], argv[3]);
+		rect = Common::Rect(args[0], args[1], args[2], args[3]);
 	}
 
 	debugC(kDebugScript, "\trect.left: %d", rect.left);
@@ -668,16 +648,16 @@ void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, uint16 ar
 	_vm->_gfx->copyBackBufferToScreen(rect);
 }
 
-void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 imageId = argv[0];
+void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 imageId = args[0];
 
 	// WORKAROUND wrong image id in mechanical staircase
 	if (imageId == 7158)
 		imageId = 7178;
 
-	Common::Rect srcRect = Common::Rect(argv[1], argv[2], argv[3], argv[4]);
+	Common::Rect srcRect = Common::Rect(args[1], args[2], args[3], args[4]);
 
-	Common::Rect dstRect = Common::Rect(argv[5], argv[6], 544, 333);
+	Common::Rect dstRect = Common::Rect(args[5], args[6], 544, 333);
 
 	if (dstRect.left == -1 || dstRect.top == -1) {
 		// Interpreted as full screen
@@ -702,14 +682,14 @@ void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, uint16 arg
 	_vm->_gfx->copyImageSectionToBackBuffer(imageId, srcRect, dstRect);
 }
 
-void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Stoneship Card 2080
 	// Used on Channelwood Card 3225 with argc = 8 i.e. Conditional Sound List
 	debugC(kDebugScript, "Opcode %d: Process Sound Block", op);
 
 	Common::MemoryWriteStreamDynamic writeStream = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
-	for (uint i = 0; i < argc; i++) {
-		writeStream.writeUint16LE(argv[i]);
+	for (uint i = 0; i < args.size(); i++) {
+		writeStream.writeUint16LE(args[i]);
 	}
 
 	Common::MemoryReadStream readStream = Common::MemoryReadStream(writeStream.getData(), writeStream.size());
@@ -718,13 +698,13 @@ void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, uint16 arg
 	_vm->applySoundBlock(soundBlock);
 }
 
-void MystScriptParser::o_soundPlaySwitch(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_soundPlaySwitch(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Switch Choice of Play Sound", op);
 
 	uint16 value = getVar(var);
 
-	if (value < argc) {
-		uint16 soundId = argv[value];
+	if (value < args.size()) {
+		uint16 soundId = args[value];
 		debugC(kDebugScript, "\tvar: %d", var);
 		debugC(kDebugScript, "\tsoundId: %d", soundId);
 
@@ -733,17 +713,17 @@ void MystScriptParser::o_soundPlaySwitch(uint16 op, uint16 var, uint16 argc, uin
 	}
 }
 
-void MystScriptParser::o_soundResumeBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_soundResumeBackground(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: soundResumeBackground", op);
 	_vm->_sound->resumeBackground();
 }
 
-void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 imageId = argv[0];
+void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 imageId = args[0];
 
-	Common::Rect srcRect = Common::Rect(argv[1], argv[2], argv[3], argv[4]);
+	Common::Rect srcRect = Common::Rect(args[1], args[2], args[3], args[4]);
 
-	Common::Rect dstRect = Common::Rect(argv[5], argv[6], 544, 333);
+	Common::Rect dstRect = Common::Rect(args[5], args[6], 544, 333);
 
 	if (dstRect.left == -1 || dstRect.top == -1) {
 		// Interpreted as full screen
@@ -768,23 +748,23 @@ void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, uint16 argc, u
 	_vm->_gfx->copyImageSectionToScreen(imageId, srcRect, dstRect);
 }
 
-void MystScriptParser::o_changeCard(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCard(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Change Card", op);
 
-	uint16 cardId = argv[0];
-	TransitionType transition = static_cast<TransitionType>(argv[1]);
+	uint16 cardId = args[0];
+	TransitionType transition = static_cast<TransitionType>(args[1]);
 
 	debugC(kDebugScript, "\tTarget Card: %d", cardId);
 
 	_vm->changeToCard(cardId, transition);
 }
 
-void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, const ArgumentsArray &args) {
 		debugC(kDebugScript, "Opcode %d: Draw Full Screen Image, Delay then Change Card", op);
 
-		uint16 imageId = argv[0];
-		uint16 cardId = argv[1];
-		TransitionType transition = static_cast<TransitionType>(argv[2]);
+		uint16 imageId = args[0];
+		uint16 cardId = args[1];
+		TransitionType transition = static_cast<TransitionType>(args[2]);
 
 		debugC(kDebugScript, "\timageId: %d", imageId);
 		debugC(kDebugScript, "\tcardId: %d", cardId);
@@ -795,10 +775,10 @@ void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, uint16 argc,
 		_vm->changeToCard(cardId, transition);
 }
 
-void MystScriptParser::o_changeMainCursor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeMainCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Change main cursor", op);
 
-	uint16 cursorId = argv[0];
+	uint16 cursorId = args[0];
 
 	debugC(kDebugScript, "Cursor: %d", cursorId);
 
@@ -806,33 +786,33 @@ void MystScriptParser::o_changeMainCursor(uint16 op, uint16 var, uint16 argc, ui
 	_vm->_cursor->setCursor(cursorId);
 }
 
-void MystScriptParser::o_hideCursor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_hideCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hide Cursor", op);
 	_vm->_cursor->hideCursor();
 }
 
-void MystScriptParser::o_showCursor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_showCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Show Cursor", op);
 	_vm->_cursor->showCursor();
 }
 
-void MystScriptParser::o_delay(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_delay(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Mechanical Card 6327 (Elevator)
 	debugC(kDebugScript, "Opcode %d: Delay", op);
 
-	uint16 time = argv[0];
+	uint16 time = args[0];
 
 	debugC(kDebugScript, "\tTime: %d", time);
 
 	_vm->wait(time);
 }
 
-void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeStack(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: changeStack", op);
 
-	uint16 targetStack = argv[0];
-	uint16 soundIdLinkSrc = argv[1];
-	uint16 soundIdLinkDst = argv[2];
+	uint16 targetStack = args[0];
+	uint16 soundIdLinkSrc = args[1];
+	uint16 soundIdLinkDst = args[2];
 
 	debugC(kDebugScript, "\tTarget Stack: %d", targetStack);
 	debugC(kDebugScript, "\tSource Stack Link Sound: %d", soundIdLinkSrc);
@@ -851,13 +831,13 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Play Sound, Change Card and Directional Update Screen Region", op);
 
-	uint16 cardId = argv[0];
-	uint16 soundId = argv[1];
-	uint16 delayBetweenSteps = argv[2];
-	uint16 dataSize = argv[3];
+	uint16 cardId = args[0];
+	uint16 soundId = args[1];
+	uint16 delayBetweenSteps = args[2];
+	uint16 dataSize = args[3];
 
 	debugC(kDebugScript, "\tcard: %d", cardId);
 	debugC(kDebugScript, "\tsound: %d", soundId);
@@ -869,15 +849,15 @@ void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, u
 
 	_vm->changeToCard(cardId, kNoTransition);
 
-	animatedUpdate(dataSize, &argv[4], delayBetweenSteps);
+	animatedUpdate(ArgumentsArray(args.begin() + 4, dataSize), delayBetweenSteps);
 }
 
-void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Play Sound and Directional Update Screen Region", op);
 
-	uint16 soundId = argv[0];
-	uint16 delayBetweenSteps = argv[1];
-	uint16 dataSize = argv[2];
+	uint16 soundId = args[0];
+	uint16 delayBetweenSteps = args[1];
+	uint16 dataSize = args[2];
 
 	debugC(kDebugScript, "\tsound: %d", soundId);
 	debugC(kDebugScript, "\tdelay between steps: %d", delayBetweenSteps);
@@ -886,22 +866,22 @@ void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, uint1
 	if (soundId)
 		_vm->_sound->playEffect(soundId);
 
-	animatedUpdate(dataSize, &argv[3], delayBetweenSteps);
+	animatedUpdate(ArgumentsArray(args.begin() + 3, dataSize), delayBetweenSteps);
 }
 
-void MystScriptParser::o_saveMainCursor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_saveMainCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Save main cursor", op);
 
 	_savedCursorId = _vm->getMainCursor();
 }
 
-void MystScriptParser::o_restoreMainCursor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_restoreMainCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Restore main cursor", op);
 
 	_vm->setMainCursor(_savedCursorId);
 }
 
-void MystScriptParser::o_soundWaitStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_soundWaitStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Selenitic Card 1191 (Maze Runner)
 	// Used on Mechanical Card 6267 (Code Lock)
 	// Used when Button is pushed...
@@ -911,7 +891,7 @@ void MystScriptParser::o_soundWaitStop(uint16 op, uint16 var, uint16 argc, uint1
 		_vm->doFrame();
 }
 
-void MystScriptParser::o_quit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_quit(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_vm->quitGame();
 }
 
@@ -922,7 +902,7 @@ void MystScriptParser::showMap() {
 	}
 }
 
-void MystScriptParser::o_exitMap(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void MystScriptParser::o_exitMap(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_vm->changeToCard(_savedMapCardId, kTransitionCopy);
 }
 
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index 1ec821b..4ae9fb5 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -31,7 +31,9 @@
 
 namespace Mohawk {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+typedef Common::Array<uint16> ArgumentsArray;
+
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class MohawkEngine_Myst;
 class MystArea;
@@ -45,14 +47,12 @@ enum MystScriptType {
 
 struct MystScriptEntry {
 	MystScriptEntry();
-	~MystScriptEntry();
 
 	MystScriptType type;
 	uint16 resourceId;
 	uint16 opcode;
 	uint16 var;
-	uint16 argc;
-	uint16 *argv;
+	ArgumentsArray args;
 	uint16 u1;
 };
 
@@ -64,7 +64,7 @@ public:
 	virtual ~MystScriptParser();
 
 	void runScript(MystScript script, MystArea *invokingResource = nullptr);
-	void runOpcode(uint16 op, uint16 var = 0, uint16 argc = 0, uint16 *argv = nullptr);
+	void runOpcode(uint16 op, uint16 var = 0, const ArgumentsArray &args = ArgumentsArray());
 	const Common::String getOpcodeDesc(uint16 op);
 	MystScript readScript(Common::SeekableReadStream *stream, MystScriptType type);
 	void setInvokingResource(MystArea *resource) { _invokingResource = resource; }
@@ -86,7 +86,7 @@ public:
 	virtual uint16 getMap() { return 0; }
 	void showMap();
 
-	void animatedUpdate(uint16 argc, uint16 *argv, uint16 delay);
+	void animatedUpdate(const ArgumentsArray &args, uint16 delay);
 
 	DECLARE_OPCODE(unknown);
 
@@ -146,7 +146,7 @@ protected:
 	MohawkEngine_Myst *_vm;
 	MystGameState::Globals &_globals;
 
-	typedef void (MystScriptParser::*OpcodeProcMyst)(uint16 op, uint16 var, uint16 argc, uint16* argv);
+	typedef void (MystScriptParser::*OpcodeProcMyst)(uint16 op, uint16 var, const ArgumentsArray &args);
 
 	struct MystOpcode {
 		MystOpcode(uint16 o, OpcodeProcMyst p, const char *d) : op(o), proc(p), desc(d) {}
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index a6e3e56..6c56ad5 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -299,7 +299,7 @@ bool Channelwood::pipeChangeValve(bool open, uint16 mask) {
 	return false;
 }
 
-void Channelwood::o_bridgeToggle(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_bridgeToggle(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Bridge rise / skink video", op);
 
 	VideoEntryPtr bridge = _vm->_video->playMovie(_vm->wrapMovieFilename("bridge", kChannelwoodStack));
@@ -317,10 +317,10 @@ void Channelwood::o_bridgeToggle(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	_vm->waitUntilMovieEnds(bridge);
 }
 
-void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_pipeExtend(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Play Pipe Movie and Sound", op);
 
-	uint16 soundId = argv[0];
+	uint16 soundId = args[0];
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
 
 	_vm->_sound->playEffect(soundId);
@@ -340,11 +340,11 @@ void Channelwood::o_pipeExtend(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	_vm->_sound->resumeBackground();
 }
 
-void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Draw Full Screen Image, Change Card, and change volume", op);
 
-	uint16 imageId = argv[0];
-	uint16 cardId = argv[1];
+	uint16 imageId = args[0];
+	uint16 cardId = args[1];
 
 	debugC(kDebugScript, "\timageId: %d", imageId);
 	debugC(kDebugScript, "\tcardId: %d", cardId);
@@ -354,14 +354,14 @@ void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, uint16 a
 
 	_vm->changeToCard(cardId, kTransitionPartToLeft);
 
-	if (argc == 3) {
-		uint16 volume = argv[2];
+	if (args.size() == 3) {
+		uint16 volume = args[2];
 		_vm->_sound->changeBackgroundVolume(volume);
 	}
 }
 
 
-void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Do Water Tank Valve Open Animation", op);
 	Common::Rect rect = getInvokingResource<MystArea>()->getRect();
 
@@ -374,7 +374,7 @@ void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, uint16 argc, uint1
 	pipeChangeValve(true, 0x80);
 }
 
-void Channelwood::o_leverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_leverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generic lever start move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -383,7 +383,7 @@ void Channelwood::o_leverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *a
 	_leverPulled = false;
 }
 
-void Channelwood::o_leverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_leverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generic lever move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -398,7 +398,7 @@ void Channelwood::o_leverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	}
 }
 
-void Channelwood::o_leverMoveFail(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_leverMoveFail(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generic lever move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -415,7 +415,7 @@ void Channelwood::o_leverMoveFail(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	}
 }
 
-void Channelwood::o_leverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_leverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generic lever end move", op);
 
 	// Get current lever frame
@@ -431,13 +431,13 @@ void Channelwood::o_leverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	_vm->checkCursorHints();
 }
 
-void Channelwood::o_leverEndMoveResumeBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_leverEndMoveResumeBackground(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_vm->_sound->resumeBackground();
-	o_leverEndMove(op, var, argc, argv);
+	o_leverEndMove(op, var, args);
 }
 
-void Channelwood::o_leverEndMoveWithSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	o_leverEndMove(op, var, argc, argv);
+void Channelwood::o_leverEndMoveWithSound(uint16 op, uint16 var, const ArgumentsArray &args) {
+	o_leverEndMove(op, var, args);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = lever->getList3(0);
@@ -445,20 +445,20 @@ void Channelwood::o_leverEndMoveWithSound(uint16 op, uint16 var, uint16 argc, ui
 		_vm->_sound->playEffect(soundId);
 }
 
-void Channelwood::o_leverElev3StartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_leverElev3StartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_vm->_gfx->copyImageToScreen(3970, Common::Rect(544, 333));
 	_vm->doFrame();
-	o_leverStartMove(op, var, argc, argv);
+	o_leverStartMove(op, var, args);
 }
 
-void Channelwood::o_leverElev3EndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	o_leverEndMove(op, var, argc, argv);
+void Channelwood::o_leverElev3EndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
+	o_leverEndMove(op, var, args);
 	_vm->_gfx->copyImageToScreen(3265, Common::Rect(544, 333));
 	_vm->doFrame();
 	_vm->_sound->playEffect(5265);
 }
 
-void Channelwood::o_pumpLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_pumpLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Pump lever move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -472,8 +472,8 @@ void Channelwood::o_pumpLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	}
 }
 
-void Channelwood::o_pumpLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	o_leverEndMove(op, var, argc, argv);
+void Channelwood::o_pumpLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
+	o_leverEndMove(op, var, args);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = lever->getList3(0);
@@ -481,7 +481,7 @@ void Channelwood::o_pumpLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16
 		_vm->_sound->playBackground(soundId, 36864);
 }
 
-void Channelwood::o_stairsDoorToggle(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_stairsDoorToggle(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Play stairs door video", op);
 
 	MystAreaVideo *movie = getInvokingResource<MystAreaVideo>();
@@ -497,7 +497,7 @@ void Channelwood::o_stairsDoorToggle(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Channelwood::o_valveHandleMove1(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_valveHandleMove1(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Valve handle move", op);
 
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
@@ -513,7 +513,7 @@ void Channelwood::o_valveHandleMove1(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Channelwood::o_valveHandleMoveStart1(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_valveHandleMoveStart1(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Valve handle move start", op);
 
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
@@ -522,10 +522,10 @@ void Channelwood::o_valveHandleMoveStart1(uint16 op, uint16 var, uint16 argc, ui
 		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
-	o_valveHandleMove1(op, var, argc, argv);
+	o_valveHandleMove1(op, var, args);
 }
 
-void Channelwood::o_valveHandleMoveStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_valveHandleMoveStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Valve handle move stop", op);
 
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
@@ -548,7 +548,7 @@ void Channelwood::o_valveHandleMoveStop(uint16 op, uint16 var, uint16 argc, uint
 	_vm->checkCursorHints();
 }
 
-void Channelwood::o_valveHandleMove2(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_valveHandleMove2(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Valve handle move", op);
 
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
@@ -564,7 +564,7 @@ void Channelwood::o_valveHandleMove2(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Channelwood::o_valveHandleMoveStart2(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_valveHandleMoveStart2(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Valve handle move start", op);
 
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
@@ -573,10 +573,10 @@ void Channelwood::o_valveHandleMoveStart2(uint16 op, uint16 var, uint16 argc, ui
 		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
-	o_valveHandleMove2(op, var, argc, argv);
+	o_valveHandleMove2(op, var, args);
 }
 
-void Channelwood::o_valveHandleMove3(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_valveHandleMove3(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Valve handle move", op);
 
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
@@ -592,7 +592,7 @@ void Channelwood::o_valveHandleMove3(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Channelwood::o_valveHandleMoveStart3(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_valveHandleMoveStart3(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Valve handle move start", op);
 
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
@@ -601,14 +601,14 @@ void Channelwood::o_valveHandleMoveStart3(uint16 op, uint16 var, uint16 argc, ui
 		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
-	o_valveHandleMove3(op, var, argc, argv);
+	o_valveHandleMove3(op, var, args);
 }
 
-void Channelwood::o_hologramMonitor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_hologramMonitor(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hologram monitor", op);
 
 	// Used on Card 3012 (Temple Hologram Monitor)
-	uint16 button = argv[0]; // 0 to 3
+	uint16 button = args[0]; // 0 to 3
 
 	if (_state.holoprojectorSelection != button || !_vm->_video->isVideoPlaying()) {
 		_state.holoprojectorSelection = button;
@@ -650,7 +650,7 @@ void Channelwood::o_hologramMonitor(uint16 op, uint16 var, uint16 argc, uint16 *
 	}
 }
 
-void Channelwood::o_drawerOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_drawerOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Open Sirius drawer", op);
 
 	_siriusDrawerState = 1;
@@ -658,7 +658,7 @@ void Channelwood::o_drawerOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	_vm->redrawArea(102, false);
 }
 
-void Channelwood::o_hologramTemple(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_hologramTemple(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Temple hologram", op);
 
 	_vm->_sound->pauseBackground();
@@ -685,14 +685,14 @@ void Channelwood::o_hologramTemple(uint16 op, uint16 var, uint16 argc, uint16 *a
 	_vm->_sound->resumeBackground();
 }
 
-void Channelwood::o_executeMouseUp(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_executeMouseUp(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Execute mouse up", op);
 
-	MystArea *resource = _vm->getViewResource<MystArea>(argv[0]);
+	MystArea *resource = _vm->getViewResource<MystArea>(args[0]);
 	resource->handleMouseUp();
 }
 
-void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Do Water Tank Valve Close Animation", op);
 	Common::Rect rect = getInvokingResource<MystArea>()->getRect();
 
@@ -705,12 +705,12 @@ void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, uint16 argc, uint
 	pipeChangeValve(false, 0x80);
 }
 
-void Channelwood::o_elevatorMovies(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_elevatorMovies(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used by Card 3262 (Elevator)
 	debugC(kDebugScript, "Opcode %d: Elevator movie", op);
 
-	uint16 elevator = argv[0];
-	uint16 direction = argv[1];
+	uint16 elevator = args[0];
+	uint16 direction = args[1];
 
 	Common::String movie;
 	uint16 x;
@@ -750,27 +750,27 @@ void Channelwood::o_elevatorMovies(uint16 op, uint16 var, uint16 argc, uint16 *a
 	_vm->_sound->resumeBackground();
 }
 
-void Channelwood::o_soundReplace(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_soundReplace(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Play sound if not already playing", op);
 
-	uint16 soundId = argv[0];
+	uint16 soundId = args[0];
 
 	if (!_vm->_sound->isEffectPlaying()) {
 		_vm->_sound->playEffect(soundId);
 	}
 }
 
-void Channelwood::o_lever_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_lever_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generic lever init", op);
 	_leverAction = getInvokingResource<MystArea>();
 }
 
-void Channelwood::o_pipeValve_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_pipeValve_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Water valve init", op);
 	_valveVar = var;
 }
 
-void Channelwood::o_drawer_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Channelwood::o_drawer_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sirius's drawer init", op);
 	_siriusDrawerState = 0;
 }
diff --git a/engines/mohawk/myst_stacks/channelwood.h b/engines/mohawk/myst_stacks/channelwood.h
index ac875e5..c6c9be7 100644
--- a/engines/mohawk/myst_stacks/channelwood.h
+++ b/engines/mohawk/myst_stacks/channelwood.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Channelwood : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/credits.cpp b/engines/mohawk/myst_stacks/credits.cpp
index b295255..e8c5387 100644
--- a/engines/mohawk/myst_stacks/credits.cpp
+++ b/engines/mohawk/myst_stacks/credits.cpp
@@ -90,7 +90,7 @@ uint16 Credits::getVar(uint16 var) {
 	}
 }
 
-void Credits::o_runCredits(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Credits::o_runCredits(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Activate the credits
 	_creditsRunning = true;
 	_curImage = 0;
diff --git a/engines/mohawk/myst_stacks/credits.h b/engines/mohawk/myst_stacks/credits.h
index c2c2037..923f98b 100644
--- a/engines/mohawk/myst_stacks/credits.h
+++ b/engines/mohawk/myst_stacks/credits.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Credits : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index 848736e..84261a8 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -76,13 +76,13 @@ void Demo::runPersistentScripts() {
 	}
 }
 
-void Demo::o_stopIntro(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Demo::o_stopIntro(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Unk", op);
 	// The original also seems to stop the movies. Not needed with this engine.
 	_vm->_gfx->fadeToBlack();
 }
 
-void Demo::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Demo::o_fadeFromBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fade from black", op);
 
 	// FIXME: This glitches when enabled. The backbuffer is drawn to screen,
@@ -90,7 +90,7 @@ void Demo::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	// _vm->_gfx->fadeFromBlack();
 }
 
-void Demo::o_fadeToBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Demo::o_fadeToBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fade to black", op);
 	_vm->_gfx->fadeToBlack();
 }
@@ -122,7 +122,7 @@ void Demo::returnToMenu_run() {
 	}
 }
 
-void Demo::o_returnToMenu_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Demo::o_returnToMenu_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Return to menu init", op);
 
 	// Used on Card 2001, 2002 and 2003
diff --git a/engines/mohawk/myst_stacks/demo.h b/engines/mohawk/myst_stacks/demo.h
index 64a3925..c2a8fce 100644
--- a/engines/mohawk/myst_stacks/demo.h
+++ b/engines/mohawk/myst_stacks/demo.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Demo : public Intro {
 public:
diff --git a/engines/mohawk/myst_stacks/dni.cpp b/engines/mohawk/myst_stacks/dni.cpp
index 8611662..bffb61e 100644
--- a/engines/mohawk/myst_stacks/dni.cpp
+++ b/engines/mohawk/myst_stacks/dni.cpp
@@ -95,7 +95,7 @@ uint16 Dni::getVar(uint16 var) {
 	}
 }
 
-void Dni::o_handPage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Dni::o_handPage(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hand page to Atrus", op);
 	// Used in Card 5014 (Atrus)
 
@@ -214,7 +214,7 @@ void Dni::atrus_run() {
 	}
 }
 
-void Dni::o_atrus_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Dni::o_atrus_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Atrus init", op);
 
 	_atrusRunning = true;
diff --git a/engines/mohawk/myst_stacks/dni.h b/engines/mohawk/myst_stacks/dni.h
index 1a5f091..75a35ec 100644
--- a/engines/mohawk/myst_stacks/dni.h
+++ b/engines/mohawk/myst_stacks/dni.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Dni : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index 2797ba3..d462a98 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -79,7 +79,7 @@ uint16 Intro::getVar(uint16 var) {
 	}
 }
 
-void Intro::o_useLinkBook(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Intro::o_useLinkBook(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Hard coded SoundId valid only for Intro Stack.
 	// Other stacks use Opcode 40, which takes SoundId values as arguments.
 	const uint16 soundIdLinkSrc = 5;
@@ -146,7 +146,7 @@ void Intro::introMovies_run() {
 	}
 }
 
-void Intro::o_playIntroMovies(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Intro::o_playIntroMovies(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_introMoviesRunning = true;
 	_introStep = 0;
 }
@@ -165,7 +165,7 @@ void Intro::mystLinkBook_run() {
 	}
 }
 
-void Intro::o_mystLinkBook_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Intro::o_mystLinkBook_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Myst link book init", op);
 
 	_linkBookMovie = getInvokingResource<MystAreaVideo>();
diff --git a/engines/mohawk/myst_stacks/intro.h b/engines/mohawk/myst_stacks/intro.h
index 0095706..266189b 100644
--- a/engines/mohawk/myst_stacks/intro.h
+++ b/engines/mohawk/myst_stacks/intro.h
@@ -34,7 +34,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Intro : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/makingof.h b/engines/mohawk/myst_stacks/makingof.h
index 41f91bc..ab4788b 100644
--- a/engines/mohawk/myst_stacks/makingof.h
+++ b/engines/mohawk/myst_stacks/makingof.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class MakingOf : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 5a1b5e0..81fbf78 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -271,13 +271,13 @@ bool Mechanical::setVarValue(uint16 var, uint16 value) {
 	return refresh;
 }
 
-void Mechanical::o_throneEnablePassage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_throneEnablePassage(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Enable throne passage", op);
 
-	_vm->_resources[argv[0]]->setEnabled(getVar(var));
+	_vm->_resources[args[0]]->setEnabled(getVar(var));
 }
 
-void Mechanical::o_birdCrankStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_birdCrankStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Mechanical bird crank start", op);
 
 	MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
@@ -292,7 +292,7 @@ void Mechanical::o_birdCrankStart(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	crankMovie->playMovie();
 }
 
-void Mechanical::o_birdCrankStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_birdCrankStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Mechanical bird crank stop", op);
 
 	MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
@@ -309,14 +309,14 @@ void Mechanical::o_birdCrankStop(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	_bird->playMovie();
 }
 
-void Mechanical::o_snakeBoxTrigger(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_snakeBoxTrigger(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Trigger Playing Of Snake Movie", op);
 
 	// Used on Mechanical Card 6043 (Weapons Rack with Snake Box)
 	_snakeBox->playMovie();
 }
 
-void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Play Stairs Movement Movie", op);
 
 	VideoEntryPtr staircase = _vm->_video->playMovie(_vm->wrapMovieFilename("hhstairs", kMechanicalStack));
@@ -334,7 +334,7 @@ void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, uint16 argc, ui
 	_vm->waitUntilMovieEnds(staircase);
 }
 
-void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Elevator rotation lever start", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -348,7 +348,7 @@ void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, uint16 argc, uin
 	_vm->_cursor->setCursor(700);
 }
 
-void Mechanical::o_elevatorRotationMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_elevatorRotationMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Elevator rotation lever move", op);
 
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
@@ -366,7 +366,7 @@ void Mechanical::o_elevatorRotationMove(uint16 op, uint16 var, uint16 argc, uint
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Elevator rotation lever stop", op);
 
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
@@ -414,7 +414,7 @@ void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, uint16 argc, uint
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressRotationSpeedStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotationSpeedStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation speed lever start", op);
 
 	_vm->_cursor->setCursor(700);
@@ -423,7 +423,7 @@ void Mechanical::o_fortressRotationSpeedStart(uint16 op, uint16 var, uint16 argc
 	lever->drawFrame(0);
 }
 
-void Mechanical::o_fortressRotationSpeedMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotationSpeedMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation speed lever move", op);
 
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
@@ -441,7 +441,7 @@ void Mechanical::o_fortressRotationSpeedMove(uint16 op, uint16 var, uint16 argc,
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressRotationSpeedStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotationSpeedStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation speed lever stop", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -457,7 +457,7 @@ void Mechanical::o_fortressRotationSpeedStop(uint16 op, uint16 var, uint16 argc,
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressRotationBrakeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotationBrakeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation brake lever start", op);
 
 	_vm->_cursor->setCursor(700);
@@ -466,7 +466,7 @@ void Mechanical::o_fortressRotationBrakeStart(uint16 op, uint16 var, uint16 argc
 	lever->drawFrame(_fortressRotationBrake);
 }
 
-void Mechanical::o_fortressRotationBrakeMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotationBrakeMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation brake lever move", op);
 
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
@@ -484,7 +484,7 @@ void Mechanical::o_fortressRotationBrakeMove(uint16 op, uint16 var, uint16 argc,
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressRotationBrakeStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotationBrakeStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation brake lever stop", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -493,7 +493,7 @@ void Mechanical::o_fortressRotationBrakeStop(uint16 op, uint16 var, uint16 argc,
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressSimulationSpeedStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulationSpeedStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever start", op);
 
 	_vm->_cursor->setCursor(700);
@@ -502,7 +502,7 @@ void Mechanical::o_fortressSimulationSpeedStart(uint16 op, uint16 var, uint16 ar
 	lever->drawFrame(0);
 }
 
-void Mechanical::o_fortressSimulationSpeedMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulationSpeedMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever move", op);
 
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
@@ -520,7 +520,7 @@ void Mechanical::o_fortressSimulationSpeedMove(uint16 op, uint16 var, uint16 arg
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressSimulationSpeedStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulationSpeedStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever stop", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -536,7 +536,7 @@ void Mechanical::o_fortressSimulationSpeedStop(uint16 op, uint16 var, uint16 arg
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressSimulationBrakeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulationBrakeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever start", op);
 
 	_vm->_cursor->setCursor(700);
@@ -545,7 +545,7 @@ void Mechanical::o_fortressSimulationBrakeStart(uint16 op, uint16 var, uint16 ar
 	lever->drawFrame(_fortressSimulationBrake);
 }
 
-void Mechanical::o_fortressSimulationBrakeMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulationBrakeMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever move", op);
 
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
@@ -563,7 +563,7 @@ void Mechanical::o_fortressSimulationBrakeMove(uint16 op, uint16 var, uint16 arg
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressSimulationBrakeStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulationBrakeStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever stop", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -572,9 +572,9 @@ void Mechanical::o_fortressSimulationBrakeStop(uint16 op, uint16 var, uint16 arg
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 startTime = argv[0];
-	uint16 endTime = argv[1];
+void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 startTime = args[0];
+	uint16 endTime = args[1];
 
 	debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
 
@@ -587,7 +587,7 @@ void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, uint16 argc, uint1
 	_vm->waitUntilMovieEnds(window);
 }
 
-void Mechanical::o_elevatorGoMiddle(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_elevatorGoMiddle(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Elevator go middle from top", op);
 
 	_elevatorTooLate = false;
@@ -634,7 +634,7 @@ void Mechanical::elevatorGoMiddle_run() {
 				_vm->wait(500);
 				_vm->_sound->playEffect(9120);
 				static uint16 moviePos[2] = { 3540, 5380 };
-				o_elevatorWindowMovie(121, 0, 2, moviePos);
+				o_elevatorWindowMovie(121, 0, ArgumentsArray(moviePos, ARRAYSIZE(moviePos)));
 				_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
 				_vm->_sound->playEffect(10120);
 				_vm->_cursor->showCursor();
@@ -647,9 +647,9 @@ void Mechanical::elevatorGoMiddle_run() {
 	}
 }
 
-void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 startTime = argv[0];
-	uint16 endTime = argv[1];
+void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 startTime = args[0];
+	uint16 endTime = args[1];
 
 	debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
 
@@ -662,7 +662,7 @@ void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, uint16 argc, uint16 *
 	_vm->waitUntilMovieEnds(window);
 }
 
-void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Set fortress position", op);
 
 	VideoEntryPtr gears = _fortressRotationGears->getVideo();
@@ -676,13 +676,13 @@ void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, uint16 arg
 	_fortressPosition = (moviePosition + 900) / 1800 % 4;
 }
 
-void Mechanical::o_mystStaircaseMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_mystStaircaseMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Myst book staircase video", op);
 
 	_vm->playMovieBlocking(_vm->wrapMovieFilename("sstairs", kMechanicalStack), 199, 108);
 }
 
-void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Wait for the elevator to go middle", op);
 
 	// Wait while the elevator times out
@@ -692,61 +692,61 @@ void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, uint16 argc, uint1
 	}
 }
 
-void Mechanical::o_crystalEnterYellow(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_crystalEnterYellow(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Crystal enter", op);
 
 	_crystalLit = 3;
 	_vm->redrawArea(20);
 }
 
-void Mechanical::o_crystalEnterGreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_crystalEnterGreen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Crystal enter", op);
 
 	_crystalLit = 1;
 	_vm->redrawArea(21);
 }
 
-void Mechanical::o_crystalEnterRed(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_crystalEnterRed(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Crystal enter", op);
 
 	_crystalLit = 2;
 	_vm->redrawArea(22);
 }
 
-void Mechanical::o_crystalLeaveYellow(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_crystalLeaveYellow(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Crystal leave", op);
 
 	_crystalLit = 0;
 	_vm->redrawArea(20);
 }
 
-void Mechanical::o_crystalLeaveGreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_crystalLeaveGreen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Crystal leave", op);
 
 	_crystalLit = 0;
 	_vm->redrawArea(21);
 }
 
-void Mechanical::o_crystalLeaveRed(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_crystalLeaveRed(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Crystal leave", op);
 
 	_crystalLit = 0;
 	_vm->redrawArea(22);
 }
 
-void Mechanical::o_throne_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_throne_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Card 6238 (Sirrus' Throne) and Card 6027 (Achenar's Throne)
 	debugC(kDebugScript, "Opcode %d: Brother throne init", op);
 
 	getInvokingResource<MystArea>()->setEnabled(getVar(var));
 }
 
-void Mechanical::o_fortressStaircase_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressStaircase_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Staircase init", op);
 
-	_vm->_resources[argv[0]]->setEnabled(!_state.staircaseState);
-	_vm->_resources[argv[1]]->setEnabled(!_state.staircaseState);
-	_vm->_resources[argv[2]]->setEnabled(_state.staircaseState);
+	_vm->_resources[args[0]]->setEnabled(!_state.staircaseState);
+	_vm->_resources[args[1]]->setEnabled(!_state.staircaseState);
+	_vm->_resources[args[2]]->setEnabled(_state.staircaseState);
 }
 
 void Mechanical::birdSing_run() {
@@ -759,7 +759,7 @@ void Mechanical::birdSing_run() {
 	}
 }
 
-void Mechanical::o_bird_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_bird_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Mechanical bird init", op);
 
 	_birdSinging = false;
@@ -767,7 +767,7 @@ void Mechanical::o_bird_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_bird = getInvokingResource<MystAreaVideo>();
 }
 
-void Mechanical::o_snakeBox_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_snakeBox_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Snake box init", op);
 
 	_snakeBox = getInvokingResource<MystAreaVideo>();
@@ -790,10 +790,10 @@ void Mechanical::elevatorRotation_run() {
 	}
 }
 
-void Mechanical::o_elevatorRotation_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_elevatorRotation_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Elevator rotation init", op);
 
-	_elevatorRotationSoundId = argv[0];
+	_elevatorRotationSoundId = args[0];
 	_elevatorRotationGearPosition = 0;
 	_elevatorRotationLeverMoving = false;
 }
@@ -870,7 +870,7 @@ void Mechanical::fortressRotation_run() {
 	}
 }
 
-void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fortress rotation init", op);
 
 	_fortressRotationGears = getInvokingResource<MystAreaVideo>();
@@ -880,10 +880,10 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
 	gears->seek(Audio::Timestamp(0, 1800 * _fortressPosition, 600));
 	gears->setRate(0);
 
-	_fortressRotationSounds[0] = argv[0];
-	_fortressRotationSounds[1] = argv[1];
-	_fortressRotationSounds[2] = argv[2];
-	_fortressRotationSounds[3] = argv[3];
+	_fortressRotationSounds[0] = args[0];
+	_fortressRotationSounds[1] = args[1];
+	_fortressRotationSounds[2] = args[2];
+	_fortressRotationSounds[3] = args[3];
 
 	_fortressRotationBrake = 0;
 
@@ -1020,18 +1020,18 @@ void Mechanical::fortressSimulation_run() {
 	}
 }
 
-void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fortress rotation simulator init", op);
 
 	_fortressSimulationHolo = getInvokingResource<MystAreaVideo>();
 
-	_fortressSimulationStartSound1 = argv[0];
-	_fortressSimulationStartSound2 = argv[1];
+	_fortressSimulationStartSound1 = args[0];
+	_fortressSimulationStartSound2 = args[1];
 
-	_fortressRotationSounds[0] = argv[2];
-	_fortressRotationSounds[1] = argv[3];
-	_fortressRotationSounds[2] = argv[4];
-	_fortressRotationSounds[3] = argv[5];
+	_fortressRotationSounds[0] = args[2];
+	_fortressRotationSounds[1] = args[3];
+	_fortressRotationSounds[2] = args[4];
+	_fortressRotationSounds[3] = args[5];
 
 	_fortressSimulationBrake = 0;
 
@@ -1042,7 +1042,7 @@ void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, uint16 argc, u
 	_vm->_cursor->hideCursor();
 }
 
-void Mechanical::o_fortressSimulationStartup_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Mechanical::o_fortressSimulationStartup_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fortress rotation simulator startup init", op);
 
 	_fortressSimulationStartup = getInvokingResource<MystAreaVideo>();
diff --git a/engines/mohawk/myst_stacks/mechanical.h b/engines/mohawk/myst_stacks/mechanical.h
index aae02df..585164f 100644
--- a/engines/mohawk/myst_stacks/mechanical.h
+++ b/engines/mohawk/myst_stacks/mechanical.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Mechanical : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 71747fa..e9449b7 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -815,7 +815,7 @@ uint16 Myst::bookCountPages(uint16 var) {
 	return cnt;
 }
 
-void Myst::o_libraryBookPageTurnLeft(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_libraryBookPageTurnLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Turn book page left", op);
 
 	if (_libraryBookPage - 1 >= 0) {
@@ -831,7 +831,7 @@ void Myst::o_libraryBookPageTurnLeft(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Myst::o_libraryBookPageTurnRight(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_libraryBookPageTurnRight(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Turn book page right", op);
 
 	if (_libraryBookPage + 1 < _libraryBookNumPages) {
@@ -847,11 +847,11 @@ void Myst::o_libraryBookPageTurnRight(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Myst Card 4162 (Fireplace Grid)
 	debugC(kDebugScript, "Opcode %d: Fireplace grid toggle button", op);
 
-	uint16 bitmask = argv[0];
+	uint16 bitmask = args[0];
 	uint16 line = _fireplaceLines[var - 17];
 
 	debugC(kDebugScript, "\tvar: %d", var);
@@ -874,9 +874,9 @@ void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, uint16 argc, uint16 *a
 	}
 }
 
-void Myst::o_fireplaceRotation(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_fireplaceRotation(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Myst Card 4162 and 4166 (Fireplace Puzzle Rotation Movies)
-	uint16 movieNum = argv[0];
+	uint16 movieNum = args[0];
 	debugC(kDebugScript, "Opcode %d: Play Fireplace Puzzle Rotation Movies", op);
 	debugC(kDebugScript, "\tmovieNum: %d", movieNum);
 
@@ -886,8 +886,8 @@ void Myst::o_fireplaceRotation(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		_vm->playMovieBlocking(_vm->wrapMovieFilename("fpin", kMystStack), 167, 4);
 }
 
-void Myst::o_courtyardBoxesCheckSolution(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 soundId = argv[0];
+void Myst::o_courtyardBoxesCheckSolution(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 soundId = args[0];
 
 	debugC(kDebugScript, "Opcode %d: Ship Puzzle Logic", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
@@ -906,7 +906,7 @@ void Myst::o_courtyardBoxesCheckSolution(uint16 op, uint16 var, uint16 argc, uin
 	}
 }
 
-void Myst::o_towerRotationStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_towerRotationStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_towerRotationBlinkLabel = false;
 	_towerRotationMapClicked = true;
 	_towerRotationSpeed = 0;
@@ -921,7 +921,7 @@ void Myst::o_towerRotationStart(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	_vm->_sound->playEffect(5378, true);
 }
 
-void Myst::o_towerRotationEnd(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_towerRotationEnd(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_towerRotationMapClicked = false;
 
 	// Set angle value to expected value
@@ -949,13 +949,13 @@ void Myst::o_towerRotationEnd(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	_towerRotationBlinkLabelCount = 0;
 }
 
-void Myst::o_imagerChangeSelection(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_imagerChangeSelection(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Dock imager change selection", op);
 
 	if (_imagerValidationStep != 10) {
 		_imagerValidationStep = 0;
 
-		int16 signedValue = argv[0];
+		int16 signedValue = args[0];
 		uint16 d1 = (_state.imagerSelection / 10) % 10;
 		uint16 d2 = _state.imagerSelection % 10;
 
@@ -975,11 +975,11 @@ void Myst::o_imagerChangeSelection(uint16 op, uint16 var, uint16 argc, uint16 *a
 	}
 }
 
-void Myst::o_dockVaultOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_dockVaultOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Myst 4143 (Dock near Marker Switch)
-	uint16 soundId = argv[0];
-	uint16 delay = argv[1];
-	uint16 directionalUpdateDataSize = argv[2];
+	uint16 soundId = args[0];
+	uint16 delay = args[1];
+	uint16 directionalUpdateDataSize = args[2];
 
 	debugC(kDebugScript, "Opcode %d: Vault Open Logic", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
@@ -1000,15 +1000,15 @@ void Myst::o_dockVaultOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 
 		_vm->_sound->playEffect(soundId);
 		_vm->redrawArea(41, false);
-		animatedUpdate(directionalUpdateDataSize, &argv[3], delay);
+		animatedUpdate(ArgumentsArray(args.begin() + 3, directionalUpdateDataSize), delay);
 	}
 }
 
-void Myst::o_dockVaultClose(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_dockVaultClose(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Myst 4143 (Dock near Marker Switch)
-	uint16 soundId = argv[0];
-	uint16 delay = argv[1];
-	uint16 directionalUpdateDataSize = argv[2];
+	uint16 soundId = args[0];
+	uint16 delay = args[1];
+	uint16 directionalUpdateDataSize = args[2];
 
 	debugC(kDebugScript, "Opcode %d: Vault Close Logic", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
@@ -1027,14 +1027,14 @@ void Myst::o_dockVaultClose(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 
 		_vm->_sound->playEffect(soundId);
 		_vm->redrawArea(41, false);
-		animatedUpdate(directionalUpdateDataSize, &argv[3], delay);
+		animatedUpdate(ArgumentsArray(args.begin() + 3, directionalUpdateDataSize), delay);
 	}
 }
 
-void Myst::o_bookGivePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	uint16 cardIdLose = argv[0];
-	uint16 cardIdBookCover = argv[1];
-	uint16 soundIdAddPage = argv[2];
+void Myst::o_bookGivePage(uint16 op, uint16 var, const ArgumentsArray &args) {
+	uint16 cardIdLose = args[0];
+	uint16 cardIdBookCover = args[1];
+	uint16 soundIdAddPage = args[2];
 
 	debugC(kDebugScript, "Opcode %d: Red and Blue Book/Page Interaction", op);
 	debugC(kDebugScript, "Var: %d", var);
@@ -1118,9 +1118,9 @@ void Myst::o_bookGivePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	}
 }
 
-void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockWheelsExecute(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006 (Clock Tower Time Controls)
-	uint16 soundId = argv[0];
+	uint16 soundId = args[0];
 
 	debugC(kDebugScript, "Opcode %d: Clock Tower Bridge Puzzle Execute Button", op);
 
@@ -1161,7 +1161,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	}
 }
 
-void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_imagerPlayButton(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Imager play button", op);
 
 	uint16 video = getVar(51);
@@ -1183,7 +1183,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 
 	// Play selected video
 	if (!_state.imagerActive && video != 3)
-		_vm->_sound->playEffect(argv[0]);
+		_vm->_sound->playEffect(args[0]);
 
 	switch (video) {
 	case 0: // Nothing
@@ -1220,7 +1220,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		_imagerMovie->setBlocking(false);
 
 		if (_state.imagerActive) {
-			_vm->_sound->playEffect(argv[1]);
+			_vm->_sound->playEffect(args[1]);
 
 			// Water disappearing
 			VideoEntryPtr water = _imagerMovie->playMovie();
@@ -1247,13 +1247,13 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	_vm->_cursor->showCursor();
 }
 
-void Myst::o_imagerEraseButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_imagerEraseButton(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Imager erase button", op);
 
 	_imagerRedButton = static_cast<MystAreaImageSwitch *>(getInvokingResource<MystArea>()->_parent);
 	for (uint i = 0; i < 4; i++)
-		_imagerSound[i] = argv[i];
-	_imagerValidationCard = argv[4];
+		_imagerSound[i] = args[i];
+	_imagerValidationCard = args[4];
 
 	if (_imagerValidationStep == 0) {
 		// Validation script is not running, run it
@@ -1322,7 +1322,7 @@ void Myst::imagerValidation_run() {
 	}
 }
 
-void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Tower elevator animation", op);
 
 	_treeStopped = true;
@@ -1331,7 +1331,7 @@ void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, uint16 argc, uint16 *
 	_vm->_sound->stopEffect();
 	_vm->_sound->pauseBackground();
 
-	switch (argv[0]) {
+	switch (args[0]) {
 	case 0:
 		_vm->playMovieBlocking(_vm->wrapMovieFilename("libdown", kMystStack), 216, 78);
 		break;
@@ -1347,7 +1347,7 @@ void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, uint16 argc, uint16 *
 	_treeStopped = false;
 }
 
-void Myst::o_generatorButtonPressed(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_generatorButtonPressed(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generator button pressed", op);
 
 	MystArea *button = getInvokingResource<MystArea>()->_parent;
@@ -1442,7 +1442,7 @@ void Myst::generatorButtonValue(MystArea *button, uint16 &mask, uint16 &value) {
 	}
 }
 
-void Myst::o_cabinSafeChangeDigit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_cabinSafeChangeDigit(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Cabin safe change digit", op);
 
 	uint16 d1 = _state.cabinSafeCombination / 100;
@@ -1461,7 +1461,7 @@ void Myst::o_cabinSafeChangeDigit(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	_vm->redrawArea(var);
 }
 
-void Myst::o_cabinSafeHandleStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_cabinSafeHandleStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Cabin safe handle start move", op);
 
 	// Used on Card 4100
@@ -1471,7 +1471,7 @@ void Myst::o_cabinSafeHandleStartMove(uint16 op, uint16 var, uint16 argc, uint16
 	_tempVar = 0;
 }
 
-void Myst::o_cabinSafeHandleMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_cabinSafeHandleMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Cabin safe handle move", op);
 
 	// Used on Card 4100
@@ -1501,7 +1501,7 @@ void Myst::o_cabinSafeHandleMove(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	}
 }
 
-void Myst::o_cabinSafeHandleEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_cabinSafeHandleEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Cabin safe handle end move", op);
 
 	// Used on Card 4100
@@ -1510,7 +1510,7 @@ void Myst::o_cabinSafeHandleEndMove(uint16 op, uint16 var, uint16 argc, uint16 *
 	_vm->checkCursorHints();
 }
 
-void Myst::o_observatoryMonthChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryMonthChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Observatory month change start", op);
 
 	_vm->_sound->pauseBackground();
@@ -1569,7 +1569,7 @@ void Myst::observatoryMonthChange_run() {
 		observatoryIncrementMonth(_observatoryIncrement);
 }
 
-void Myst::o_observatoryDayChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryDayChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Observatory day change start", op);
 
 	_vm->_sound->pauseBackground();
@@ -1629,7 +1629,7 @@ void Myst::observatoryDayChange_run() {
 		observatoryIncrementDay(_observatoryIncrement);
 }
 
-void Myst::o_observatoryYearChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryYearChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Observatory year change start", op);
 
 	_vm->_sound->pauseBackground();
@@ -1683,7 +1683,7 @@ void Myst::observatoryYearChange_run() {
 		observatoryIncrementYear(_observatoryIncrement);
 }
 
-void Myst::o_observatoryTimeChangeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryTimeChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Observatory time change start", op);
 
 	_vm->_sound->pauseBackground();
@@ -1742,7 +1742,7 @@ void Myst::observatoryTimeChange_run() {
 		observatoryIncrementTime(_observatoryIncrement);
 }
 
-void Myst::o_observatoryGoButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryGoButton(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Observatory go button", op);
 
 	// Setting not at target
@@ -1750,7 +1750,7 @@ void Myst::o_observatoryGoButton(uint16 op, uint16 var, uint16 argc, uint16 *arg
 			|| _state.observatoryMonthTarget != _state.observatoryMonthSetting
 			|| _state.observatoryYearTarget != _state.observatoryYearSetting
 			|| _state.observatoryTimeTarget != _state.observatoryTimeSetting) {
-		uint16 soundId = argv[0];
+		uint16 soundId = args[0];
 		_vm->_sound->playEffect(soundId);
 
 		int16 distance = _state.observatoryYearTarget - _state.observatoryYearSetting;
@@ -1776,31 +1776,31 @@ void Myst::o_observatoryGoButton(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	}
 }
 
-void Myst::o_observatoryMonthSliderMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryMonthSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Month slider move", op);
 
 	observatoryUpdateMonth();
 }
 
-void Myst::o_observatoryDaySliderMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryDaySliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Day slider move", op);
 
 	observatoryUpdateDay();
 }
 
-void Myst::o_observatoryYearSliderMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryYearSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Year slider move", op);
 
 	observatoryUpdateYear();
 }
 
-void Myst::o_observatoryTimeSliderMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryTimeSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Time slider move", op);
 
 	observatoryUpdateTime();
 }
 
-void Myst::o_circuitBreakerStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_circuitBreakerStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Circuit breaker start move", op);
 
 	MystVideoInfo *breaker = getInvokingResource<MystVideoInfo>();
@@ -1809,7 +1809,7 @@ void Myst::o_circuitBreakerStartMove(uint16 op, uint16 var, uint16 argc, uint16
 	_tempVar = 0;
 }
 
-void Myst::o_circuitBreakerMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_circuitBreakerMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Circuit breaker move", op);
 
 	MystVideoInfo *breaker = getInvokingResource<MystVideoInfo>();
@@ -1860,7 +1860,7 @@ void Myst::o_circuitBreakerMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	}
 }
 
-void Myst::o_circuitBreakerEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_circuitBreakerEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Circuit breaker end move", op);
 
 	MystVideoInfo *breaker = getInvokingResource<MystVideoInfo>();
@@ -1868,7 +1868,7 @@ void Myst::o_circuitBreakerEndMove(uint16 op, uint16 var, uint16 argc, uint16 *a
 	_vm->checkCursorHints();
 }
 
-void Myst::o_boilerIncreasePressureStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_boilerIncreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Boiler increase pressure start", op);
 
 	_treeStopped = true;
@@ -1878,7 +1878,7 @@ void Myst::o_boilerIncreasePressureStart(uint16 op, uint16 var, uint16 argc, uin
 	_boilerPressureIncreasing = true;
 }
 
-void Myst::o_boilerLightPilot(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_boilerLightPilot(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Boiler light pilot", op);
 
 	// Match is lit
@@ -1940,7 +1940,7 @@ void Myst::boilerResetGauge(const Common::Rational &rate) {
 	_cabinGaugeMovie->setRate(rate);
 }
 
-void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Boiler increase pressure stop", op);
 
 	_treeStopped = false;
@@ -2006,7 +2006,7 @@ void Myst::boilerPressureDecrease_run() {
 	}
 }
 
-void Myst::o_boilerDecreasePressureStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_boilerDecreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Boiler decrease pressure start", op);
 
 	_treeStopped = true;
@@ -2015,7 +2015,7 @@ void Myst::o_boilerDecreasePressureStart(uint16 op, uint16 var, uint16 argc, uin
 	_boilerPressureDecreasing = true;
 }
 
-void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Boiler decrease pressure stop", op);
 
 	_treeStopped = false;
@@ -2038,14 +2038,14 @@ void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
 	}
 }
 
-void Myst::o_basementIncreasePressureStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_basementIncreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Basement increase pressure start", op);
 
 	_treeStopped = true;
 	_basementPressureIncreasing = true;
 }
 
-void Myst::o_basementIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_basementIncreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Basement increase pressure stop", op);
 
 	_treeStopped = false;
@@ -2079,14 +2079,14 @@ void Myst::basementPressureDecrease_run() {
 	}
 }
 
-void Myst::o_basementDecreasePressureStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_basementDecreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Basement decrease pressure start", op);
 
 	_treeStopped = true;
 	_basementPressureDecreasing = true;
 }
 
-void Myst::o_basementDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_basementDecreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Basement decrease pressure stop", op);
 
 	_treeStopped = false;
@@ -2163,7 +2163,7 @@ uint32 Myst::treeNextMoveDelay(uint16 pressure) {
 		return 25000 * pressure / 13 + 3000;
 }
 
-void Myst::o_rocketSoundSliderStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketSoundSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket slider start move", op);
 
 	_rocketSliderSound = 0;
@@ -2172,13 +2172,13 @@ void Myst::o_rocketSoundSliderStartMove(uint16 op, uint16 var, uint16 argc, uint
 	rocketSliderMove();
 }
 
-void Myst::o_rocketSoundSliderMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketSoundSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket slider move", op);
 
 	rocketSliderMove();
 }
 
-void Myst::o_rocketSoundSliderEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketSoundSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket slider end move", op);
 
 	_vm->checkCursorHints();
@@ -2295,7 +2295,7 @@ void Myst::rocketCheckSolution() {
 	_vm->_cursor->showCursor();
 }
 
-void Myst::o_rocketPianoStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketPianoStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket piano start move", op);
 
 	MystAreaDrag *key = getInvokingResource<MystAreaDrag>();
@@ -2319,7 +2319,7 @@ void Myst::o_rocketPianoStart(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	}
 }
 
-void Myst::o_rocketPianoMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketPianoMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket piano move", op);
 
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
@@ -2366,7 +2366,7 @@ void Myst::o_rocketPianoMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	}
 }
 
-void Myst::o_rocketPianoStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketPianoStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket piano end move", op);
 
 	MystAreaImageSwitch *key = getInvokingResource<MystAreaImageSwitch>();
@@ -2383,7 +2383,7 @@ void Myst::o_rocketPianoStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_vm->_sound->resumeBackground();
 }
 
-void Myst::o_rocketLeverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket lever start move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -2393,7 +2393,7 @@ void Myst::o_rocketLeverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	lever->drawFrame(0);
 }
 
-void Myst::o_rocketOpenBook(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketOpenBook(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket open link book", op);
 
 	// Flyby movie
@@ -2403,7 +2403,7 @@ void Myst::o_rocketOpenBook(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_tempVar = 2;
 }
 
-void Myst::o_rocketLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket lever move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -2432,7 +2432,7 @@ void Myst::o_rocketLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_rocketLeverPosition = step;
 }
 
-void Myst::o_rocketLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket lever end move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -2442,7 +2442,7 @@ void Myst::o_rocketLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	lever->drawFrame(0);
 }
 
-void Myst::o_cabinLeave(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_cabinLeave(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Leave cabin", op);
 
 	// If match is lit, put out
@@ -2454,7 +2454,7 @@ void Myst::o_cabinLeave(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	}
 }
 
-void Myst::o_treePressureReleaseStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_treePressureReleaseStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Tree pressure release start", op);
 
 	Common::Rect src = Common::Rect(0, 0, 49, 86);
@@ -2470,7 +2470,7 @@ void Myst::o_treePressureReleaseStart(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Myst::o_treePressureReleaseStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_treePressureReleaseStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Tree pressure release stop", op);
 
 	Common::Rect rect = Common::Rect(78, 46, 127, 132);
@@ -2480,7 +2480,7 @@ void Myst::o_treePressureReleaseStop(uint16 op, uint16 var, uint16 argc, uint16
 	_treeMinPosition = 0;
 }
 
-void Myst::o_observatoryMonthSliderStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryMonthSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Month slider start move", op);
 
 	_vm->_cursor->setCursor(700);
@@ -2489,7 +2489,7 @@ void Myst::o_observatoryMonthSliderStartMove(uint16 op, uint16 var, uint16 argc,
 	observatoryUpdateMonth();
 }
 
-void Myst::o_observatoryMonthSliderEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryMonthSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Month slider end move", op);
 
 	_vm->checkCursorHints();
@@ -2511,7 +2511,7 @@ void Myst::observatoryUpdateMonth() {
 	}
 }
 
-void Myst::o_observatoryDaySliderStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryDaySliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Day slider start move", op);
 
 	_vm->_cursor->setCursor(700);
@@ -2520,7 +2520,7 @@ void Myst::o_observatoryDaySliderStartMove(uint16 op, uint16 var, uint16 argc, u
 	observatoryUpdateDay();
 }
 
-void Myst::o_observatoryDaySliderEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryDaySliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Day slider end move", op);
 
 	_vm->checkCursorHints();
@@ -2543,7 +2543,7 @@ void Myst::observatoryUpdateDay() {
 	}
 }
 
-void Myst::o_observatoryYearSliderStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryYearSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Year slider start move", op);
 
 	_vm->_cursor->setCursor(700);
@@ -2552,7 +2552,7 @@ void Myst::o_observatoryYearSliderStartMove(uint16 op, uint16 var, uint16 argc,
 	observatoryUpdateYear();
 }
 
-void Myst::o_observatoryYearSliderEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryYearSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Year slider end move", op);
 
 	_vm->checkCursorHints();
@@ -2577,7 +2577,7 @@ void Myst::observatoryUpdateYear() {
 	}
 }
 
-void Myst::o_observatoryTimeSliderStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryTimeSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Time slider start move", op);
 
 	_vm->_cursor->setCursor(700);
@@ -2586,7 +2586,7 @@ void Myst::o_observatoryTimeSliderStartMove(uint16 op, uint16 var, uint16 argc,
 	observatoryUpdateTime();
 }
 
-void Myst::o_observatoryTimeSliderEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryTimeSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Time slider end move", op);
 
 	_vm->checkCursorHints();
@@ -2615,12 +2615,12 @@ void Myst::observatoryUpdateTime() {
 	}
 }
 
-void Myst::o_libraryCombinationBookStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_libraryCombinationBookStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Combination book stop turning pages", op);
 	_libraryCombinationBookPagesTurning = false;
 }
 
-void Myst::o_cabinMatchLight(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_cabinMatchLight(uint16 op, uint16 var, const ArgumentsArray &args) {
 	if (!_cabinMatchState) {
 		_vm->_sound->playEffect(4103);
 
@@ -2659,34 +2659,34 @@ void Myst::matchBurn_run() {
 	}
 }
 
-void Myst::o_courtyardBoxEnter(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_courtyardBoxEnter(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Mouse enters courtyard box", op);
 	_tempVar = 1;
 	_vm->_sound->playEffect(_courtyardBoxSound);
 	_vm->redrawArea(var);
 }
 
-void Myst::o_courtyardBoxLeave(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_courtyardBoxLeave(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Mouse leaves courtyard box", op);
 	_tempVar = 0;
 	_vm->redrawArea(var);
 }
 
-void Myst::o_clockMinuteWheelStartTurn(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockMinuteWheelStartTurn(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006
 	debugC(kDebugScript, "Opcode %d: Minute wheel start turn", op);
 
 	clockWheelStartTurn(2);
 }
 
-void Myst::o_clockWheelEndTurn(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockWheelEndTurn(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006
 	debugC(kDebugScript, "Opcode %d: Wheel end turn", op);
 
 	_clockTurningWheel = 0;
 }
 
-void Myst::o_clockHourWheelStartTurn(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockHourWheelStartTurn(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006
 	debugC(kDebugScript, "Opcode %d: Hour wheel start turn", op);
 
@@ -2739,7 +2739,7 @@ void Myst::clockWheelTurn(uint16 var) {
 	}
 }
 
-void Myst::o_libraryCombinationBookStartRight(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_libraryCombinationBookStartRight(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Combination book start turning pages right", op);
 
 	_tempVar = 0;
@@ -2748,7 +2748,7 @@ void Myst::o_libraryCombinationBookStartRight(uint16 op, uint16 var, uint16 argc
 	_libraryCombinationBookPagesTurning = true;
 }
 
-void Myst::o_libraryCombinationBookStartLeft(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_libraryCombinationBookStartLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Combination book start turning pages left", op);
 
 	_tempVar = 0;
@@ -2818,7 +2818,7 @@ void Myst::libraryCombinationBook_run() {
 	}
 }
 
-void Myst::o_observatoryChangeSettingStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatoryChangeSettingStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Observatory change setting stop", op);
 
 	// Stop persistent scripts
@@ -2837,11 +2837,11 @@ void Myst::o_observatoryChangeSettingStop(uint16 op, uint16 var, uint16 argc, ui
 	_vm->_sound->resumeBackground();
 }
 
-void Myst::o_dockVaultForceClose(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_dockVaultForceClose(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used on Myst 4143 (Dock near Marker Switch)
-	uint16 soundId = argv[0];
-	uint16 delay = argv[1];
-	uint16 directionalUpdateDataSize = argv[2];
+	uint16 soundId = args[0];
+	uint16 delay = args[1];
+	uint16 directionalUpdateDataSize = args[2];
 
 	debugC(kDebugScript, "Opcode %d: Vault Force Close", op);
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
@@ -2857,16 +2857,16 @@ void Myst::o_dockVaultForceClose(uint16 op, uint16 var, uint16 argc, uint16 *arg
 		_dockVaultState = 0;
 		_vm->_sound->playEffect(soundId);
 		_vm->redrawArea(41, false);
-		animatedUpdate(directionalUpdateDataSize, &argv[3], delay);
+		animatedUpdate(ArgumentsArray(args.begin() + 3, directionalUpdateDataSize), delay);
 	}
 }
 
-void Myst::o_imagerEraseStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_imagerEraseStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Imager stop erase", op);
 	_imagerValidationRunning = false;
 }
 
-void Myst::o_clockLeverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Clock lever start move", op);
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(0);
@@ -2875,7 +2875,7 @@ void Myst::o_clockLeverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	_clockLeverPulled = false;
 }
 
-void Myst::o_clockLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Clock left lever move", op);
 
 	if (!_clockLeverPulled) {
@@ -2953,7 +2953,7 @@ void Myst::clockGears_run() {
 	}
 }
 
-void Myst::o_clockLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Clock lever end move", op);
 	static const char *videos[] = { "cl1wg1", "cl1wg2", "cl1wg3", "cl1wlfch" };
 
@@ -3012,7 +3012,7 @@ void Myst::clockGearsCheckSolution() {
 	}
 }
 
-void Myst::o_clockResetLeverStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockResetLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Clock reset lever start move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -3020,7 +3020,7 @@ void Myst::o_clockResetLeverStartMove(uint16 op, uint16 var, uint16 argc, uint16
 	_vm->_cursor->setCursor(700);
 }
 
-void Myst::o_clockResetLeverMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockResetLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Clock reset lever move", op);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
@@ -3117,7 +3117,7 @@ void Myst::clockResetGear(uint16 gear) {
 	_clockGearsPositions[gear] = 3;
 }
 
-void Myst::o_clockResetLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockResetLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Clock reset lever end move", op);
 
 	// Get current lever frame
@@ -3128,18 +3128,18 @@ void Myst::o_clockResetLeverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *
 	_vm->checkCursorHints();
 }
 
-void Myst::o_libraryBook_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_libraryBook_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_libraryBookPage = 0;
-	_libraryBookNumPages = argv[0];
-	_libraryBookBaseImage = argv[1];
-	_libraryBookSound1 = argv[2];
-	_libraryBookSound2 = argv[3];
+	_libraryBookNumPages = args[0];
+	_libraryBookBaseImage = args[1];
+	_libraryBookSound1 = args[2];
+	_libraryBookSound2 = args[3];
 }
 
-void Myst::o_courtyardBox_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_courtyardBox_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Courtyard box init", op);
 
-	_courtyardBoxSound = argv[0];
+	_courtyardBoxSound = args[0];
 }
 
 void Myst::towerRotationMap_run() {
@@ -3182,10 +3182,10 @@ void Myst::towerRotationMap_run() {
 	}
 }
 
-void Myst::o_towerRotationMap_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_towerRotationMap_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_towerRotationMapRunning = true;
 	_towerRotationMapTower = getInvokingResource<MystAreaImageSwitch>();
-	_towerRotationMapLabel = _vm->getViewResource<MystAreaImageSwitch>(argv[0]);
+	_towerRotationMapLabel = _vm->getViewResource<MystAreaImageSwitch>(args[0]);
 	_tempVar = 0;
 	_startTime = 0;
 	_towerRotationMapClicked = false;
@@ -3298,20 +3298,20 @@ void Myst::towerRotationMapRotate() {
 	towerRotationMapDrawLine(center, end);
 }
 
-void Myst::o_forechamberDoor_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_forechamberDoor_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used for Card 4138 (Dock Forechamber Door)
 	// Set forechamber door to closed
 	_tempVar = 0;
 }
 
-void Myst::o_shipAccess_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_shipAccess_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Enable acces to the ship
 	if (_state.shipFloating) {
 		getInvokingResource<MystArea>()->setEnabled(true);
 	}
 }
 
-void Myst::o_butterflies_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_butterflies_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Butterflies movie init", op);
 
 	// Used for Card 4256 (Butterfly Movie Activation)
@@ -3323,7 +3323,7 @@ void Myst::o_butterflies_init(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	}
 }
 
-void Myst::o_imager_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_imager_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Imager init", op);
 	debugC(kDebugScript, "Var: %d", var);
 
@@ -3369,11 +3369,11 @@ void Myst::libraryBookcaseTransform_run(void) {
 	}
 }
 
-void Myst::o_libraryBookcaseTransform_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_libraryBookcaseTransform_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	if (_libraryBookcaseChanged) {
 		MystAreaActionSwitch *resource = getInvokingResource<MystAreaActionSwitch>();
 		_libraryBookcaseMovie = static_cast<MystAreaVideo *>(resource->getSubResource(getVar(0)));
-		_libraryBookcaseSoundId = argv[0];
+		_libraryBookcaseSoundId = args[0];
 		_libraryBookcaseMoving = true;
 	}
 }
@@ -3395,14 +3395,14 @@ void Myst::generatorControlRoom_run(void) {
 	}
 }
 
-void Myst::o_generatorControlRoom_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_generatorControlRoom_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generator control room init", op);
 
 	_generatorVoltage = _state.generatorVoltage;
 	_generatorControlRoomRunning = true;
 }
 
-void Myst::o_fireplace_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_fireplace_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fireplace grid init", op);
 
 	// Clear fireplace grid
@@ -3410,7 +3410,7 @@ void Myst::o_fireplace_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 		_fireplaceLines[i] = 0;
 }
 
-void Myst::o_clockGears_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_clockGears_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used for Card 4113 (Clock Tower Cog Puzzle)
 	debugC(kDebugScript, "Opcode %d: Gears puzzle init", op);
 
@@ -3428,7 +3428,7 @@ void Myst::o_clockGears_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	}
 }
 
-void Myst::o_gulls1_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_gulls1_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Gulls init", op);
 
 	if (!_state.shipFloating) {
@@ -3460,22 +3460,22 @@ void Myst::gullsFly1_run() {
 	}
 }
 
-void Myst::o_observatory_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_observatory_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Stellar observatory init", op);
 
 	_tempVar = 0;
 	_observatoryNotInitialized = true;
 	_observatoryVisualizer = getInvokingResource<MystAreaImageSwitch>();
-	_observatoryGoButton = _vm->getViewResource<MystAreaImageSwitch>(argv[0]);
+	_observatoryGoButton = _vm->getViewResource<MystAreaImageSwitch>(args[0]);
 	if (observatoryIsDDMMYYYY2400()) {
-		_observatoryDaySlider = _vm->getViewResource<MystAreaSlider>(argv[1]);
-		_observatoryMonthSlider = _vm->getViewResource<MystAreaSlider>(argv[2]);
+		_observatoryDaySlider = _vm->getViewResource<MystAreaSlider>(args[1]);
+		_observatoryMonthSlider = _vm->getViewResource<MystAreaSlider>(args[2]);
 	} else {
-		_observatoryMonthSlider = _vm->getViewResource<MystAreaSlider>(argv[1]);
-		_observatoryDaySlider = _vm->getViewResource<MystAreaSlider>(argv[2]);
+		_observatoryMonthSlider = _vm->getViewResource<MystAreaSlider>(args[1]);
+		_observatoryDaySlider = _vm->getViewResource<MystAreaSlider>(args[2]);
 	}
-	_observatoryYearSlider = _vm->getViewResource<MystAreaSlider>(argv[3]);
-	_observatoryTimeSlider = _vm->getViewResource<MystAreaSlider>(argv[4]);
+	_observatoryYearSlider = _vm->getViewResource<MystAreaSlider>(args[3]);
+	_observatoryTimeSlider = _vm->getViewResource<MystAreaSlider>(args[4]);
 
 	// Set date selection sliders position
 	_observatoryDaySlider->setPosition(_state.observatoryDaySlider);
@@ -3579,7 +3579,7 @@ void Myst::observatory_run() {
 	}
 }
 
-void Myst::o_gulls2_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_gulls2_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Gulls init", op);
 
 	if (!_state.shipFloating) {
@@ -3605,23 +3605,23 @@ void Myst::gullsFly2_run() {
 	}
 }
 
-void Myst::o_treeCard_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_treeCard_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Enter tree card", op);
 
 	_tree = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Myst::o_treeEntry_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_treeEntry_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Enter tree card with entry", op);
 
 	_treeAlcove = getInvokingResource<MystArea>();
-	_treeMinAccessiblePosition = argv[0];
-	_treeMaxAccessiblePosition = argv[1];
+	_treeMinAccessiblePosition = args[0];
+	_treeMaxAccessiblePosition = args[1];
 
 	treeSetAlcoveAccessible();
 }
 
-void Myst::o_boilerMovies_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_boilerMovies_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Boiler movies init", op);
 
 	boilerFireInit();
@@ -3697,14 +3697,14 @@ void Myst::boilerGaugeInit() {
 	_cabinGaugeMovieEnabled = true;
 }
 
-void Myst::o_rocketSliders_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketSliders_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket sliders init", op);
 
-	_rocketSlider1 = _vm->getViewResource<MystAreaSlider>(argv[0]);
-	_rocketSlider2 = _vm->getViewResource<MystAreaSlider>(argv[1]);
-	_rocketSlider3 = _vm->getViewResource<MystAreaSlider>(argv[2]);
-	_rocketSlider4 = _vm->getViewResource<MystAreaSlider>(argv[3]);
-	_rocketSlider5 = _vm->getViewResource<MystAreaSlider>(argv[4]);
+	_rocketSlider1 = _vm->getViewResource<MystAreaSlider>(args[0]);
+	_rocketSlider2 = _vm->getViewResource<MystAreaSlider>(args[1]);
+	_rocketSlider3 = _vm->getViewResource<MystAreaSlider>(args[2]);
+	_rocketSlider4 = _vm->getViewResource<MystAreaSlider>(args[3]);
+	_rocketSlider5 = _vm->getViewResource<MystAreaSlider>(args[4]);
 
 	// Initialize sliders position
 	for (uint i = 0; i < 5; i++)
@@ -3718,12 +3718,12 @@ void Myst::o_rocketSliders_init(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	_rocketSlider5->setPosition(_state.rocketSliderPosition[4]);
 }
 
-void Myst::o_rocketLinkVideo_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_rocketLinkVideo_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Rocket link video init", op);
 	_tempVar = 0;
 }
 
-void Myst::o_greenBook_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_greenBook_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used for Card 4168 (Green Book Movies)
 	debugC(kDebugScript, "Opcode %d: Green book init", op);
 
@@ -3775,7 +3775,7 @@ void Myst::greenBook_run() {
 	}
 }
 
-void Myst::o_gulls3_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_gulls3_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Gulls init", op);
 
 	if (!_state.shipFloating) {
@@ -3803,7 +3803,7 @@ void Myst::gullsFly3_run() {
 	}
 }
 
-void Myst::o_bookAddSpecialPage_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_bookAddSpecialPage_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Book Exit Function", op);
 
 	uint16 numPages = bookCountPages(var);
@@ -3817,19 +3817,19 @@ void Myst::o_bookAddSpecialPage_exit(uint16 op, uint16 var, uint16 argc, uint16
 	}
 }
 
-void Myst::o_treeCard_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_treeCard_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Exit tree card", op);
 
 	_tree = nullptr;
 }
 
-void Myst::o_treeEntry_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_treeEntry_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Exit tree card with entry", op);
 
 	_treeAlcove = nullptr;
 }
 
-void Myst::o_boiler_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_boiler_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Exit boiler card", op);
 
 	_cabinGaugeMovie = VideoEntryPtr();
@@ -3838,7 +3838,7 @@ void Myst::o_boiler_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_cabinGaugeMovieEnabled = false;
 }
 
-void Myst::o_generatorControlRoom_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Myst::o_generatorControlRoom_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generator room exit", op);
 
 	_generatorVoltage = _state.generatorVoltage;
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index 870daa8..f3c9087 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Myst : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index 3a2524d..db657e5 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -79,18 +79,18 @@ void Preview::runPersistentScripts() {
 		speech_run();
 }
 
-void Preview::o_fadeToBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Preview::o_fadeToBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fade to black", op);
 	_vm->_gfx->fadeToBlack();
 }
 
-void Preview::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Preview::o_fadeFromBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Fade from black", op);
 
 	_vm->_gfx->fadeFromBlack();
 }
 
-void Preview::o_stayHere(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Preview::o_stayHere(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Stay here dialog", op);
 
 	// Nuh-uh! No leaving the library in the demo!
@@ -98,7 +98,7 @@ void Preview::o_stayHere(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	dialog.runModal();
 }
 
-void Preview::o_speechStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Preview::o_speechStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Speech stop", op);
 
 	_vm->_sound->stopSpeech();
@@ -225,7 +225,7 @@ void Preview::speech_run() {
 	}
 }
 
-void Preview::o_speech_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Preview::o_speech_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Speech init", op);
 
 	// Used for Card 3000 (Closed Myst Book)
@@ -233,18 +233,18 @@ void Preview::o_speech_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_speechRunning = true;
 }
 
-void Preview::o_library_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Preview::o_library_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Library init", op);
 
 	// Used for Card 3002 (Myst Island Overview)
 	_library = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Preview::o_libraryBookcaseTransformDemo_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Preview::o_libraryBookcaseTransformDemo_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	if (_libraryBookcaseChanged) {
 		MystAreaActionSwitch *resource = getInvokingResource<MystAreaActionSwitch>();
 		_libraryBookcaseMovie = static_cast<MystAreaVideo *>(resource->getSubResource(getVar(303)));
-		_libraryBookcaseSoundId = argv[0];
+		_libraryBookcaseSoundId = args[0];
 		_libraryBookcaseMoving = true;
 	}
 }
diff --git a/engines/mohawk/myst_stacks/preview.h b/engines/mohawk/myst_stacks/preview.h
index 7a818a1..dbbd6c2 100644
--- a/engines/mohawk/myst_stacks/preview.h
+++ b/engines/mohawk/myst_stacks/preview.h
@@ -35,7 +35,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Preview : public Myst {
 public:
diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 774efcd..fe1a64a 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -285,7 +285,7 @@ bool Selenitic::setVarValue(uint16 var, uint16 value) {
 	return refresh;
 }
 
-void Selenitic::o_mazeRunnerMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	uint16 oldPosition = _mazeRunnerPosition;
 	uint16 move = var;
 
@@ -566,14 +566,14 @@ void Selenitic::mazeRunnerPlaySoundHelp() {
 	_mazeRunnerLight->drawConditionalDataToScreen(0);
 }
 
-void Selenitic::o_mazeRunnerSoundRepeat(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerSoundRepeat(uint16 op, uint16 var, const ArgumentsArray &args) {
 	mazeRunnerPlaySoundHelp();
 }
 
 /**
  * Sound receiver sigma button
  */
-void Selenitic::o_soundReceiverSigma(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundReceiverSigma(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound receiver sigma button", op);
 
 	_vm->_cursor->hideCursor();
@@ -625,7 +625,7 @@ void Selenitic::o_soundReceiverSigma(uint16 op, uint16 var, uint16 argc, uint16
 /**
  * Sound receiver right button
  */
-void Selenitic::o_soundReceiverRight(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundReceiverRight(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound receiver right", op);
 
 	soundReceiverLeftRight(1);
@@ -634,7 +634,7 @@ void Selenitic::o_soundReceiverRight(uint16 op, uint16 var, uint16 argc, uint16
 /**
  * Sound receiver left button
  */
-void Selenitic::o_soundReceiverLeft(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundReceiverLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound receiver left", op);
 
 	soundReceiverLeftRight(2);
@@ -697,7 +697,7 @@ void Selenitic::soundReceiverDrawAngle() {
 /**
  * Sound receiver source selection buttons
  */
-void Selenitic::o_soundReceiverSource(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundReceiverSource(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound receiver source", op);
 
 	if (_soundReceiverSigmaPressed) {
@@ -719,7 +719,7 @@ void Selenitic::o_soundReceiverSource(uint16 op, uint16 var, uint16 argc, uint16
 
 		_vm->_sound->stopEffect();
 
-		uint16 soundId = argv[0];
+		uint16 soundId = args[0];
 		_vm->_sound->stopBackground();
 		_vm->_sound->playEffect(soundId);
 
@@ -731,23 +731,24 @@ void Selenitic::o_soundReceiverSource(uint16 op, uint16 var, uint16 argc, uint16
 	_vm->_cursor->showCursor();
 }
 
-void Selenitic::o_mazeRunnerDoorButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerDoorButton(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used for Selenitic Maze Runner Exit Logic
-	uint16 cardIdExit = argv[0];
-	uint16 cardIdEntry = argv[1];
+	uint16 cardIdExit = args[0];
+	uint16 cardIdEntry = args[1];
+	uint16 updateDataSize = args[2];
 
 	if (_mazeRunnerPosition == 288) {
 		_vm->changeToCard(cardIdEntry, kNoTransition);
 		_vm->_sound->playEffect(cardIdEntry);
-		animatedUpdate(argv[2], &argv[3], 10);
+		animatedUpdate(ArgumentsArray(args.begin() + 3, updateDataSize), 10);
 	} else if (_mazeRunnerPosition == 289) {
 		_vm->changeToCard(cardIdExit, kNoTransition);
 		_vm->_sound->playEffect(cardIdExit);
-		animatedUpdate(argv[2], &argv[3], 10);
+		animatedUpdate(ArgumentsArray(args.begin() + 3, updateDataSize), 10);
 	}
 }
 
-void Selenitic::o_soundReceiverUpdateSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundReceiverUpdateSound(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound receiver update sound", op);
 
 	soundReceiverUpdateSound();
@@ -795,7 +796,7 @@ MystAreaSlider *Selenitic::soundLockSliderFromVar(uint16 var) {
 	return nullptr;
 }
 
-void Selenitic::o_soundLockMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundLockMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound lock move", op);
 
 	MystAreaSlider *slider = soundLockSliderFromVar(var);
@@ -807,7 +808,7 @@ void Selenitic::o_soundLockMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	}
 }
 
-void Selenitic::o_soundLockStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundLockStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound lock start move", op);
 
 	MystAreaSlider *slider = soundLockSliderFromVar(var);
@@ -819,7 +820,7 @@ void Selenitic::o_soundLockStartMove(uint16 op, uint16 var, uint16 argc, uint16
 	_vm->_sound->playEffect(_soundLockSoundId, true);
 }
 
-void Selenitic::o_soundLockEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundLockEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound lock end move", op);
 
 	MystAreaSlider *slider = soundLockSliderFromVar(var);
@@ -878,7 +879,7 @@ void Selenitic::soundLockCheckSolution(MystAreaSlider *slider, uint16 value, uin
 	_vm->_sound->stopEffect();
 }
 
-void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundLockButton(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound lock button", op);
 
 	bool solved = true;
@@ -900,15 +901,18 @@ void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	if (solved) {
 		_soundLockButton->drawConditionalDataToScreen(2);
 
-		uint16 cardIdClosed = argv[0];
-		uint16 cardIdOpen = argv[1];
+		uint16 cardIdClosed = args[0];
+		uint16 cardIdOpen = args[1];
 
 		_vm->changeToCard(cardIdClosed, kTransitionDissolve);
 
 		_vm->changeToCard(cardIdOpen, kNoTransition);
-		_vm->_sound->playEffect(argv[2]);
+		_vm->_sound->playEffect(args[2]);
 
-		animatedUpdate(argv[4], &argv[5], argv[3]);
+		uint16 animationDelay = args[3];
+		uint16 animationDataSize = args[4];
+
+		animatedUpdate(ArgumentsArray(args.begin() + 5, animationDataSize), animationDelay);
 	} else {
 		_soundLockButton->drawConditionalDataToScreen(0);
 	}
@@ -916,7 +920,7 @@ void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	_vm->_cursor->showCursor();
 }
 
-void Selenitic::o_soundReceiverEndMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundReceiverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound receiver end move", op);
 
 	uint16 oldDirection = _soundReceiverDirection;
@@ -933,15 +937,15 @@ void Selenitic::o_soundReceiverEndMove(uint16 op, uint16 var, uint16 argc, uint1
 	}
 }
 
-void Selenitic::o_mazeRunnerCompass_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerCompass_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerCompass = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Selenitic::o_mazeRunnerWindow_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerWindow_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerWindow = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Selenitic::o_mazeRunnerLight_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerLight_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerLight = getInvokingResource<MystAreaImageSwitch>();
 }
 
@@ -1061,7 +1065,7 @@ void Selenitic::soundReceiverSolution(uint16 source, uint16 &solution, bool &ena
 	}
 }
 
-void Selenitic::o_soundReceiver_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundReceiver_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound receiver init", op);
 
 	// Used for Card 1245 (Sound Receiver)
@@ -1090,7 +1094,7 @@ void Selenitic::o_soundReceiver_init(uint16 op, uint16 var, uint16 argc, uint16
 	_soundReceiverSigmaPressed = false;
 }
 
-void Selenitic::o_soundLock_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_soundLock_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Sound lock init", op);
 
 	for (uint i = 0; i < _vm->_resources.size(); i++) {
@@ -1125,11 +1129,11 @@ void Selenitic::o_soundLock_init(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	_soundLockSoundId = 0;
 }
 
-void Selenitic::o_mazeRunnerRight_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerRight_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerRightButton = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Selenitic::o_mazeRunnerLeft_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Selenitic::o_mazeRunnerLeft_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerLeftButton = getInvokingResource<MystAreaImageSwitch>();
 }
 
diff --git a/engines/mohawk/myst_stacks/selenitic.h b/engines/mohawk/myst_stacks/selenitic.h
index fc96497..706bee5 100644
--- a/engines/mohawk/myst_stacks/selenitic.h
+++ b/engines/mohawk/myst_stacks/selenitic.h
@@ -34,7 +34,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Selenitic : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp
index 0560608..851ce84 100644
--- a/engines/mohawk/myst_stacks/slides.cpp
+++ b/engines/mohawk/myst_stacks/slides.cpp
@@ -68,15 +68,15 @@ void Slides::runPersistentScripts() {
 	}
 }
 
-void Slides::o_returnToMenu(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Slides::o_returnToMenu(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Return to menu", op);
 
 	// Go to the information screens of the menu
 	_vm->changeToStack(kDemoStack, 2002, 0, 0);
 }
 
-void Slides::o_setCardSwap(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	_nextCardID = argv[0];
+void Slides::o_setCardSwap(uint16 op, uint16 var, const ArgumentsArray &args) {
+	_nextCardID = args[0];
 
 	debugC(kDebugScript, "Opcode %d: Set next card %d", op, _nextCardID);
 
diff --git a/engines/mohawk/myst_stacks/slides.h b/engines/mohawk/myst_stacks/slides.h
index a0c9ae5..6215447 100644
--- a/engines/mohawk/myst_stacks/slides.h
+++ b/engines/mohawk/myst_stacks/slides.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Slides : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 706bd72..6196618 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -383,7 +383,7 @@ bool Stoneship::setVarValue(uint16 var, uint16 value) {
 	return refresh;
 }
 
-void Stoneship::o_pumpTurnOff(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_pumpTurnOff(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Turn off previous pump selection", op);
 
 	if (_state.pumpState) {
@@ -413,19 +413,19 @@ void Stoneship::o_pumpTurnOff(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	}
 }
 
-void Stoneship::o_brotherDoorOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_brotherDoorOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Open brother door", op);
 
 	_brotherDoorOpen = 1;
 	_vm->redrawArea(19, 0);
-	animatedUpdate(argc, argv, 5);
+	animatedUpdate(args, 5);
 }
 
-void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Play Book Room Movie", op);
 
-	uint16 startTime = argv[0];
-	uint16 endTime = argv[1];
+	uint16 startTime = args[0];
+	uint16 endTime = args[1];
 
 	VideoEntryPtr book = _vm->_video->playMovie(_vm->wrapMovieFilename("bkroom", kStoneshipStack));
 	if (!book)
@@ -436,10 +436,10 @@ void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, uint16 argc, uint16 *arg
 	_vm->waitUntilMovieEnds(book);
 }
 
-void Stoneship::o_drawerOpenSirius(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_drawerOpenSirius(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Open drawer", op);
 
-	MystAreaImageSwitch *drawer = _vm->getViewResource<MystAreaImageSwitch>(argv[0]);
+	MystAreaImageSwitch *drawer = _vm->getViewResource<MystAreaImageSwitch>(args[0]);
 
 	if (drawer->getImageSwitchVar() == 35) {
 		drawer->drawConditionalDataToScreen(getVar(102), 0);
@@ -448,24 +448,24 @@ void Stoneship::o_drawerOpenSirius(uint16 op, uint16 var, uint16 argc, uint16 *a
 	}
 
 	TransitionType transition = kTransitionTopToBottom;
-	if (argc == 2 && argv[1])
+	if (args.size() == 2 && args[1])
 		transition = kTransitionCopy;
 
 	_vm->_gfx->runTransition(transition, drawer->getRect(), 25, 5);
 }
 
-void Stoneship::o_drawerClose(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_drawerClose(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Close drawer", op);
-	drawerClose(argv[0]);
+	drawerClose(args[0]);
 }
 
-void Stoneship::o_telescopeStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_telescopeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	_telescopeOldMouse = mouse.x;
 	_vm->_cursor->setCursor(700);
 }
 
-void Stoneship::o_telescopeMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_telescopeMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Telescope move", op);
 
 	MystAreaDrag *display = getInvokingResource<MystAreaDrag>();
@@ -483,11 +483,11 @@ void Stoneship::o_telescopeMove(uint16 op, uint16 var, uint16 argc, uint16 *argv
     telescopeLighthouseDraw();
 }
 
-void Stoneship::o_telescopeStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_telescopeStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 }
 
-void Stoneship::o_generatorStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_generatorStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generator start", op);
 
 	MystAreaDrag *handle = getInvokingResource<MystAreaDrag>();
@@ -513,7 +513,7 @@ void Stoneship::o_generatorStart(uint16 op, uint16 var, uint16 argc, uint16 *arg
 		_vm->_sound->playEffect(soundId, true);
 }
 
-void Stoneship::o_generatorStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_generatorStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Generator stop", op);
 
 	_batteryCharging = false;
@@ -580,21 +580,21 @@ void Stoneship::batteryDeplete_run() {
 	}
 }
 
-void Stoneship::o_drawerOpenAchenar(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_drawerOpenAchenar(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Open drawer", op);
 
-	MystAreaImageSwitch *drawer = _vm->getViewResource<MystAreaImageSwitch>(argv[0]);
+	MystAreaImageSwitch *drawer = _vm->getViewResource<MystAreaImageSwitch>(args[0]);
 	drawer->drawConditionalDataToScreen(0, 0);
 	_vm->_gfx->runTransition(kTransitionTopToBottom, drawer->getRect(), 25, 5);
 }
 
-void Stoneship::o_hologramPlayback(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_hologramPlayback(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used for Card 2013 (Achenar's Rose-Skull Hologram)
 	debugC(kDebugScript, "Opcode %d: Rose-Skull Hologram Playback", op);
 
-	uint16 startPoint = argv[0];
-	uint16 endPoint = argv[1];
-	// uint16 direction = argv[2];
+	uint16 startPoint = args[0];
+	uint16 endPoint = args[1];
+	// uint16 direction = args[2];
 
 	_hologramDisplay->setBlocking(false);
 	VideoEntryPtr displayMovie = _hologramDisplay->playMovie();
@@ -610,12 +610,12 @@ void Stoneship::o_hologramPlayback(uint16 op, uint16 var, uint16 argc, uint16 *a
 	_vm->waitUntilMovieEnds(displayMovie);
 }
 
-void Stoneship::o_hologramSelectionStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_hologramSelectionStart(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hologram start move", op);
 	//_vm->_cursor->setCursor(0);
 }
 
-void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hologram move", op);
 
 	MystAreaDrag *handle = getInvokingResource<MystAreaDrag>();
@@ -642,16 +642,16 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, uint16 argc, uint
 	}
 }
 
-void Stoneship::o_hologramSelectionStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_hologramSelectionStop(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hologram stop move", op);
 	_vm->checkCursorHints();
 }
 
-void Stoneship::o_compassButton(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_compassButton(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Compass rose button pressed", op);
 	// Used on Card 2111 (Compass Rose)
 	// Called when Button Clicked.
-	uint16 correctButton = argv[0];
+	uint16 correctButton = args[0];
 
 	if (correctButton) {
 		// Correct Button -> Light On Logic
@@ -666,10 +666,10 @@ void Stoneship::o_compassButton(uint16 op, uint16 var, uint16 argc, uint16 *argv
 		_batteryDepleting = false;
 	}
 
-	o_redrawCard(op, var, argc, argv);
+	o_redrawCard(op, var, args);
 }
 
-void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_chestValveVideos(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Chest valve videos", op);
 
 	Common::String movie = _vm->wrapMovieFilename("ligspig", kStoneshipStack);
@@ -721,7 +721,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 	}
 }
 
-void Stoneship::o_chestDropKey(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_chestDropKey(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: drop chest key", op);
 
 	// If holding Key to Lamp Room Trapdoor, drop to bottom of
@@ -732,7 +732,7 @@ void Stoneship::o_chestDropKey(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	}
 }
 
-void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_trapLockOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Trap lock open video", op);
 
 	Common::String movie = _vm->wrapMovieFilename("openloc", kStoneshipStack);
@@ -759,9 +759,9 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		_vm->_sound->playEffect(4143);
 }
 
-void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used for Cards 2285, 2289, 2247, 2251 (Side Doors in Tunnels Down To Brothers Rooms)
-	uint16 movieId = argv[0];
+	uint16 movieId = args[0];
 
 	debugC(kDebugScript, "Opcode %d: Play Side Door Movies", op);
 	debugC(kDebugScript, "\tmovieId: %d", movieId);
@@ -795,14 +795,14 @@ void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	_vm->_cursor->showCursor();
 }
 
-void Stoneship::o_cloudOrbEnter(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_cloudOrbEnter(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Cloud orb enter", op);
 
 	_vm->_sound->playEffect(_cloudOrbSound, true);
 	_cloudOrbMovie->playMovie();
 }
 
-void Stoneship::o_cloudOrbLeave(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_cloudOrbLeave(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Cloud orb leave", op);
 
 	_cloudOrbMovie->pauseMovie(true);
@@ -810,12 +810,12 @@ void Stoneship::o_cloudOrbLeave(uint16 op, uint16 var, uint16 argc, uint16 *argv
 	_vm->_gfx->runTransition(kTransitionTopToBottom, getInvokingResource<MystArea>()->getRect(), 4, 0);
 }
 
-void Stoneship::o_drawerCloseOpened(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_drawerCloseOpened(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Close open drawer", op);
 
 	uint16 drawerOpen = getVar(var);
 	if (drawerOpen)
-		drawerClose(argv[0] + drawerOpen - 1);
+		drawerClose(args[0] + drawerOpen - 1);
 }
 
 void Stoneship::drawerClose(uint16 drawer) {
@@ -827,14 +827,14 @@ void Stoneship::drawerClose(uint16 drawer) {
 	_vm->_gfx->runTransition(kTransitionBottomToTop, res->getRect(), 25, 5);
 }
 
-void Stoneship::o_hologramDisplay_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_hologramDisplay_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hologram display init", op);
 	_hologramDisplay = getInvokingResource<MystAreaVideo>();
 
 	_hologramDisplayPos = 0;
 }
 
-void Stoneship::o_hologramSelection_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_hologramSelection_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Hologram selection init", op);
 	_hologramSelection = getInvokingResource<MystAreaVideo>();
 }
@@ -853,7 +853,7 @@ void Stoneship::batteryGaugeUpdate() {
 	_batteryGauge->setRect(rect);
 }
 
-void Stoneship::o_battery_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_battery_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	// Used for Card 2160 (Lighthouse Battery Pack Closeup)
 	debugC(kDebugScript, "Opcode %d: Battery init", op);
 
@@ -862,16 +862,16 @@ void Stoneship::o_battery_init(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 	batteryGaugeUpdate();
 }
 
-void Stoneship::o_tunnelEnter_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_tunnelEnter_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Tunnel enter", op);
 
-	o_tunnel_init(op, var, argc, argv);
+	o_tunnel_init(op, var, args);
 
 	_tunnelRunning = true;
 	_tunnelNextTime = _vm->_system->getMillis() + 1500;
 }
 
-void Stoneship::o_batteryGauge_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_batteryGauge_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Battery gauge init", op);
 	_batteryLastCharge = batteryRemainingCharge();
 	_batteryGaugeRunning = true;
@@ -892,18 +892,18 @@ void Stoneship::batteryGauge_run() {
 	}
 }
 
-void Stoneship::o_tunnel_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_tunnel_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 		debugC(kDebugScript, "Opcode %d: Tunnel card init", op);
 
-		_tunnelImagesCount = argv[0];
+		_tunnelImagesCount = args[0];
 
 		assert(_tunnelImagesCount <= 2 && "Too many images");
 
 		for (uint i = 0; i < _tunnelImagesCount; i++) {
-			_tunnelImages[i] = argv[i + 1];
+			_tunnelImages[i] = args[i + 1];
 		}
 
-		_tunnelAlarmSound = argv[argc - 1];
+		_tunnelAlarmSound = args[args.size() - 1];
 
 		debugC(kDebugScript, "\timage count: %d", _tunnelImagesCount);
 		debugC(kDebugScript, "\tsoundIdAlarm: %d", _tunnelAlarmSound);
@@ -930,25 +930,25 @@ void Stoneship::tunnel_run() {
 	}
 }
 
-void Stoneship::o_tunnelLeave_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_tunnelLeave_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Tunnel leave", op);
 
 	_tunnelRunning = false;
 }
 
-void Stoneship::o_chest_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_chest_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Chest init", op);
 
 	_state.chestOpenState = 0;
 }
 
-void Stoneship::o_telescope_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_telescope_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Telescope init", op);
 
 	// Used in Card 2218 (Telescope view)
-	_telescopePanorama = argv[0];
-	_telescopeLighthouseOff = argv[1];
-	_telescopeLighthouseOn = argv[2];
+	_telescopePanorama = args[0];
+	_telescopeLighthouseOff = args[1];
+	_telescopeLighthouseOn = args[2];
 	_telescopePosition = 0;
 
 	_telescopeRunning = true;
@@ -990,30 +990,30 @@ void Stoneship::telescopeLighthouseDraw() {
 	}
 }
 
-void Stoneship::o_achenarDrawers_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_achenarDrawers_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Achenar's Room Drawers Init", op);
 
 	// Used for Card 2004 (Achenar's Room Drawers)
 	if (!_chestAchenarBottomDrawerClosed) {
-		uint16 count1 = argv[0];
+		uint16 count1 = args[0];
 		for (uint16 i = 0; i < count1; i++) {
-			debugC(kDebugScript, "Disable hotspot index %d", argv[i + 1]);
-			_vm->setResourceEnabled(argv[i + 1], false);
+			debugC(kDebugScript, "Disable hotspot index %d", args[i + 1]);
+			_vm->setResourceEnabled(args[i + 1], false);
 		}
-		uint16 count2 = argv[count1 + 1];
+		uint16 count2 = args[count1 + 1];
 		for (uint16 i = 0; i < count2; i++) {
-			debugC(kDebugScript, "Enable hotspot index %d", argv[i + count1 + 2]);
-			_vm->setResourceEnabled(argv[i + count1 + 2], true);
+			debugC(kDebugScript, "Enable hotspot index %d", args[i + count1 + 2]);
+			_vm->setResourceEnabled(args[i + count1 + 2], true);
 		}
 	}
 }
 
-void Stoneship::o_cloudOrb_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+void Stoneship::o_cloudOrb_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	debugC(kDebugScript, "Opcode %d: Cloud orb init", op);
 
 	_cloudOrbMovie = getInvokingResource<MystAreaVideo>();
-	_cloudOrbSound = argv[0];
-	_cloudOrbStopSound = argv[1];
+	_cloudOrbSound = args[0];
+	_cloudOrbStopSound = args[1];
 }
 
 } // End of namespace MystStacks
diff --git a/engines/mohawk/myst_stacks/stoneship.h b/engines/mohawk/myst_stacks/stoneship.h
index 776641a..b98c410 100644
--- a/engines/mohawk/myst_stacks/stoneship.h
+++ b/engines/mohawk/myst_stacks/stoneship.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
+#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
 
 class Stoneship : public MystScriptParser {
 public:


Commit: a99397f12667657d2c360695d7243f8541c1cdf3
    https://github.com/scummvm/scummvm/commit/a99397f12667657d2c360695d7243f8541c1cdf3
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Improve script execution tracing

Changed paths:
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_scripts.h
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/channelwood.h
    engines/mohawk/myst_stacks/credits.cpp
    engines/mohawk/myst_stacks/credits.h
    engines/mohawk/myst_stacks/demo.cpp
    engines/mohawk/myst_stacks/demo.h
    engines/mohawk/myst_stacks/dni.cpp
    engines/mohawk/myst_stacks/dni.h
    engines/mohawk/myst_stacks/intro.cpp
    engines/mohawk/myst_stacks/intro.h
    engines/mohawk/myst_stacks/makingof.h
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/mechanical.h
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/myst.h
    engines/mohawk/myst_stacks/preview.cpp
    engines/mohawk/myst_stacks/preview.h
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/myst_stacks/selenitic.h
    engines/mohawk/myst_stacks/slides.cpp
    engines/mohawk/myst_stacks/slides.h
    engines/mohawk/myst_stacks/stoneship.cpp
    engines/mohawk/myst_stacks/stoneship.h


diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index f3caee6..ce742f3 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -28,6 +28,7 @@
 #include "mohawk/myst_sound.h"
 #include "mohawk/video.h"
 
+#include "common/debug-channels.h"
 #include "common/system.h"
 #include "common/memstream.h"
 #include "common/textconsole.h"
@@ -100,8 +101,8 @@ void MystScriptParser::setupCommonOpcodes() {
 	OPCODE(4, o_redrawCard);
 	// Opcode 5 Not Present
 	OPCODE(6, o_goToDestForward);
-	OPCODE(7, o_goToDestLeft);
-	OPCODE(8, o_goToDestRight);
+	OPCODE(7, o_goToDestRight);
+	OPCODE(8, o_goToDestLeft);
 	OPCODE(9, o_triggerMovie);
 	OPCODE(10, o_toggleVarNoRedraw);
 	// Opcode 11 Not Present
@@ -150,13 +151,10 @@ void MystScriptParser::setupCommonOpcodes() {
 #undef OPCODE
 
 void MystScriptParser::runScript(MystScript script, MystArea *invokingResource) {
-	debugC(kDebugScript, "Script Size: %d", script->size());
-
 	_scriptNestingLevel++;
 
 	for (uint16 i = 0; i < script->size(); i++) {
 		MystScriptEntry &entry = (*script)[i];
-		debugC(kDebugScript, "\tOpcode %d: %d", i, entry.opcode);
 
 		if (entry.type == kMystScriptNormal)
 			_invokingResource = invokingResource;
@@ -175,7 +173,11 @@ void MystScriptParser::runOpcode(uint16 op, uint16 var, const ArgumentsArray &ar
 	bool ranOpcode = false;
 	for (uint16 i = 0; i < _opcodes.size(); i++)
 		if (_opcodes[i]->op == op) {
-			(this->*(_opcodes[i]->proc)) (op, var, args);
+			if (DebugMan.isDebugChannelEnabled(kDebugScript)) {
+				debugC(kDebugScript, "Running command: %s", describeCommand(*_opcodes[i], var, args).c_str());
+			}
+
+			(this->*(_opcodes[i]->proc)) (var, args);
 			ranOpcode = true;
 			break;
 		}
@@ -198,6 +200,22 @@ const Common::String MystScriptParser::getOpcodeDesc(uint16 op) {
 	return Common::String::format("%d", op);
 }
 
+Common::String MystScriptParser::describeCommand(const MystOpcode &command, uint16 var, const ArgumentsArray &args) {
+	Common::String desc = Common::String::format("%s(", command.desc);
+
+	if (var != 0) {
+		desc += Common::String::format("var = %d%s", var, args.size() != 0 ? ", " : "");
+	}
+
+	for (uint16 j = 0; j < args.size(); j++) {
+		desc += Common::String::format("%d", args[j]);
+		if (j != args.size() - 1)
+			desc += ", ";
+	}
+	desc += ")";
+	return desc;
+}
+
 MystScript MystScriptParser::readScript(Common::SeekableReadStream *stream, MystScriptType type) {
 	assert(stream);
 	assert(type != kMystScriptNone);
@@ -280,44 +298,22 @@ void MystScriptParser::animatedUpdate(const ArgumentsArray &args, uint16 delay)
 	}
 }
 
-void MystScriptParser::unknown(uint16 op, uint16 var, const ArgumentsArray &args) {
-	warning("Unimplemented opcode 0x%02x (%d)", op, op);
-	warning("\tUses var %d", var);
-	warning("\tArg count = %d", args.size());
-
-	if (!args.empty()) {
-		Common::String str;
-		str += Common::String::format("%d", args[0]);
-
-		for (uint16 i = 1; i < args.size(); i++)
-			str += Common::String::format(", %d", args[i]);
-
-		warning("\tArgs: %s\n", str.c_str());
-	}
+void MystScriptParser::NOP(uint16 var, const ArgumentsArray &args) {
 }
 
-void MystScriptParser::NOP(uint16 op, uint16 var, const ArgumentsArray &args) {
-}
-
-void MystScriptParser::o_toggleVar(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Toggle var %d", op, var);
-
+void MystScriptParser::o_toggleVar(uint16 var, const ArgumentsArray &args) {
 	toggleVar(var);
 	_vm->redrawArea(var);
 }
 
-void MystScriptParser::o_setVar(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Set var %d: %d", op, var, args[0]);
-
+void MystScriptParser::o_setVar(uint16 var, const ArgumentsArray &args) {
 	if (setVarValue(var, args[0]))
 		_vm->redrawArea(var);
 }
 
-void MystScriptParser::o_changeCardSwitch4(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_changeCardSwitch4(uint16 var, const ArgumentsArray &args) {
 	uint16 value = getVar(var);
 
-	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
-
 	if (value)
 		_vm->changeToCard(args[value -1 ], kTransitionDissolve);
 	else if (_invokingResource != nullptr)
@@ -326,11 +322,9 @@ void MystScriptParser::o_changeCardSwitch4(uint16 op, uint16 var, const Argument
 		warning("Missing invokingResource in altDest call");
 }
 
-void MystScriptParser::o_changeCardSwitchLtR(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_changeCardSwitchLtR(uint16 var, const ArgumentsArray &args) {
 	uint16 value = getVar(var);
 
-	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
-
 	if (value)
 		_vm->changeToCard(args[value -1 ], kTransitionLeftToRight);
 	else if (_invokingResource != nullptr)
@@ -339,11 +333,9 @@ void MystScriptParser::o_changeCardSwitchLtR(uint16 op, uint16 var, const Argume
 		warning("Missing invokingResource in altDest call");
 }
 
-void MystScriptParser::o_changeCardSwitchRtL(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_changeCardSwitchRtL(uint16 var, const ArgumentsArray &args) {
 	uint16 value = getVar(var);
 
-	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
-
 	if (value)
 		_vm->changeToCard(args[value -1 ], kTransitionRightToLeft);
 	else if (_invokingResource != nullptr)
@@ -352,7 +344,7 @@ void MystScriptParser::o_changeCardSwitchRtL(uint16 op, uint16 var, const Argume
 		warning("Missing invokingResource in altDest call");
 }
 
-void MystScriptParser::o_takePage(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_takePage(uint16 var, const ArgumentsArray &args) {
 	// In most game releases, the first opcode argument is the new mouse cursor.
 	// However, in the original v1.0 English release this opcode takes no argument.
 	uint16 cursorId; // = args[0];
@@ -375,8 +367,6 @@ void MystScriptParser::o_takePage(uint16 op, uint16 var, const ArgumentsArray &a
 
 	uint16 oldPage = _globals.heldPage;
 
-	debugC(kDebugScript, "Opcode %d: takePage Var %d CursorId %d", op, var, cursorId);
-
 	// Take / drop page
 	toggleVar(var);
 
@@ -394,61 +384,48 @@ void MystScriptParser::o_takePage(uint16 op, uint16 var, const ArgumentsArray &a
 	}
 }
 
-void MystScriptParser::o_redrawCard(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Redraw card", op);
-
+void MystScriptParser::o_redrawCard(uint16 var, const ArgumentsArray &args) {
 	_vm->drawCardBackground();
 	_vm->drawResourceImages();
 	_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
 }
 
-void MystScriptParser::o_goToDest(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
-
+void MystScriptParser::o_goToDest(uint16 var, const ArgumentsArray &args) {
 	if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionCopy);
 	else
-		warning("Opcode %d: Missing invokingResource", op);
+		warning("Opcode o_goToDest: Missing invokingResource");
 }
 
-void MystScriptParser::o_goToDestForward(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
-
+void MystScriptParser::o_goToDestForward(uint16 var, const ArgumentsArray &args) {
 	if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionDissolve);
 	else
-		warning("Opcode %d: Missing invokingResource", op);
+		warning("Opcode o_goToDestForward: Missing invokingResource");
 }
 
-void MystScriptParser::o_goToDestLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
-
+void MystScriptParser::o_goToDestRight(uint16 var, const ArgumentsArray &args) {
 	if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionPartToRight);
 	else
-		warning("Opcode %d: Missing invokingResource", op);
+		warning("Opcode o_goToDestRight: Missing invokingResource");
 }
 
-void MystScriptParser::o_goToDestRight(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
-
+void MystScriptParser::o_goToDestLeft(uint16 var, const ArgumentsArray &args) {
 	if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionPartToLeft);
 	else
-		warning("Opcode %d: Missing invokingResource", op);
+		warning("Opcode o_goToDestLeft: Missing invokingResource");
 }
 
-void MystScriptParser::o_goToDestUp(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
-
+void MystScriptParser::o_goToDestUp(uint16 var, const ArgumentsArray &args) {
 	if (_invokingResource != nullptr)
 		_vm->changeToCard(_invokingResource->getDest(), kTransitionTopToBottom);
 	else
-		warning("Opcode %d: Missing invokingResource", op);
+		warning("Opcode o_goToDestUp: Missing invokingResource");
 }
 
-void MystScriptParser::o_triggerMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Trigger Type 6 Resource Movie..", op);
+void MystScriptParser::o_triggerMovie(uint16 var, const ArgumentsArray &args) {
 	// The original has code to pause the background music before playing the movie,
 	// if the movie has a sound track, as well as code to resume it afterwards. But since
 	// the movie has not yet been loaded at this point, it is impossible to know
@@ -458,46 +435,31 @@ void MystScriptParser::o_triggerMovie(uint16 op, uint16 var, const ArgumentsArra
 	if (args.size() == 1)
 		direction = args[0];
 
-	debugC(kDebugScript, "\tDirection: %d", direction);
-
 	// Trigger resource 6 movie overriding play direction
 	MystAreaVideo *resource = getInvokingResource<MystAreaVideo>();
 	resource->setDirection(direction);
 	resource->playMovie();
 }
 
-void MystScriptParser::o_toggleVarNoRedraw(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: toggleVarNoRedraw", op);
-
+void MystScriptParser::o_toggleVarNoRedraw(uint16 var, const ArgumentsArray &args) {
 	toggleVar(var);
 }
 
-void MystScriptParser::o_drawAreaState(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: drawAreaState, state: %d", op, args[0]);
-	debugC(kDebugScript, "\tVar: %d", var);
-
+void MystScriptParser::o_drawAreaState(uint16 var, const ArgumentsArray &args) {
 	MystAreaImageSwitch *parent = static_cast<MystAreaImageSwitch *>(getInvokingResource<MystArea>()->_parent);
 	parent->drawConditionalDataToScreen(args[0]);
 }
 
-void MystScriptParser::o_redrawAreaForVar(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: redraw area", op);
-	debugC(kDebugScript, "\tvar: %d", var);
-
+void MystScriptParser::o_redrawAreaForVar(uint16 var, const ArgumentsArray &args) {
 	_vm->redrawArea(var);
 }
 
-void MystScriptParser::o_changeCardDirectional(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_changeCardDirectional(uint16 var, const ArgumentsArray &args) {
 
 	// Used by Channelwood Card 3262 (In Elevator)
-	debugC(kDebugScript, "Opcode %d: Change Card with optional directional update", op);
-
 	uint16 cardId = args[0];
 	uint16 directionalUpdateDataSize = args[1];
 
-	debugC(kDebugScript, "\tcardId: %d", cardId);
-	debugC(kDebugScript, "\tdirectonal update data size: %d", directionalUpdateDataSize);
-
 	_vm->changeToCard(cardId, kNoTransition);
 
 	animatedUpdate(ArgumentsArray(args.begin() + 2, directionalUpdateDataSize), 0);
@@ -507,24 +469,16 @@ void MystScriptParser::o_changeCardDirectional(uint16 op, uint16 var, const Argu
 // but with the current cardId stored.
 // Opcode 18 then "pops" this stored CardId and returns to that card.
 
-void MystScriptParser::o_changeCardPush(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Jump to Card Id, Storing Current Card Id", op);
-
+void MystScriptParser::o_changeCardPush(uint16 var, const ArgumentsArray &args) {
 	_savedCardId = _vm->getCurCard();
 
 	uint16 cardId = args[0];
 	TransitionType transition = static_cast<TransitionType>(args[1]);
 
-	debugC(kDebugScript, "\tCurrent CardId: %d", _savedCardId);
-	debugC(kDebugScript, "\tJump to CardId: %d", cardId);
-
 	_vm->changeToCard(cardId, transition);
 }
 
-void MystScriptParser::o_changeCardPop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Return To Stored Card Id", op);
-	debugC(kDebugScript, "\tCardId: %d", _savedCardId);
-
+void MystScriptParser::o_changeCardPop(uint16 var, const ArgumentsArray &args) {
 	if (_savedCardId == 0) {
 		warning("No pushed card to go back to");
 		return;
@@ -535,14 +489,10 @@ void MystScriptParser::o_changeCardPop(uint16 op, uint16 var, const ArgumentsArr
 	_vm->changeToCard(_savedCardId, transition);
 }
 
-void MystScriptParser::o_enableAreas(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Enable Hotspots", op);
-
+void MystScriptParser::o_enableAreas(uint16 var, const ArgumentsArray &args) {
 	uint16 count = args[0];
 
 	for (uint16 i = 0; i < count; i++) {
-		debugC(kDebugScript, "Enable hotspot index %d", args[i + 1]);
-
 		MystArea *resource = nullptr;
 		if (args[i + 1] == 0xFFFF)
 			resource = _invokingResource;
@@ -556,14 +506,10 @@ void MystScriptParser::o_enableAreas(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void MystScriptParser::o_disableAreas(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Disable Hotspots", op);
-
+void MystScriptParser::o_disableAreas(uint16 var, const ArgumentsArray &args) {
 	uint16 count = args[0];
 
 	for (uint16 i = 0; i < count; i++) {
-		debugC(kDebugScript, "Disable hotspot index %d", args[i + 1]);
-
 		MystArea *resource = nullptr;
 		if (args[i + 1] == 0xFFFF)
 			resource = _invokingResource;
@@ -577,20 +523,14 @@ void MystScriptParser::o_disableAreas(uint16 op, uint16 var, const ArgumentsArra
 	}
 }
 
-void MystScriptParser::o_directionalUpdate(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Transition / Directional update", op);
-
+void MystScriptParser::o_directionalUpdate(uint16 var, const ArgumentsArray &args) {
 	animatedUpdate(args, 0);
 }
 
-void MystScriptParser::o_toggleAreasActivation(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Toggle areas activation", op);
-
+void MystScriptParser::o_toggleAreasActivation(uint16 var, const ArgumentsArray &args) {
 	uint16 count = args[0];
 
 	for (uint16 i = 0; i < count; i++) {
-		debugC(kDebugScript, "Enable/Disable hotspot index %d", args[i + 1]);
-
 		MystArea *resource = nullptr;
 		if (args[i + 1] == 0xFFFF)
 			resource = _invokingResource;
@@ -604,33 +544,24 @@ void MystScriptParser::o_toggleAreasActivation(uint16 op, uint16 var, const Argu
 	}
 }
 
-void MystScriptParser::o_playSound(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_playSound(uint16 var, const ArgumentsArray &args) {
 	uint16 soundId = args[0];
 
-	debugC(kDebugScript, "Opcode %d: playSound", op);
-	debugC(kDebugScript, "\tsoundId: %d", soundId);
-
 	_vm->_sound->playEffect(soundId);
 }
 
-void MystScriptParser::o_stopSoundBackground(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: stopSoundBackground", op);
+void MystScriptParser::o_stopSoundBackground(uint16 var, const ArgumentsArray &args) {
 	_vm->_sound->stopBackground();
 }
 
-void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_playSoundBlocking(uint16 var, const ArgumentsArray &args) {
 	uint16 soundId = args[0];
 
-	debugC(kDebugScript, "Opcode %d: playSoundBlocking", op);
-	debugC(kDebugScript, "\tsoundId: %d", soundId);
-
 	_vm->_sound->stopEffect();
 	_vm->playSoundBlocking(soundId);
 }
 
-void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Copy back buffer to screen", op);
-
+void MystScriptParser::o_copyBackBufferToScreen(uint16 var, const ArgumentsArray &args) {
 	Common::Rect rect;
 	if (args[0] == 0xFFFF) {
 		// Used in Stoneship Card 2111 (Compass Rose)
@@ -648,7 +579,7 @@ void MystScriptParser::o_copyBackBufferToScreen(uint16 op, uint16 var, const Arg
 	_vm->_gfx->copyBackBufferToScreen(rect);
 }
 
-void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_copyImageToBackBuffer(uint16 var, const ArgumentsArray &args) {
 	uint16 imageId = args[0];
 
 	// WORKAROUND wrong image id in mechanical staircase
@@ -668,8 +599,6 @@ void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, const Argu
 	dstRect.right = dstRect.left + srcRect.width();
 	dstRect.bottom = dstRect.top + srcRect.height();
 
-	debugC(kDebugScript, "Opcode %d: Copy image to back buffer", op);
-	debugC(kDebugScript, "\timageId: %d", imageId);
 	debugC(kDebugScript, "\tsrcRect.left: %d", srcRect.left);
 	debugC(kDebugScript, "\tsrcRect.top: %d", srcRect.top);
 	debugC(kDebugScript, "\tsrcRect.right: %d", srcRect.right);
@@ -682,11 +611,9 @@ void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, const Argu
 	_vm->_gfx->copyImageSectionToBackBuffer(imageId, srcRect, dstRect);
 }
 
-void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_changeBackgroundSound(uint16 var, const ArgumentsArray &args) {
 	// Used on Stoneship Card 2080
 	// Used on Channelwood Card 3225 with argc = 8 i.e. Conditional Sound List
-	debugC(kDebugScript, "Opcode %d: Process Sound Block", op);
-
 	Common::MemoryWriteStreamDynamic writeStream = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
 	for (uint i = 0; i < args.size(); i++) {
 		writeStream.writeUint16LE(args[i]);
@@ -698,27 +625,21 @@ void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, const Argu
 	_vm->applySoundBlock(soundBlock);
 }
 
-void MystScriptParser::o_soundPlaySwitch(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Switch Choice of Play Sound", op);
-
+void MystScriptParser::o_soundPlaySwitch(uint16 var, const ArgumentsArray &args) {
 	uint16 value = getVar(var);
 
 	if (value < args.size()) {
 		uint16 soundId = args[value];
-		debugC(kDebugScript, "\tvar: %d", var);
-		debugC(kDebugScript, "\tsoundId: %d", soundId);
-
 		if (soundId)
 			_vm->_sound->playEffect(soundId);
 	}
 }
 
-void MystScriptParser::o_soundResumeBackground(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: soundResumeBackground", op);
+void MystScriptParser::o_soundResumeBackground(uint16 var, const ArgumentsArray &args) {
 	_vm->_sound->resumeBackground();
 }
 
-void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_copyImageToScreen(uint16 var, const ArgumentsArray &args) {
 	uint16 imageId = args[0];
 
 	Common::Rect srcRect = Common::Rect(args[1], args[2], args[3], args[4]);
@@ -734,8 +655,6 @@ void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, const Argument
 	dstRect.right = dstRect.left + srcRect.width();
 	dstRect.bottom = dstRect.top + srcRect.height();
 
-	debugC(kDebugScript, "Opcode %d: Copy image to screen", op);
-	debugC(kDebugScript, "\timageId: %d", imageId);
 	debugC(kDebugScript, "\tsrcRect.left: %d", srcRect.left);
 	debugC(kDebugScript, "\tsrcRect.top: %d", srcRect.top);
 	debugC(kDebugScript, "\tsrcRect.right: %d", srcRect.right);
@@ -748,73 +667,51 @@ void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, const Argument
 	_vm->_gfx->copyImageSectionToScreen(imageId, srcRect, dstRect);
 }
 
-void MystScriptParser::o_changeCard(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Change Card", op);
-
+void MystScriptParser::o_changeCard(uint16 var, const ArgumentsArray &args) {
 	uint16 cardId = args[0];
 	TransitionType transition = static_cast<TransitionType>(args[1]);
 
-	debugC(kDebugScript, "\tTarget Card: %d", cardId);
-
 	_vm->changeToCard(cardId, transition);
 }
 
-void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, const ArgumentsArray &args) {
-		debugC(kDebugScript, "Opcode %d: Draw Full Screen Image, Delay then Change Card", op);
-
+void MystScriptParser::o_drawImageChangeCard(uint16 var, const ArgumentsArray &args) {
 		uint16 imageId = args[0];
 		uint16 cardId = args[1];
 		TransitionType transition = static_cast<TransitionType>(args[2]);
 
-		debugC(kDebugScript, "\timageId: %d", imageId);
-		debugC(kDebugScript, "\tcardId: %d", cardId);
-
 		_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
 		_vm->wait(200);
 
 		_vm->changeToCard(cardId, transition);
 }
 
-void MystScriptParser::o_changeMainCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Change main cursor", op);
-
+void MystScriptParser::o_changeMainCursor(uint16 var, const ArgumentsArray &args) {
 	uint16 cursorId = args[0];
 
-	debugC(kDebugScript, "Cursor: %d", cursorId);
-
 	_vm->setMainCursor(cursorId);
 	_vm->_cursor->setCursor(cursorId);
 }
 
-void MystScriptParser::o_hideCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hide Cursor", op);
+void MystScriptParser::o_hideCursor(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->hideCursor();
 }
 
-void MystScriptParser::o_showCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Show Cursor", op);
+void MystScriptParser::o_showCursor(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->showCursor();
 }
 
-void MystScriptParser::o_delay(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_delay(uint16 var, const ArgumentsArray &args) {
 	// Used on Mechanical Card 6327 (Elevator)
-	debugC(kDebugScript, "Opcode %d: Delay", op);
-
 	uint16 time = args[0];
 
-	debugC(kDebugScript, "\tTime: %d", time);
-
 	_vm->wait(time);
 }
 
-void MystScriptParser::o_changeStack(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: changeStack", op);
-
+void MystScriptParser::o_changeStack(uint16 var, const ArgumentsArray &args) {
 	uint16 targetStack = args[0];
 	uint16 soundIdLinkSrc = args[1];
 	uint16 soundIdLinkDst = args[2];
 
-	debugC(kDebugScript, "\tTarget Stack: %d", targetStack);
 	debugC(kDebugScript, "\tSource Stack Link Sound: %d", soundIdLinkSrc);
 	debugC(kDebugScript, "\tDestination Stack Link Sound: %d", soundIdLinkDst);
 
@@ -831,9 +728,7 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Play Sound, Change Card and Directional Update Screen Region", op);
-
+void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 var, const ArgumentsArray &args) {
 	uint16 cardId = args[0];
 	uint16 soundId = args[1];
 	uint16 delayBetweenSteps = args[2];
@@ -852,9 +747,7 @@ void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, c
 	animatedUpdate(ArgumentsArray(args.begin() + 4, dataSize), delayBetweenSteps);
 }
 
-void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Play Sound and Directional Update Screen Region", op);
-
+void MystScriptParser::o_directionalUpdatePlaySound(uint16 var, const ArgumentsArray &args) {
 	uint16 soundId = args[0];
 	uint16 delayBetweenSteps = args[1];
 	uint16 dataSize = args[2];
@@ -869,29 +762,23 @@ void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, const
 	animatedUpdate(ArgumentsArray(args.begin() + 3, dataSize), delayBetweenSteps);
 }
 
-void MystScriptParser::o_saveMainCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Save main cursor", op);
-
+void MystScriptParser::o_saveMainCursor(uint16 var, const ArgumentsArray &args) {
 	_savedCursorId = _vm->getMainCursor();
 }
 
-void MystScriptParser::o_restoreMainCursor(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Restore main cursor", op);
-
+void MystScriptParser::o_restoreMainCursor(uint16 var, const ArgumentsArray &args) {
 	_vm->setMainCursor(_savedCursorId);
 }
 
-void MystScriptParser::o_soundWaitStop(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_soundWaitStop(uint16 var, const ArgumentsArray &args) {
 	// Used on Selenitic Card 1191 (Maze Runner)
 	// Used on Mechanical Card 6267 (Code Lock)
 	// Used when Button is pushed...
-	debugC(kDebugScript, "Opcode %d: Wait for foreground sound to finish", op);
-
 	while (_vm->_sound->isEffectPlaying())
 		_vm->doFrame();
 }
 
-void MystScriptParser::o_quit(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_quit(uint16 var, const ArgumentsArray &args) {
 	_vm->quitGame();
 }
 
@@ -902,7 +789,7 @@ void MystScriptParser::showMap() {
 	}
 }
 
-void MystScriptParser::o_exitMap(uint16 op, uint16 var, const ArgumentsArray &args) {
+void MystScriptParser::o_exitMap(uint16 var, const ArgumentsArray &args) {
 	_vm->changeToCard(_savedMapCardId, kTransitionCopy);
 }
 
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index 4ae9fb5..ec22fec 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -33,7 +33,7 @@ namespace Mohawk {
 
 typedef Common::Array<uint16> ArgumentsArray;
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class MohawkEngine_Myst;
 class MystArea;
@@ -88,8 +88,6 @@ public:
 
 	void animatedUpdate(const ArgumentsArray &args, uint16 delay);
 
-	DECLARE_OPCODE(unknown);
-
 	// Common opcodes
 	DECLARE_OPCODE(o_toggleVar);
 	DECLARE_OPCODE(o_setVar);
@@ -100,8 +98,8 @@ public:
 	DECLARE_OPCODE(o_redrawCard);
 	DECLARE_OPCODE(o_goToDest);
 	DECLARE_OPCODE(o_goToDestForward);
-	DECLARE_OPCODE(o_goToDestLeft);
 	DECLARE_OPCODE(o_goToDestRight);
+	DECLARE_OPCODE(o_goToDestLeft);
 	DECLARE_OPCODE(o_goToDestUp);
 	DECLARE_OPCODE(o_triggerMovie);
 	DECLARE_OPCODE(o_toggleVarNoRedraw);
@@ -146,7 +144,7 @@ protected:
 	MohawkEngine_Myst *_vm;
 	MystGameState::Globals &_globals;
 
-	typedef void (MystScriptParser::*OpcodeProcMyst)(uint16 op, uint16 var, const ArgumentsArray &args);
+	typedef void (MystScriptParser::*OpcodeProcMyst)(uint16 var, const ArgumentsArray &args);
 
 	struct MystOpcode {
 		MystOpcode(uint16 o, OpcodeProcMyst p, const char *d) : op(o), proc(p), desc(d) {}
@@ -175,6 +173,8 @@ protected:
 private:
 	MystArea *_invokingResource;
 	int32 _scriptNestingLevel;
+
+	Common::String describeCommand(const MystOpcode &command, uint16 var, const ArgumentsArray &args);
 };
 
 template<class T>
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 6c56ad5..208275d 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -299,9 +299,7 @@ bool Channelwood::pipeChangeValve(bool open, uint16 mask) {
 	return false;
 }
 
-void Channelwood::o_bridgeToggle(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Bridge rise / skink video", op);
-
+void Channelwood::o_bridgeToggle(uint16 var, const ArgumentsArray &args) {
 	VideoEntryPtr bridge = _vm->_video->playMovie(_vm->wrapMovieFilename("bridge", kChannelwoodStack));
 	if (!bridge)
 		error("Failed to open 'bridge' movie");
@@ -317,9 +315,7 @@ void Channelwood::o_bridgeToggle(uint16 op, uint16 var, const ArgumentsArray &ar
 	_vm->waitUntilMovieEnds(bridge);
 }
 
-void Channelwood::o_pipeExtend(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Play Pipe Movie and Sound", op);
-
+void Channelwood::o_pipeExtend(uint16 var, const ArgumentsArray &args) {
 	uint16 soundId = args[0];
 	debugC(kDebugScript, "\tsoundId: %d", soundId);
 
@@ -340,9 +336,7 @@ void Channelwood::o_pipeExtend(uint16 op, uint16 var, const ArgumentsArray &args
 	_vm->_sound->resumeBackground();
 }
 
-void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Draw Full Screen Image, Change Card, and change volume", op);
-
+void Channelwood::o_drawImageChangeCardAndVolume(uint16 var, const ArgumentsArray &args) {
 	uint16 imageId = args[0];
 	uint16 cardId = args[1];
 
@@ -361,8 +355,7 @@ void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, const Ar
 }
 
 
-void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Do Water Tank Valve Open Animation", op);
+void Channelwood::o_waterTankValveOpen(uint16 var, const ArgumentsArray &args) {
 	Common::Rect rect = getInvokingResource<MystArea>()->getRect();
 
 	for (uint i = 0; i < 2; i++)
@@ -374,18 +367,14 @@ void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, const ArgumentsArr
 	pipeChangeValve(true, 0x80);
 }
 
-void Channelwood::o_leverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generic lever start move", op);
-
+void Channelwood::o_leverStartMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(0);
 	_vm->_cursor->setCursor(700);
 	_leverPulled = false;
 }
 
-void Channelwood::o_leverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generic lever move", op);
-
+void Channelwood::o_leverMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	if (lever->pullLeverV()) {
@@ -398,9 +387,7 @@ void Channelwood::o_leverMove(uint16 op, uint16 var, const ArgumentsArray &args)
 	}
 }
 
-void Channelwood::o_leverMoveFail(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generic lever move", op);
-
+void Channelwood::o_leverMoveFail(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	if (lever->pullLeverV()) {
@@ -415,9 +402,7 @@ void Channelwood::o_leverMoveFail(uint16 op, uint16 var, const ArgumentsArray &a
 	}
 }
 
-void Channelwood::o_leverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generic lever end move", op);
-
+void Channelwood::o_leverEndMove(uint16 var, const ArgumentsArray &args) {
 	// Get current lever frame
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -431,13 +416,13 @@ void Channelwood::o_leverEndMove(uint16 op, uint16 var, const ArgumentsArray &ar
 	_vm->checkCursorHints();
 }
 
-void Channelwood::o_leverEndMoveResumeBackground(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Channelwood::o_leverEndMoveResumeBackground(uint16 var, const ArgumentsArray &args) {
 	_vm->_sound->resumeBackground();
-	o_leverEndMove(op, var, args);
+	o_leverEndMove(var, args);
 }
 
-void Channelwood::o_leverEndMoveWithSound(uint16 op, uint16 var, const ArgumentsArray &args) {
-	o_leverEndMove(op, var, args);
+void Channelwood::o_leverEndMoveWithSound(uint16 var, const ArgumentsArray &args) {
+	o_leverEndMove(var, args);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = lever->getList3(0);
@@ -445,22 +430,20 @@ void Channelwood::o_leverEndMoveWithSound(uint16 op, uint16 var, const Arguments
 		_vm->_sound->playEffect(soundId);
 }
 
-void Channelwood::o_leverElev3StartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Channelwood::o_leverElev3StartMove(uint16 var, const ArgumentsArray &args) {
 	_vm->_gfx->copyImageToScreen(3970, Common::Rect(544, 333));
 	_vm->doFrame();
-	o_leverStartMove(op, var, args);
+	o_leverStartMove(var, args);
 }
 
-void Channelwood::o_leverElev3EndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	o_leverEndMove(op, var, args);
+void Channelwood::o_leverElev3EndMove(uint16 var, const ArgumentsArray &args) {
+	o_leverEndMove(var, args);
 	_vm->_gfx->copyImageToScreen(3265, Common::Rect(544, 333));
 	_vm->doFrame();
 	_vm->_sound->playEffect(5265);
 }
 
-void Channelwood::o_pumpLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Pump lever move", op);
-
+void Channelwood::o_pumpLeverMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	if (lever->pullLeverV()) {
@@ -472,8 +455,8 @@ void Channelwood::o_pumpLeverMove(uint16 op, uint16 var, const ArgumentsArray &a
 	}
 }
 
-void Channelwood::o_pumpLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	o_leverEndMove(op, var, args);
+void Channelwood::o_pumpLeverEndMove(uint16 var, const ArgumentsArray &args) {
+	o_leverEndMove(var, args);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = lever->getList3(0);
@@ -481,9 +464,7 @@ void Channelwood::o_pumpLeverEndMove(uint16 op, uint16 var, const ArgumentsArray
 		_vm->_sound->playBackground(soundId, 36864);
 }
 
-void Channelwood::o_stairsDoorToggle(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Play stairs door video", op);
-
+void Channelwood::o_stairsDoorToggle(uint16 var, const ArgumentsArray &args) {
 	MystAreaVideo *movie = getInvokingResource<MystAreaVideo>();
 
 	if (_state.stairsUpperDoorState) {
@@ -497,9 +478,7 @@ void Channelwood::o_stairsDoorToggle(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void Channelwood::o_valveHandleMove1(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Valve handle move", op);
-
+void Channelwood::o_valveHandleMove1(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 
@@ -513,21 +492,17 @@ void Channelwood::o_valveHandleMove1(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void Channelwood::o_valveHandleMoveStart1(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Valve handle move start", op);
-
+void Channelwood::o_valveHandleMoveStart1(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = handle->getList1(0);
 	if (soundId)
 		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
-	o_valveHandleMove1(op, var, args);
+	o_valveHandleMove1(var, args);
 }
 
-void Channelwood::o_valveHandleMoveStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Valve handle move stop", op);
-
+void Channelwood::o_valveHandleMoveStop(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 
 	// Update state with valve position
@@ -548,9 +523,7 @@ void Channelwood::o_valveHandleMoveStop(uint16 op, uint16 var, const ArgumentsAr
 	_vm->checkCursorHints();
 }
 
-void Channelwood::o_valveHandleMove2(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Valve handle move", op);
-
+void Channelwood::o_valveHandleMove2(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 
@@ -564,21 +537,17 @@ void Channelwood::o_valveHandleMove2(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void Channelwood::o_valveHandleMoveStart2(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Valve handle move start", op);
-
+void Channelwood::o_valveHandleMoveStart2(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = handle->getList1(0);
 	if (soundId)
 		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
-	o_valveHandleMove2(op, var, args);
+	o_valveHandleMove2(var, args);
 }
 
-void Channelwood::o_valveHandleMove3(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Valve handle move", op);
-
+void Channelwood::o_valveHandleMove3(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 
@@ -592,21 +561,17 @@ void Channelwood::o_valveHandleMove3(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void Channelwood::o_valveHandleMoveStart3(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Valve handle move start", op);
-
+void Channelwood::o_valveHandleMoveStart3(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	uint16 soundId = handle->getList1(0);
 	if (soundId)
 		_vm->_sound->playEffect(soundId);
 	_vm->_cursor->setCursor(700);
 
-	o_valveHandleMove3(op, var, args);
+	o_valveHandleMove3(var, args);
 }
 
-void Channelwood::o_hologramMonitor(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hologram monitor", op);
-
+void Channelwood::o_hologramMonitor(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 3012 (Temple Hologram Monitor)
 	uint16 button = args[0]; // 0 to 3
 
@@ -644,23 +609,19 @@ void Channelwood::o_hologramMonitor(uint16 op, uint16 var, const ArgumentsArray
 			video->moveTo(226, 68);
 			break;
 		default:
-			warning("Opcode %d Control Variable Out of Range", op);
+			warning("Opcode o_hologramMonitor Control Variable Out of Range");
 			break;
 		}
 	}
 }
 
-void Channelwood::o_drawerOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Open Sirius drawer", op);
-
+void Channelwood::o_drawerOpen(uint16 var, const ArgumentsArray &args) {
 	_siriusDrawerState = 1;
 	_vm->redrawArea(18, false);
 	_vm->redrawArea(102, false);
 }
 
-void Channelwood::o_hologramTemple(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Temple hologram", op);
-
+void Channelwood::o_hologramTemple(uint16 var, const ArgumentsArray &args) {
 	_vm->_sound->pauseBackground();
 
 	// Used on Card 3333 (Temple Hologram)
@@ -678,22 +639,19 @@ void Channelwood::o_hologramTemple(uint16 op, uint16 var, const ArgumentsArray &
 		_vm->playMovieBlocking(_vm->wrapMovieFilename("holosmsg", kChannelwoodStack), 127, 45);
 		break;
 	default:
-		warning("Opcode %d Control Variable Out of Range", op);
+		warning("Opcode o_hologramTemple Control Variable Out of Range");
 		break;
 	}
 
 	_vm->_sound->resumeBackground();
 }
 
-void Channelwood::o_executeMouseUp(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Execute mouse up", op);
-
+void Channelwood::o_executeMouseUp(uint16 var, const ArgumentsArray &args) {
 	MystArea *resource = _vm->getViewResource<MystArea>(args[0]);
 	resource->handleMouseUp();
 }
 
-void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Do Water Tank Valve Close Animation", op);
+void Channelwood::o_waterTankValveClose(uint16 var, const ArgumentsArray &args) {
 	Common::Rect rect = getInvokingResource<MystArea>()->getRect();
 
 	for (uint i = 0; i < 2; i++)
@@ -705,10 +663,8 @@ void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, const ArgumentsAr
 	pipeChangeValve(false, 0x80);
 }
 
-void Channelwood::o_elevatorMovies(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Channelwood::o_elevatorMovies(uint16 var, const ArgumentsArray &args) {
 	// Used by Card 3262 (Elevator)
-	debugC(kDebugScript, "Opcode %d: Elevator movie", op);
-
 	uint16 elevator = args[0];
 	uint16 direction = args[1];
 
@@ -750,9 +706,7 @@ void Channelwood::o_elevatorMovies(uint16 op, uint16 var, const ArgumentsArray &
 	_vm->_sound->resumeBackground();
 }
 
-void Channelwood::o_soundReplace(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Play sound if not already playing", op);
-
+void Channelwood::o_soundReplace(uint16 var, const ArgumentsArray &args) {
 	uint16 soundId = args[0];
 
 	if (!_vm->_sound->isEffectPlaying()) {
@@ -760,18 +714,15 @@ void Channelwood::o_soundReplace(uint16 op, uint16 var, const ArgumentsArray &ar
 	}
 }
 
-void Channelwood::o_lever_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generic lever init", op);
+void Channelwood::o_lever_init(uint16 var, const ArgumentsArray &args) {
 	_leverAction = getInvokingResource<MystArea>();
 }
 
-void Channelwood::o_pipeValve_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Water valve init", op);
+void Channelwood::o_pipeValve_init(uint16 var, const ArgumentsArray &args) {
 	_valveVar = var;
 }
 
-void Channelwood::o_drawer_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sirius's drawer init", op);
+void Channelwood::o_drawer_init(uint16 var, const ArgumentsArray &args) {
 	_siriusDrawerState = 0;
 }
 
diff --git a/engines/mohawk/myst_stacks/channelwood.h b/engines/mohawk/myst_stacks/channelwood.h
index c6c9be7..6b8ba9d 100644
--- a/engines/mohawk/myst_stacks/channelwood.h
+++ b/engines/mohawk/myst_stacks/channelwood.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Channelwood : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/credits.cpp b/engines/mohawk/myst_stacks/credits.cpp
index e8c5387..752e624 100644
--- a/engines/mohawk/myst_stacks/credits.cpp
+++ b/engines/mohawk/myst_stacks/credits.cpp
@@ -90,7 +90,7 @@ uint16 Credits::getVar(uint16 var) {
 	}
 }
 
-void Credits::o_runCredits(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Credits::o_runCredits(uint16 var, const ArgumentsArray &args) {
 	// Activate the credits
 	_creditsRunning = true;
 	_curImage = 0;
diff --git a/engines/mohawk/myst_stacks/credits.h b/engines/mohawk/myst_stacks/credits.h
index 923f98b..bea5381 100644
--- a/engines/mohawk/myst_stacks/credits.h
+++ b/engines/mohawk/myst_stacks/credits.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Credits : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index 84261a8..92c1dc7 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -76,22 +76,18 @@ void Demo::runPersistentScripts() {
 	}
 }
 
-void Demo::o_stopIntro(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Unk", op);
+void Demo::o_stopIntro(uint16 var, const ArgumentsArray &args) {
 	// The original also seems to stop the movies. Not needed with this engine.
 	_vm->_gfx->fadeToBlack();
 }
 
-void Demo::o_fadeFromBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fade from black", op);
-
+void Demo::o_fadeFromBlack(uint16 var, const ArgumentsArray &args) {
 	// FIXME: This glitches when enabled. The backbuffer is drawn to screen,
 	// and then the fading occurs, causing the background to appear for one frame.
 	// _vm->_gfx->fadeFromBlack();
 }
 
-void Demo::o_fadeToBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fade to black", op);
+void Demo::o_fadeToBlack(uint16 var, const ArgumentsArray &args) {
 	_vm->_gfx->fadeToBlack();
 }
 
@@ -122,9 +118,7 @@ void Demo::returnToMenu_run() {
 	}
 }
 
-void Demo::o_returnToMenu_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Return to menu init", op);
-
+void Demo::o_returnToMenu_init(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 2001, 2002 and 2003
 	_returnToMenuNextTime = _vm->_system->getMillis() + 5000;
 	_returnToMenuRunning = true;
diff --git a/engines/mohawk/myst_stacks/demo.h b/engines/mohawk/myst_stacks/demo.h
index c2a8fce..337ddaa 100644
--- a/engines/mohawk/myst_stacks/demo.h
+++ b/engines/mohawk/myst_stacks/demo.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Demo : public Intro {
 public:
diff --git a/engines/mohawk/myst_stacks/dni.cpp b/engines/mohawk/myst_stacks/dni.cpp
index bffb61e..b0b485b 100644
--- a/engines/mohawk/myst_stacks/dni.cpp
+++ b/engines/mohawk/myst_stacks/dni.cpp
@@ -95,8 +95,7 @@ uint16 Dni::getVar(uint16 var) {
 	}
 }
 
-void Dni::o_handPage(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hand page to Atrus", op);
+void Dni::o_handPage(uint16 var, const ArgumentsArray &args) {
 	// Used in Card 5014 (Atrus)
 
 	// Find Atrus movie
@@ -214,9 +213,7 @@ void Dni::atrus_run() {
 	}
 }
 
-void Dni::o_atrus_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Atrus init", op);
-
+void Dni::o_atrus_init(uint16 var, const ArgumentsArray &args) {
 	_atrusRunning = true;
 }
 
diff --git a/engines/mohawk/myst_stacks/dni.h b/engines/mohawk/myst_stacks/dni.h
index 75a35ec..9a8b937 100644
--- a/engines/mohawk/myst_stacks/dni.h
+++ b/engines/mohawk/myst_stacks/dni.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Dni : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index d462a98..c4cd209 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -79,15 +79,12 @@ uint16 Intro::getVar(uint16 var) {
 	}
 }
 
-void Intro::o_useLinkBook(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Intro::o_useLinkBook(uint16 var, const ArgumentsArray &args) {
 	// Hard coded SoundId valid only for Intro Stack.
 	// Other stacks use Opcode 40, which takes SoundId values as arguments.
 	const uint16 soundIdLinkSrc = 5;
 	const uint16 soundIdLinkDst[] = { 2282, 3029, 6396, 7122, 3137, 0, 9038, 5134, 0, 4739, 4741 };
 
-	debugC(kDebugScript, "Opcode %d: o_useLinkBook", op);
-	debugC(kDebugScript, "\tvar: %d", var);
-
 	// Change to dest stack
 	_vm->changeToStack(_stackMap[_globals.currentAge], _startCard[_globals.currentAge], soundIdLinkSrc, soundIdLinkDst[_globals.currentAge]);
 }
@@ -146,7 +143,7 @@ void Intro::introMovies_run() {
 	}
 }
 
-void Intro::o_playIntroMovies(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Intro::o_playIntroMovies(uint16 var, const ArgumentsArray &args) {
 	_introMoviesRunning = true;
 	_introStep = 0;
 }
@@ -165,9 +162,7 @@ void Intro::mystLinkBook_run() {
 	}
 }
 
-void Intro::o_mystLinkBook_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Myst link book init", op);
-
+void Intro::o_mystLinkBook_init(uint16 var, const ArgumentsArray &args) {
 	_linkBookMovie = getInvokingResource<MystAreaVideo>();
 	_startTime = 1;
 	_linkBookRunning = true;
diff --git a/engines/mohawk/myst_stacks/intro.h b/engines/mohawk/myst_stacks/intro.h
index 266189b..938a30e 100644
--- a/engines/mohawk/myst_stacks/intro.h
+++ b/engines/mohawk/myst_stacks/intro.h
@@ -34,7 +34,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Intro : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/makingof.h b/engines/mohawk/myst_stacks/makingof.h
index ab4788b..cdc64d2 100644
--- a/engines/mohawk/myst_stacks/makingof.h
+++ b/engines/mohawk/myst_stacks/makingof.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class MakingOf : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 81fbf78..fb109ac 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -271,15 +271,11 @@ bool Mechanical::setVarValue(uint16 var, uint16 value) {
 	return refresh;
 }
 
-void Mechanical::o_throneEnablePassage(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Enable throne passage", op);
-
+void Mechanical::o_throneEnablePassage(uint16 var, const ArgumentsArray &args) {
 	_vm->_resources[args[0]]->setEnabled(getVar(var));
 }
 
-void Mechanical::o_birdCrankStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Mechanical bird crank start", op);
-
+void Mechanical::o_birdCrankStart(uint16 var, const ArgumentsArray &args) {
 	MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
 
 	uint16 crankSoundId = crank->getList2(0);
@@ -292,9 +288,7 @@ void Mechanical::o_birdCrankStart(uint16 op, uint16 var, const ArgumentsArray &a
 	crankMovie->playMovie();
 }
 
-void Mechanical::o_birdCrankStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Mechanical bird crank stop", op);
-
+void Mechanical::o_birdCrankStop(uint16 var, const ArgumentsArray &args) {
 	MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
 
 	MystAreaVideo *crankMovie = static_cast<MystAreaVideo *>(crank->getSubResource(0));
@@ -309,16 +303,12 @@ void Mechanical::o_birdCrankStop(uint16 op, uint16 var, const ArgumentsArray &ar
 	_bird->playMovie();
 }
 
-void Mechanical::o_snakeBoxTrigger(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Trigger Playing Of Snake Movie", op);
-
+void Mechanical::o_snakeBoxTrigger(uint16 var, const ArgumentsArray &args) {
 	// Used on Mechanical Card 6043 (Weapons Rack with Snake Box)
 	_snakeBox->playMovie();
 }
 
-void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Play Stairs Movement Movie", op);
-
+void Mechanical::o_fortressStaircaseMovie(uint16 var, const ArgumentsArray &args) {
 	VideoEntryPtr staircase = _vm->_video->playMovie(_vm->wrapMovieFilename("hhstairs", kMechanicalStack));
 	if (!staircase)
 		error("Failed to open hhstairs movie");
@@ -334,9 +324,7 @@ void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, const Arguments
 	_vm->waitUntilMovieEnds(staircase);
 }
 
-void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Elevator rotation lever start", op);
-
+void Mechanical::o_elevatorRotationStart(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(0);
 
@@ -348,9 +336,7 @@ void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, const ArgumentsA
 	_vm->_cursor->setCursor(700);
 }
 
-void Mechanical::o_elevatorRotationMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Elevator rotation lever move", op);
-
+void Mechanical::o_elevatorRotationMove(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -366,9 +352,7 @@ void Mechanical::o_elevatorRotationMove(uint16 op, uint16 var, const ArgumentsAr
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Elevator rotation lever stop", op);
-
+void Mechanical::o_elevatorRotationStop(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -414,18 +398,14 @@ void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, const ArgumentsAr
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressRotationSpeedStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation speed lever start", op);
-
+void Mechanical::o_fortressRotationSpeedStart(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(0);
 }
 
-void Mechanical::o_fortressRotationSpeedMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation speed lever move", op);
-
+void Mechanical::o_fortressRotationSpeedMove(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -441,9 +421,7 @@ void Mechanical::o_fortressRotationSpeedMove(uint16 op, uint16 var, const Argume
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressRotationSpeedStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation speed lever stop", op);
-
+void Mechanical::o_fortressRotationSpeedStop(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	// Release lever
@@ -457,18 +435,14 @@ void Mechanical::o_fortressRotationSpeedStop(uint16 op, uint16 var, const Argume
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressRotationBrakeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation brake lever start", op);
-
+void Mechanical::o_fortressRotationBrakeStart(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(_fortressRotationBrake);
 }
 
-void Mechanical::o_fortressRotationBrakeMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation brake lever move", op);
-
+void Mechanical::o_fortressRotationBrakeMove(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -484,27 +458,21 @@ void Mechanical::o_fortressRotationBrakeMove(uint16 op, uint16 var, const Argume
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressRotationBrakeStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation brake lever stop", op);
-
+void Mechanical::o_fortressRotationBrakeStop(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(_fortressRotationBrake);
 
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressSimulationSpeedStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever start", op);
-
+void Mechanical::o_fortressSimulationSpeedStart(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(0);
 }
 
-void Mechanical::o_fortressSimulationSpeedMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever move", op);
-
+void Mechanical::o_fortressSimulationSpeedMove(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -520,9 +488,7 @@ void Mechanical::o_fortressSimulationSpeedMove(uint16 op, uint16 var, const Argu
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressSimulationSpeedStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever stop", op);
-
+void Mechanical::o_fortressSimulationSpeedStop(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	// Release lever
@@ -536,18 +502,14 @@ void Mechanical::o_fortressSimulationSpeedStop(uint16 op, uint16 var, const Argu
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_fortressSimulationBrakeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever start", op);
-
+void Mechanical::o_fortressSimulationBrakeStart(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(_fortressSimulationBrake);
 }
 
-void Mechanical::o_fortressSimulationBrakeMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever move", op);
-
+void Mechanical::o_fortressSimulationBrakeMove(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -563,21 +525,17 @@ void Mechanical::o_fortressSimulationBrakeMove(uint16 op, uint16 var, const Argu
 	lever->drawFrame(step);
 }
 
-void Mechanical::o_fortressSimulationBrakeStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever stop", op);
-
+void Mechanical::o_fortressSimulationBrakeStop(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(_fortressSimulationBrake);
 
 	_vm->checkCursorHints();
 }
 
-void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Mechanical::o_elevatorWindowMovie(uint16 var, const ArgumentsArray &args) {
 	uint16 startTime = args[0];
 	uint16 endTime = args[1];
 
-	debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
-
 	VideoEntryPtr window = _vm->_video->playMovie(_vm->wrapMovieFilename("ewindow", kMechanicalStack));
 	if (!window)
 		error("Failed to open ewindow movie");
@@ -587,9 +545,7 @@ void Mechanical::o_elevatorWindowMovie(uint16 op, uint16 var, const ArgumentsArr
 	_vm->waitUntilMovieEnds(window);
 }
 
-void Mechanical::o_elevatorGoMiddle(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Elevator go middle from top", op);
-
+void Mechanical::o_elevatorGoMiddle(uint16 var, const ArgumentsArray &args) {
 	_elevatorTooLate = false;
 	_elevatorTopCounter = 5;
 	_elevatorGoingMiddle = true;
@@ -634,7 +590,7 @@ void Mechanical::elevatorGoMiddle_run() {
 				_vm->wait(500);
 				_vm->_sound->playEffect(9120);
 				static uint16 moviePos[2] = { 3540, 5380 };
-				o_elevatorWindowMovie(121, 0, ArgumentsArray(moviePos, ARRAYSIZE(moviePos)));
+				o_elevatorWindowMovie(0, ArgumentsArray(moviePos, ARRAYSIZE(moviePos)));
 				_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
 				_vm->_sound->playEffect(10120);
 				_vm->_cursor->showCursor();
@@ -647,12 +603,10 @@ void Mechanical::elevatorGoMiddle_run() {
 	}
 }
 
-void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Mechanical::o_elevatorTopMovie(uint16 var, const ArgumentsArray &args) {
 	uint16 startTime = args[0];
 	uint16 endTime = args[1];
 
-	debugC(kDebugScript, "Opcode %d Movie Time Index %d to %d", op, startTime, endTime);
-
 	VideoEntryPtr window = _vm->_video->playMovie(_vm->wrapMovieFilename("hcelev", kMechanicalStack));
 	if (!window)
 		error("Failed to open hcelev movie");
@@ -662,9 +616,7 @@ void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, const ArgumentsArray
 	_vm->waitUntilMovieEnds(window);
 }
 
-void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Set fortress position", op);
-
+void Mechanical::o_fortressRotationSetPosition(uint16 var, const ArgumentsArray &args) {
 	VideoEntryPtr gears = _fortressRotationGears->getVideo();
 	uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
 
@@ -676,15 +628,11 @@ void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, const Argu
 	_fortressPosition = (moviePosition + 900) / 1800 % 4;
 }
 
-void Mechanical::o_mystStaircaseMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Myst book staircase video", op);
-
+void Mechanical::o_mystStaircaseMovie(uint16 var, const ArgumentsArray &args) {
 	_vm->playMovieBlocking(_vm->wrapMovieFilename("sstairs", kMechanicalStack), 199, 108);
 }
 
-void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Wait for the elevator to go middle", op);
-
+void Mechanical::o_elevatorWaitTimeout(uint16 var, const ArgumentsArray &args) {
 	// Wait while the elevator times out
 	while (_elevatorGoingMiddle) {
 		runPersistentScripts();
@@ -692,58 +640,42 @@ void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, const ArgumentsArr
 	}
 }
 
-void Mechanical::o_crystalEnterYellow(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Crystal enter", op);
-
+void Mechanical::o_crystalEnterYellow(uint16 var, const ArgumentsArray &args) {
 	_crystalLit = 3;
 	_vm->redrawArea(20);
 }
 
-void Mechanical::o_crystalEnterGreen(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Crystal enter", op);
-
+void Mechanical::o_crystalEnterGreen(uint16 var, const ArgumentsArray &args) {
 	_crystalLit = 1;
 	_vm->redrawArea(21);
 }
 
-void Mechanical::o_crystalEnterRed(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Crystal enter", op);
-
+void Mechanical::o_crystalEnterRed(uint16 var, const ArgumentsArray &args) {
 	_crystalLit = 2;
 	_vm->redrawArea(22);
 }
 
-void Mechanical::o_crystalLeaveYellow(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Crystal leave", op);
-
+void Mechanical::o_crystalLeaveYellow(uint16 var, const ArgumentsArray &args) {
 	_crystalLit = 0;
 	_vm->redrawArea(20);
 }
 
-void Mechanical::o_crystalLeaveGreen(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Crystal leave", op);
-
+void Mechanical::o_crystalLeaveGreen(uint16 var, const ArgumentsArray &args) {
 	_crystalLit = 0;
 	_vm->redrawArea(21);
 }
 
-void Mechanical::o_crystalLeaveRed(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Crystal leave", op);
-
+void Mechanical::o_crystalLeaveRed(uint16 var, const ArgumentsArray &args) {
 	_crystalLit = 0;
 	_vm->redrawArea(22);
 }
 
-void Mechanical::o_throne_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Mechanical::o_throne_init(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 6238 (Sirrus' Throne) and Card 6027 (Achenar's Throne)
-	debugC(kDebugScript, "Opcode %d: Brother throne init", op);
-
 	getInvokingResource<MystArea>()->setEnabled(getVar(var));
 }
 
-void Mechanical::o_fortressStaircase_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Staircase init", op);
-
+void Mechanical::o_fortressStaircase_init(uint16 var, const ArgumentsArray &args) {
 	_vm->_resources[args[0]]->setEnabled(!_state.staircaseState);
 	_vm->_resources[args[1]]->setEnabled(!_state.staircaseState);
 	_vm->_resources[args[2]]->setEnabled(_state.staircaseState);
@@ -759,17 +691,13 @@ void Mechanical::birdSing_run() {
 	}
 }
 
-void Mechanical::o_bird_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Mechanical bird init", op);
-
+void Mechanical::o_bird_init(uint16 var, const ArgumentsArray &args) {
 	_birdSinging = false;
 	_birdSingEndTime = 0;
 	_bird = getInvokingResource<MystAreaVideo>();
 }
 
-void Mechanical::o_snakeBox_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Snake box init", op);
-
+void Mechanical::o_snakeBox_init(uint16 var, const ArgumentsArray &args) {
 	_snakeBox = getInvokingResource<MystAreaVideo>();
 }
 
@@ -790,9 +718,7 @@ void Mechanical::elevatorRotation_run() {
 	}
 }
 
-void Mechanical::o_elevatorRotation_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Elevator rotation init", op);
-
+void Mechanical::o_elevatorRotation_init(uint16 var, const ArgumentsArray &args) {
 	_elevatorRotationSoundId = args[0];
 	_elevatorRotationGearPosition = 0;
 	_elevatorRotationLeverMoving = false;
@@ -870,9 +796,7 @@ void Mechanical::fortressRotation_run() {
 	}
 }
 
-void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fortress rotation init", op);
-
+void Mechanical::o_fortressRotation_init(uint16 var, const ArgumentsArray &args) {
 	_fortressRotationGears = getInvokingResource<MystAreaVideo>();
 
 	VideoEntryPtr gears = _fortressRotationGears->playMovie();
@@ -1020,9 +944,7 @@ void Mechanical::fortressSimulation_run() {
 	}
 }
 
-void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fortress rotation simulator init", op);
-
+void Mechanical::o_fortressSimulation_init(uint16 var, const ArgumentsArray &args) {
 	_fortressSimulationHolo = getInvokingResource<MystAreaVideo>();
 
 	_fortressSimulationStartSound1 = args[0];
@@ -1042,9 +964,7 @@ void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, const Argument
 	_vm->_cursor->hideCursor();
 }
 
-void Mechanical::o_fortressSimulationStartup_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fortress rotation simulator startup init", op);
-
+void Mechanical::o_fortressSimulationStartup_init(uint16 var, const ArgumentsArray &args) {
 	_fortressSimulationStartup = getInvokingResource<MystAreaVideo>();
 }
 
diff --git a/engines/mohawk/myst_stacks/mechanical.h b/engines/mohawk/myst_stacks/mechanical.h
index 585164f..46cfe68 100644
--- a/engines/mohawk/myst_stacks/mechanical.h
+++ b/engines/mohawk/myst_stacks/mechanical.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Mechanical : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index e9449b7..1a6fc3e 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -96,15 +96,15 @@ void Myst::setupOpcodes() {
 	OPCODE(127, o_clockLeverEndMove);
 	OPCODE(128, o_treePressureReleaseStart);
 	if (!observatoryIsDDMMYYYY2400()) {
-		OPCODE(129, o_observatoryMonthChangeStart);
-		OPCODE(130, o_observatoryMonthChangeStart);
-		OPCODE(131, o_observatoryDayChangeStart);
-		OPCODE(132, o_observatoryDayChangeStart);
+		OPCODE(129, o_observatoryMonthChangeStartIncrease);
+		OPCODE(130, o_observatoryMonthChangeStartDecrease);
+		OPCODE(131, o_observatoryDayChangeStartIncrease);
+		OPCODE(132, o_observatoryDayChangeStartDecrease);
 	} else {
-		OPCODE(129, o_observatoryDayChangeStart);
-		OPCODE(130, o_observatoryDayChangeStart);
-		OPCODE(131, o_observatoryMonthChangeStart);
-		OPCODE(132, o_observatoryMonthChangeStart);
+		OPCODE(129, o_observatoryDayChangeStartIncrease);
+		OPCODE(130, o_observatoryDayChangeStartDecrease);
+		OPCODE(131, o_observatoryMonthChangeStartIncrease);
+		OPCODE(132, o_observatoryMonthChangeStartDecrease);
 	}
 	OPCODE(133, o_observatoryGoButton);
 	OPCODE(134, o_observatoryMonthSliderMove);
@@ -117,8 +117,8 @@ void Myst::setupOpcodes() {
 	OPCODE(141, o_circuitBreakerStartMove);
 	OPCODE(142, o_circuitBreakerMove);
 	OPCODE(143, o_circuitBreakerEndMove);
-	OPCODE(144, o_clockLeverMove);
-	OPCODE(145, o_clockLeverMove);
+	OPCODE(144, o_clockLeverMoveLeft);
+	OPCODE(145, o_clockLeverMoveRight);
 	OPCODE(146, o_boilerIncreasePressureStart);
 	OPCODE(147, o_boilerLightPilot);
 	OPCODE(148, NOP);
@@ -163,12 +163,12 @@ void Myst::setupOpcodes() {
 	OPCODE(189, o_clockHourWheelStartTurn);
 	OPCODE(190, o_libraryCombinationBookStartRight);
 	OPCODE(191, o_libraryCombinationBookStartLeft);
-	OPCODE(192, o_observatoryTimeChangeStart);
+	OPCODE(192, o_observatoryTimeChangeStartIncrease);
 	OPCODE(193, NOP);
 	OPCODE(194, o_observatoryChangeSettingStop);
-	OPCODE(195, o_observatoryTimeChangeStart);
-	OPCODE(196, o_observatoryYearChangeStart);
-	OPCODE(197, o_observatoryYearChangeStart);
+	OPCODE(195, o_observatoryTimeChangeStartDecrease);
+	OPCODE(196, o_observatoryYearChangeStartIncrease);
+	OPCODE(197, o_observatoryYearChangeStartDecrease);
 	OPCODE(198, o_dockVaultForceClose);
 	OPCODE(199, o_imagerEraseStop);
 
@@ -815,9 +815,7 @@ uint16 Myst::bookCountPages(uint16 var) {
 	return cnt;
 }
 
-void Myst::o_libraryBookPageTurnLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Turn book page left", op);
-
+void Myst::o_libraryBookPageTurnLeft(uint16 var, const ArgumentsArray &args) {
 	if (_libraryBookPage - 1 >= 0) {
 		_libraryBookPage--;
 
@@ -831,9 +829,7 @@ void Myst::o_libraryBookPageTurnLeft(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void Myst::o_libraryBookPageTurnRight(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Turn book page right", op);
-
+void Myst::o_libraryBookPageTurnRight(uint16 var, const ArgumentsArray &args) {
 	if (_libraryBookPage + 1 < _libraryBookNumPages) {
 		_libraryBookPage++;
 
@@ -847,16 +843,11 @@ void Myst::o_libraryBookPageTurnRight(uint16 op, uint16 var, const ArgumentsArra
 	}
 }
 
-void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_fireplaceToggleButton(uint16 var, const ArgumentsArray &args) {
 	// Used on Myst Card 4162 (Fireplace Grid)
-	debugC(kDebugScript, "Opcode %d: Fireplace grid toggle button", op);
-
 	uint16 bitmask = args[0];
 	uint16 line = _fireplaceLines[var - 17];
 
-	debugC(kDebugScript, "\tvar: %d", var);
-	debugC(kDebugScript, "\tbitmask: 0x%02X", bitmask);
-
 	if (line & bitmask) {
 		// Unset button
 		for (uint i = 4795; i >= 4779; i--) {
@@ -874,11 +865,9 @@ void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, const ArgumentsArray &
 	}
 }
 
-void Myst::o_fireplaceRotation(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_fireplaceRotation(uint16 var, const ArgumentsArray &args) {
 	// Used on Myst Card 4162 and 4166 (Fireplace Puzzle Rotation Movies)
 	uint16 movieNum = args[0];
-	debugC(kDebugScript, "Opcode %d: Play Fireplace Puzzle Rotation Movies", op);
-	debugC(kDebugScript, "\tmovieNum: %d", movieNum);
 
 	if (movieNum)
 		_vm->playMovieBlocking(_vm->wrapMovieFilename("fpout", kMystStack), 167, 4);
@@ -886,12 +875,9 @@ void Myst::o_fireplaceRotation(uint16 op, uint16 var, const ArgumentsArray &args
 		_vm->playMovieBlocking(_vm->wrapMovieFilename("fpin", kMystStack), 167, 4);
 }
 
-void Myst::o_courtyardBoxesCheckSolution(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_courtyardBoxesCheckSolution(uint16 var, const ArgumentsArray &args) {
 	uint16 soundId = args[0];
 
-	debugC(kDebugScript, "Opcode %d: Ship Puzzle Logic", op);
-	debugC(kDebugScript, "\tsoundId: %d", soundId);
-
 	// Change ship state if the boxes are correctly enabled
 	if (_state.courtyardImageBoxes == 50 && !_state.shipFloating) {
 		_vm->_cursor->hideCursor();
@@ -906,7 +892,7 @@ void Myst::o_courtyardBoxesCheckSolution(uint16 op, uint16 var, const ArgumentsA
 	}
 }
 
-void Myst::o_towerRotationStart(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_towerRotationStart(uint16 var, const ArgumentsArray &args) {
 	_towerRotationBlinkLabel = false;
 	_towerRotationMapClicked = true;
 	_towerRotationSpeed = 0;
@@ -921,7 +907,7 @@ void Myst::o_towerRotationStart(uint16 op, uint16 var, const ArgumentsArray &arg
 	_vm->_sound->playEffect(5378, true);
 }
 
-void Myst::o_towerRotationEnd(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_towerRotationEnd(uint16 var, const ArgumentsArray &args) {
 	_towerRotationMapClicked = false;
 
 	// Set angle value to expected value
@@ -949,9 +935,7 @@ void Myst::o_towerRotationEnd(uint16 op, uint16 var, const ArgumentsArray &args)
 	_towerRotationBlinkLabelCount = 0;
 }
 
-void Myst::o_imagerChangeSelection(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Dock imager change selection", op);
-
+void Myst::o_imagerChangeSelection(uint16 var, const ArgumentsArray &args) {
 	if (_imagerValidationStep != 10) {
 		_imagerValidationStep = 0;
 
@@ -975,16 +959,12 @@ void Myst::o_imagerChangeSelection(uint16 op, uint16 var, const ArgumentsArray &
 	}
 }
 
-void Myst::o_dockVaultOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_dockVaultOpen(uint16 var, const ArgumentsArray &args) {
 	// Used on Myst 4143 (Dock near Marker Switch)
 	uint16 soundId = args[0];
 	uint16 delay = args[1];
 	uint16 directionalUpdateDataSize = args[2];
 
-	debugC(kDebugScript, "Opcode %d: Vault Open Logic", op);
-	debugC(kDebugScript, "\tsoundId: %d", soundId);
-	debugC(kDebugScript, "\tdirectionalUpdateDataSize: %d", directionalUpdateDataSize);
-
 	if ((_state.cabinMarkerSwitch == 1) &&
 		(_state.clockTowerMarkerSwitch == 1) &&
 		(_state.dockMarkerSwitch == 0) &&
@@ -1004,16 +984,12 @@ void Myst::o_dockVaultOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
 	}
 }
 
-void Myst::o_dockVaultClose(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_dockVaultClose(uint16 var, const ArgumentsArray &args) {
 	// Used on Myst 4143 (Dock near Marker Switch)
 	uint16 soundId = args[0];
 	uint16 delay = args[1];
 	uint16 directionalUpdateDataSize = args[2];
 
-	debugC(kDebugScript, "Opcode %d: Vault Close Logic", op);
-	debugC(kDebugScript, "\tsoundId: %d", soundId);
-	debugC(kDebugScript, "\tdirectionalUpdateDataSize: %d", directionalUpdateDataSize);
-
 	if ((_state.cabinMarkerSwitch == 1) &&
 		(_state.clockTowerMarkerSwitch == 1) &&
 		(_state.dockMarkerSwitch == 1) &&
@@ -1031,13 +1007,11 @@ void Myst::o_dockVaultClose(uint16 op, uint16 var, const ArgumentsArray &args) {
 	}
 }
 
-void Myst::o_bookGivePage(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_bookGivePage(uint16 var, const ArgumentsArray &args) {
 	uint16 cardIdLose = args[0];
 	uint16 cardIdBookCover = args[1];
 	uint16 soundIdAddPage = args[2];
 
-	debugC(kDebugScript, "Opcode %d: Red and Blue Book/Page Interaction", op);
-	debugC(kDebugScript, "Var: %d", var);
 	debugC(kDebugScript, "Card Id (Lose): %d", cardIdLose);
 	debugC(kDebugScript, "Card Id (Book Cover): %d", cardIdBookCover);
 	debugC(kDebugScript, "SoundId (Add Page): %d", soundIdAddPage);
@@ -1054,31 +1028,37 @@ void Myst::o_bookGivePage(uint16 op, uint16 var, const ArgumentsArray &args) {
 	switch (_globals.heldPage) {
 	case 7:
 		bookVar = 100;
+		// fallthrough
 	case 1:
 		mask = 1;
 		break;
 	case 8:
 		bookVar = 100;
+		// fallthrough
 	case 2:
 		mask = 2;
 		break;
 	case 9:
 		bookVar = 100;
+		// fallthrough
 	case 3:
 		mask = 4;
 		break;
 	case 10:
 		bookVar = 100;
+		// fallthrough
 	case 4:
 		mask = 8;
 		break;
 	case 11:
 		bookVar = 100;
+		// fallthrough
 	case 5:
 		mask = 16;
 		break;
 	case 12:
 		bookVar = 100;
+		// fallthrough
 	case 6:
 		mask = 32;
 		break;
@@ -1118,12 +1098,10 @@ void Myst::o_bookGivePage(uint16 op, uint16 var, const ArgumentsArray &args) {
 	}
 }
 
-void Myst::o_clockWheelsExecute(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_clockWheelsExecute(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006 (Clock Tower Time Controls)
 	uint16 soundId = args[0];
 
-	debugC(kDebugScript, "Opcode %d: Clock Tower Bridge Puzzle Execute Button", op);
-
 	// Correct time is 2:40
 	bool correctTime = _state.clockTowerHourPosition == 2
 						&& _state.clockTowerMinutePosition == 40;
@@ -1161,9 +1139,7 @@ void Myst::o_clockWheelsExecute(uint16 op, uint16 var, const ArgumentsArray &arg
 	}
 }
 
-void Myst::o_imagerPlayButton(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Imager play button", op);
-
+void Myst::o_imagerPlayButton(uint16 var, const ArgumentsArray &args) {
 	uint16 video = getVar(51);
 
 	// Press button
@@ -1247,9 +1223,7 @@ void Myst::o_imagerPlayButton(uint16 op, uint16 var, const ArgumentsArray &args)
 	_vm->_cursor->showCursor();
 }
 
-void Myst::o_imagerEraseButton(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Imager erase button", op);
-
+void Myst::o_imagerEraseButton(uint16 var, const ArgumentsArray &args) {
 	_imagerRedButton = static_cast<MystAreaImageSwitch *>(getInvokingResource<MystArea>()->_parent);
 	for (uint i = 0; i < 4; i++)
 		_imagerSound[i] = args[i];
@@ -1322,9 +1296,7 @@ void Myst::imagerValidation_run() {
 	}
 }
 
-void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Tower elevator animation", op);
-
+void Myst::o_towerElevatorAnimation(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = true;
 
 	_vm->_cursor->hideCursor();
@@ -1347,9 +1319,7 @@ void Myst::o_towerElevatorAnimation(uint16 op, uint16 var, const ArgumentsArray
 	_treeStopped = false;
 }
 
-void Myst::o_generatorButtonPressed(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generator button pressed", op);
-
+void Myst::o_generatorButtonPressed(uint16 var, const ArgumentsArray &args) {
 	MystArea *button = getInvokingResource<MystArea>()->_parent;
 
 	generatorRedrawRocket();
@@ -1442,9 +1412,7 @@ void Myst::generatorButtonValue(MystArea *button, uint16 &mask, uint16 &value) {
 	}
 }
 
-void Myst::o_cabinSafeChangeDigit(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Cabin safe change digit", op);
-
+void Myst::o_cabinSafeChangeDigit(uint16 var, const ArgumentsArray &args) {
 	uint16 d1 = _state.cabinSafeCombination / 100;
 	uint16 d2 = (_state.cabinSafeCombination / 10) % 10;
 	uint16 d3 = _state.cabinSafeCombination % 10;
@@ -1461,9 +1429,7 @@ void Myst::o_cabinSafeChangeDigit(uint16 op, uint16 var, const ArgumentsArray &a
 	_vm->redrawArea(var);
 }
 
-void Myst::o_cabinSafeHandleStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Cabin safe handle start move", op);
-
+void Myst::o_cabinSafeHandleStartMove(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4100
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	handle->drawFrame(0);
@@ -1471,9 +1437,7 @@ void Myst::o_cabinSafeHandleStartMove(uint16 op, uint16 var, const ArgumentsArra
 	_tempVar = 0;
 }
 
-void Myst::o_cabinSafeHandleMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Cabin safe handle move", op);
-
+void Myst::o_cabinSafeHandleMove(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4100
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 
@@ -1501,21 +1465,25 @@ void Myst::o_cabinSafeHandleMove(uint16 op, uint16 var, const ArgumentsArray &ar
 	}
 }
 
-void Myst::o_cabinSafeHandleEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Cabin safe handle end move", op);
-
+void Myst::o_cabinSafeHandleEndMove(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4100
 	MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
 	handle->drawFrame(0);
 	_vm->checkCursorHints();
 }
 
-void Myst::o_observatoryMonthChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Observatory month change start", op);
+void Myst::o_observatoryMonthChangeStartIncrease(uint16 var, const ArgumentsArray &args) {
+	observatoryMonthChangeStart(true);
+}
+
+void Myst::o_observatoryMonthChangeStartDecrease(uint16 var, const ArgumentsArray &args) {
+	observatoryMonthChangeStart(false);
+}
 
+void Myst::observatoryMonthChangeStart(bool increase) {
 	_vm->_sound->pauseBackground();
 
-	if (op == 129 || op == 131) {
+	if (increase) {
 		// Increase
 		if (observatoryIsDDMMYYYY2400())
 			_vm->_gfx->copyImageSectionToScreen(11098, Common::Rect(36, 0, 48, 9), Common::Rect(351, 70, 363, 79));
@@ -1569,12 +1537,18 @@ void Myst::observatoryMonthChange_run() {
 		observatoryIncrementMonth(_observatoryIncrement);
 }
 
-void Myst::o_observatoryDayChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Observatory day change start", op);
+void Myst::o_observatoryDayChangeStartIncrease(uint16 var, const ArgumentsArray &args) {
+	observatoryDayChangeStart(true);
+}
+
+void Myst::o_observatoryDayChangeStartDecrease(uint16 var, const ArgumentsArray &args) {
+	observatoryDayChangeStart(false);
+}
 
+void Myst::observatoryDayChangeStart(bool increase) {
 	_vm->_sound->pauseBackground();
 
-	if (op == 129 || op == 131) {
+	if (increase) {
 		// Increase
 		if (observatoryIsDDMMYYYY2400())
 			_vm->_gfx->copyImageSectionToScreen(11098, Common::Rect(0, 0, 12, 9), Common::Rect(315, 70, 327, 79));
@@ -1629,12 +1603,18 @@ void Myst::observatoryDayChange_run() {
 		observatoryIncrementDay(_observatoryIncrement);
 }
 
-void Myst::o_observatoryYearChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Observatory year change start", op);
+void Myst::o_observatoryYearChangeStartIncrease(uint16 var, const ArgumentsArray &args) {
+	observatoryYearChangeStart(true);
+}
+
+void Myst::o_observatoryYearChangeStartDecrease(uint16 var, const ArgumentsArray &args) {
+	observatoryYearChangeStart(false);
+}
 
+void Myst::observatoryYearChangeStart(bool increase) {
 	_vm->_sound->pauseBackground();
 
-	if (op == 196) {
+	if (increase) {
 		// Increase
 		_vm->_gfx->copyImageSectionToScreen(11098, Common::Rect(72, 0, 84, 9), Common::Rect(387, 70, 399, 79));
 		_observatoryIncrement = -1;
@@ -1683,12 +1663,18 @@ void Myst::observatoryYearChange_run() {
 		observatoryIncrementYear(_observatoryIncrement);
 }
 
-void Myst::o_observatoryTimeChangeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Observatory time change start", op);
+void Myst::o_observatoryTimeChangeStartIncrease(uint16 var, const ArgumentsArray &args) {
+	observatoryTimeChangeStart(true);
+}
+
+void Myst::o_observatoryTimeChangeStartDecrease(uint16 var, const ArgumentsArray &args) {
+	observatoryTimeChangeStart(false);
+}
 
+void Myst::observatoryTimeChangeStart(bool increase) {
 	_vm->_sound->pauseBackground();
 
-	if (op == 192) {
+	if (increase) {
 		// Increase
 		_vm->_gfx->copyImageSectionToScreen(11098, Common::Rect(109, 0, 121, 9), Common::Rect(424, 70, 436, 79));
 		_observatoryIncrement = -1;
@@ -1742,9 +1728,7 @@ void Myst::observatoryTimeChange_run() {
 		observatoryIncrementTime(_observatoryIncrement);
 }
 
-void Myst::o_observatoryGoButton(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Observatory go button", op);
-
+void Myst::o_observatoryGoButton(uint16 var, const ArgumentsArray &args) {
 	// Setting not at target
 	if (_state.observatoryDayTarget != _state.observatoryDaySetting
 			|| _state.observatoryMonthTarget != _state.observatoryMonthSetting
@@ -1776,42 +1760,30 @@ void Myst::o_observatoryGoButton(uint16 op, uint16 var, const ArgumentsArray &ar
 	}
 }
 
-void Myst::o_observatoryMonthSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Month slider move", op);
-
+void Myst::o_observatoryMonthSliderMove(uint16 var, const ArgumentsArray &args) {
 	observatoryUpdateMonth();
 }
 
-void Myst::o_observatoryDaySliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Day slider move", op);
-
+void Myst::o_observatoryDaySliderMove(uint16 var, const ArgumentsArray &args) {
 	observatoryUpdateDay();
 }
 
-void Myst::o_observatoryYearSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Year slider move", op);
-
+void Myst::o_observatoryYearSliderMove(uint16 var, const ArgumentsArray &args) {
 	observatoryUpdateYear();
 }
 
-void Myst::o_observatoryTimeSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Time slider move", op);
-
+void Myst::o_observatoryTimeSliderMove(uint16 var, const ArgumentsArray &args) {
 	observatoryUpdateTime();
 }
 
-void Myst::o_circuitBreakerStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Circuit breaker start move", op);
-
+void Myst::o_circuitBreakerStartMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *breaker = getInvokingResource<MystVideoInfo>();
 	breaker->drawFrame(0);
 	_vm->_cursor->setCursor(700);
 	_tempVar = 0;
 }
 
-void Myst::o_circuitBreakerMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Circuit breaker move", op);
-
+void Myst::o_circuitBreakerMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *breaker = getInvokingResource<MystVideoInfo>();
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 
@@ -1860,17 +1832,13 @@ void Myst::o_circuitBreakerMove(uint16 op, uint16 var, const ArgumentsArray &arg
 	}
 }
 
-void Myst::o_circuitBreakerEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Circuit breaker end move", op);
-
+void Myst::o_circuitBreakerEndMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *breaker = getInvokingResource<MystVideoInfo>();
 	_vm->redrawArea(breaker->getImageSwitchVar());
 	_vm->checkCursorHints();
 }
 
-void Myst::o_boilerIncreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Boiler increase pressure start", op);
-
+void Myst::o_boilerIncreasePressureStart(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = true;
 	if (_state.cabinValvePosition < 25)
 		_vm->_sound->stopBackground();
@@ -1878,9 +1846,7 @@ void Myst::o_boilerIncreasePressureStart(uint16 op, uint16 var, const ArgumentsA
 	_boilerPressureIncreasing = true;
 }
 
-void Myst::o_boilerLightPilot(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Boiler light pilot", op);
-
+void Myst::o_boilerLightPilot(uint16 var, const ArgumentsArray &args) {
 	// Match is lit
 	if (_cabinMatchState == 1) {
 		_state.cabinPilotLightLit = 1;
@@ -1940,9 +1906,7 @@ void Myst::boilerResetGauge(const Common::Rational &rate) {
 	_cabinGaugeMovie->setRate(rate);
 }
 
-void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Boiler increase pressure stop", op);
-
+void Myst::o_boilerIncreasePressureStop(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = false;
 	_boilerPressureIncreasing = false;
 	_state.treeLastMoveTime = _vm->_system->getMillis();
@@ -2006,18 +1970,14 @@ void Myst::boilerPressureDecrease_run() {
 	}
 }
 
-void Myst::o_boilerDecreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Boiler decrease pressure start", op);
-
+void Myst::o_boilerDecreasePressureStart(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = true;
 	_vm->_sound->stopBackground();
 
 	_boilerPressureDecreasing = true;
 }
 
-void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Boiler decrease pressure stop", op);
-
+void Myst::o_boilerDecreasePressureStop(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = false;
 	_boilerPressureDecreasing = false;
 	_state.treeLastMoveTime = _vm->_system->getMillis();
@@ -2038,16 +1998,12 @@ void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, const ArgumentsAr
 	}
 }
 
-void Myst::o_basementIncreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Basement increase pressure start", op);
-
+void Myst::o_basementIncreasePressureStart(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = true;
 	_basementPressureIncreasing = true;
 }
 
-void Myst::o_basementIncreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Basement increase pressure stop", op);
-
+void Myst::o_basementIncreasePressureStop(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = false;
 	_basementPressureIncreasing = false;
 	_state.treeLastMoveTime = _vm->_system->getMillis();
@@ -2079,16 +2035,12 @@ void Myst::basementPressureDecrease_run() {
 	}
 }
 
-void Myst::o_basementDecreasePressureStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Basement decrease pressure start", op);
-
+void Myst::o_basementDecreasePressureStart(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = true;
 	_basementPressureDecreasing = true;
 }
 
-void Myst::o_basementDecreasePressureStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Basement decrease pressure stop", op);
-
+void Myst::o_basementDecreasePressureStop(uint16 var, const ArgumentsArray &args) {
 	_treeStopped = false;
 	_basementPressureDecreasing = false;
 	_state.treeLastMoveTime = _vm->_system->getMillis();
@@ -2163,24 +2115,18 @@ uint32 Myst::treeNextMoveDelay(uint16 pressure) {
 		return 25000 * pressure / 13 + 3000;
 }
 
-void Myst::o_rocketSoundSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket slider start move", op);
-
+void Myst::o_rocketSoundSliderStartMove(uint16 var, const ArgumentsArray &args) {
 	_rocketSliderSound = 0;
 	_vm->_cursor->setCursor(700);
 	_vm->_sound->pauseBackground();
 	rocketSliderMove();
 }
 
-void Myst::o_rocketSoundSliderMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket slider move", op);
-
+void Myst::o_rocketSoundSliderMove(uint16 var, const ArgumentsArray &args) {
 	rocketSliderMove();
 }
 
-void Myst::o_rocketSoundSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket slider end move", op);
-
+void Myst::o_rocketSoundSliderEndMove(uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 
 	if (_state.generatorVoltage == 59 && !_state.generatorBreakers && _rocketSliderSound)
@@ -2295,9 +2241,7 @@ void Myst::rocketCheckSolution() {
 	_vm->_cursor->showCursor();
 }
 
-void Myst::o_rocketPianoStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket piano start move", op);
-
+void Myst::o_rocketPianoStart(uint16 var, const ArgumentsArray &args) {
 	MystAreaDrag *key = getInvokingResource<MystAreaDrag>();
 
 	// What the hell??
@@ -2319,9 +2263,7 @@ void Myst::o_rocketPianoStart(uint16 op, uint16 var, const ArgumentsArray &args)
 	}
 }
 
-void Myst::o_rocketPianoMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket piano move", op);
-
+void Myst::o_rocketPianoMove(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	Common::Rect piano = Common::Rect(85, 123, 460, 270);
 
@@ -2366,9 +2308,7 @@ void Myst::o_rocketPianoMove(uint16 op, uint16 var, const ArgumentsArray &args)
 	}
 }
 
-void Myst::o_rocketPianoStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket piano end move", op);
-
+void Myst::o_rocketPianoStop(uint16 var, const ArgumentsArray &args) {
 	MystAreaImageSwitch *key = getInvokingResource<MystAreaImageSwitch>();
 
 	Common::Rect src = key->getSubImage(0).rect;
@@ -2383,9 +2323,7 @@ void Myst::o_rocketPianoStop(uint16 op, uint16 var, const ArgumentsArray &args)
 	_vm->_sound->resumeBackground();
 }
 
-void Myst::o_rocketLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket lever start move", op);
-
+void Myst::o_rocketLeverStartMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	_vm->_cursor->setCursor(700);
@@ -2393,9 +2331,7 @@ void Myst::o_rocketLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &a
 	lever->drawFrame(0);
 }
 
-void Myst::o_rocketOpenBook(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket open link book", op);
-
+void Myst::o_rocketOpenBook(uint16 var, const ArgumentsArray &args) {
 	// Flyby movie
 	_rocketLinkBook->setBounds(Audio::Timestamp(0, 3500, 600), Audio::Timestamp(0, 13100, 600));
 
@@ -2403,9 +2339,7 @@ void Myst::o_rocketOpenBook(uint16 op, uint16 var, const ArgumentsArray &args) {
 	_tempVar = 2;
 }
 
-void Myst::o_rocketLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket lever move", op);
-
+void Myst::o_rocketLeverMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 
@@ -2432,9 +2366,7 @@ void Myst::o_rocketLeverMove(uint16 op, uint16 var, const ArgumentsArray &args)
 	_rocketLeverPosition = step;
 }
 
-void Myst::o_rocketLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket lever end move", op);
-
+void Myst::o_rocketLeverEndMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	_vm->checkCursorHints();
@@ -2442,9 +2374,7 @@ void Myst::o_rocketLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &arg
 	lever->drawFrame(0);
 }
 
-void Myst::o_cabinLeave(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Leave cabin", op);
-
+void Myst::o_cabinLeave(uint16 var, const ArgumentsArray &args) {
 	// If match is lit, put out
 	if (_cabinMatchState == 1) {
 		_matchGoOutTime = _vm->_system->getMillis();
@@ -2454,9 +2384,7 @@ void Myst::o_cabinLeave(uint16 op, uint16 var, const ArgumentsArray &args) {
 	}
 }
 
-void Myst::o_treePressureReleaseStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Tree pressure release start", op);
-
+void Myst::o_treePressureReleaseStart(uint16 var, const ArgumentsArray &args) {
 	Common::Rect src = Common::Rect(0, 0, 49, 86);
 	Common::Rect dest = Common::Rect(78, 46, 127, 132);
 	_vm->_gfx->copyImageSectionToScreen(4631, src, dest);
@@ -2470,9 +2398,7 @@ void Myst::o_treePressureReleaseStart(uint16 op, uint16 var, const ArgumentsArra
 	}
 }
 
-void Myst::o_treePressureReleaseStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Tree pressure release stop", op);
-
+void Myst::o_treePressureReleaseStop(uint16 var, const ArgumentsArray &args) {
 	Common::Rect rect = Common::Rect(78, 46, 127, 132);
 	_vm->_gfx->copyBackBufferToScreen(rect);
 
@@ -2480,18 +2406,14 @@ void Myst::o_treePressureReleaseStop(uint16 op, uint16 var, const ArgumentsArray
 	_treeMinPosition = 0;
 }
 
-void Myst::o_observatoryMonthSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Month slider start move", op);
-
+void Myst::o_observatoryMonthSliderStartMove(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 	_vm->_sound->pauseBackground();
 
 	observatoryUpdateMonth();
 }
 
-void Myst::o_observatoryMonthSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Month slider end move", op);
-
+void Myst::o_observatoryMonthSliderEndMove(uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 	_vm->_sound->resumeBackground();
 
@@ -2511,18 +2433,14 @@ void Myst::observatoryUpdateMonth() {
 	}
 }
 
-void Myst::o_observatoryDaySliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Day slider start move", op);
-
+void Myst::o_observatoryDaySliderStartMove(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 	_vm->_sound->pauseBackground();
 
 	observatoryUpdateDay();
 }
 
-void Myst::o_observatoryDaySliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Day slider end move", op);
-
+void Myst::o_observatoryDaySliderEndMove(uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 	_vm->_sound->resumeBackground();
 
@@ -2543,18 +2461,14 @@ void Myst::observatoryUpdateDay() {
 	}
 }
 
-void Myst::o_observatoryYearSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Year slider start move", op);
-
+void Myst::o_observatoryYearSliderStartMove(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 	_vm->_sound->pauseBackground();
 
 	observatoryUpdateYear();
 }
 
-void Myst::o_observatoryYearSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Year slider end move", op);
-
+void Myst::o_observatoryYearSliderEndMove(uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 	_vm->_sound->resumeBackground();
 
@@ -2577,18 +2491,14 @@ void Myst::observatoryUpdateYear() {
 	}
 }
 
-void Myst::o_observatoryTimeSliderStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Time slider start move", op);
-
+void Myst::o_observatoryTimeSliderStartMove(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->setCursor(700);
 	_vm->_sound->pauseBackground();
 
 	observatoryUpdateTime();
 }
 
-void Myst::o_observatoryTimeSliderEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Time slider end move", op);
-
+void Myst::o_observatoryTimeSliderEndMove(uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 	_vm->_sound->resumeBackground();
 
@@ -2615,12 +2525,11 @@ void Myst::observatoryUpdateTime() {
 	}
 }
 
-void Myst::o_libraryCombinationBookStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Combination book stop turning pages", op);
+void Myst::o_libraryCombinationBookStop(uint16 var, const ArgumentsArray &args) {
 	_libraryCombinationBookPagesTurning = false;
 }
 
-void Myst::o_cabinMatchLight(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_cabinMatchLight(uint16 var, const ArgumentsArray &args) {
 	if (!_cabinMatchState) {
 		_vm->_sound->playEffect(4103);
 
@@ -2659,37 +2568,29 @@ void Myst::matchBurn_run() {
 	}
 }
 
-void Myst::o_courtyardBoxEnter(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Mouse enters courtyard box", op);
+void Myst::o_courtyardBoxEnter(uint16 var, const ArgumentsArray &args) {
 	_tempVar = 1;
 	_vm->_sound->playEffect(_courtyardBoxSound);
 	_vm->redrawArea(var);
 }
 
-void Myst::o_courtyardBoxLeave(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Mouse leaves courtyard box", op);
+void Myst::o_courtyardBoxLeave(uint16 var, const ArgumentsArray &args) {
 	_tempVar = 0;
 	_vm->redrawArea(var);
 }
 
-void Myst::o_clockMinuteWheelStartTurn(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_clockMinuteWheelStartTurn(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006
-	debugC(kDebugScript, "Opcode %d: Minute wheel start turn", op);
-
 	clockWheelStartTurn(2);
 }
 
-void Myst::o_clockWheelEndTurn(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_clockWheelEndTurn(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006
-	debugC(kDebugScript, "Opcode %d: Wheel end turn", op);
-
 	_clockTurningWheel = 0;
 }
 
-void Myst::o_clockHourWheelStartTurn(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_clockHourWheelStartTurn(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 4006
-	debugC(kDebugScript, "Opcode %d: Hour wheel start turn", op);
-
 	clockWheelStartTurn(1);
 }
 
@@ -2739,18 +2640,14 @@ void Myst::clockWheelTurn(uint16 var) {
 	}
 }
 
-void Myst::o_libraryCombinationBookStartRight(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Combination book start turning pages right", op);
-
+void Myst::o_libraryCombinationBookStartRight(uint16 var, const ArgumentsArray &args) {
 	_tempVar = 0;
 	libraryCombinationBookTurnRight();
 	_startTime = _vm->_system->getMillis();
 	_libraryCombinationBookPagesTurning = true;
 }
 
-void Myst::o_libraryCombinationBookStartLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Combination book start turning pages left", op);
-
+void Myst::o_libraryCombinationBookStartLeft(uint16 var, const ArgumentsArray &args) {
 	_tempVar = 0;
 	libraryCombinationBookTurnLeft();
 	_startTime = _vm->_system->getMillis();
@@ -2818,9 +2715,7 @@ void Myst::libraryCombinationBook_run() {
 	}
 }
 
-void Myst::o_observatoryChangeSettingStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Observatory change setting stop", op);
-
+void Myst::o_observatoryChangeSettingStop(uint16 var, const ArgumentsArray &args) {
 	// Stop persistent scripts
 	_observatoryMonthChanging = false;
 	_observatoryDayChanging = false;
@@ -2837,16 +2732,12 @@ void Myst::o_observatoryChangeSettingStop(uint16 op, uint16 var, const Arguments
 	_vm->_sound->resumeBackground();
 }
 
-void Myst::o_dockVaultForceClose(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_dockVaultForceClose(uint16 var, const ArgumentsArray &args) {
 	// Used on Myst 4143 (Dock near Marker Switch)
 	uint16 soundId = args[0];
 	uint16 delay = args[1];
 	uint16 directionalUpdateDataSize = args[2];
 
-	debugC(kDebugScript, "Opcode %d: Vault Force Close", op);
-	debugC(kDebugScript, "\tsoundId: %d", soundId);
-	debugC(kDebugScript, "\tdirectionalUpdateDataSize: %d", directionalUpdateDataSize);
-
 	if (_dockVaultState) {
 		// Open switch
 		_state.dockMarkerSwitch = 1;
@@ -2861,13 +2752,11 @@ void Myst::o_dockVaultForceClose(uint16 op, uint16 var, const ArgumentsArray &ar
 	}
 }
 
-void Myst::o_imagerEraseStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Imager stop erase", op);
+void Myst::o_imagerEraseStop(uint16 var, const ArgumentsArray &args) {
 	_imagerValidationRunning = false;
 }
 
-void Myst::o_clockLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Clock lever start move", op);
+void Myst::o_clockLeverStartMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(0);
 	_vm->_cursor->setCursor(700);
@@ -2875,9 +2764,15 @@ void Myst::o_clockLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &ar
 	_clockLeverPulled = false;
 }
 
-void Myst::o_clockLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Clock left lever move", op);
+void Myst::o_clockLeverMoveLeft(uint16 var, const ArgumentsArray &args) {
+	clockLeverMove(true);
+}
+
+void Myst::o_clockLeverMoveRight(uint16 var, const ArgumentsArray &args) {
+	clockLeverMove(false);
+}
 
+void Myst::clockLeverMove(bool leftLever) {
 	if (!_clockLeverPulled) {
 		MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -2889,7 +2784,7 @@ void Myst::o_clockLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
 				clockGearForwardOneStep(1);
 
 				// Left lever
-				if (op == 144)
+				if (leftLever)
 					clockGearForwardOneStep(2);
 				else // Right lever
 					clockGearForwardOneStep(0);
@@ -2953,8 +2848,7 @@ void Myst::clockGears_run() {
 	}
 }
 
-void Myst::o_clockLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Clock lever end move", op);
+void Myst::o_clockLeverEndMove(uint16 var, const ArgumentsArray &args) {
 	static const char *videos[] = { "cl1wg1", "cl1wg2", "cl1wg3", "cl1wlfch" };
 
 	_vm->_cursor->hideCursor();
@@ -3012,17 +2906,13 @@ void Myst::clockGearsCheckSolution() {
 	}
 }
 
-void Myst::o_clockResetLeverStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Clock reset lever start move", op);
-
+void Myst::o_clockResetLeverStartMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 	lever->drawFrame(0);
 	_vm->_cursor->setCursor(700);
 }
 
-void Myst::o_clockResetLeverMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Clock reset lever move", op);
-
+void Myst::o_clockResetLeverMove(uint16 var, const ArgumentsArray &args) {
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
 	// If pulled
@@ -3117,9 +3007,7 @@ void Myst::clockResetGear(uint16 gear) {
 	_clockGearsPositions[gear] = 3;
 }
 
-void Myst::o_clockResetLeverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Clock reset lever end move", op);
-
+void Myst::o_clockResetLeverEndMove(uint16 var, const ArgumentsArray &args) {
 	// Get current lever frame
 	MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 
@@ -3128,7 +3016,7 @@ void Myst::o_clockResetLeverEndMove(uint16 op, uint16 var, const ArgumentsArray
 	_vm->checkCursorHints();
 }
 
-void Myst::o_libraryBook_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_libraryBook_init(uint16 var, const ArgumentsArray &args) {
 	_libraryBookPage = 0;
 	_libraryBookNumPages = args[0];
 	_libraryBookBaseImage = args[1];
@@ -3136,9 +3024,7 @@ void Myst::o_libraryBook_init(uint16 op, uint16 var, const ArgumentsArray &args)
 	_libraryBookSound2 = args[3];
 }
 
-void Myst::o_courtyardBox_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Courtyard box init", op);
-
+void Myst::o_courtyardBox_init(uint16 var, const ArgumentsArray &args) {
 	_courtyardBoxSound = args[0];
 }
 
@@ -3182,7 +3068,7 @@ void Myst::towerRotationMap_run() {
 	}
 }
 
-void Myst::o_towerRotationMap_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_towerRotationMap_init(uint16 var, const ArgumentsArray &args) {
 	_towerRotationMapRunning = true;
 	_towerRotationMapTower = getInvokingResource<MystAreaImageSwitch>();
 	_towerRotationMapLabel = _vm->getViewResource<MystAreaImageSwitch>(args[0]);
@@ -3298,22 +3184,20 @@ void Myst::towerRotationMapRotate() {
 	towerRotationMapDrawLine(center, end);
 }
 
-void Myst::o_forechamberDoor_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_forechamberDoor_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 4138 (Dock Forechamber Door)
 	// Set forechamber door to closed
 	_tempVar = 0;
 }
 
-void Myst::o_shipAccess_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_shipAccess_init(uint16 var, const ArgumentsArray &args) {
 	// Enable acces to the ship
 	if (_state.shipFloating) {
 		getInvokingResource<MystArea>()->setEnabled(true);
 	}
 }
 
-void Myst::o_butterflies_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Butterflies movie init", op);
-
+void Myst::o_butterflies_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 4256 (Butterfly Movie Activation)
 	if (!_butterfliesMoviePlayed) {
 		MystAreaVideo *butterflies = getInvokingResource<MystAreaVideo>();
@@ -3323,10 +3207,7 @@ void Myst::o_butterflies_init(uint16 op, uint16 var, const ArgumentsArray &args)
 	}
 }
 
-void Myst::o_imager_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Imager init", op);
-	debugC(kDebugScript, "Var: %d", var);
-
+void Myst::o_imager_init(uint16 var, const ArgumentsArray &args) {
 	MystAreaActionSwitch *select = getInvokingResource<MystAreaActionSwitch>();
 	_imagerMovie = static_cast<MystAreaVideo *>(select->getSubResource(getVar(var)));
 	_imagerRunning = true;
@@ -3369,7 +3250,7 @@ void Myst::libraryBookcaseTransform_run(void) {
 	}
 }
 
-void Myst::o_libraryBookcaseTransform_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_libraryBookcaseTransform_init(uint16 var, const ArgumentsArray &args) {
 	if (_libraryBookcaseChanged) {
 		MystAreaActionSwitch *resource = getInvokingResource<MystAreaActionSwitch>();
 		_libraryBookcaseMovie = static_cast<MystAreaVideo *>(resource->getSubResource(getVar(0)));
@@ -3395,25 +3276,19 @@ void Myst::generatorControlRoom_run(void) {
 	}
 }
 
-void Myst::o_generatorControlRoom_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generator control room init", op);
-
+void Myst::o_generatorControlRoom_init(uint16 var, const ArgumentsArray &args) {
 	_generatorVoltage = _state.generatorVoltage;
 	_generatorControlRoomRunning = true;
 }
 
-void Myst::o_fireplace_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fireplace grid init", op);
-
+void Myst::o_fireplace_init(uint16 var, const ArgumentsArray &args) {
 	// Clear fireplace grid
 	for (uint i = 0; i < 6; i++)
 		_fireplaceLines[i] = 0;
 }
 
-void Myst::o_clockGears_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_clockGears_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 4113 (Clock Tower Cog Puzzle)
-	debugC(kDebugScript, "Opcode %d: Gears puzzle init", op);
-
 	// Set gears position
 	if (_state.gearsOpen) {
 		_clockGearsPositions[0] = 2;
@@ -3428,9 +3303,7 @@ void Myst::o_clockGears_init(uint16 op, uint16 var, const ArgumentsArray &args)
 	}
 }
 
-void Myst::o_gulls1_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Gulls init", op);
-
+void Myst::o_gulls1_init(uint16 var, const ArgumentsArray &args) {
 	if (!_state.shipFloating) {
 		_gullsNextTime = _vm->_system->getMillis() + 2000;
 		_gullsFlying1 = true;
@@ -3460,9 +3333,7 @@ void Myst::gullsFly1_run() {
 	}
 }
 
-void Myst::o_observatory_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Stellar observatory init", op);
-
+void Myst::o_observatory_init(uint16 var, const ArgumentsArray &args) {
 	_tempVar = 0;
 	_observatoryNotInitialized = true;
 	_observatoryVisualizer = getInvokingResource<MystAreaImageSwitch>();
@@ -3579,9 +3450,7 @@ void Myst::observatory_run() {
 	}
 }
 
-void Myst::o_gulls2_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Gulls init", op);
-
+void Myst::o_gulls2_init(uint16 var, const ArgumentsArray &args) {
 	if (!_state.shipFloating) {
 		_gullsNextTime = _vm->_system->getMillis() + 2000;
 		_gullsFlying2 = true;
@@ -3605,15 +3474,11 @@ void Myst::gullsFly2_run() {
 	}
 }
 
-void Myst::o_treeCard_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Enter tree card", op);
-
+void Myst::o_treeCard_init(uint16 var, const ArgumentsArray &args) {
 	_tree = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Myst::o_treeEntry_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Enter tree card with entry", op);
-
+void Myst::o_treeEntry_init(uint16 var, const ArgumentsArray &args) {
 	_treeAlcove = getInvokingResource<MystArea>();
 	_treeMinAccessiblePosition = args[0];
 	_treeMaxAccessiblePosition = args[1];
@@ -3621,9 +3486,7 @@ void Myst::o_treeEntry_init(uint16 op, uint16 var, const ArgumentsArray &args) {
 	treeSetAlcoveAccessible();
 }
 
-void Myst::o_boilerMovies_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Boiler movies init", op);
-
+void Myst::o_boilerMovies_init(uint16 var, const ArgumentsArray &args) {
 	boilerFireInit();
 	boilerGaugeInit();
 }
@@ -3697,9 +3560,7 @@ void Myst::boilerGaugeInit() {
 	_cabinGaugeMovieEnabled = true;
 }
 
-void Myst::o_rocketSliders_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket sliders init", op);
-
+void Myst::o_rocketSliders_init(uint16 var, const ArgumentsArray &args) {
 	_rocketSlider1 = _vm->getViewResource<MystAreaSlider>(args[0]);
 	_rocketSlider2 = _vm->getViewResource<MystAreaSlider>(args[1]);
 	_rocketSlider3 = _vm->getViewResource<MystAreaSlider>(args[2]);
@@ -3718,15 +3579,12 @@ void Myst::o_rocketSliders_init(uint16 op, uint16 var, const ArgumentsArray &arg
 	_rocketSlider5->setPosition(_state.rocketSliderPosition[4]);
 }
 
-void Myst::o_rocketLinkVideo_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Rocket link video init", op);
+void Myst::o_rocketLinkVideo_init(uint16 var, const ArgumentsArray &args) {
 	_tempVar = 0;
 }
 
-void Myst::o_greenBook_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Myst::o_greenBook_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 4168 (Green Book Movies)
-	debugC(kDebugScript, "Opcode %d: Green book init", op);
-
 	_greenBookRunning = true;
 	_tempVar = 1;
 }
@@ -3775,9 +3633,7 @@ void Myst::greenBook_run() {
 	}
 }
 
-void Myst::o_gulls3_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Gulls init", op);
-
+void Myst::o_gulls3_init(uint16 var, const ArgumentsArray &args) {
 	if (!_state.shipFloating) {
 		_gullsNextTime = _vm->_system->getMillis() + 2000;
 		_gullsFlying3 = true;
@@ -3803,9 +3659,7 @@ void Myst::gullsFly3_run() {
 	}
 }
 
-void Myst::o_bookAddSpecialPage_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Book Exit Function", op);
-
+void Myst::o_bookAddSpecialPage_exit(uint16 var, const ArgumentsArray &args) {
 	uint16 numPages = bookCountPages(var);
 
 	// Add special page
@@ -3817,30 +3671,22 @@ void Myst::o_bookAddSpecialPage_exit(uint16 op, uint16 var, const ArgumentsArray
 	}
 }
 
-void Myst::o_treeCard_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Exit tree card", op);
-
+void Myst::o_treeCard_exit(uint16 var, const ArgumentsArray &args) {
 	_tree = nullptr;
 }
 
-void Myst::o_treeEntry_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Exit tree card with entry", op);
-
+void Myst::o_treeEntry_exit(uint16 var, const ArgumentsArray &args) {
 	_treeAlcove = nullptr;
 }
 
-void Myst::o_boiler_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Exit boiler card", op);
-
+void Myst::o_boiler_exit(uint16 var, const ArgumentsArray &args) {
 	_cabinGaugeMovie = VideoEntryPtr();
 	_cabinFireMovie = VideoEntryPtr();
 
 	_cabinGaugeMovieEnabled = false;
 }
 
-void Myst::o_generatorControlRoom_exit(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generator room exit", op);
-
+void Myst::o_generatorControlRoom_exit(uint16 var, const ArgumentsArray &args) {
 	_generatorVoltage = _state.generatorVoltage;
 }
 
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index f3c9087..2da33f0 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Myst : public MystScriptParser {
 public:
@@ -96,8 +96,10 @@ protected:
 	DECLARE_OPCODE(o_cabinSafeHandleMove);
 	DECLARE_OPCODE(o_cabinSafeHandleEndMove);
 	DECLARE_OPCODE(o_treePressureReleaseStart);
-	DECLARE_OPCODE(o_observatoryMonthChangeStart);
-	DECLARE_OPCODE(o_observatoryDayChangeStart);
+	DECLARE_OPCODE(o_observatoryMonthChangeStartIncrease);
+	DECLARE_OPCODE(o_observatoryMonthChangeStartDecrease);
+	DECLARE_OPCODE(o_observatoryDayChangeStartIncrease);
+	DECLARE_OPCODE(o_observatoryDayChangeStartDecrease);
 	DECLARE_OPCODE(o_observatoryGoButton);
 	DECLARE_OPCODE(o_observatoryMonthSliderMove);
 	DECLARE_OPCODE(o_observatoryDaySliderMove);
@@ -143,7 +145,8 @@ protected:
 	DECLARE_OPCODE(o_clockWheelEndTurn);
 	DECLARE_OPCODE(o_clockHourWheelStartTurn);
 	DECLARE_OPCODE(o_clockLeverStartMove);
-	DECLARE_OPCODE(o_clockLeverMove);
+	DECLARE_OPCODE(o_clockLeverMoveLeft);
+	DECLARE_OPCODE(o_clockLeverMoveRight);
 	DECLARE_OPCODE(o_clockLeverEndMove);
 	DECLARE_OPCODE(o_clockResetLeverStartMove);
 	DECLARE_OPCODE(o_clockResetLeverMove);
@@ -151,9 +154,11 @@ protected:
 
 	DECLARE_OPCODE(o_libraryCombinationBookStartRight);
 	DECLARE_OPCODE(o_libraryCombinationBookStartLeft);
-	DECLARE_OPCODE(o_observatoryTimeChangeStart);
+	DECLARE_OPCODE(o_observatoryTimeChangeStartIncrease);
+	DECLARE_OPCODE(o_observatoryTimeChangeStartDecrease);
 	DECLARE_OPCODE(o_observatoryChangeSettingStop);
-	DECLARE_OPCODE(o_observatoryYearChangeStart);
+	DECLARE_OPCODE(o_observatoryYearChangeStartIncrease);
+	DECLARE_OPCODE(o_observatoryYearChangeStartDecrease);
 	DECLARE_OPCODE(o_dockVaultForceClose);
 	DECLARE_OPCODE(o_imagerEraseStop);
 
@@ -311,6 +316,7 @@ protected:
 	void clockWheelStartTurn(uint16 wheel);
 	void clockWheelTurn(uint16 var);
 
+	void clockLeverMove(bool leftLever);
 	void clockGearForwardOneStep(uint16 gear);
 	void clockWeightDownOneStep();
 	void clockGearsCheckSolution();
@@ -336,6 +342,10 @@ protected:
 	bool observatoryIsDDMMYYYY2400();
 	void observatorySetTargetToSetting();
 	void observatoryUpdateVisualizer(uint16 x, uint16 y);
+	void observatoryMonthChangeStart(bool increase);
+	void observatoryDayChangeStart(bool increase);
+	void observatoryYearChangeStart(bool increase);
+	void observatoryTimeChangeStart(bool increase);
 	void observatoryIncrementMonth(int16 increment);
 	void observatoryIncrementDay(int16 increment);
 	void observatoryIncrementYear(int16 increment);
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index db657e5..9ad40b0 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -79,28 +79,22 @@ void Preview::runPersistentScripts() {
 		speech_run();
 }
 
-void Preview::o_fadeToBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fade to black", op);
+void Preview::o_fadeToBlack(uint16 var, const ArgumentsArray &args) {
 	_vm->_gfx->fadeToBlack();
 }
 
-void Preview::o_fadeFromBlack(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Fade from black", op);
+void Preview::o_fadeFromBlack(uint16 var, const ArgumentsArray &args) {
 
 	_vm->_gfx->fadeFromBlack();
 }
 
-void Preview::o_stayHere(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Stay here dialog", op);
-
+void Preview::o_stayHere(uint16 var, const ArgumentsArray &args) {
 	// Nuh-uh! No leaving the library in the demo!
 	GUI::MessageDialog dialog("You can't leave the library in the demo.");
 	dialog.runModal();
 }
 
-void Preview::o_speechStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Speech stop", op);
-
+void Preview::o_speechStop(uint16 var, const ArgumentsArray &args) {
 	_vm->_sound->stopSpeech();
 	_speechRunning = false;
 	_globals.currentAge = 2;
@@ -225,22 +219,18 @@ void Preview::speech_run() {
 	}
 }
 
-void Preview::o_speech_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Speech init", op);
-
+void Preview::o_speech_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 3000 (Closed Myst Book)
 	_speechStep = 0;
 	_speechRunning = true;
 }
 
-void Preview::o_library_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Library init", op);
-
+void Preview::o_library_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 3002 (Myst Island Overview)
 	_library = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Preview::o_libraryBookcaseTransformDemo_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Preview::o_libraryBookcaseTransformDemo_init(uint16 var, const ArgumentsArray &args) {
 	if (_libraryBookcaseChanged) {
 		MystAreaActionSwitch *resource = getInvokingResource<MystAreaActionSwitch>();
 		_libraryBookcaseMovie = static_cast<MystAreaVideo *>(resource->getSubResource(getVar(303)));
diff --git a/engines/mohawk/myst_stacks/preview.h b/engines/mohawk/myst_stacks/preview.h
index dbbd6c2..6c0fe83 100644
--- a/engines/mohawk/myst_stacks/preview.h
+++ b/engines/mohawk/myst_stacks/preview.h
@@ -35,7 +35,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Preview : public Myst {
 public:
diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index fe1a64a..427635b 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -285,7 +285,7 @@ bool Selenitic::setVarValue(uint16 var, uint16 value) {
 	return refresh;
 }
 
-void Selenitic::o_mazeRunnerMove(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerMove(uint16 var, const ArgumentsArray &args) {
 	uint16 oldPosition = _mazeRunnerPosition;
 	uint16 move = var;
 
@@ -566,16 +566,11 @@ void Selenitic::mazeRunnerPlaySoundHelp() {
 	_mazeRunnerLight->drawConditionalDataToScreen(0);
 }
 
-void Selenitic::o_mazeRunnerSoundRepeat(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerSoundRepeat(uint16 var, const ArgumentsArray &args) {
 	mazeRunnerPlaySoundHelp();
 }
 
-/**
- * Sound receiver sigma button
- */
-void Selenitic::o_soundReceiverSigma(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound receiver sigma button", op);
-
+void Selenitic::o_soundReceiverSigma(uint16 var, const ArgumentsArray &args) {
 	_vm->_cursor->hideCursor();
 
 	_soundReceiverCurrentSource->drawConditionalDataToScreen(0);
@@ -622,26 +617,15 @@ void Selenitic::o_soundReceiverSigma(uint16 op, uint16 var, const ArgumentsArray
 	_vm->_cursor->showCursor();
 }
 
-/**
- * Sound receiver right button
- */
-void Selenitic::o_soundReceiverRight(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound receiver right", op);
-
+void Selenitic::o_soundReceiverRight(uint16 var, const ArgumentsArray &args) {
 	soundReceiverLeftRight(1);
 }
 
-/**
- * Sound receiver left button
- */
-void Selenitic::o_soundReceiverLeft(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound receiver left", op);
-
+void Selenitic::o_soundReceiverLeft(uint16 var, const ArgumentsArray &args) {
 	soundReceiverLeftRight(2);
 }
 
 void Selenitic::soundReceiverLeftRight(uint direction) {
-
 	if (_soundReceiverSigmaPressed) {
 		_soundReceiverSigmaButton->drawConditionalDataToScreen(0);
 		_soundReceiverSigmaPressed = false;
@@ -694,12 +678,7 @@ void Selenitic::soundReceiverDrawAngle() {
 	_vm->redrawResource(_soundReceiverAngle4);
 }
 
-/**
- * Sound receiver source selection buttons
- */
-void Selenitic::o_soundReceiverSource(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound receiver source", op);
-
+void Selenitic::o_soundReceiverSource(uint16 var, const ArgumentsArray &args) {
 	if (_soundReceiverSigmaPressed) {
 		_soundReceiverSigmaButton->drawConditionalDataToScreen(0);
 		_soundReceiverSigmaPressed = false;
@@ -731,7 +710,7 @@ void Selenitic::o_soundReceiverSource(uint16 op, uint16 var, const ArgumentsArra
 	_vm->_cursor->showCursor();
 }
 
-void Selenitic::o_mazeRunnerDoorButton(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerDoorButton(uint16 var, const ArgumentsArray &args) {
 	// Used for Selenitic Maze Runner Exit Logic
 	uint16 cardIdExit = args[0];
 	uint16 cardIdEntry = args[1];
@@ -748,9 +727,7 @@ void Selenitic::o_mazeRunnerDoorButton(uint16 op, uint16 var, const ArgumentsArr
 	}
 }
 
-void Selenitic::o_soundReceiverUpdateSound(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound receiver update sound", op);
-
+void Selenitic::o_soundReceiverUpdateSound(uint16 var, const ArgumentsArray &args) {
 	soundReceiverUpdateSound();
 }
 
@@ -796,9 +773,7 @@ MystAreaSlider *Selenitic::soundLockSliderFromVar(uint16 var) {
 	return nullptr;
 }
 
-void Selenitic::o_soundLockMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound lock move", op);
-
+void Selenitic::o_soundLockMove(uint16 var, const ArgumentsArray &args) {
 	MystAreaSlider *slider = soundLockSliderFromVar(var);
 
 	uint16 soundId = soundLockCurrentSound(slider->_pos.y, true);
@@ -808,9 +783,7 @@ void Selenitic::o_soundLockMove(uint16 op, uint16 var, const ArgumentsArray &arg
 	}
 }
 
-void Selenitic::o_soundLockStartMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound lock start move", op);
-
+void Selenitic::o_soundLockStartMove(uint16 var, const ArgumentsArray &args) {
 	MystAreaSlider *slider = soundLockSliderFromVar(var);
 
 	_vm->_cursor->setCursor(700);
@@ -820,9 +793,7 @@ void Selenitic::o_soundLockStartMove(uint16 op, uint16 var, const ArgumentsArray
 	_vm->_sound->playEffect(_soundLockSoundId, true);
 }
 
-void Selenitic::o_soundLockEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound lock end move", op);
-
+void Selenitic::o_soundLockEndMove(uint16 var, const ArgumentsArray &args) {
 	MystAreaSlider *slider = soundLockSliderFromVar(var);
 	uint16 *value = &_state.soundLockSliderPositions[0];
 
@@ -879,9 +850,7 @@ void Selenitic::soundLockCheckSolution(MystAreaSlider *slider, uint16 value, uin
 	_vm->_sound->stopEffect();
 }
 
-void Selenitic::o_soundLockButton(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound lock button", op);
-
+void Selenitic::o_soundLockButton(uint16 var, const ArgumentsArray &args) {
 	bool solved = true;
 
 	_vm->_sound->pauseBackground();
@@ -920,9 +889,7 @@ void Selenitic::o_soundLockButton(uint16 op, uint16 var, const ArgumentsArray &a
 	_vm->_cursor->showCursor();
 }
 
-void Selenitic::o_soundReceiverEndMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound receiver end move", op);
-
+void Selenitic::o_soundReceiverEndMove(uint16 var, const ArgumentsArray &args) {
 	uint16 oldDirection = _soundReceiverDirection;
 
 	if (_soundReceiverDirection) {
@@ -937,15 +904,15 @@ void Selenitic::o_soundReceiverEndMove(uint16 op, uint16 var, const ArgumentsArr
 	}
 }
 
-void Selenitic::o_mazeRunnerCompass_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerCompass_init(uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerCompass = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Selenitic::o_mazeRunnerWindow_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerWindow_init(uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerWindow = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Selenitic::o_mazeRunnerLight_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerLight_init(uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerLight = getInvokingResource<MystAreaImageSwitch>();
 }
 
@@ -1065,9 +1032,7 @@ void Selenitic::soundReceiverSolution(uint16 source, uint16 &solution, bool &ena
 	}
 }
 
-void Selenitic::o_soundReceiver_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound receiver init", op);
-
+void Selenitic::o_soundReceiver_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 1245 (Sound Receiver)
 	_soundReceiverRunning = true;
 
@@ -1094,9 +1059,7 @@ void Selenitic::o_soundReceiver_init(uint16 op, uint16 var, const ArgumentsArray
 	_soundReceiverSigmaPressed = false;
 }
 
-void Selenitic::o_soundLock_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Sound lock init", op);
-
+void Selenitic::o_soundLock_init(uint16 var, const ArgumentsArray &args) {
 	for (uint i = 0; i < _vm->_resources.size(); i++) {
 		if (_vm->_resources[i]->type == kMystAreaSlider) {
 			switch (_vm->_resources[i]->getImageSwitchVar()) {
@@ -1129,11 +1092,11 @@ void Selenitic::o_soundLock_init(uint16 op, uint16 var, const ArgumentsArray &ar
 	_soundLockSoundId = 0;
 }
 
-void Selenitic::o_mazeRunnerRight_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerRight_init(uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerRightButton = getInvokingResource<MystAreaImageSwitch>();
 }
 
-void Selenitic::o_mazeRunnerLeft_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Selenitic::o_mazeRunnerLeft_init(uint16 var, const ArgumentsArray &args) {
 	_mazeRunnerLeftButton = getInvokingResource<MystAreaImageSwitch>();
 }
 
diff --git a/engines/mohawk/myst_stacks/selenitic.h b/engines/mohawk/myst_stacks/selenitic.h
index 706bee5..e0b4564 100644
--- a/engines/mohawk/myst_stacks/selenitic.h
+++ b/engines/mohawk/myst_stacks/selenitic.h
@@ -34,7 +34,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Selenitic : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp
index 851ce84..070724c 100644
--- a/engines/mohawk/myst_stacks/slides.cpp
+++ b/engines/mohawk/myst_stacks/slides.cpp
@@ -68,18 +68,14 @@ void Slides::runPersistentScripts() {
 	}
 }
 
-void Slides::o_returnToMenu(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Return to menu", op);
-
+void Slides::o_returnToMenu(uint16 var, const ArgumentsArray &args) {
 	// Go to the information screens of the menu
 	_vm->changeToStack(kDemoStack, 2002, 0, 0);
 }
 
-void Slides::o_setCardSwap(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Slides::o_setCardSwap(uint16 var, const ArgumentsArray &args) {
 	_nextCardID = args[0];
 
-	debugC(kDebugScript, "Opcode %d: Set next card %d", op, _nextCardID);
-
 	_nextCardTime = _vm->_system->getMillis() + 5000;
 	_cardSwapEnabled = true;
 }
diff --git a/engines/mohawk/myst_stacks/slides.h b/engines/mohawk/myst_stacks/slides.h
index 6215447..63fd9c8 100644
--- a/engines/mohawk/myst_stacks/slides.h
+++ b/engines/mohawk/myst_stacks/slides.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Slides : public MystScriptParser {
 public:
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 6196618..bfe1b19 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -383,9 +383,7 @@ bool Stoneship::setVarValue(uint16 var, uint16 value) {
 	return refresh;
 }
 
-void Stoneship::o_pumpTurnOff(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Turn off previous pump selection", op);
-
+void Stoneship::o_pumpTurnOff(uint16 var, const ArgumentsArray &args) {
 	if (_state.pumpState) {
 		uint16 buttonVar = 0;
 
@@ -413,17 +411,13 @@ void Stoneship::o_pumpTurnOff(uint16 op, uint16 var, const ArgumentsArray &args)
 	}
 }
 
-void Stoneship::o_brotherDoorOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Open brother door", op);
-
+void Stoneship::o_brotherDoorOpen(uint16 var, const ArgumentsArray &args) {
 	_brotherDoorOpen = 1;
 	_vm->redrawArea(19, 0);
 	animatedUpdate(args, 5);
 }
 
-void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Play Book Room Movie", op);
-
+void Stoneship::o_cabinBookMovie(uint16 var, const ArgumentsArray &args) {
 	uint16 startTime = args[0];
 	uint16 endTime = args[1];
 
@@ -436,9 +430,7 @@ void Stoneship::o_cabinBookMovie(uint16 op, uint16 var, const ArgumentsArray &ar
 	_vm->waitUntilMovieEnds(book);
 }
 
-void Stoneship::o_drawerOpenSirius(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Open drawer", op);
-
+void Stoneship::o_drawerOpenSirius(uint16 var, const ArgumentsArray &args) {
 	MystAreaImageSwitch *drawer = _vm->getViewResource<MystAreaImageSwitch>(args[0]);
 
 	if (drawer->getImageSwitchVar() == 35) {
@@ -454,20 +446,17 @@ void Stoneship::o_drawerOpenSirius(uint16 op, uint16 var, const ArgumentsArray &
 	_vm->_gfx->runTransition(transition, drawer->getRect(), 25, 5);
 }
 
-void Stoneship::o_drawerClose(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Close drawer", op);
+void Stoneship::o_drawerClose(uint16 var, const ArgumentsArray &args) {
 	drawerClose(args[0]);
 }
 
-void Stoneship::o_telescopeStart(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Stoneship::o_telescopeStart(uint16 var, const ArgumentsArray &args) {
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 	_telescopeOldMouse = mouse.x;
 	_vm->_cursor->setCursor(700);
 }
 
-void Stoneship::o_telescopeMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Telescope move", op);
-
+void Stoneship::o_telescopeMove(uint16 var, const ArgumentsArray &args) {
 	MystAreaDrag *display = getInvokingResource<MystAreaDrag>();
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 
@@ -483,13 +472,11 @@ void Stoneship::o_telescopeMove(uint16 op, uint16 var, const ArgumentsArray &arg
     telescopeLighthouseDraw();
 }
 
-void Stoneship::o_telescopeStop(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Stoneship::o_telescopeStop(uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 }
 
-void Stoneship::o_generatorStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generator start", op);
-
+void Stoneship::o_generatorStart(uint16 var, const ArgumentsArray &args) {
 	MystAreaDrag *handle = getInvokingResource<MystAreaDrag>();
 
 	uint16 soundId = handle->getList1(0);
@@ -513,9 +500,7 @@ void Stoneship::o_generatorStart(uint16 op, uint16 var, const ArgumentsArray &ar
 		_vm->_sound->playEffect(soundId, true);
 }
 
-void Stoneship::o_generatorStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Generator stop", op);
-
+void Stoneship::o_generatorStop(uint16 var, const ArgumentsArray &args) {
 	_batteryCharging = false;
 
 	if (_state.generatorDuration) {
@@ -580,18 +565,14 @@ void Stoneship::batteryDeplete_run() {
 	}
 }
 
-void Stoneship::o_drawerOpenAchenar(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Open drawer", op);
-
+void Stoneship::o_drawerOpenAchenar(uint16 var, const ArgumentsArray &args) {
 	MystAreaImageSwitch *drawer = _vm->getViewResource<MystAreaImageSwitch>(args[0]);
 	drawer->drawConditionalDataToScreen(0, 0);
 	_vm->_gfx->runTransition(kTransitionTopToBottom, drawer->getRect(), 25, 5);
 }
 
-void Stoneship::o_hologramPlayback(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Stoneship::o_hologramPlayback(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 2013 (Achenar's Rose-Skull Hologram)
-	debugC(kDebugScript, "Opcode %d: Rose-Skull Hologram Playback", op);
-
 	uint16 startPoint = args[0];
 	uint16 endPoint = args[1];
 	// uint16 direction = args[2];
@@ -610,14 +591,11 @@ void Stoneship::o_hologramPlayback(uint16 op, uint16 var, const ArgumentsArray &
 	_vm->waitUntilMovieEnds(displayMovie);
 }
 
-void Stoneship::o_hologramSelectionStart(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hologram start move", op);
+void Stoneship::o_hologramSelectionStart(uint16 var, const ArgumentsArray &args) {
 	//_vm->_cursor->setCursor(0);
 }
 
-void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hologram move", op);
-
+void Stoneship::o_hologramSelectionMove(uint16 var, const ArgumentsArray &args) {
 	MystAreaDrag *handle = getInvokingResource<MystAreaDrag>();
 	const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
 
@@ -642,13 +620,11 @@ void Stoneship::o_hologramSelectionMove(uint16 op, uint16 var, const ArgumentsAr
 	}
 }
 
-void Stoneship::o_hologramSelectionStop(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hologram stop move", op);
+void Stoneship::o_hologramSelectionStop(uint16 var, const ArgumentsArray &args) {
 	_vm->checkCursorHints();
 }
 
-void Stoneship::o_compassButton(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Compass rose button pressed", op);
+void Stoneship::o_compassButton(uint16 var, const ArgumentsArray &args) {
 	// Used on Card 2111 (Compass Rose)
 	// Called when Button Clicked.
 	uint16 correctButton = args[0];
@@ -666,12 +642,10 @@ void Stoneship::o_compassButton(uint16 op, uint16 var, const ArgumentsArray &arg
 		_batteryDepleting = false;
 	}
 
-	o_redrawCard(op, var, args);
+	o_redrawCard(var, args);
 }
 
-void Stoneship::o_chestValveVideos(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Chest valve videos", op);
-
+void Stoneship::o_chestValveVideos(uint16 var, const ArgumentsArray &args) {
 	Common::String movie = _vm->wrapMovieFilename("ligspig", kStoneshipStack);
 
 	_vm->_sound->playEffect(2132);
@@ -721,9 +695,7 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, const ArgumentsArray &
 	}
 }
 
-void Stoneship::o_chestDropKey(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: drop chest key", op);
-
+void Stoneship::o_chestDropKey(uint16 var, const ArgumentsArray &args) {
 	// If holding Key to Lamp Room Trapdoor, drop to bottom of
 	// Lighthouse...
 	if (_state.trapdoorKeyState == 1) {
@@ -732,9 +704,7 @@ void Stoneship::o_chestDropKey(uint16 op, uint16 var, const ArgumentsArray &args
 	}
 }
 
-void Stoneship::o_trapLockOpen(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Trap lock open video", op);
-
+void Stoneship::o_trapLockOpen(uint16 var, const ArgumentsArray &args) {
 	Common::String movie = _vm->wrapMovieFilename("openloc", kStoneshipStack);
 
 	VideoEntryPtr lock = _vm->_video->playMovie(movie);
@@ -759,13 +729,10 @@ void Stoneship::o_trapLockOpen(uint16 op, uint16 var, const ArgumentsArray &args
 		_vm->_sound->playEffect(4143);
 }
 
-void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Stoneship::o_sideDoorsMovies(uint16 var, const ArgumentsArray &args) {
 	// Used for Cards 2285, 2289, 2247, 2251 (Side Doors in Tunnels Down To Brothers Rooms)
 	uint16 movieId = args[0];
 
-	debugC(kDebugScript, "Opcode %d: Play Side Door Movies", op);
-	debugC(kDebugScript, "\tmovieId: %d", movieId);
-
 	_vm->_cursor->hideCursor();
 	_vm->_sound->pauseBackground();
 
@@ -795,24 +762,18 @@ void Stoneship::o_sideDoorsMovies(uint16 op, uint16 var, const ArgumentsArray &a
 	_vm->_cursor->showCursor();
 }
 
-void Stoneship::o_cloudOrbEnter(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Cloud orb enter", op);
-
+void Stoneship::o_cloudOrbEnter(uint16 var, const ArgumentsArray &args) {
 	_vm->_sound->playEffect(_cloudOrbSound, true);
 	_cloudOrbMovie->playMovie();
 }
 
-void Stoneship::o_cloudOrbLeave(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Cloud orb leave", op);
-
+void Stoneship::o_cloudOrbLeave(uint16 var, const ArgumentsArray &args) {
 	_cloudOrbMovie->pauseMovie(true);
 	_vm->_sound->playEffect(_cloudOrbStopSound);
 	_vm->_gfx->runTransition(kTransitionTopToBottom, getInvokingResource<MystArea>()->getRect(), 4, 0);
 }
 
-void Stoneship::o_drawerCloseOpened(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Close open drawer", op);
-
+void Stoneship::o_drawerCloseOpened(uint16 var, const ArgumentsArray &args) {
 	uint16 drawerOpen = getVar(var);
 	if (drawerOpen)
 		drawerClose(args[0] + drawerOpen - 1);
@@ -827,15 +788,13 @@ void Stoneship::drawerClose(uint16 drawer) {
 	_vm->_gfx->runTransition(kTransitionBottomToTop, res->getRect(), 25, 5);
 }
 
-void Stoneship::o_hologramDisplay_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hologram display init", op);
+void Stoneship::o_hologramDisplay_init(uint16 var, const ArgumentsArray &args) {
 	_hologramDisplay = getInvokingResource<MystAreaVideo>();
 
 	_hologramDisplayPos = 0;
 }
 
-void Stoneship::o_hologramSelection_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Hologram selection init", op);
+void Stoneship::o_hologramSelection_init(uint16 var, const ArgumentsArray &args) {
 	_hologramSelection = getInvokingResource<MystAreaVideo>();
 }
 
@@ -853,26 +812,21 @@ void Stoneship::batteryGaugeUpdate() {
 	_batteryGauge->setRect(rect);
 }
 
-void Stoneship::o_battery_init(uint16 op, uint16 var, const ArgumentsArray &args) {
+void Stoneship::o_battery_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 2160 (Lighthouse Battery Pack Closeup)
-	debugC(kDebugScript, "Opcode %d: Battery init", op);
-
 	_batteryGauge = getInvokingResource<MystAreaImageSwitch>();
 
 	batteryGaugeUpdate();
 }
 
-void Stoneship::o_tunnelEnter_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Tunnel enter", op);
-
-	o_tunnel_init(op, var, args);
+void Stoneship::o_tunnelEnter_init(uint16 var, const ArgumentsArray &args) {
+	o_tunnel_init(var, args);
 
 	_tunnelRunning = true;
 	_tunnelNextTime = _vm->_system->getMillis() + 1500;
 }
 
-void Stoneship::o_batteryGauge_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Battery gauge init", op);
+void Stoneship::o_batteryGauge_init(uint16 var, const ArgumentsArray &args) {
 	_batteryLastCharge = batteryRemainingCharge();
 	_batteryGaugeRunning = true;
 }
@@ -892,9 +846,7 @@ void Stoneship::batteryGauge_run() {
 	}
 }
 
-void Stoneship::o_tunnel_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-		debugC(kDebugScript, "Opcode %d: Tunnel card init", op);
-
+void Stoneship::o_tunnel_init(uint16 var, const ArgumentsArray &args) {
 		_tunnelImagesCount = args[0];
 
 		assert(_tunnelImagesCount <= 2 && "Too many images");
@@ -930,21 +882,15 @@ void Stoneship::tunnel_run() {
 	}
 }
 
-void Stoneship::o_tunnelLeave_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Tunnel leave", op);
-
+void Stoneship::o_tunnelLeave_init(uint16 var, const ArgumentsArray &args) {
 	_tunnelRunning = false;
 }
 
-void Stoneship::o_chest_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Chest init", op);
-
+void Stoneship::o_chest_init(uint16 var, const ArgumentsArray &args) {
 	_state.chestOpenState = 0;
 }
 
-void Stoneship::o_telescope_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Telescope init", op);
-
+void Stoneship::o_telescope_init(uint16 var, const ArgumentsArray &args) {
 	// Used in Card 2218 (Telescope view)
 	_telescopePanorama = args[0];
 	_telescopeLighthouseOff = args[1];
@@ -990,9 +936,7 @@ void Stoneship::telescopeLighthouseDraw() {
 	}
 }
 
-void Stoneship::o_achenarDrawers_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Achenar's Room Drawers Init", op);
-
+void Stoneship::o_achenarDrawers_init(uint16 var, const ArgumentsArray &args) {
 	// Used for Card 2004 (Achenar's Room Drawers)
 	if (!_chestAchenarBottomDrawerClosed) {
 		uint16 count1 = args[0];
@@ -1008,9 +952,7 @@ void Stoneship::o_achenarDrawers_init(uint16 op, uint16 var, const ArgumentsArra
 	}
 }
 
-void Stoneship::o_cloudOrb_init(uint16 op, uint16 var, const ArgumentsArray &args) {
-	debugC(kDebugScript, "Opcode %d: Cloud orb init", op);
-
+void Stoneship::o_cloudOrb_init(uint16 var, const ArgumentsArray &args) {
 	_cloudOrbMovie = getInvokingResource<MystAreaVideo>();
 	_cloudOrbSound = args[0];
 	_cloudOrbStopSound = args[1];
diff --git a/engines/mohawk/myst_stacks/stoneship.h b/engines/mohawk/myst_stacks/stoneship.h
index b98c410..dca7ce8 100644
--- a/engines/mohawk/myst_stacks/stoneship.h
+++ b/engines/mohawk/myst_stacks/stoneship.h
@@ -33,7 +33,7 @@ struct MystScriptEntry;
 
 namespace MystStacks {
 
-#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, const ArgumentsArray &args)
+#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
 
 class Stoneship : public MystScriptParser {
 public:


Commit: 757459bd49d9c2aeae1b346d58c033891f668875
    https://github.com/scummvm/scummvm/commit/757459bd49d9c2aeae1b346d58c033891f668875
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Don't cast function pointers when registering commands

Changed paths:
    engines/mohawk/myst_scripts.cpp
    engines/mohawk/myst_scripts.h
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/credits.cpp
    engines/mohawk/myst_stacks/demo.cpp
    engines/mohawk/myst_stacks/dni.cpp
    engines/mohawk/myst_stacks/intro.cpp
    engines/mohawk/myst_stacks/makingof.cpp
    engines/mohawk/myst_stacks/mechanical.cpp
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/preview.cpp
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/myst_stacks/slides.cpp
    engines/mohawk/myst_stacks/stoneship.cpp


diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index ce742f3..ba42650 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -84,71 +84,81 @@ MystScriptParser::MystScriptParser(MohawkEngine_Myst *vm) :
 }
 
 MystScriptParser::~MystScriptParser() {
-	for (uint32 i = 0; i < _opcodes.size(); i++)
-		delete _opcodes[i];
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, &MystScriptParser::x, #x))
-
 void MystScriptParser::setupCommonOpcodes() {
 	// These opcodes are common to each stack
 
 	// "Standard" Opcodes
-	OPCODE(0, o_toggleVar);
-	OPCODE(1, o_setVar);
-	OPCODE(2, o_changeCardSwitch4);
-	OPCODE(3, o_takePage);
-	OPCODE(4, o_redrawCard);
+	REGISTER_OPCODE(0, MystScriptParser, o_toggleVar);
+	REGISTER_OPCODE(1, MystScriptParser, o_setVar);
+	REGISTER_OPCODE(2, MystScriptParser, o_changeCardSwitch4);
+	REGISTER_OPCODE(3, MystScriptParser, o_takePage);
+	REGISTER_OPCODE(4, MystScriptParser, o_redrawCard);
 	// Opcode 5 Not Present
-	OPCODE(6, o_goToDestForward);
-	OPCODE(7, o_goToDestRight);
-	OPCODE(8, o_goToDestLeft);
-	OPCODE(9, o_triggerMovie);
-	OPCODE(10, o_toggleVarNoRedraw);
+	REGISTER_OPCODE(6, MystScriptParser, o_goToDestForward);
+	REGISTER_OPCODE(7, MystScriptParser, o_goToDestRight);
+	REGISTER_OPCODE(8, MystScriptParser, o_goToDestLeft);
+	REGISTER_OPCODE(9, MystScriptParser, o_triggerMovie);
+	REGISTER_OPCODE(10, MystScriptParser, o_toggleVarNoRedraw);
 	// Opcode 11 Not Present
-	OPCODE(12, o_changeCardSwitchLtR);
-	OPCODE(13, o_changeCardSwitchRtL);
-	OPCODE(14, o_drawAreaState);
-	OPCODE(15, o_redrawAreaForVar);
-	OPCODE(16, o_changeCardDirectional);
-	OPCODE(17, o_changeCardPush);
-	OPCODE(18, o_changeCardPop);
-	OPCODE(19, o_enableAreas);
-	OPCODE(20, o_disableAreas);
-	OPCODE(21, o_directionalUpdate);
-	OPCODE(22, o_goToDestUp);
-	OPCODE(23, o_toggleAreasActivation);
-	OPCODE(24, o_playSound);
+	REGISTER_OPCODE(12, MystScriptParser, o_changeCardSwitchLtR);
+	REGISTER_OPCODE(13, MystScriptParser, o_changeCardSwitchRtL);
+	REGISTER_OPCODE(14, MystScriptParser, o_drawAreaState);
+	REGISTER_OPCODE(15, MystScriptParser, o_redrawAreaForVar);
+	REGISTER_OPCODE(16, MystScriptParser, o_changeCardDirectional);
+	REGISTER_OPCODE(17, MystScriptParser, o_changeCardPush);
+	REGISTER_OPCODE(18, MystScriptParser, o_changeCardPop);
+	REGISTER_OPCODE(19, MystScriptParser, o_enableAreas);
+	REGISTER_OPCODE(20, MystScriptParser, o_disableAreas);
+	REGISTER_OPCODE(21, MystScriptParser, o_directionalUpdate);
+	REGISTER_OPCODE(22, MystScriptParser, o_goToDestUp);
+	REGISTER_OPCODE(23, MystScriptParser, o_toggleAreasActivation);
+	REGISTER_OPCODE(24, MystScriptParser, o_playSound);
 	// Opcode 25 is unused; original calls replaceSoundMyst
-	OPCODE(26, o_stopSoundBackground);
-	OPCODE(27, o_playSoundBlocking);
-	OPCODE(28, o_copyBackBufferToScreen);
-	OPCODE(29, o_copyImageToBackBuffer);
-	OPCODE(30, o_changeBackgroundSound);
-	OPCODE(31, o_soundPlaySwitch);
-	OPCODE(32, o_soundResumeBackground);
-	OPCODE(33, o_copyImageToScreen);
-	OPCODE(34, o_changeCard);
-	OPCODE(35, o_drawImageChangeCard);
-	OPCODE(36, o_changeMainCursor);
-	OPCODE(37, o_hideCursor);
-	OPCODE(38, o_showCursor);
-	OPCODE(39, o_delay);
-	OPCODE(40, o_changeStack);
-	OPCODE(41, o_changeCardPlaySoundDirectional);
-	OPCODE(42, o_directionalUpdatePlaySound);
-	OPCODE(43, o_saveMainCursor);
-	OPCODE(44, o_restoreMainCursor);
+	REGISTER_OPCODE(26, MystScriptParser, o_stopSoundBackground);
+	REGISTER_OPCODE(27, MystScriptParser, o_playSoundBlocking);
+	REGISTER_OPCODE(28, MystScriptParser, o_copyBackBufferToScreen);
+	REGISTER_OPCODE(29, MystScriptParser, o_copyImageToBackBuffer);
+	REGISTER_OPCODE(30, MystScriptParser, o_changeBackgroundSound);
+	REGISTER_OPCODE(31, MystScriptParser, o_soundPlaySwitch);
+	REGISTER_OPCODE(32, MystScriptParser, o_soundResumeBackground);
+	REGISTER_OPCODE(33, MystScriptParser, o_copyImageToScreen);
+	REGISTER_OPCODE(34, MystScriptParser, o_changeCard);
+	REGISTER_OPCODE(35, MystScriptParser, o_drawImageChangeCard);
+	REGISTER_OPCODE(36, MystScriptParser, o_changeMainCursor);
+	REGISTER_OPCODE(37, MystScriptParser, o_hideCursor);
+	REGISTER_OPCODE(38, MystScriptParser, o_showCursor);
+	REGISTER_OPCODE(39, MystScriptParser, o_delay);
+	REGISTER_OPCODE(40, MystScriptParser, o_changeStack);
+	REGISTER_OPCODE(41, MystScriptParser, o_changeCardPlaySoundDirectional);
+	REGISTER_OPCODE(42, MystScriptParser, o_directionalUpdatePlaySound);
+	REGISTER_OPCODE(43, MystScriptParser, o_saveMainCursor);
+	REGISTER_OPCODE(44, MystScriptParser, o_restoreMainCursor);
 	// Opcode 45 Not Present
-	OPCODE(46, o_soundWaitStop);
-	OPCODE(48, o_goToDest);
-	OPCODE(51, o_exitMap);
+	REGISTER_OPCODE(46, MystScriptParser, o_soundWaitStop);
+	REGISTER_OPCODE(48, MystScriptParser, o_goToDest);
+	REGISTER_OPCODE(51, MystScriptParser, o_exitMap);
 	// Opcodes 47 to 99 Not Present
 
-	OPCODE(0xFFFF, NOP);
+	REGISTER_OPCODE(0xFFFF, MystScriptParser, NOP);
+}
+
+void MystScriptParser::registerOpcode(uint16 op, const char *name, OpcodeProcMyst *command) {
+	_opcodes.push_back(MystOpcode(op, command, name));
 }
 
-#undef OPCODE
+void MystScriptParser::overrideOpcode(uint16 op, const char *name, MystScriptParser::OpcodeProcMyst *command) {
+	for (uint i = 0; i < _opcodes.size(); i++) {
+		if (_opcodes[i].op == op) {
+			_opcodes[i].desc = name;
+			_opcodes[i].proc = Common::SharedPtr<OpcodeProcMyst>(command);
+			return;
+		}
+	}
+
+	warning("Unable to find opcode %d to override with '%s'", op, name);
+}
 
 void MystScriptParser::runScript(MystScript script, MystArea *invokingResource) {
 	_scriptNestingLevel++;
@@ -172,12 +182,12 @@ void MystScriptParser::runOpcode(uint16 op, uint16 var, const ArgumentsArray &ar
 
 	bool ranOpcode = false;
 	for (uint16 i = 0; i < _opcodes.size(); i++)
-		if (_opcodes[i]->op == op) {
+		if (_opcodes[i].op == op) {
 			if (DebugMan.isDebugChannelEnabled(kDebugScript)) {
-				debugC(kDebugScript, "Running command: %s", describeCommand(*_opcodes[i], var, args).c_str());
+				debugC(kDebugScript, "Running command: %s", describeCommand(_opcodes[i], var, args).c_str());
 			}
 
-			(this->*(_opcodes[i]->proc)) (var, args);
+			(*_opcodes[i].proc)(var, args);
 			ranOpcode = true;
 			break;
 		}
@@ -194,8 +204,8 @@ bool MystScriptParser::isScriptRunning() const {
 
 const Common::String MystScriptParser::getOpcodeDesc(uint16 op) {
 	for (uint16 i = 0; i < _opcodes.size(); i++)
-		if (_opcodes[i]->op == op)
-			return _opcodes[i]->desc;
+		if (_opcodes[i].op == op)
+			return _opcodes[i].desc;
 
 	return Common::String::format("%d", op);
 }
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index ec22fec..a336f02 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -144,17 +144,20 @@ protected:
 	MohawkEngine_Myst *_vm;
 	MystGameState::Globals &_globals;
 
-	typedef void (MystScriptParser::*OpcodeProcMyst)(uint16 var, const ArgumentsArray &args);
+	typedef Common::Functor2<uint16, const ArgumentsArray &, void> OpcodeProcMyst;
 
-	struct MystOpcode {
-		MystOpcode(uint16 o, OpcodeProcMyst p, const char *d) : op(o), proc(p), desc(d) {}
+#define REGISTER_OPCODE(op, cls, method) \
+		registerOpcode( \
+			op, #method, new Common::Functor2Mem<uint16, const ArgumentsArray &, void, cls>(this, &cls::method) \
+		)
 
-		uint16 op;
-		OpcodeProcMyst proc;
-		const char *desc;
-	};
+#define OVERRIDE_OPCODE(op, cls, method) \
+		overrideOpcode( \
+			op, #method, new Common::Functor2Mem<uint16, const ArgumentsArray &, void, cls>(this, &cls::method) \
+		)
 
-	Common::Array<MystOpcode *> _opcodes;
+	void registerOpcode(uint16 op, const char *name, OpcodeProcMyst *command);
+	void overrideOpcode(uint16 op, const char *name, OpcodeProcMyst *command);
 
 	uint16 _savedCardId;
 	uint16 _savedMapCardId;
@@ -171,6 +174,16 @@ protected:
 	T *getInvokingResource() const;
 
 private:
+	struct MystOpcode {
+		MystOpcode(uint16 o, OpcodeProcMyst *p, const char *d) : op(o), proc(p), desc(d) {}
+
+		uint16 op;
+		Common::SharedPtr<OpcodeProcMyst> proc;
+		const char *desc;
+	};
+
+	Common::Array<MystOpcode> _opcodes;
+
 	MystArea *_invokingResource;
 	int32 _scriptNestingLevel;
 
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 208275d..4777e92 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -44,51 +44,47 @@ Channelwood::Channelwood(MohawkEngine_Myst *vm) :
 Channelwood::~Channelwood() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Channelwood::x, #x))
-
 void Channelwood::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_bridgeToggle);
-	OPCODE(101, o_pipeExtend);
-	OPCODE(102, o_drawImageChangeCardAndVolume);
-	OPCODE(104, o_waterTankValveOpen);
-	OPCODE(105, o_leverStartMove);
-	OPCODE(106, o_leverEndMove);
-	OPCODE(107, o_leverMoveFail);
-	OPCODE(108, o_leverMove);
-	OPCODE(109, o_stairsDoorToggle);
-	OPCODE(110, o_valveHandleMove1);
-	OPCODE(111, o_valveHandleMoveStart1);
-	OPCODE(112, o_valveHandleMoveStop);
-	OPCODE(113, o_valveHandleMove2);
-	OPCODE(114, o_valveHandleMoveStart2);
-	OPCODE(115, o_valveHandleMove3);
-	OPCODE(116, o_valveHandleMoveStart3);
-	OPCODE(117, o_hologramMonitor);
-	OPCODE(118, o_drawerOpen);
-	OPCODE(119, o_hologramTemple);
-	OPCODE(120, o_leverElev3StartMove);
-	OPCODE(121, o_leverElev3EndMove);
-	OPCODE(122, o_waterTankValveClose);
-	OPCODE(123, o_executeMouseUp);
-	OPCODE(124, o_leverEndMoveWithSound);
-	OPCODE(125, o_pumpLeverMove);
-	OPCODE(126, o_pumpLeverEndMove);
-	OPCODE(127, o_elevatorMovies);
-	OPCODE(128, o_leverEndMoveResumeBackground);
-	OPCODE(129, o_soundReplace);
+	REGISTER_OPCODE(100, Channelwood, o_bridgeToggle);
+	REGISTER_OPCODE(101, Channelwood, o_pipeExtend);
+	REGISTER_OPCODE(102, Channelwood, o_drawImageChangeCardAndVolume);
+	REGISTER_OPCODE(104, Channelwood, o_waterTankValveOpen);
+	REGISTER_OPCODE(105, Channelwood, o_leverStartMove);
+	REGISTER_OPCODE(106, Channelwood, o_leverEndMove);
+	REGISTER_OPCODE(107, Channelwood, o_leverMoveFail);
+	REGISTER_OPCODE(108, Channelwood, o_leverMove);
+	REGISTER_OPCODE(109, Channelwood, o_stairsDoorToggle);
+	REGISTER_OPCODE(110, Channelwood, o_valveHandleMove1);
+	REGISTER_OPCODE(111, Channelwood, o_valveHandleMoveStart1);
+	REGISTER_OPCODE(112, Channelwood, o_valveHandleMoveStop);
+	REGISTER_OPCODE(113, Channelwood, o_valveHandleMove2);
+	REGISTER_OPCODE(114, Channelwood, o_valveHandleMoveStart2);
+	REGISTER_OPCODE(115, Channelwood, o_valveHandleMove3);
+	REGISTER_OPCODE(116, Channelwood, o_valveHandleMoveStart3);
+	REGISTER_OPCODE(117, Channelwood, o_hologramMonitor);
+	REGISTER_OPCODE(118, Channelwood, o_drawerOpen);
+	REGISTER_OPCODE(119, Channelwood, o_hologramTemple);
+	REGISTER_OPCODE(120, Channelwood, o_leverElev3StartMove);
+	REGISTER_OPCODE(121, Channelwood, o_leverElev3EndMove);
+	REGISTER_OPCODE(122, Channelwood, o_waterTankValveClose);
+	REGISTER_OPCODE(123, Channelwood, o_executeMouseUp);
+	REGISTER_OPCODE(124, Channelwood, o_leverEndMoveWithSound);
+	REGISTER_OPCODE(125, Channelwood, o_pumpLeverMove);
+	REGISTER_OPCODE(126, Channelwood, o_pumpLeverEndMove);
+	REGISTER_OPCODE(127, Channelwood, o_elevatorMovies);
+	REGISTER_OPCODE(128, Channelwood, o_leverEndMoveResumeBackground);
+	REGISTER_OPCODE(129, Channelwood, o_soundReplace);
 
 	// "Init" Opcodes
-	OPCODE(201, o_lever_init);
-	OPCODE(202, o_pipeValve_init);
-	OPCODE(203, o_drawer_init);
+	REGISTER_OPCODE(201, Channelwood, o_lever_init);
+	REGISTER_OPCODE(202, Channelwood, o_pipeValve_init);
+	REGISTER_OPCODE(203, Channelwood, o_drawer_init);
 
 	// "Exit" Opcodes
-	OPCODE(300, NOP);
+	REGISTER_OPCODE(300, Channelwood, NOP);
 }
 
-#undef OPCODE
-
 void Channelwood::disablePersistentScripts() {
 
 }
diff --git a/engines/mohawk/myst_stacks/credits.cpp b/engines/mohawk/myst_stacks/credits.cpp
index 752e624..ba49ac2 100644
--- a/engines/mohawk/myst_stacks/credits.cpp
+++ b/engines/mohawk/myst_stacks/credits.cpp
@@ -42,18 +42,14 @@ Credits::Credits(MohawkEngine_Myst *vm) : MystScriptParser(vm) {
 Credits::~Credits() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Credits::x, #x))
-
 void Credits::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_quit);
+	REGISTER_OPCODE(100, Credits, o_quit);
 
 	// "Init" Opcodes
-	OPCODE(200, o_runCredits);
+	REGISTER_OPCODE(200, Credits, o_runCredits);
 }
 
-#undef OPCODE
-
 void Credits::disablePersistentScripts() {
 	_creditsRunning = false;
 }
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index 92c1dc7..7ae5568 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -39,29 +39,16 @@ Demo::Demo(MohawkEngine_Myst *vm) : Intro(vm) {
 Demo::~Demo() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Demo::x, #x))
-
-#define OVERRIDE_OPCODE(opcode, x) \
-	for (uint32 i = 0; i < _opcodes.size(); i++) \
-		if (_opcodes[i]->op == opcode) { \
-			_opcodes[i]->proc = (OpcodeProcMyst) &Demo::x; \
-			_opcodes[i]->desc = #x; \
-			break; \
-		}
-
 void Demo::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OVERRIDE_OPCODE(100, o_stopIntro);
-	OPCODE(101, o_fadeFromBlack);
-	OPCODE(102, o_fadeToBlack);
+	OVERRIDE_OPCODE(100, Demo, o_stopIntro);
+	REGISTER_OPCODE(101, Demo, o_fadeFromBlack);
+	REGISTER_OPCODE(102, Demo, o_fadeToBlack);
 
 	// "Init" Opcodes
-	OVERRIDE_OPCODE(201, o_returnToMenu_init);
+	OVERRIDE_OPCODE(201, Demo, o_returnToMenu_init);
 }
 
-#undef OPCODE
-#undef OVERRIDE_OPCODE
-
 void Demo::disablePersistentScripts() {
 	Intro::disablePersistentScripts();
 
diff --git a/engines/mohawk/myst_stacks/dni.cpp b/engines/mohawk/myst_stacks/dni.cpp
index b0b485b..c668a8c 100644
--- a/engines/mohawk/myst_stacks/dni.cpp
+++ b/engines/mohawk/myst_stacks/dni.cpp
@@ -42,22 +42,18 @@ Dni::Dni(MohawkEngine_Myst *vm) :
 Dni::~Dni() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Dni::x, #x))
-
 void Dni::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, NOP);
-	OPCODE(101, o_handPage);
+	REGISTER_OPCODE(100, Dni, NOP);
+	REGISTER_OPCODE(101, Dni, o_handPage);
 
 	// "Init" Opcodes
-	OPCODE(200, o_atrus_init);
+	REGISTER_OPCODE(200, Dni, o_atrus_init);
 
 	// "Exit" Opcodes
-	OPCODE(300, NOP);
+	REGISTER_OPCODE(300, Dni, NOP);
 }
 
-#undef OPCODE
-
 void Dni::disablePersistentScripts() {
 	_atrusRunning = false;
 	_waitForLoop = false;
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index c4cd209..b77fa08 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -38,22 +38,18 @@ Intro::Intro(MohawkEngine_Myst *vm) : MystScriptParser(vm) {
 Intro::~Intro() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Intro::x, #x))
-
 void Intro::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_useLinkBook);
+	REGISTER_OPCODE(100, Intro, o_useLinkBook);
 
 	// "Init" Opcodes
-	OPCODE(200, o_playIntroMovies);
-	OPCODE(201, o_mystLinkBook_init);
+	REGISTER_OPCODE(200, Intro, o_playIntroMovies);
+	REGISTER_OPCODE(201, Intro, o_mystLinkBook_init);
 
 	// "Exit" Opcodes
-	OPCODE(300, NOP);
+	REGISTER_OPCODE(300, Intro, NOP);
 }
 
-#undef OPCODE
-
 void Intro::disablePersistentScripts() {
 	_introMoviesRunning = false;
 	_linkBookRunning = false;
diff --git a/engines/mohawk/myst_stacks/makingof.cpp b/engines/mohawk/myst_stacks/makingof.cpp
index a0a1f35..2907c53 100644
--- a/engines/mohawk/myst_stacks/makingof.cpp
+++ b/engines/mohawk/myst_stacks/makingof.cpp
@@ -37,15 +37,11 @@ MakingOf::MakingOf(MohawkEngine_Myst *vm) : MystScriptParser(vm) {
 MakingOf::~MakingOf() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &MakingOf::x, #x))
-
 void MakingOf::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_quit);
+	REGISTER_OPCODE(100, MakingOf, o_quit);
 }
 
-#undef OPCODE
-
 void MakingOf::disablePersistentScripts() {
 }
 
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index fb109ac..0f07e8b 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -58,60 +58,56 @@ Mechanical::Mechanical(MohawkEngine_Myst *vm) :
 Mechanical::~Mechanical() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Mechanical::x, #x))
-
 void Mechanical::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_throneEnablePassage);
-	OPCODE(101, o_birdCrankStart);
-	OPCODE(102, NOP);
-	OPCODE(103, o_birdCrankStop);
-	OPCODE(104, o_snakeBoxTrigger);
-	OPCODE(105, o_fortressStaircaseMovie);
-	OPCODE(106, o_elevatorRotationStart);
-	OPCODE(107, o_elevatorRotationMove);
-	OPCODE(108, o_elevatorRotationStop);
-	OPCODE(109, o_fortressRotationSpeedStart);
-	OPCODE(110, o_fortressRotationSpeedMove);
-	OPCODE(111, o_fortressRotationSpeedStop);
-	OPCODE(112, o_fortressRotationBrakeStart);
-	OPCODE(113, o_fortressRotationBrakeMove);
-	OPCODE(114, o_fortressRotationBrakeStop);
-	OPCODE(115, o_fortressSimulationSpeedStart);
-	OPCODE(116, o_fortressSimulationSpeedMove);
-	OPCODE(117, o_fortressSimulationSpeedStop);
-	OPCODE(118, o_fortressSimulationBrakeStart);
-	OPCODE(119, o_fortressSimulationBrakeMove);
-	OPCODE(120, o_fortressSimulationBrakeStop);
-	OPCODE(121, o_elevatorWindowMovie);
-	OPCODE(122, o_elevatorGoMiddle);
-	OPCODE(123, o_elevatorTopMovie);
-	OPCODE(124, o_fortressRotationSetPosition);
-	OPCODE(125, o_mystStaircaseMovie);
-	OPCODE(126, o_elevatorWaitTimeout);
-	OPCODE(127, o_crystalEnterYellow);
-	OPCODE(128, o_crystalLeaveYellow);
-	OPCODE(129, o_crystalEnterGreen);
-	OPCODE(130, o_crystalLeaveGreen);
-	OPCODE(131, o_crystalEnterRed);
-	OPCODE(132, o_crystalLeaveRed);
+	REGISTER_OPCODE(100, Mechanical, o_throneEnablePassage);
+	REGISTER_OPCODE(101, Mechanical, o_birdCrankStart);
+	REGISTER_OPCODE(102, Mechanical, NOP);
+	REGISTER_OPCODE(103, Mechanical, o_birdCrankStop);
+	REGISTER_OPCODE(104, Mechanical, o_snakeBoxTrigger);
+	REGISTER_OPCODE(105, Mechanical, o_fortressStaircaseMovie);
+	REGISTER_OPCODE(106, Mechanical, o_elevatorRotationStart);
+	REGISTER_OPCODE(107, Mechanical, o_elevatorRotationMove);
+	REGISTER_OPCODE(108, Mechanical, o_elevatorRotationStop);
+	REGISTER_OPCODE(109, Mechanical, o_fortressRotationSpeedStart);
+	REGISTER_OPCODE(110, Mechanical, o_fortressRotationSpeedMove);
+	REGISTER_OPCODE(111, Mechanical, o_fortressRotationSpeedStop);
+	REGISTER_OPCODE(112, Mechanical, o_fortressRotationBrakeStart);
+	REGISTER_OPCODE(113, Mechanical, o_fortressRotationBrakeMove);
+	REGISTER_OPCODE(114, Mechanical, o_fortressRotationBrakeStop);
+	REGISTER_OPCODE(115, Mechanical, o_fortressSimulationSpeedStart);
+	REGISTER_OPCODE(116, Mechanical, o_fortressSimulationSpeedMove);
+	REGISTER_OPCODE(117, Mechanical, o_fortressSimulationSpeedStop);
+	REGISTER_OPCODE(118, Mechanical, o_fortressSimulationBrakeStart);
+	REGISTER_OPCODE(119, Mechanical, o_fortressSimulationBrakeMove);
+	REGISTER_OPCODE(120, Mechanical, o_fortressSimulationBrakeStop);
+	REGISTER_OPCODE(121, Mechanical, o_elevatorWindowMovie);
+	REGISTER_OPCODE(122, Mechanical, o_elevatorGoMiddle);
+	REGISTER_OPCODE(123, Mechanical, o_elevatorTopMovie);
+	REGISTER_OPCODE(124, Mechanical, o_fortressRotationSetPosition);
+	REGISTER_OPCODE(125, Mechanical, o_mystStaircaseMovie);
+	REGISTER_OPCODE(126, Mechanical, o_elevatorWaitTimeout);
+	REGISTER_OPCODE(127, Mechanical, o_crystalEnterYellow);
+	REGISTER_OPCODE(128, Mechanical, o_crystalLeaveYellow);
+	REGISTER_OPCODE(129, Mechanical, o_crystalEnterGreen);
+	REGISTER_OPCODE(130, Mechanical, o_crystalLeaveGreen);
+	REGISTER_OPCODE(131, Mechanical, o_crystalEnterRed);
+	REGISTER_OPCODE(132, Mechanical, o_crystalLeaveRed);
 
 	// "Init" Opcodes
-	OPCODE(200, o_throne_init);
-	OPCODE(201, o_fortressStaircase_init);
-	OPCODE(202, o_bird_init);
-	OPCODE(203, o_snakeBox_init);
-	OPCODE(204, o_elevatorRotation_init);
-	OPCODE(205, o_fortressRotation_init);
-	OPCODE(206, o_fortressSimulation_init);
-	OPCODE(209, o_fortressSimulationStartup_init);
+	REGISTER_OPCODE(200, Mechanical, o_throne_init);
+	REGISTER_OPCODE(201, Mechanical, o_fortressStaircase_init);
+	REGISTER_OPCODE(202, Mechanical, o_bird_init);
+	REGISTER_OPCODE(203, Mechanical, o_snakeBox_init);
+	REGISTER_OPCODE(204, Mechanical, o_elevatorRotation_init);
+	REGISTER_OPCODE(205, Mechanical, o_fortressRotation_init);
+	REGISTER_OPCODE(206, Mechanical, o_fortressSimulation_init);
+	REGISTER_OPCODE(209, Mechanical, o_fortressSimulationStartup_init);
 
 	// "Exit" Opcodes
-	OPCODE(300, NOP);
+	REGISTER_OPCODE(300, Mechanical, NOP);
 }
 
-#undef OPCODE
-
 void Mechanical::disablePersistentScripts() {
 	_fortressSimulationRunning = false;
 	_elevatorRotationLeverMoving = false;
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 1a6fc3e..8bf7596 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -66,151 +66,147 @@ Myst::Myst(MohawkEngine_Myst *vm) :
 Myst::~Myst() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Myst::x, #x))
-
 void Myst::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, NOP);
-	OPCODE(101, o_libraryBookPageTurnLeft);
-	OPCODE(102, o_libraryBookPageTurnRight);
-	OPCODE(103, o_fireplaceToggleButton);
-	OPCODE(104, o_fireplaceRotation);
-	OPCODE(105, o_courtyardBoxesCheckSolution);
-	OPCODE(106, o_towerRotationStart);
-	OPCODE(107, NOP);
-	OPCODE(108, o_towerRotationEnd);
-	OPCODE(109, o_imagerChangeSelection);
-	OPCODE(113, o_dockVaultOpen);
-	OPCODE(114, o_dockVaultClose);
-	OPCODE(115, o_bookGivePage);
-	OPCODE(116, o_clockWheelsExecute);
-	OPCODE(117, o_imagerPlayButton);
-	OPCODE(118, o_imagerEraseButton);
-	OPCODE(119, o_towerElevatorAnimation);
-	OPCODE(120, o_generatorButtonPressed);
-	OPCODE(121, o_cabinSafeChangeDigit);
-	OPCODE(122, o_cabinSafeHandleStartMove);
-	OPCODE(123, o_cabinSafeHandleMove);
-	OPCODE(124, o_cabinSafeHandleEndMove);
-	OPCODE(126, o_clockLeverStartMove);
-	OPCODE(127, o_clockLeverEndMove);
-	OPCODE(128, o_treePressureReleaseStart);
+	REGISTER_OPCODE(100, Myst, NOP);
+	REGISTER_OPCODE(101, Myst, o_libraryBookPageTurnLeft);
+	REGISTER_OPCODE(102, Myst, o_libraryBookPageTurnRight);
+	REGISTER_OPCODE(103, Myst, o_fireplaceToggleButton);
+	REGISTER_OPCODE(104, Myst, o_fireplaceRotation);
+	REGISTER_OPCODE(105, Myst, o_courtyardBoxesCheckSolution);
+	REGISTER_OPCODE(106, Myst, o_towerRotationStart);
+	REGISTER_OPCODE(107, Myst, NOP);
+	REGISTER_OPCODE(108, Myst, o_towerRotationEnd);
+	REGISTER_OPCODE(109, Myst, o_imagerChangeSelection);
+	REGISTER_OPCODE(113, Myst, o_dockVaultOpen);
+	REGISTER_OPCODE(114, Myst, o_dockVaultClose);
+	REGISTER_OPCODE(115, Myst, o_bookGivePage);
+	REGISTER_OPCODE(116, Myst, o_clockWheelsExecute);
+	REGISTER_OPCODE(117, Myst, o_imagerPlayButton);
+	REGISTER_OPCODE(118, Myst, o_imagerEraseButton);
+	REGISTER_OPCODE(119, Myst, o_towerElevatorAnimation);
+	REGISTER_OPCODE(120, Myst, o_generatorButtonPressed);
+	REGISTER_OPCODE(121, Myst, o_cabinSafeChangeDigit);
+	REGISTER_OPCODE(122, Myst, o_cabinSafeHandleStartMove);
+	REGISTER_OPCODE(123, Myst, o_cabinSafeHandleMove);
+	REGISTER_OPCODE(124, Myst, o_cabinSafeHandleEndMove);
+	REGISTER_OPCODE(126, Myst, o_clockLeverStartMove);
+	REGISTER_OPCODE(127, Myst, o_clockLeverEndMove);
+	REGISTER_OPCODE(128, Myst, o_treePressureReleaseStart);
 	if (!observatoryIsDDMMYYYY2400()) {
-		OPCODE(129, o_observatoryMonthChangeStartIncrease);
-		OPCODE(130, o_observatoryMonthChangeStartDecrease);
-		OPCODE(131, o_observatoryDayChangeStartIncrease);
-		OPCODE(132, o_observatoryDayChangeStartDecrease);
+		REGISTER_OPCODE(129, Myst, o_observatoryMonthChangeStartIncrease);
+		REGISTER_OPCODE(130, Myst, o_observatoryMonthChangeStartDecrease);
+		REGISTER_OPCODE(131, Myst, o_observatoryDayChangeStartIncrease);
+		REGISTER_OPCODE(132, Myst, o_observatoryDayChangeStartDecrease);
 	} else {
-		OPCODE(129, o_observatoryDayChangeStartIncrease);
-		OPCODE(130, o_observatoryDayChangeStartDecrease);
-		OPCODE(131, o_observatoryMonthChangeStartIncrease);
-		OPCODE(132, o_observatoryMonthChangeStartDecrease);
-	}
-	OPCODE(133, o_observatoryGoButton);
-	OPCODE(134, o_observatoryMonthSliderMove);
-	OPCODE(135, o_observatoryDaySliderMove);
-	OPCODE(136, o_observatoryYearSliderMove);
-	OPCODE(137, o_observatoryTimeSliderMove);
-	OPCODE(138, o_clockResetLeverStartMove);
-	OPCODE(139, o_clockResetLeverMove);
-	OPCODE(140, o_clockResetLeverEndMove);
-	OPCODE(141, o_circuitBreakerStartMove);
-	OPCODE(142, o_circuitBreakerMove);
-	OPCODE(143, o_circuitBreakerEndMove);
-	OPCODE(144, o_clockLeverMoveLeft);
-	OPCODE(145, o_clockLeverMoveRight);
-	OPCODE(146, o_boilerIncreasePressureStart);
-	OPCODE(147, o_boilerLightPilot);
-	OPCODE(148, NOP);
-	OPCODE(149, o_boilerIncreasePressureStop);
-	OPCODE(150, o_boilerDecreasePressureStart);
-	OPCODE(151, o_boilerDecreasePressureStop);
-	OPCODE(152, NOP);
-	OPCODE(153, o_basementIncreasePressureStart);
-	OPCODE(154, o_basementIncreasePressureStop);
-	OPCODE(155, o_basementDecreasePressureStart);
-	OPCODE(156, o_basementDecreasePressureStop);
-	OPCODE(157, o_rocketPianoMove);
-	OPCODE(158, o_rocketSoundSliderStartMove);
-	OPCODE(159, o_rocketSoundSliderMove);
-	OPCODE(160, o_rocketSoundSliderEndMove);
-	OPCODE(161, o_rocketPianoStart);
-	OPCODE(162, o_rocketPianoStop);
-	OPCODE(163, o_rocketLeverStartMove);
-	OPCODE(164, o_rocketOpenBook);
-	OPCODE(165, o_rocketLeverMove);
-	OPCODE(166, o_rocketLeverEndMove);
-	OPCODE(167, NOP);
-	OPCODE(168, o_treePressureReleaseStop);
-	OPCODE(169, o_cabinLeave);
-	OPCODE(170, o_observatoryMonthSliderStartMove);
-	OPCODE(171, o_observatoryMonthSliderEndMove);
-	OPCODE(172, o_observatoryDaySliderStartMove);
-	OPCODE(173, o_observatoryDaySliderEndMove);
-	OPCODE(174, o_observatoryYearSliderStartMove);
-	OPCODE(175, o_observatoryYearSliderEndMove);
-	OPCODE(176, o_observatoryTimeSliderStartMove);
-	OPCODE(177, o_observatoryTimeSliderEndMove);
-	OPCODE(180, o_libraryCombinationBookStop);
-	OPCODE(181, NOP);
-	OPCODE(182, o_cabinMatchLight);
-	OPCODE(183, o_courtyardBoxEnter);
-	OPCODE(184, o_courtyardBoxLeave);
-	OPCODE(185, NOP);
-	OPCODE(186, o_clockMinuteWheelStartTurn);
-	OPCODE(187, NOP);
-	OPCODE(188, o_clockWheelEndTurn);
-	OPCODE(189, o_clockHourWheelStartTurn);
-	OPCODE(190, o_libraryCombinationBookStartRight);
-	OPCODE(191, o_libraryCombinationBookStartLeft);
-	OPCODE(192, o_observatoryTimeChangeStartIncrease);
-	OPCODE(193, NOP);
-	OPCODE(194, o_observatoryChangeSettingStop);
-	OPCODE(195, o_observatoryTimeChangeStartDecrease);
-	OPCODE(196, o_observatoryYearChangeStartIncrease);
-	OPCODE(197, o_observatoryYearChangeStartDecrease);
-	OPCODE(198, o_dockVaultForceClose);
-	OPCODE(199, o_imagerEraseStop);
+		REGISTER_OPCODE(129, Myst, o_observatoryDayChangeStartIncrease);
+		REGISTER_OPCODE(130, Myst, o_observatoryDayChangeStartDecrease);
+		REGISTER_OPCODE(131, Myst, o_observatoryMonthChangeStartIncrease);
+		REGISTER_OPCODE(132, Myst, o_observatoryMonthChangeStartDecrease);
+	}
+	REGISTER_OPCODE(133, Myst, o_observatoryGoButton);
+	REGISTER_OPCODE(134, Myst, o_observatoryMonthSliderMove);
+	REGISTER_OPCODE(135, Myst, o_observatoryDaySliderMove);
+	REGISTER_OPCODE(136, Myst, o_observatoryYearSliderMove);
+	REGISTER_OPCODE(137, Myst, o_observatoryTimeSliderMove);
+	REGISTER_OPCODE(138, Myst, o_clockResetLeverStartMove);
+	REGISTER_OPCODE(139, Myst, o_clockResetLeverMove);
+	REGISTER_OPCODE(140, Myst, o_clockResetLeverEndMove);
+	REGISTER_OPCODE(141, Myst, o_circuitBreakerStartMove);
+	REGISTER_OPCODE(142, Myst, o_circuitBreakerMove);
+	REGISTER_OPCODE(143, Myst, o_circuitBreakerEndMove);
+	REGISTER_OPCODE(144, Myst, o_clockLeverMoveLeft);
+	REGISTER_OPCODE(145, Myst, o_clockLeverMoveRight);
+	REGISTER_OPCODE(146, Myst, o_boilerIncreasePressureStart);
+	REGISTER_OPCODE(147, Myst, o_boilerLightPilot);
+	REGISTER_OPCODE(148, Myst, NOP);
+	REGISTER_OPCODE(149, Myst, o_boilerIncreasePressureStop);
+	REGISTER_OPCODE(150, Myst, o_boilerDecreasePressureStart);
+	REGISTER_OPCODE(151, Myst, o_boilerDecreasePressureStop);
+	REGISTER_OPCODE(152, Myst, NOP);
+	REGISTER_OPCODE(153, Myst, o_basementIncreasePressureStart);
+	REGISTER_OPCODE(154, Myst, o_basementIncreasePressureStop);
+	REGISTER_OPCODE(155, Myst, o_basementDecreasePressureStart);
+	REGISTER_OPCODE(156, Myst, o_basementDecreasePressureStop);
+	REGISTER_OPCODE(157, Myst, o_rocketPianoMove);
+	REGISTER_OPCODE(158, Myst, o_rocketSoundSliderStartMove);
+	REGISTER_OPCODE(159, Myst, o_rocketSoundSliderMove);
+	REGISTER_OPCODE(160, Myst, o_rocketSoundSliderEndMove);
+	REGISTER_OPCODE(161, Myst, o_rocketPianoStart);
+	REGISTER_OPCODE(162, Myst, o_rocketPianoStop);
+	REGISTER_OPCODE(163, Myst, o_rocketLeverStartMove);
+	REGISTER_OPCODE(164, Myst, o_rocketOpenBook);
+	REGISTER_OPCODE(165, Myst, o_rocketLeverMove);
+	REGISTER_OPCODE(166, Myst, o_rocketLeverEndMove);
+	REGISTER_OPCODE(167, Myst, NOP);
+	REGISTER_OPCODE(168, Myst, o_treePressureReleaseStop);
+	REGISTER_OPCODE(169, Myst, o_cabinLeave);
+	REGISTER_OPCODE(170, Myst, o_observatoryMonthSliderStartMove);
+	REGISTER_OPCODE(171, Myst, o_observatoryMonthSliderEndMove);
+	REGISTER_OPCODE(172, Myst, o_observatoryDaySliderStartMove);
+	REGISTER_OPCODE(173, Myst, o_observatoryDaySliderEndMove);
+	REGISTER_OPCODE(174, Myst, o_observatoryYearSliderStartMove);
+	REGISTER_OPCODE(175, Myst, o_observatoryYearSliderEndMove);
+	REGISTER_OPCODE(176, Myst, o_observatoryTimeSliderStartMove);
+	REGISTER_OPCODE(177, Myst, o_observatoryTimeSliderEndMove);
+	REGISTER_OPCODE(180, Myst, o_libraryCombinationBookStop);
+	REGISTER_OPCODE(181, Myst, NOP);
+	REGISTER_OPCODE(182, Myst, o_cabinMatchLight);
+	REGISTER_OPCODE(183, Myst, o_courtyardBoxEnter);
+	REGISTER_OPCODE(184, Myst, o_courtyardBoxLeave);
+	REGISTER_OPCODE(185, Myst, NOP);
+	REGISTER_OPCODE(186, Myst, o_clockMinuteWheelStartTurn);
+	REGISTER_OPCODE(187, Myst, NOP);
+	REGISTER_OPCODE(188, Myst, o_clockWheelEndTurn);
+	REGISTER_OPCODE(189, Myst, o_clockHourWheelStartTurn);
+	REGISTER_OPCODE(190, Myst, o_libraryCombinationBookStartRight);
+	REGISTER_OPCODE(191, Myst, o_libraryCombinationBookStartLeft);
+	REGISTER_OPCODE(192, Myst, o_observatoryTimeChangeStartIncrease);
+	REGISTER_OPCODE(193, Myst, NOP);
+	REGISTER_OPCODE(194, Myst, o_observatoryChangeSettingStop);
+	REGISTER_OPCODE(195, Myst, o_observatoryTimeChangeStartDecrease);
+	REGISTER_OPCODE(196, Myst, o_observatoryYearChangeStartIncrease);
+	REGISTER_OPCODE(197, Myst, o_observatoryYearChangeStartDecrease);
+	REGISTER_OPCODE(198, Myst, o_dockVaultForceClose);
+	REGISTER_OPCODE(199, Myst, o_imagerEraseStop);
 
 	// "Init" Opcodes
-	OPCODE(200, o_libraryBook_init);
-	OPCODE(201, o_courtyardBox_init);
-	OPCODE(202, o_towerRotationMap_init);
-	OPCODE(203, o_forechamberDoor_init);
-	OPCODE(204, o_shipAccess_init);
-	OPCODE(205, NOP);
-	OPCODE(206, o_butterflies_init);
-	OPCODE(208, o_imager_init);
-	OPCODE(209, o_libraryBookcaseTransform_init);
-	OPCODE(210, o_generatorControlRoom_init);
-	OPCODE(211, o_fireplace_init);
-	OPCODE(212, o_clockGears_init);
-	OPCODE(213, o_gulls1_init);
-	OPCODE(214, o_observatory_init);
-	OPCODE(215, o_gulls2_init);
-	OPCODE(216, o_treeCard_init);
-	OPCODE(217, o_treeEntry_init);
-	OPCODE(218, o_boilerMovies_init);
-	OPCODE(219, o_rocketSliders_init);
-	OPCODE(220, o_rocketLinkVideo_init);
-	OPCODE(221, o_greenBook_init);
-	OPCODE(222, o_gulls3_init);
+	REGISTER_OPCODE(200, Myst, o_libraryBook_init);
+	REGISTER_OPCODE(201, Myst, o_courtyardBox_init);
+	REGISTER_OPCODE(202, Myst, o_towerRotationMap_init);
+	REGISTER_OPCODE(203, Myst, o_forechamberDoor_init);
+	REGISTER_OPCODE(204, Myst, o_shipAccess_init);
+	REGISTER_OPCODE(205, Myst, NOP);
+	REGISTER_OPCODE(206, Myst, o_butterflies_init);
+	REGISTER_OPCODE(208, Myst, o_imager_init);
+	REGISTER_OPCODE(209, Myst, o_libraryBookcaseTransform_init);
+	REGISTER_OPCODE(210, Myst, o_generatorControlRoom_init);
+	REGISTER_OPCODE(211, Myst, o_fireplace_init);
+	REGISTER_OPCODE(212, Myst, o_clockGears_init);
+	REGISTER_OPCODE(213, Myst, o_gulls1_init);
+	REGISTER_OPCODE(214, Myst, o_observatory_init);
+	REGISTER_OPCODE(215, Myst, o_gulls2_init);
+	REGISTER_OPCODE(216, Myst, o_treeCard_init);
+	REGISTER_OPCODE(217, Myst, o_treeEntry_init);
+	REGISTER_OPCODE(218, Myst, o_boilerMovies_init);
+	REGISTER_OPCODE(219, Myst, o_rocketSliders_init);
+	REGISTER_OPCODE(220, Myst, o_rocketLinkVideo_init);
+	REGISTER_OPCODE(221, Myst, o_greenBook_init);
+	REGISTER_OPCODE(222, Myst, o_gulls3_init);
 
 	// "Exit" Opcodes
-	OPCODE(300, o_bookAddSpecialPage_exit);
-	OPCODE(301, NOP);
-	OPCODE(302, NOP);
-	OPCODE(303, NOP);
-	OPCODE(304, o_treeCard_exit);
-	OPCODE(305, o_treeEntry_exit);
-	OPCODE(306, o_boiler_exit);
-	OPCODE(307, o_generatorControlRoom_exit);
-	OPCODE(308, NOP);
-	OPCODE(309, NOP);
-	OPCODE(312, NOP);
-}
-
-#undef OPCODE
+	REGISTER_OPCODE(300, Myst, o_bookAddSpecialPage_exit);
+	REGISTER_OPCODE(301, Myst, NOP);
+	REGISTER_OPCODE(302, Myst, NOP);
+	REGISTER_OPCODE(303, Myst, NOP);
+	REGISTER_OPCODE(304, Myst, o_treeCard_exit);
+	REGISTER_OPCODE(305, Myst, o_treeEntry_exit);
+	REGISTER_OPCODE(306, Myst, o_boiler_exit);
+	REGISTER_OPCODE(307, Myst, o_generatorControlRoom_exit);
+	REGISTER_OPCODE(308, Myst, NOP);
+	REGISTER_OPCODE(309, Myst, NOP);
+	REGISTER_OPCODE(312, Myst, NOP);
+}
 
 void Myst::disablePersistentScripts() {
 	_libraryBookcaseMoving = false;
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index 9ad40b0..bc0dd04 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -42,32 +42,19 @@ Preview::Preview(MohawkEngine_Myst *vm) : Myst(vm) {
 Preview::~Preview() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Preview::x, #x))
-
-#define OVERRIDE_OPCODE(opcode, x) \
-	for (uint32 i = 0; i < _opcodes.size(); i++) \
-		if (_opcodes[i]->op == opcode) { \
-			_opcodes[i]->proc = (OpcodeProcMyst) &Preview::x; \
-			_opcodes[i]->desc = #x; \
-			break; \
-		}
-
 void Preview::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OVERRIDE_OPCODE(196, o_fadeToBlack);
-	OVERRIDE_OPCODE(197, o_fadeFromBlack);
-	OVERRIDE_OPCODE(198, o_stayHere);
-	OVERRIDE_OPCODE(199, o_speechStop);
+	OVERRIDE_OPCODE(196, Preview, o_fadeToBlack);
+	OVERRIDE_OPCODE(197, Preview, o_fadeFromBlack);
+	OVERRIDE_OPCODE(198, Preview, o_stayHere);
+	OVERRIDE_OPCODE(199, Preview, o_speechStop);
 
 	// "Init" Opcodes
-	OVERRIDE_OPCODE(209, o_libraryBookcaseTransformDemo_init);
-	OPCODE(298, o_speech_init);
-	OPCODE(299, o_library_init);
+	OVERRIDE_OPCODE(209, Preview, o_libraryBookcaseTransformDemo_init);
+	REGISTER_OPCODE(298, Preview, o_speech_init);
+	REGISTER_OPCODE(299, Preview, o_library_init);
 }
 
-#undef OPCODE
-#undef OVERRIDE_OPCODE
-
 void Preview::disablePersistentScripts() {
 	Myst::disablePersistentScripts();
 }
diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 427635b..087143a 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -49,41 +49,37 @@ Selenitic::Selenitic(MohawkEngine_Myst *vm) :
 Selenitic::~Selenitic() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Selenitic::x, #x))
-
 void Selenitic::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_mazeRunnerMove);
-	OPCODE(101, o_mazeRunnerSoundRepeat);
-	OPCODE(102, o_soundReceiverSigma);
-	OPCODE(103, o_soundReceiverRight);
-	OPCODE(104, o_soundReceiverLeft);
-	OPCODE(105, o_soundReceiverSource);
-	OPCODE(106, o_soundReceiverSource);
-	OPCODE(107, o_soundReceiverSource);
-	OPCODE(108, o_soundReceiverSource);
-	OPCODE(109, o_soundReceiverSource);
-	OPCODE(110, o_mazeRunnerDoorButton);
-	OPCODE(111, o_soundReceiverUpdateSound);
-	OPCODE(112, o_soundLockMove);
-	OPCODE(113, o_soundLockStartMove);
-	OPCODE(114, o_soundLockEndMove);
-	OPCODE(115, o_soundLockButton);
-	OPCODE(116, NOP);
-	OPCODE(117, o_soundReceiverEndMove);
+	REGISTER_OPCODE(100, Selenitic, o_mazeRunnerMove);
+	REGISTER_OPCODE(101, Selenitic, o_mazeRunnerSoundRepeat);
+	REGISTER_OPCODE(102, Selenitic, o_soundReceiverSigma);
+	REGISTER_OPCODE(103, Selenitic, o_soundReceiverRight);
+	REGISTER_OPCODE(104, Selenitic, o_soundReceiverLeft);
+	REGISTER_OPCODE(105, Selenitic, o_soundReceiverSource);
+	REGISTER_OPCODE(106, Selenitic, o_soundReceiverSource);
+	REGISTER_OPCODE(107, Selenitic, o_soundReceiverSource);
+	REGISTER_OPCODE(108, Selenitic, o_soundReceiverSource);
+	REGISTER_OPCODE(109, Selenitic, o_soundReceiverSource);
+	REGISTER_OPCODE(110, Selenitic, o_mazeRunnerDoorButton);
+	REGISTER_OPCODE(111, Selenitic, o_soundReceiverUpdateSound);
+	REGISTER_OPCODE(112, Selenitic, o_soundLockMove);
+	REGISTER_OPCODE(113, Selenitic, o_soundLockStartMove);
+	REGISTER_OPCODE(114, Selenitic, o_soundLockEndMove);
+	REGISTER_OPCODE(115, Selenitic, o_soundLockButton);
+	REGISTER_OPCODE(116, Selenitic, NOP);
+	REGISTER_OPCODE(117, Selenitic, o_soundReceiverEndMove);
 
 	// "Init" Opcodes
-	OPCODE(200, o_mazeRunnerCompass_init);
-	OPCODE(201, o_mazeRunnerWindow_init);
-	OPCODE(202, o_mazeRunnerLight_init);
-	OPCODE(203, o_soundReceiver_init);
-	OPCODE(204, o_soundLock_init);
-	OPCODE(205, o_mazeRunnerRight_init);
-	OPCODE(206, o_mazeRunnerLeft_init);
+	REGISTER_OPCODE(200, Selenitic, o_mazeRunnerCompass_init);
+	REGISTER_OPCODE(201, Selenitic, o_mazeRunnerWindow_init);
+	REGISTER_OPCODE(202, Selenitic, o_mazeRunnerLight_init);
+	REGISTER_OPCODE(203, Selenitic, o_soundReceiver_init);
+	REGISTER_OPCODE(204, Selenitic, o_soundLock_init);
+	REGISTER_OPCODE(205, Selenitic, o_mazeRunnerRight_init);
+	REGISTER_OPCODE(206, Selenitic, o_mazeRunnerLeft_init);
 }
 
-#undef OPCODE
-
 void Selenitic::disablePersistentScripts() {
 	_soundReceiverRunning = false;
 }
diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp
index 070724c..f8c388d 100644
--- a/engines/mohawk/myst_stacks/slides.cpp
+++ b/engines/mohawk/myst_stacks/slides.cpp
@@ -41,18 +41,14 @@ Slides::Slides(MohawkEngine_Myst *vm) : MystScriptParser(vm) {
 Slides::~Slides() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Slides::x, #x))
-
 void Slides::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_returnToMenu);
+	REGISTER_OPCODE(100, Slides, o_returnToMenu);
 
 	// "Init" Opcodes
-	OPCODE(200, o_setCardSwap);
+	REGISTER_OPCODE(200, Slides, o_setCardSwap);
 }
 
-#undef OPCODE
-
 void Slides::disablePersistentScripts() {
 	_cardSwapEnabled = false;
 }
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index bfe1b19..f4b3830 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -66,54 +66,50 @@ Stoneship::Stoneship(MohawkEngine_Myst *vm) :
 Stoneship::~Stoneship() {
 }
 
-#define OPCODE(op, x) _opcodes.push_back(new MystOpcode(op, (OpcodeProcMyst) &Stoneship::x, #x))
-
 void Stoneship::setupOpcodes() {
 	// "Stack-Specific" Opcodes
-	OPCODE(100, o_pumpTurnOff);
-	OPCODE(101, o_brotherDoorOpen);
-	OPCODE(102, o_cabinBookMovie);
-	OPCODE(103, o_drawerOpenSirius);
-	OPCODE(104, o_drawerClose);
-	OPCODE(105, o_telescopeStart);
-	OPCODE(106, o_telescopeMove);
-	OPCODE(107, o_telescopeStop);
-	OPCODE(108, o_generatorStart);
-	OPCODE(109, NOP);
-	OPCODE(110, o_generatorStop);
-	OPCODE(111, o_drawerOpenAchenar);
-	OPCODE(112, o_hologramPlayback);
-	OPCODE(113, o_hologramSelectionStart);
-	OPCODE(114, o_hologramSelectionMove);
-	OPCODE(115, o_hologramSelectionStop);
-	OPCODE(116, o_compassButton);
-	OPCODE(117, o_chestValveVideos);
-	OPCODE(118, o_chestDropKey);
-	OPCODE(119, o_trapLockOpen);
-	OPCODE(120, o_sideDoorsMovies);
-	OPCODE(121, o_cloudOrbEnter);
-	OPCODE(122, o_cloudOrbLeave);
-	OPCODE(125, o_drawerCloseOpened);
+	REGISTER_OPCODE(100, Stoneship, o_pumpTurnOff);
+	REGISTER_OPCODE(101, Stoneship, o_brotherDoorOpen);
+	REGISTER_OPCODE(102, Stoneship, o_cabinBookMovie);
+	REGISTER_OPCODE(103, Stoneship, o_drawerOpenSirius);
+	REGISTER_OPCODE(104, Stoneship, o_drawerClose);
+	REGISTER_OPCODE(105, Stoneship, o_telescopeStart);
+	REGISTER_OPCODE(106, Stoneship, o_telescopeMove);
+	REGISTER_OPCODE(107, Stoneship, o_telescopeStop);
+	REGISTER_OPCODE(108, Stoneship, o_generatorStart);
+	REGISTER_OPCODE(109, Stoneship, NOP);
+	REGISTER_OPCODE(110, Stoneship, o_generatorStop);
+	REGISTER_OPCODE(111, Stoneship, o_drawerOpenAchenar);
+	REGISTER_OPCODE(112, Stoneship, o_hologramPlayback);
+	REGISTER_OPCODE(113, Stoneship, o_hologramSelectionStart);
+	REGISTER_OPCODE(114, Stoneship, o_hologramSelectionMove);
+	REGISTER_OPCODE(115, Stoneship, o_hologramSelectionStop);
+	REGISTER_OPCODE(116, Stoneship, o_compassButton);
+	REGISTER_OPCODE(117, Stoneship, o_chestValveVideos);
+	REGISTER_OPCODE(118, Stoneship, o_chestDropKey);
+	REGISTER_OPCODE(119, Stoneship, o_trapLockOpen);
+	REGISTER_OPCODE(120, Stoneship, o_sideDoorsMovies);
+	REGISTER_OPCODE(121, Stoneship, o_cloudOrbEnter);
+	REGISTER_OPCODE(122, Stoneship, o_cloudOrbLeave);
+	REGISTER_OPCODE(125, Stoneship, o_drawerCloseOpened);
 
 	// "Init" Opcodes
-	OPCODE(200, o_hologramDisplay_init);
-	OPCODE(201, o_hologramSelection_init);
-	OPCODE(202, o_battery_init);
-	OPCODE(203, o_tunnelEnter_init);
-	OPCODE(204, o_batteryGauge_init);
-	OPCODE(205, o_tunnel_init);
-	OPCODE(206, o_tunnelLeave_init);
-	OPCODE(207, o_chest_init);
-	OPCODE(208, o_telescope_init);
-	OPCODE(209, o_achenarDrawers_init);
-	OPCODE(210, o_cloudOrb_init);
+	REGISTER_OPCODE(200, Stoneship, o_hologramDisplay_init);
+	REGISTER_OPCODE(201, Stoneship, o_hologramSelection_init);
+	REGISTER_OPCODE(202, Stoneship, o_battery_init);
+	REGISTER_OPCODE(203, Stoneship, o_tunnelEnter_init);
+	REGISTER_OPCODE(204, Stoneship, o_batteryGauge_init);
+	REGISTER_OPCODE(205, Stoneship, o_tunnel_init);
+	REGISTER_OPCODE(206, Stoneship, o_tunnelLeave_init);
+	REGISTER_OPCODE(207, Stoneship, o_chest_init);
+	REGISTER_OPCODE(208, Stoneship, o_telescope_init);
+	REGISTER_OPCODE(209, Stoneship, o_achenarDrawers_init);
+	REGISTER_OPCODE(210, Stoneship, o_cloudOrb_init);
 
 	// "Exit" Opcodes
-	OPCODE(300, NOP);
+	REGISTER_OPCODE(300, Stoneship, NOP);
 }
 
-#undef OPCODE
-
 void Stoneship::disablePersistentScripts() {
 	_batteryCharging = false;
 	_batteryDepleting = false;


Commit: 7ac1bd9a57782f0488327f4b0de36d79f44aaeeb
    https://github.com/scummvm/scummvm/commit/7ac1bd9a57782f0488327f4b0de36d79f44aaeeb
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Fix error when checking the rocket sliders solution twice

The game was trying to start playing the linking book video in a
blocking way whereas it was set to loop by the first check.

Fixes #9914.

Changed paths:
    engines/mohawk/myst_stacks/myst.cpp
    engines/mohawk/myst_stacks/myst.h


diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 8bf7596..37b0d4f 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -203,7 +203,7 @@ void Myst::setupOpcodes() {
 	REGISTER_OPCODE(305, Myst, o_treeEntry_exit);
 	REGISTER_OPCODE(306, Myst, o_boiler_exit);
 	REGISTER_OPCODE(307, Myst, o_generatorControlRoom_exit);
-	REGISTER_OPCODE(308, Myst, NOP);
+	REGISTER_OPCODE(308, Myst, o_rocketSliders_exit);
 	REGISTER_OPCODE(309, Myst, NOP);
 	REGISTER_OPCODE(312, Myst, NOP);
 }
@@ -2201,7 +2201,7 @@ void Myst::rocketCheckSolution() {
 
 	_vm->_sound->stopEffect();
 
-	if (solved) {
+	if (solved && !_rocketLinkBook) {
 		// Reset lever position
 		MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
 		lever->drawFrame(0);
@@ -2341,8 +2341,8 @@ void Myst::o_rocketLeverMove(uint16 var, const ArgumentsArray &args) {
 
 	// Make the lever follow the mouse
 	int16 maxStep = lever->getStepsV() - 1;
-    Common::Rect rect = lever->getRect();
-    int16 step = ((mouse.y - rect.top) * lever->getStepsV()) / rect.height();
+	Common::Rect rect = lever->getRect();
+	int16 step = ((mouse.y - rect.top) * lever->getStepsV()) / rect.height();
 	step = CLIP<uint16>(step, 0, maxStep);
 
 	lever->drawFrame(step);
@@ -3557,6 +3557,7 @@ void Myst::boilerGaugeInit() {
 }
 
 void Myst::o_rocketSliders_init(uint16 var, const ArgumentsArray &args) {
+	_rocketLinkBook.reset();
 	_rocketSlider1 = _vm->getViewResource<MystAreaSlider>(args[0]);
 	_rocketSlider2 = _vm->getViewResource<MystAreaSlider>(args[1]);
 	_rocketSlider3 = _vm->getViewResource<MystAreaSlider>(args[2]);
@@ -3686,5 +3687,14 @@ void Myst::o_generatorControlRoom_exit(uint16 var, const ArgumentsArray &args) {
 	_generatorVoltage = _state.generatorVoltage;
 }
 
+void Myst::o_rocketSliders_exit(uint16 var, const ArgumentsArray &args) {
+	_rocketLinkBook.reset();
+	_rocketSlider1 = nullptr;
+	_rocketSlider2 = nullptr;
+	_rocketSlider3 = nullptr;
+	_rocketSlider4 = nullptr;
+	_rocketSlider5 = nullptr;
+}
+
 } // End of namespace MystStacks
 } // End of namespace Mohawk
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index 2da33f0..2100126 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -189,6 +189,7 @@ protected:
 	DECLARE_OPCODE(o_treeEntry_exit);
 	DECLARE_OPCODE(o_boiler_exit);
 	DECLARE_OPCODE(o_generatorControlRoom_exit);
+	DECLARE_OPCODE(o_rocketSliders_exit);
 
 
 	MystGameState::Myst &_state;


Commit: 2597e69f29a4b603cbfc7d53d034a2a9d3405de4
    https://github.com/scummvm/scummvm/commit/2597e69f29a4b603cbfc7d53d034a2a9d3405de4
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-22T20:38:56+02:00

Commit Message:
MOHAWK: Myst: Fix Selenitic sound receiver buttons not flashing

The new screen update strategy does not allow scripts to draw twice at
the same location for blinking.

Changed paths:
    engines/mohawk/myst_stacks/selenitic.cpp
    engines/mohawk/myst_stacks/selenitic.h


diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 087143a..e943904 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -44,6 +44,7 @@ Selenitic::Selenitic(MohawkEngine_Myst *vm) :
 
 	_soundReceiverDirection = 0;
 	_soundReceiverStartTime = 0;
+	_soundReceiverNearBlinkCounter = 0;
 }
 
 Selenitic::~Selenitic() {
@@ -990,13 +991,26 @@ uint16 Selenitic::soundReceiverCurrentSound(uint16 source, uint16 position) {
 		if (position == solution) {
 			soundId = soundIdGood;
 		} else if (position > solution && position <= solution + 50) {
-			_soundReceiverLeftButton->drawConditionalDataToScreen(2);
-			_soundReceiverLeftButton->drawConditionalDataToScreen(0);
+			_soundReceiverNearBlinkCounter++;
+			if (_soundReceiverNearBlinkCounter % 2) {
+				_soundReceiverLeftButton->drawConditionalDataToScreen(2);
+			} else {
+				_soundReceiverLeftButton->drawConditionalDataToScreen(0);
+			}
 			soundId = soundIdNear;
 		} else if (position < solution && position >= solution - 50) {
-			_soundReceiverRightButton->drawConditionalDataToScreen(2);
-			_soundReceiverRightButton->drawConditionalDataToScreen(0);
+			_soundReceiverNearBlinkCounter++;
+			if (_soundReceiverNearBlinkCounter % 2) {
+				_soundReceiverRightButton->drawConditionalDataToScreen(2);
+			} else {
+				_soundReceiverRightButton->drawConditionalDataToScreen(0);
+			}
 			soundId = soundIdNear;
+		} else if (_soundReceiverNearBlinkCounter > 0) {
+			// Make sure the buttons don't stay highlighted when leaving the 'near' area
+			_soundReceiverRightButton->drawConditionalDataToScreen(0);
+			_soundReceiverLeftButton->drawConditionalDataToScreen(0);
+			_soundReceiverNearBlinkCounter = 0;
 		}
 	}
 
@@ -1053,6 +1067,7 @@ void Selenitic::o_soundReceiver_init(uint16 var, const ArgumentsArray &args) {
 	soundReceiverSetSubimageRect();
 
 	_soundReceiverSigmaPressed = false;
+	_soundReceiverNearBlinkCounter = 0;
 }
 
 void Selenitic::o_soundLock_init(uint16 var, const ArgumentsArray &args) {
diff --git a/engines/mohawk/myst_stacks/selenitic.h b/engines/mohawk/myst_stacks/selenitic.h
index e0b4564..341886d 100644
--- a/engines/mohawk/myst_stacks/selenitic.h
+++ b/engines/mohawk/myst_stacks/selenitic.h
@@ -86,6 +86,7 @@ private:
 	uint16 _soundReceiverDirection; // 120
 	uint16 _soundReceiverSpeed; // 122
 	uint32 _soundReceiverStartTime; //124
+	uint _soundReceiverNearBlinkCounter;
 	MystAreaImageSwitch *_soundReceiverViewer; // 128
 	MystAreaImageSwitch *_soundReceiverRightButton; // 132
 	MystAreaImageSwitch *_soundReceiverLeftButton; // 136





More information about the Scummvm-git-logs mailing list