[Scummvm-cvs-logs] scummvm master -> 611900d3c36ca9acaecca195f477841b9e8015df

bgK bastien.bouclet at gmail.com
Sun Dec 16 06:58:17 CET 2012


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

Summary:
fdad5ec7b4 MOHAWK: Allow changing video rates
8050bca8d3 MOHAWK: Implement the Myst boiler movies
adf3a8d7dd MOHAWK: Play the gear closing movie in Myst
bbc760c51c MOHAWK: Implement Mechanical fortress rotation
5d90c93385 MOHAWK: Play Channelwood stairs door closing movie backwards
e0c923fd5a MOHAWK: Play Stoneship chest valve opening movie backwards
fb02d1decd MOHAWK: Add a workaround for Myst ME fortress rotation bug
4ae8b3b1e8 MOHAWK: Fix Myst ME's clock tower weight not going back up
0358a44738 MOHAWK: Implement the last two Myst opcodes
07ee25c87d MOHAWK: Implement most of Myst's transition system
611900d3c3 MOHAWK: The cancel button of Myst's dialog was actually saving


Commit: fdad5ec7b408fd9e45d69de2a2a9ca9e1796d1a5
    https://github.com/scummvm/scummvm/commit/fdad5ec7b408fd9e45d69de2a2a9ca9e1796d1a5
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:00-08:00

Commit Message:
MOHAWK: Allow changing video rates

getVideoDuration now returns an Timestamp

Changed paths:
    engines/mohawk/riven.cpp
    engines/mohawk/riven_external.cpp
    engines/mohawk/video.cpp
    engines/mohawk/video.h



diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 32613c6..9a18d68 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -830,7 +830,7 @@ static void sunnersTopStairsTimer(MohawkEngine_Riven *vm) {
 		} else if (sunnerTime < vm->getTotalPlayTime()) {
 			VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(1, 3));
 
-			timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(2, 15) * 1000;
+			timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(2, 15) * 1000;
 		}
 
 		sunnerTime = timerTime + vm->getTotalPlayTime();
@@ -868,7 +868,7 @@ static void sunnersMidStairsTimer(MohawkEngine_Riven *vm) {
 
 			VideoHandle handle = vm->_video->playMovieRiven(movie);
 
-			timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 10) * 1000;
+			timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(1, 10) * 1000;
 		}
 
 		sunnerTime = timerTime + vm->getTotalPlayTime();
@@ -898,7 +898,7 @@ static void sunnersLowerStairsTimer(MohawkEngine_Riven *vm) {
 		} else if (sunnerTime < vm->getTotalPlayTime()) {
 			VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(3, 5));
 
-			timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+			timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
 		}
 
 		sunnerTime = timerTime + vm->getTotalPlayTime();
@@ -932,7 +932,7 @@ static void sunnersBeachTimer(MohawkEngine_Riven *vm) {
 			vm->_video->activateMLST(mlstID, vm->getCurCard());
 			VideoHandle handle = vm->_video->playMovieRiven(mlstID);
 
-			timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+			timerTime = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
 		}
 
 		sunnerTime = timerTime + vm->getTotalPlayTime();
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 337a57e..384e89a 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -1467,7 +1467,7 @@ static void catherineViewerIdleTimer(MohawkEngine_Riven *vm) {
 	VideoHandle videoHandle = vm->_video->playMovieRiven(30);
 
 	// Reset the timer
-	vm->installTimer(&catherineViewerIdleTimer, vm->_video->getDuration(videoHandle) + vm->_rnd->getRandomNumber(60) * 1000);
+	vm->installTimer(&catherineViewerIdleTimer, vm->_video->getDuration(videoHandle).msecs() + vm->_rnd->getRandomNumber(60) * 1000);
 }
 
 void RivenExternal::xglview_prisonon(uint16 argc, uint16 *argv) {
@@ -1507,7 +1507,7 @@ void RivenExternal::xglview_prisonon(uint16 argc, uint16 *argv) {
 		_vm->_video->activateMLST(cathMovie, _vm->getCurCard());
 		VideoHandle videoHandle = _vm->_video->playMovieRiven(30);
 
-		timeUntilNextMovie = _vm->_video->getDuration(videoHandle) + _vm->_rnd->getRandomNumber(60) * 1000;
+		timeUntilNextMovie = _vm->_video->getDuration(videoHandle).msecs() + _vm->_rnd->getRandomNumber(60) * 1000;
 	} else {
 		// Otherwise, just redraw the imager
 		timeUntilNextMovie = _vm->_rnd->getRandomNumberRng(10, 20) * 1000;
@@ -2335,7 +2335,7 @@ static void rebelPrisonWindowTimer(MohawkEngine_Riven *vm) {
 	VideoHandle handle = vm->_video->playMovieRiven(movie);
 
 	// Ensure the next video starts after this one ends
-	uint32 timeUntilNextVideo = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(38, 58) * 1000;
+	uint32 timeUntilNextVideo = vm->_video->getDuration(handle).msecs() + vm->_rnd->getRandomNumberRng(38, 58) * 1000;
 
 	// Save the time in case we leave the card and return
 	vm->_vars["rvillagetime"] = timeUntilNextVideo + vm->getTotalPlayTime();
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index b1b9972..51e991a 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -493,9 +493,9 @@ uint32 VideoManager::getTime(VideoHandle handle) {
 	return _videoStreams[handle]->getTime();
 }
 
-uint32 VideoManager::getDuration(VideoHandle handle) {
+Audio::Timestamp VideoManager::getDuration(VideoHandle handle) {
 	assert(handle != NULL_VID_HANDLE);
-	return _videoStreams[handle]->getDuration().msecs();
+	return _videoStreams[handle]->getDuration();
 }
 
 bool VideoManager::endOfVideo(VideoHandle handle) {
@@ -536,6 +536,11 @@ void VideoManager::setVideoLooping(VideoHandle handle, bool loop) {
 	_videoStreams[handle].loop = loop;
 }
 
+void VideoManager::setVideoRate(VideoHandle handle, const Common::Rational &rate) {
+	assert(handle != NULL_VID_HANDLE);
+	_videoStreams[handle]->setRate(rate);
+}
+
 void VideoManager::pauseMovie(VideoHandle handle, bool pause) {
 	assert(handle != NULL_VID_HANDLE);
 	_videoStreams[handle]->pauseVideo(pause);
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index 6d27839..9641d36 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -101,12 +101,13 @@ public:
 	int getCurFrame(VideoHandle handle);
 	uint32 getFrameCount(VideoHandle handle);
 	uint32 getTime(VideoHandle handle);
-	uint32 getDuration(VideoHandle videoHandle);
+	Audio::Timestamp getDuration(VideoHandle videoHandle);
 	bool endOfVideo(VideoHandle handle);
 	void setVideoBounds(VideoHandle handle, Audio::Timestamp start, Audio::Timestamp end);
 	void drawVideoFrame(VideoHandle handle, Audio::Timestamp time);
 	void seekToTime(VideoHandle handle, Audio::Timestamp time);
 	void setVideoLooping(VideoHandle handle, bool loop);
+	void setVideoRate(VideoHandle handle, const Common::Rational &rate);
 	void waitUntilMovieEnds(VideoHandle videoHandle);
 	void delayUntilMovieEnds(VideoHandle videoHandle);
 	void pauseMovie(VideoHandle videoHandle, bool pause);


Commit: 8050bca8d32d42bc3572d2158b6fdc4e7b9c3861
    https://github.com/scummvm/scummvm/commit/8050bca8d32d42bc3572d2158b6fdc4e7b9c3861
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:00-08:00

Commit Message:
MOHAWK: Implement the Myst boiler movies

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 c1ddc74..036faef 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -51,6 +51,8 @@ Myst::Myst(MohawkEngine_Myst *vm) :
 	_dockVaultState = 0;
 	_cabinDoorOpened = 0;
 	_cabinMatchState = 2;
+	_cabinGaugeMovie = NULL_VID_HANDLE;
+	_cabinFireMovie = NULL_VID_HANDLE;
 	_matchBurning = false;
 	_tree = 0;
 	_treeAlcove = 0;
@@ -189,7 +191,7 @@ void Myst::setupOpcodes() {
 	OPCODE(215, o_gulls2_init);
 	OPCODE(216, o_treeCard_init);
 	OPCODE(217, o_treeEntry_init);
-	OPCODE(218, opcode_218);
+	OPCODE(218, o_boilerMovies_init);
 	OPCODE(219, o_rocketSliders_init);
 	OPCODE(220, o_rocketLinkVideo_init);
 	OPCODE(221, o_greenBook_init);
@@ -202,7 +204,7 @@ void Myst::setupOpcodes() {
 	OPCODE(303, NOP);
 	OPCODE(304, o_treeCard_exit);
 	OPCODE(305, o_treeEntry_exit);
-	OPCODE(306, NOP);
+	OPCODE(306, o_boiler_exit);
 	OPCODE(307, o_generatorControlRoom_exit);
 	OPCODE(308, NOP);
 	OPCODE(309, NOP);
@@ -1869,17 +1871,50 @@ void Myst::o_boilerLightPilot(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 		_state.cabinPilotLightLit = 1;
 		_vm->redrawArea(98);
 
+		boilerFireUpdate(false);
+
 		// Put out match
 		_matchGoOutTime = _vm->_system->getMillis();
 
 		if (_state.cabinValvePosition > 0)
 			_vm->_sound->replaceBackgroundMyst(8098, 49152);
 
-		if (_state.cabinValvePosition > 12)
+		if (_state.cabinValvePosition > 12) {
+			// Compute the speed of the gauge to synchronize it with the next tree move
+			uint32 delay = treeNextMoveDelay(_state.cabinValvePosition);
+			Common::Rational rate = boilerComputeGaugeRate(_state.cabinValvePosition, delay);
+			boilerResetGauge(rate);
+
 			_state.treeLastMoveTime = _vm->_system->getMillis();
+		}
+	}
+}
 
-		// TODO: Complete. Play movies
+Common::Rational Myst::boilerComputeGaugeRate(uint16 pressure, uint32 delay) {
+	Common::Rational rate = Common::Rational(2088, delay);
+	if (pressure < 12)
+		return -rate;
+	else
+		return rate;
+}
+
+void Myst::boilerResetGauge(const Common::Rational &rate) {
+	if (_vm->_video->endOfVideo(_cabinGaugeMovie)) {
+		if (_vm->getCurCard() == 4098) {
+			_cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabingau", kMystStack), 243, 96);
+		} else {
+			_cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabcgfar", kMystStack), 254, 136);
+		}
 	}
+
+	Audio::Timestamp goTo;
+	if (rate > 0)
+		goTo = Audio::Timestamp(0, 0, 600);
+	else
+		goTo = _vm->_video->getDuration(_cabinGaugeMovie);
+
+	_vm->_video->seekToTime(_cabinGaugeMovie, goTo);
+	_vm->_video->setVideoRate(_cabinGaugeMovie, rate);
 }
 
 void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -1893,7 +1928,12 @@ void Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
 		if (_state.cabinValvePosition > 0)
 			_vm->_sound->replaceBackgroundMyst(8098, 49152);
 
-		// TODO: Play movies
+		if (!_vm->_video->endOfVideo(_cabinGaugeMovie)) {
+			uint16 delay = treeNextMoveDelay(_state.cabinValvePosition);
+			Common::Rational rate = boilerComputeGaugeRate(_state.cabinValvePosition, delay);
+			_vm->_video->setVideoRate(_cabinGaugeMovie, rate);
+		}
+
 	} else if (_state.cabinValvePosition > 0)
 		_vm->_sound->replaceBackgroundMyst(4098, _state.cabinValvePosition << 10);
 }
@@ -1903,7 +1943,8 @@ void Myst::boilerPressureIncrease_run() {
 	if (!_vm->_sound->isPlaying(5098) && _state.cabinValvePosition < 25) {
 		_state.cabinValvePosition++;
 		if (_state.cabinValvePosition == 1) {
-			// TODO: Play fire movie
+			// Set fire to high
+			boilerFireUpdate(false);
 
 			// Draw fire
 			_vm->redrawArea(305);
@@ -1927,7 +1968,8 @@ void Myst::boilerPressureDecrease_run() {
 	if (!_vm->_sound->isPlaying(5098) && _state.cabinValvePosition > 0) {
 		_state.cabinValvePosition--;
 		if (_state.cabinValvePosition == 0) {
-			// TODO: Play fire movie
+			// Set fire to low
+			boilerFireUpdate(false);
 
 			// Draw fire
 			_vm->redrawArea(305);
@@ -1961,7 +2003,12 @@ void Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint
 		if (_state.cabinValvePosition > 0)
 			_vm->_sound->replaceBackgroundMyst(8098, 49152);
 
-		// TODO: Play movies
+		if (!_vm->_video->endOfVideo(_cabinGaugeMovie)) {
+			uint16 delay = treeNextMoveDelay(_state.cabinValvePosition);
+			Common::Rational rate = boilerComputeGaugeRate(_state.cabinValvePosition, delay);
+			_vm->_video->setVideoRate(_cabinGaugeMovie, rate);
+		}
+
 	} else {
 		if (_state.cabinValvePosition > 0)
 			_vm->_sound->replaceBackgroundMyst(4098, _state.cabinValvePosition << 10);
@@ -2067,6 +2114,11 @@ void Myst::tree_run() {
 				// Check if alcove is accessible
 				treeSetAlcoveAccessible();
 
+				if (_cabinGaugeMovie != NULL_VID_HANDLE) {
+					Common::Rational rate = boilerComputeGaugeRate(pressure, delay);
+					boilerResetGauge(rate);
+				}
+
 				_state.treeLastMoveTime = time;
 			}
 		}
@@ -3510,24 +3562,62 @@ void Myst::o_treeEntry_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	treeSetAlcoveAccessible();
 }
 
-void Myst::opcode_218(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	varUnusedCheck(op, var);
+void Myst::o_boilerMovies_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Boiler movies init", op);
+
+	boilerFireInit();
+	boilerGaugeInit();
+}
+
+void Myst::boilerFireInit() {
+	if (_vm->getCurCard() == 4098) {
+		_cabinFireMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabfire", kMystStack), 240, 279, true);
+		_vm->_video->pauseMovie(_cabinFireMovie, true);
 
-	// Used for Card 4097 (Cabin Boiler)
-	// TODO: Fill in logic
-	if (false) {
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("cabfirfr", kMystStack), 254, 244);
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("cabcgfar", kMystStack), 254, 138);
+		_vm->redrawArea(305);
+		boilerFireUpdate(true);
+	} else {
+		if (_state.cabinPilotLightLit == 1 && _state.cabinValvePosition >= 1) {
+			_cabinFireMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabfirfr", kMystStack), 254, 244, true);
+		}
 	}
+}
 
-	// Used for Card 4098 (Cabin Boiler)
-	// TODO: Fill in logic
-	if (false) {
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("cabfire", kMystStack), 240, 279);
-		_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("cabingau", kMystStack), 243, 97);
+void Myst::boilerFireUpdate(bool init) {
+	uint position = _vm->_video->getTime(_cabinFireMovie);
+
+	if (_state.cabinPilotLightLit == 1) {
+		if (_state.cabinValvePosition == 0) {
+			if (position > (uint)Audio::Timestamp(0, 200, 600).msecs() || init) {
+				_vm->_video->setVideoBounds(_cabinFireMovie, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 100, 600));
+				_vm->_video->pauseMovie(_cabinFireMovie, false);
+			}
+		} else {
+			if (position < (uint)Audio::Timestamp(0, 200, 600).msecs() || init) {
+				_vm->_video->setVideoBounds(_cabinFireMovie, Audio::Timestamp(0, 201, 600), Audio::Timestamp(0, 1900, 600));
+				_vm->_video->pauseMovie(_cabinFireMovie, false);
+			}
+		}
 	}
 }
 
+void Myst::boilerGaugeInit() {
+	if (_vm->getCurCard() == 4098) {
+		_cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabingau", kMystStack), 243, 96);
+	} else {
+		_cabinGaugeMovie = _vm->_video->playMovie(_vm->wrapMovieFilename("cabcgfar", kMystStack), 254, 136);
+	}
+
+	Audio::Timestamp frame;
+
+	if (_state.cabinPilotLightLit == 1 && _state.cabinValvePosition > 12)
+		frame = _vm->_video->getDuration(_cabinGaugeMovie);
+	else
+		frame = Audio::Timestamp(0, 0, 600);
+
+	_vm->_video->drawVideoFrame(_cabinGaugeMovie, frame);
+}
+
 void Myst::o_rocketSliders_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Rocket sliders init", op);
 
@@ -3648,6 +3738,13 @@ void Myst::o_treeEntry_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	_treeAlcove = 0;
 }
 
+void Myst::o_boiler_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Exit boiler card", op);
+
+	_cabinGaugeMovie = NULL_VID_HANDLE;
+	_cabinFireMovie = NULL_VID_HANDLE;
+}
+
 void Myst::o_generatorControlRoom_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Generator room exit", op);
 
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index e9bff08..8ecb3e4 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -174,7 +174,7 @@ private:
 	DECLARE_OPCODE(o_gulls2_init);
 	DECLARE_OPCODE(o_treeCard_init);
 	DECLARE_OPCODE(o_treeEntry_init);
-	DECLARE_OPCODE(opcode_218);
+	DECLARE_OPCODE(o_boilerMovies_init);
 	DECLARE_OPCODE(o_rocketSliders_init);
 	DECLARE_OPCODE(o_rocketLinkVideo_init);
 	DECLARE_OPCODE(o_greenBook_init);
@@ -183,6 +183,7 @@ private:
 	DECLARE_OPCODE(o_bookAddSpecialPage_exit);
 	DECLARE_OPCODE(o_treeCard_exit);
 	DECLARE_OPCODE(o_treeEntry_exit);
+	DECLARE_OPCODE(o_boiler_exit);
 	DECLARE_OPCODE(o_generatorControlRoom_exit);
 
 
@@ -259,6 +260,9 @@ private:
 	uint16 _cabinMatchState; // 60
 	uint32 _matchGoOutTime; // 144
 
+	VideoHandle _cabinFireMovie; // 240
+	VideoHandle _cabinGaugeMovie; // 244
+
 	bool _boilerPressureIncreasing;
 	bool _boilerPressureDecreasing;
 	bool _basementPressureIncreasing;
@@ -317,6 +321,12 @@ private:
 	Common::Point towerRotationMapComputeCoords(const Common::Point &center, uint16 angle);
 	void towerRotationMapDrawLine(const Common::Point &center, const Common::Point &end);
 
+	void boilerFireInit();
+	void boilerFireUpdate(bool init);
+	void boilerGaugeInit();
+	Common::Rational boilerComputeGaugeRate(uint16 pressure, uint32 delay);
+	void boilerResetGauge(const Common::Rational &rate);
+
 	void treeSetAlcoveAccessible();
 	uint32 treeNextMoveDelay(uint16 pressure);
 


Commit: adf3a8d7dde028422e0340a5c6995ce9b93376cb
    https://github.com/scummvm/scummvm/commit/adf3a8d7dde028422e0340a5c6995ce9b93376cb
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:01-08:00

Commit Message:
MOHAWK: Play the gear closing movie in Myst

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



diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index 036faef..d91655f 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -3020,7 +3020,12 @@ void Myst::clockReset() {
 		_vm->_system->delayMillis(1000);
 		_vm->_sound->replaceSoundMyst(7113);
 
-		// TODO: Play cl1wggat backwards
+		// Gear closing movie
+		VideoHandle handle = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wggat", kMystStack) , 195, 225);
+		_vm->_video->seekToTime(handle, _vm->_video->getDuration(handle));
+		_vm->_video->setVideoRate(handle, -1);
+		_vm->_video->waitUntilMovieEnds(handle);
+
 		// Redraw gear
 		_state.gearsOpen = 0;
 		_vm->redrawArea(40);


Commit: bbc760c51c9961e9ed65bb43901face1579d5b47
    https://github.com/scummvm/scummvm/commit/bbc760c51c9961e9ed65bb43901face1579d5b47
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:01-08:00

Commit Message:
MOHAWK: Implement Mechanical fortress rotation

Both the simulation and the actual rotation.

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



diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 79de033..2d84207 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -41,6 +41,9 @@ Mechanical::Mechanical(MohawkEngine_Myst *vm) :
 
 	_mystStaircaseState = false;
 	_fortressPosition = 0;
+	_fortressRotationSpeed = 0;
+	_fortressSimulationSpeed = 0;
+	_gearsWereRunning = false;
 }
 
 Mechanical::~Mechanical() {
@@ -776,8 +779,56 @@ void Mechanical::o_elevatorRotation_init(uint16 op, uint16 var, uint16 argc, uin
 }
 
 void Mechanical::fortressRotation_run() {
-	// Used for Card 6156 (Fortress Rotation Controls)
-	// TODO: Fill in function...
+	VideoHandle gears = _fortressRotationGears->playMovie();
+
+	double oldRate = _vm->_video->getVideoRate(gears).toDouble();
+
+	uint32 moviePosition = Audio::Timestamp(_vm->_video->getTime(gears), 600).totalNumberOfFrames();
+
+	int32 positionInQuarter = 900 - (moviePosition + 900) % 1800;
+
+	// Are the gears moving?
+	if (oldRate >= 0.1 || ABS<int32>(positionInQuarter) >= 30 || _fortressRotationBrake) {
+
+		double newRate = oldRate;
+		if (_fortressRotationBrake && (double)_fortressRotationBrake * 0.2 > oldRate) {
+			newRate += 0.1;
+		}
+
+		// Don't let the gears get stuck between two fortress positions
+		if (ABS<double>(oldRate) <= 0.05) {
+			if (oldRate <= 0.0) {
+				newRate += oldRate;
+			} else {
+				newRate -= oldRate;
+			}
+		} else {
+			if (oldRate <= 0.0) {
+				newRate += 0.05;
+			} else {
+				newRate -= 0.05;
+			}
+		}
+
+		// Adjust speed accordingly to acceleration lever
+		newRate +=  (double) (positionInQuarter / 1500.0)
+				* (double) (9 - _fortressRotationSpeed) / 9.0;
+
+		newRate = CLIP<double>(newRate, -2.5, 2.5);
+
+		_vm->_video->setVideoRate(gears, Common::Rational(newRate * 1000.0, 1000));
+
+		_gearsWereRunning = true;
+	} else if (_gearsWereRunning) {
+		// The fortress has stopped. Set its new position
+		_fortressPosition = (moviePosition + 900) / 1800 % 4;
+
+		_vm->_video->setVideoRate(gears, 0);
+		_vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * _fortressPosition, 600));
+		_vm->_sound->playSoundBlocking(_fortressRotationSounds[_fortressPosition]);
+
+		_gearsWereRunning = false;
+	}
 }
 
 void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -785,6 +836,11 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
 
 	_fortressRotationGears = static_cast<MystResourceType6 *>(_invokingResource);
 
+	VideoHandle gears = _fortressRotationGears->playMovie();
+	_vm->_video->setVideoLooping(gears, true);
+	_vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * _fortressPosition, 600));
+	_vm->_video->setVideoRate(gears, 0);
+
 	_fortressRotationSounds[0] = argv[0];
 	_fortressRotationSounds[1] = argv[1];
 	_fortressRotationSounds[2] = argv[2];
@@ -793,11 +849,96 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
 	_fortressRotationBrake = 0;
 
 	_fortressRotationRunning = true;
+	_gearsWereRunning = false;
 }
 
 void Mechanical::fortressSimulation_run() {
-	// Used for Card 6044 (Fortress Rotation Simulator)
-	// TODO: Fill in function...
+	if (_fortressSimulationInit) {
+		// Init sequence
+		_vm->_sound->replaceBackgroundMyst(_fortressSimulationStartSound1, 65535);
+		_vm->skippableWait(5000);
+		_vm->_sound->replaceSoundMyst(_fortressSimulationStartSound2);
+
+		// Update movie while the sound is playing
+		VideoHandle startup = _fortressSimulationStartup->playMovie();
+		while (_vm->_sound->isPlaying(_fortressSimulationStartSound2)) {
+			if (_vm->_video->updateMovies())
+				_vm->_system->updateScreen();
+
+			_vm->_system->delayMillis(10);
+		}
+		_vm->_sound->replaceBackgroundMyst(_fortressSimulationStartSound1, 65535);
+		_vm->_video->waitUntilMovieEnds(startup);
+		_vm->_sound->stopBackgroundMyst();
+		_vm->_sound->replaceSoundMyst(_fortressSimulationStartSound2);
+
+
+		Common::Rect src = Common::Rect(0, 0, 176, 176);
+		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);
+		VideoHandle holo = _fortressSimulationHolo->playMovie();
+		_vm->_video->setVideoLooping(holo, true);
+		_vm->_video->setVideoRate(holo, 0);
+
+		_vm->_cursor->showCursor();
+
+		_fortressSimulationInit = false;
+	} else {
+		VideoHandle holo = _fortressSimulationHolo->playMovie();
+
+		double oldRate = _vm->_video->getVideoRate(holo).toDouble();
+
+		uint32 moviePosition = Audio::Timestamp(_vm->_video->getTime(holo), 600).totalNumberOfFrames();
+
+		int32 positionInQuarter = 900 - (moviePosition + 900) % 1800;
+
+		// Are the gears moving?
+		if (oldRate >= 0.1 || ABS<int32>(positionInQuarter) >= 30 || _fortressSimulationBrake) {
+
+			double newRate = oldRate;
+			if (_fortressSimulationBrake && (double)_fortressSimulationBrake * 0.2 > oldRate) {
+				newRate += 0.1;
+			}
+
+			// Don't let the gears get stuck between two fortress positions
+			if (ABS<double>(oldRate) <= 0.05) {
+				if (oldRate <= 0.0) {
+					newRate += oldRate;
+				} else {
+					newRate -= oldRate;
+				}
+			} else {
+				if (oldRate <= 0.0) {
+					newRate += 0.05;
+				} else {
+					newRate -= 0.05;
+				}
+			}
+
+			// Adjust speed accordingly to acceleration lever
+			newRate +=  (double) (positionInQuarter / 1500.0)
+					* (double) (9 - _fortressSimulationSpeed) / 9.0;
+
+			newRate = CLIP<double>(newRate, -2.5, 2.5);
+
+			_vm->_video->setVideoRate(holo, Common::Rational(newRate * 1000.0, 1000));
+
+			_gearsWereRunning = true;
+		} else if (_gearsWereRunning) {
+			// The fortress has stopped. Set its new position
+			uint16 simulationPosition = (moviePosition + 900) / 1800 % 4;
+
+			_vm->_video->setVideoRate(holo, 0);
+			_vm->_video->seekToTime(holo, Audio::Timestamp(0, 1800 * simulationPosition, 600));
+			_vm->_sound->playSoundBlocking(	_fortressRotationSounds[simulationPosition]);
+
+			_gearsWereRunning = false;
+		}
+	}
 }
 
 void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -816,6 +957,10 @@ void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, uint16 argc, u
 	_fortressSimulationBrake = 0;
 
 	_fortressSimulationRunning = true;
+	_gearsWereRunning = false;
+	_fortressSimulationInit = true;
+
+	_vm->_cursor->hideCursor();
 }
 
 void Mechanical::o_fortressSimulationStartup_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/myst_stacks/mechanical.h b/engines/mohawk/myst_stacks/mechanical.h
index 3bd7f2d..ab8b60c 100644
--- a/engines/mohawk/myst_stacks/mechanical.h
+++ b/engines/mohawk/myst_stacks/mechanical.h
@@ -104,6 +104,7 @@ private:
 	bool _mystStaircaseState; // 76
 
 	bool _fortressRotationRunning;
+	bool _gearsWereRunning;
 	uint16 _fortressRotationSpeed; // 78
 	uint16 _fortressRotationBrake; // 80
 	uint16 _fortressPosition; // 82
@@ -111,6 +112,7 @@ private:
 	MystResourceType6 *_fortressRotationGears; // 172
 
 	bool _fortressSimulationRunning;
+	bool _fortressSimulationInit; // 94
 	uint16 _fortressSimulationSpeed; // 96
 	uint16 _fortressSimulationBrake; // 98
 	uint16 _fortressSimulationStartSound1; // 102
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index 51e991a..8b0130d 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -536,6 +536,11 @@ void VideoManager::setVideoLooping(VideoHandle handle, bool loop) {
 	_videoStreams[handle].loop = loop;
 }
 
+Common::Rational VideoManager::getVideoRate(VideoHandle handle) const {
+	assert(handle != NULL_VID_HANDLE);
+	return _videoStreams[handle]->getRate();
+}
+
 void VideoManager::setVideoRate(VideoHandle handle, const Common::Rational &rate) {
 	assert(handle != NULL_VID_HANDLE);
 	_videoStreams[handle]->setRate(rate);
diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h
index 9641d36..2c4c827 100644
--- a/engines/mohawk/video.h
+++ b/engines/mohawk/video.h
@@ -107,6 +107,7 @@ public:
 	void drawVideoFrame(VideoHandle handle, Audio::Timestamp time);
 	void seekToTime(VideoHandle handle, Audio::Timestamp time);
 	void setVideoLooping(VideoHandle handle, bool loop);
+	Common::Rational getVideoRate(VideoHandle handle) const;
 	void setVideoRate(VideoHandle handle, const Common::Rational &rate);
 	void waitUntilMovieEnds(VideoHandle videoHandle);
 	void delayUntilMovieEnds(VideoHandle videoHandle);


Commit: 5d90c93385359b293f351bfd1ad66d4d1cb243d3
    https://github.com/scummvm/scummvm/commit/5d90c93385359b293f351bfd1ad66d4d1cb243d3
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:01-08:00

Commit Message:
MOHAWK: Play Channelwood stairs door closing movie backwards

Changed paths:
    engines/mohawk/myst_areas.cpp
    engines/mohawk/myst_stacks/channelwood.cpp



diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index a54b67b..a1f965a 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -202,22 +202,23 @@ VideoHandle MystResourceType6::playMovie() {
 	// Check if the video is already running
 	VideoHandle handle = _vm->_video->findVideoHandle(_videoFile);
 
-	if (_direction != 1)
-		warning("Playing QT movies backwards is not implemented");
-
 	// If the video is not running, play it
 	if (handle == NULL_VID_HANDLE || _vm->_video->endOfVideo(handle)) {
-		if (_playBlocking) {
-			_vm->_video->playMovieBlocking(_videoFile, _left, _top);
-			handle = NULL_VID_HANDLE;
-		} else {
-			handle = _vm->_video->playMovie(_videoFile, _left, _top, _loop);
+		handle = _vm->_video->playMovie(_videoFile, _left, _top, _loop);
+		if (_direction == -1) {
+			_vm->_video->seekToTime(handle, _vm->_video->getDuration(handle));
+			_vm->_video->setVideoRate(handle, -1);
 		}
 	} else {
 		// Resume the video
 		_vm->_video->pauseMovie(handle, false);
 	}
 
+	if (_playBlocking) {
+		_vm->_video->waitUntilMovieEnds(handle);
+		handle = NULL_VID_HANDLE;
+	}
+
 	return handle;
 }
 
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 069281f..c32ab3a 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -476,9 +476,12 @@ void Channelwood::o_stairsDoorToggle(uint16 op, uint16 var, uint16 argc, uint16
 	MystResourceType6 *movie = static_cast<MystResourceType6 *>(_invokingResource);
 
 	if (_state.stairsUpperDoorState) {
-		// TODO: Play backwards
+		// Close door, play the open movie backwards
+		movie->setDirection(-1);
 		movie->playMovie();
 	} else {
+		// Open door
+		movie->setDirection(1);
 		movie->playMovie();
 	}
 }


Commit: e0c923fd5a5481eadf3d863617cca7dbf5197c52
    https://github.com/scummvm/scummvm/commit/e0c923fd5a5481eadf3d863617cca7dbf5197c52
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:01-08:00

Commit Message:
MOHAWK: Play Stoneship chest valve opening movie backwards

Changed paths:
    engines/mohawk/myst_stacks/stoneship.cpp



diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index ef228e6..595f9db 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -692,9 +692,9 @@ void Stoneship::o_chestValveVideos(uint16 op, uint16 var, uint16 argc, uint16 *a
 		_vm->_sound->resumeBackgroundMyst();
 	} else {
 		// Valve opening
-		// TODO: Play backwards
 		VideoHandle valve = _vm->_video->playMovie(movie, 97, 267);
-		_vm->_video->setVideoBounds(valve, Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 350, 600));
+		_vm->_video->seekToTime(valve, Audio::Timestamp(0, 350, 600));
+		_vm->_video->setVideoRate(valve, -1);
 		_vm->_video->waitUntilMovieEnds(valve);
 	}
 }


Commit: fb02d1decd467b6758f09374dd71036d65e5f9e5
    https://github.com/scummvm/scummvm/commit/fb02d1decd467b6758f09374dd71036d65e5f9e5
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:01-08:00

Commit Message:
MOHAWK: Add a workaround for Myst ME fortress rotation bug

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



diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 2d84207..88368cf 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -44,6 +44,10 @@ Mechanical::Mechanical(MohawkEngine_Myst *vm) :
 	_fortressRotationSpeed = 0;
 	_fortressSimulationSpeed = 0;
 	_gearsWereRunning = false;
+
+	_fortressRotationShortMovieWorkaround = false;
+	_fortressRotationShortMovieCount = 0;
+	_fortressRotationShortMovieLast = 0;
 }
 
 Mechanical::~Mechanical() {
@@ -785,6 +789,20 @@ void Mechanical::fortressRotation_run() {
 
 	uint32 moviePosition = Audio::Timestamp(_vm->_video->getTime(gears), 600).totalNumberOfFrames();
 
+	// Myst ME short movie workaround, explained in o_fortressRotation_init
+	if (_fortressRotationShortMovieWorkaround) {
+		// Detect if we just looped
+		if (ABS<int32>(_fortressRotationShortMovieLast - 3680) < 50
+				&& ABS<int32>(moviePosition) < 50) {
+			_fortressRotationShortMovieCount++;
+		}
+
+		_fortressRotationShortMovieLast = moviePosition;
+
+		// Simulate longer movie
+		moviePosition += 3600 * _fortressRotationShortMovieCount;
+	}
+
 	int32 positionInQuarter = 900 - (moviePosition + 900) % 1800;
 
 	// Are the gears moving?
@@ -824,7 +842,13 @@ void Mechanical::fortressRotation_run() {
 		_fortressPosition = (moviePosition + 900) / 1800 % 4;
 
 		_vm->_video->setVideoRate(gears, 0);
-		_vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * _fortressPosition, 600));
+
+		if (!_fortressRotationShortMovieWorkaround) {
+			_vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * _fortressPosition, 600));
+		} else {
+			_vm->_video->seekToTime(gears, Audio::Timestamp(0, 1800 * (_fortressPosition % 2), 600));
+		}
+
 		_vm->_sound->playSoundBlocking(_fortressRotationSounds[_fortressPosition]);
 
 		_gearsWereRunning = false;
@@ -848,6 +872,22 @@ void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uin
 
 	_fortressRotationBrake = 0;
 
+	// WORKAROUND for the tower rotation bug in Myst ME.
+	// The original engine only allowed to visit two out of the three small islands,
+	// preventing the game from being fully completable.
+	// The fortress rotation is computed from the current position in the movie
+	// hcgears.mov. The version of this movie that shipped with the ME edition is
+	// too short to allow to visit all the islands.
+	// ScummVM simulates a longer movie by counting the number of times the movie
+	// looped and adding that time to the current movie position.
+	// Hence allowing the fortress position to be properly computed.
+	uint32 movieDuration = _vm->_video->getDuration(gears).convertToFramerate(600).totalNumberOfFrames();
+	if (movieDuration == 3680) {
+		_fortressRotationShortMovieWorkaround = true;
+		_fortressRotationShortMovieCount = 0;
+		_fortressRotationShortMovieLast = 0;
+	}
+
 	_fortressRotationRunning = true;
 	_gearsWereRunning = false;
 }
diff --git a/engines/mohawk/myst_stacks/mechanical.h b/engines/mohawk/myst_stacks/mechanical.h
index ab8b60c..01a1971 100644
--- a/engines/mohawk/myst_stacks/mechanical.h
+++ b/engines/mohawk/myst_stacks/mechanical.h
@@ -111,6 +111,10 @@ private:
 	uint16 _fortressRotationSounds[4]; // 86 to 92
 	MystResourceType6 *_fortressRotationGears; // 172
 
+	bool _fortressRotationShortMovieWorkaround;
+	uint32 _fortressRotationShortMovieCount;
+	uint32 _fortressRotationShortMovieLast;
+
 	bool _fortressSimulationRunning;
 	bool _fortressSimulationInit; // 94
 	uint16 _fortressSimulationSpeed; // 96


Commit: 4ae8b3b1e863e2a6ad7d216447f85f480499ad75
    https://github.com/scummvm/scummvm/commit/4ae8b3b1e863e2a6ad7d216447f85f480499ad75
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:01-08:00

Commit Message:
MOHAWK: Fix Myst ME's clock tower weight not going back up

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



diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index d91655f..f09c992 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -3037,16 +3037,9 @@ void Myst::clockReset() {
 void Myst::clockResetWeight() {
 	_clockWeightVideo = _vm->_video->playMovie(_vm->wrapMovieFilename("cl1wlfch", kMystStack) , 124, 0);
 
-	if (!(_vm->getFeatures() & GF_ME)) {
-		// Set video bounds, weight going up
-		_vm->_video->setVideoBounds(_clockWeightVideo,
-				Audio::Timestamp(0, 2214 * 2 - _clockWeightPosition, 600),
-				Audio::Timestamp(0, 2214 * 2, 600));
-	} else {
-		//FIXME: Needs QT backwards playing, for now just display the weight up
-		warning("Weight going back up not implemented");
-		_vm->_video->drawVideoFrame(_clockWeightVideo, Audio::Timestamp(0, 0, 600));
-	}
+	// Play the movie backwards, weight going up
+	_vm->_video->seekToTime(_clockWeightVideo, Audio::Timestamp(0, _clockWeightPosition, 600));
+	_vm->_video->setVideoRate(_clockWeightVideo, -1);
 
 	// Reset position
 	_clockWeightPosition = 0;


Commit: 0358a44738f1f1567156dc8e90025dd89414605f
    https://github.com/scummvm/scummvm/commit/0358a44738f1f1567156dc8e90025dd89414605f
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:51:01-08:00

Commit Message:
MOHAWK: Implement the last two Myst opcodes

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



diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 88368cf..6a925ab 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -81,9 +81,9 @@ void Mechanical::setupOpcodes() {
 	OPCODE(121, o_elevatorWindowMovie);
 	OPCODE(122, o_elevatorGoMiddle);
 	OPCODE(123, o_elevatorTopMovie);
-	OPCODE(124, opcode_124);
+	OPCODE(124, o_fortressRotationSetPosition);
 	OPCODE(125, o_mystStaircaseMovie);
-	OPCODE(126, opcode_126);
+	OPCODE(126, o_elevatorWaitTimeout);
 	OPCODE(127, o_crystalEnterYellow);
 	OPCODE(128, o_crystalLeaveYellow);
 	OPCODE(129, o_crystalEnterGreen);
@@ -110,7 +110,6 @@ void Mechanical::setupOpcodes() {
 void Mechanical::disablePersistentScripts() {
 	_fortressSimulationRunning = false;
 	_elevatorRotationLeverMoving = false;
-	_elevatorGoingMiddle = false;
 	_birdSinging = false;
 	_fortressRotationRunning = false;
 }
@@ -606,30 +605,33 @@ void Mechanical::elevatorGoMiddle_run() {
 				_vm->_gfx->copyBackBufferToScreen(Common::Rect(10, 137, 61, 165));
 				_vm->_system->updateScreen();
 			 }
-		} else if (_elevatorInCabin) {
+		} else {
 			_elevatorTooLate = true;
-
-			// Elevator going to middle animation
-			_vm->_cursor->hideCursor();
-			_vm->_sound->playSoundBlocking(11120);
-			_vm->_gfx->copyImageToBackBuffer(6118, Common::Rect(544, 333));
-			_vm->_sound->replaceSoundMyst(12120);
-			_vm->_gfx->runTransition(2, Common::Rect(177, 0, 370, 333), 25, 0);
-			_vm->_sound->playSoundBlocking(13120);
-			_vm->_sound->replaceSoundMyst(8120);
-			_vm->_gfx->copyImageToBackBuffer(6327, Common::Rect(544, 333));
-			_vm->_system->delayMillis(500);
-			_vm->_sound->replaceSoundMyst(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->_cursor->showCursor();
-
 			_elevatorGoingMiddle = false;
-			_elevatorPosition = 1;
 
-			_vm->changeToCard(6327, true);
+			if (_elevatorInCabin) {
+
+				// Elevator going to middle animation
+				_vm->_cursor->hideCursor();
+				_vm->_sound->playSoundBlocking(11120);
+				_vm->_gfx->copyImageToBackBuffer(6118, Common::Rect(544, 333));
+				_vm->_sound->replaceSoundMyst(12120);
+				_vm->_gfx->runTransition(2, Common::Rect(177, 0, 370, 333), 25, 0);
+				_vm->_sound->playSoundBlocking(13120);
+				_vm->_sound->replaceSoundMyst(8120);
+				_vm->_gfx->copyImageToBackBuffer(6327, Common::Rect(544, 333));
+				_vm->_system->delayMillis(500);
+				_vm->_sound->replaceSoundMyst(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->_cursor->showCursor();
+
+				_elevatorPosition = 1;
+
+				_vm->changeToCard(6327, true);
+			}
 		}
 	}
 }
@@ -645,16 +647,18 @@ void Mechanical::o_elevatorTopMovie(uint16 op, uint16 var, uint16 argc, uint16 *
 	_vm->_video->waitUntilMovieEnds(window);
 }
 
-void Mechanical::opcode_124(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	varUnusedCheck(op, var);
+void Mechanical::o_fortressRotationSetPosition(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Set fortress position", op);
 
-	if (argc == 0) {
-		// Used by Card 6156 (Fortress Rotation Controls)
-		// Called when Red Exit Button Pressed to raise Elevator
+	VideoHandle gears = _fortressRotationGears->playMovie();
+	uint32 moviePosition = Audio::Timestamp(_vm->_video->getTime(gears), 600).totalNumberOfFrames();
 
-		// TODO: Fill in Code...
-	} else
-		unknown(op, var, argc, argv);
+	// Myst ME short movie workaround, explained in o_fortressRotation_init
+	if (_fortressRotationShortMovieWorkaround) {
+		moviePosition += 3600 * _fortressRotationShortMovieCount;
+	}
+
+	_fortressPosition = (moviePosition + 900) / 1800 % 4;
 }
 
 void Mechanical::o_mystStaircaseMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -663,17 +667,14 @@ void Mechanical::o_mystStaircaseMovie(uint16 op, uint16 var, uint16 argc, uint16
 	_vm->_video->playMovieBlocking(_vm->wrapMovieFilename("sstairs", kMechanicalStack), 199, 108);
 }
 
-void Mechanical::opcode_126(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	varUnusedCheck(op, var);
-
-	if (argc == 0) {
-		// Used by Card 6120 (Fortress Elevator)
-		// Called when Red Exit Button Pressed to raise Elevator and
-		// exit is clicked...
+void Mechanical::o_elevatorWaitTimeout(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Wait for the elevator to go middle", op);
 
-		// TODO: Fill in Code...
-	} else
-		unknown(op, var, argc, argv);
+	// Wait while the elevator times out
+	while (_elevatorGoingMiddle) {
+		runPersistentScripts();
+		_vm->skippableWait(10);
+	}
 }
 
 void Mechanical::o_crystalEnterYellow(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/myst_stacks/mechanical.h b/engines/mohawk/myst_stacks/mechanical.h
index 01a1971..7f3d514 100644
--- a/engines/mohawk/myst_stacks/mechanical.h
+++ b/engines/mohawk/myst_stacks/mechanical.h
@@ -80,9 +80,9 @@ private:
 	DECLARE_OPCODE(o_elevatorWindowMovie);
 	DECLARE_OPCODE(o_elevatorGoMiddle);
 	DECLARE_OPCODE(o_elevatorTopMovie);
-	DECLARE_OPCODE(opcode_124);
+	DECLARE_OPCODE(o_fortressRotationSetPosition);
 	DECLARE_OPCODE(o_mystStaircaseMovie);
-	DECLARE_OPCODE(opcode_126);
+	DECLARE_OPCODE(o_elevatorWaitTimeout);
 	DECLARE_OPCODE(o_crystalEnterYellow);
 	DECLARE_OPCODE(o_crystalEnterGreen);
 	DECLARE_OPCODE(o_crystalEnterRed);


Commit: 07ee25c87df1aa7599664ec97ea5fb277b0c4f89
    https://github.com/scummvm/scummvm/commit/07ee25c87df1aa7599664ec97ea5fb277b0c4f89
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:54:13-08:00

Commit Message:
MOHAWK: Implement most of Myst's transition system

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_scripts.h
    engines/mohawk/myst_stacks/channelwood.cpp
    engines/mohawk/myst_stacks/demo.cpp
    engines/mohawk/myst_stacks/intro.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/console.cpp b/engines/mohawk/console.cpp
index a7a650d..fc957e8 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -75,7 +75,7 @@ bool MystConsole::Cmd_ChangeCard(int argc, const char **argv) {
 	}
 
 	_vm->_sound->stopSound();
-	_vm->changeToCard((uint16)atoi(argv[1]), true);
+	_vm->changeToCard((uint16)atoi(argv[1]), kTransitionCopy);
 
 	return false;
 }
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 9c0e642..380bf3b 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -523,7 +523,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
 			_video->playMovieBlockingCentered(wrapMovieFilename(flyby, kMasterpieceOnly));
 	}
 
-	changeToCard(card, true);
+	changeToCard(card, kTransitionCopy);
 
 	if (linkDstSound)
 		_sound->playSoundBlocking(linkDstSound);
@@ -549,7 +549,7 @@ void MohawkEngine_Myst::drawCardBackground() {
 	_gfx->copyImageToBackBuffer(getCardBackgroundId(), Common::Rect(0, 0, 544, 332));
 }
 
-void MohawkEngine_Myst::changeToCard(uint16 card, bool updateScreen) {
+void MohawkEngine_Myst::changeToCard(uint16 card, TransitionType transition) {
 	debug(2, "changeToCard(%d)", card);
 
 	_scriptParser->disablePersistentScripts();
@@ -629,9 +629,11 @@ void MohawkEngine_Myst::changeToCard(uint16 card, bool updateScreen) {
 	}
 
 	// Make sure the screen is updated
-	if (updateScreen) {
-		_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
-		_system->updateScreen();
+	if (transition != kNoTransition) {
+		if (!_gameState->_globals.transitions)
+			transition = kTransitionCopy;
+
+		_gfx->runTransition(transition, Common::Rect(544, 333), 10, 0);
 	}
 
 	// Make sure we have the right cursor showing
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 30770f7..43559e2 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -75,6 +75,20 @@ enum {
 	kStoneshipStack			// Stoneship Age
 };
 
+// Transitions
+enum TransitionType {
+	kTransitionLeftToRight	= 0,
+	kTransitionRightToLeft	= 1,
+	kTransitionUnk2			= 2,
+	kTransitionDissolve		= 4,
+	kTransitionTopToBottom	= 5,
+	kTransitionBottomToTop	= 6,
+	kTransitionPartToRight	= 9,
+	kTransitionPartToLeft	= 10,
+	kTransitionCopy			= 11,
+	kNoTransition			= 999
+};
+
 const uint16 kMasterpieceOnly = 0xFFFF;
 
 struct MystCondition {
@@ -154,7 +168,7 @@ public:
 	void reloadSaveList();
 
 	void changeToStack(uint16 stack, uint16 card, uint16 linkSrcSound, uint16 linkDstSound);
-	void changeToCard(uint16 card, bool updateScreen);
+	void changeToCard(uint16 card, TransitionType transition);
 	uint16 getCurCard() { return _curCard; }
 	uint16 getCurStack() { return _curStack; }
 	void setMainCursor(uint16 cursor);
diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp
index a1f965a..12a2c7f 100644
--- a/engines/mohawk/myst_areas.cpp
+++ b/engines/mohawk/myst_areas.cpp
@@ -70,10 +70,30 @@ MystResource::~MystResource() {
 }
 
 void MystResource::handleMouseUp() {
-	if (_dest != 0)
-		_vm->changeToCard(_dest, true);
-	else
+	if (_dest == 0) {
 		warning("Movement type resource with null destination at position (%d, %d), (%d, %d)", _rect.left, _rect.top, _rect.right, _rect.bottom);
+		return;
+	}
+
+	uint16 opcode;
+
+	switch (type) {
+	case kMystForwardArea:
+		opcode = 6;
+		break;
+	case kMystLeftArea:
+		opcode = 8;
+		break;
+	case kMystRightArea:
+		opcode = 7;
+		break;
+	default:
+		opcode = 48;
+		break;
+	}
+
+	_vm->_scriptParser->setInvokingResource(this);
+	_vm->_scriptParser->runOpcode(opcode, 0);
 }
 
 bool MystResource::canBecomeActive() {
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
index 2df0f7e..9eeb191 100644
--- a/engines/mohawk/myst_graphics.cpp
+++ b/engines/mohawk/myst_graphics.cpp
@@ -209,14 +209,14 @@ void MystGraphics::copyBackBufferToScreen(Common::Rect r) {
 	_vm->_system->copyRectToScreen(_backBuffer->getBasePtr(r.left, r.top), _backBuffer->pitch, r.left, r.top, r.width(), r.height());
 }
 
-void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay) {
+void MystGraphics::runTransition(TransitionType type, Common::Rect rect, uint16 steps, uint16 delay) {
 
 	// Do not artificially delay during transitions
 	int oldEnableDrawingTimeSimulation = _enableDrawingTimeSimulation;
 	_enableDrawingTimeSimulation = 0;
 
 	switch (type) {
-	case 0:	{
+	case kTransitionLeftToRight:	{
 			debugC(kDebugScript, "Left to Right");
 
 			uint16 step = (rect.right - rect.left) / steps;
@@ -239,7 +239,7 @@ void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, u
 			}
 		}
 		break;
-	case 1:	{
+	case kTransitionRightToLeft:	{
 			debugC(kDebugScript, "Right to Left");
 
 			uint16 step = (rect.right - rect.left) / steps;
@@ -262,7 +262,16 @@ void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, u
 			}
 		}
 		break;
-	case 5:	{
+	case kTransitionDissolve: {
+			debugC(kDebugScript, "Dissolve");
+
+			for (int16 step = 0; step < 8; step++) {
+				simulatePreviousDrawDelay(rect);
+				transitionDissolve(rect, step);
+			}
+		}
+		break;
+	case kTransitionTopToBottom:	{
 			debugC(kDebugScript, "Top to Bottom");
 
 			uint16 step = (rect.bottom - rect.top) / steps;
@@ -285,7 +294,7 @@ void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, u
 			}
 		}
 		break;
-	case 6:	{
+	case kTransitionBottomToTop:	{
 			debugC(kDebugScript, "Bottom to Top");
 
 			uint16 step = (rect.bottom - rect.top) / steps;
@@ -308,10 +317,23 @@ void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, u
 			}
 		}
 		break;
-	default:
-		warning("Unknown Update Direction");
+	case kTransitionPartToRight: {
+			debugC(kDebugScript, "Partial left to right");
+
+			transitionPartialToRight(rect, 75, 3);
+		}
+		break;
+	case kTransitionPartToLeft: {
+			debugC(kDebugScript, "Partial right to left");
 
+			transitionPartialToLeft(rect, 75, 3);
+		}
+		break;
+	default:
 		//TODO: Replace minimal implementation
+		warning("Unknown transition %d", type);
+		// Fallthrough
+	case kTransitionCopy:
 		copyBackBufferToScreen(rect);
 		_vm->_system->updateScreen();
 		break;
@@ -320,6 +342,130 @@ void MystGraphics::runTransition(uint16 type, Common::Rect rect, uint16 steps, u
 	_enableDrawingTimeSimulation = oldEnableDrawingTimeSimulation;
 }
 
+
+void MystGraphics::transitionDissolve(Common::Rect rect, uint step) {
+	static const bool pattern[][4][4] = {
+		{
+			{ true,  false, false, false },
+			{ false, false, false, false },
+			{ false, false, true,  false },
+			{ false, false, false, false }
+		},
+		{
+			{ false, false, true,  false },
+			{ false, false, false, false },
+			{ true,  false, false, false },
+			{ false, false, false, false }
+		},
+		{
+			{ false, false, false, false },
+			{ false, true,  false, false },
+			{ false, false, false, false },
+			{ false, false, false, true  }
+		},
+		{
+			{ false, false, false, false },
+			{ false, false, false, true  },
+			{ false, false, false, false },
+			{ false, true,  false, false }
+		},
+		{
+			{ false, false, false, false },
+			{ false, false, true,  false },
+			{ false, true,  false, false },
+			{ false, false, false, false }
+		},
+		{
+			{ false, true,  false, false },
+			{ false, false, false, false },
+			{ false, false, false, false },
+			{ false, false, true,  false }
+		},
+		{
+			{ false, false, false, false },
+			{ true,  false, false, false },
+			{ false, false, false, true  },
+			{ false, false, false, false }
+		},
+		{
+			{ false, false, false, true  },
+			{ false, false, false, false },
+			{ false, false, false, false },
+			{ true,  false, false, false }
+		}
+	};
+
+	rect.clip(_viewport);
+
+	Graphics::Surface *screen = _vm->_system->lockScreen();
+
+	for (uint16 y = rect.top; y < rect.bottom; y++) {
+		const bool *linePattern = pattern[step][y % 4];
+
+		if (!linePattern[0] && !linePattern[1] && !linePattern[2] && !linePattern[3])
+			continue;
+
+		for (uint16 x = rect.left; x < rect.right; x++) {
+			if (linePattern[x % 4]) {
+				if (_pixelFormat.bytesPerPixel == 2) {
+					uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
+					*dst = *(const uint16 *)_backBuffer->getBasePtr(x, y);
+				} else {
+					uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
+					*dst = *(const uint32 *)_backBuffer->getBasePtr(x, y);
+				}
+			}
+		}
+	}
+
+	_vm->_system->unlockScreen();
+	_vm->_system->updateScreen();
+}
+
+void MystGraphics::transitionPartialToRight(Common::Rect rect, uint32 width, uint32 steps)
+{
+	rect.clip(_viewport);
+
+	uint32 stepWidth = width / steps;
+	Common::Rect srcRect = Common::Rect(rect.right, rect.top, rect.right, rect.bottom);
+	Common::Rect dstRect = Common::Rect(rect.left, rect.top, rect.left, rect.bottom);
+
+	for (uint step = 1; step <= steps; step++) {
+		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->_system->updateScreen();
+	}
+
+	copyBackBufferToScreen(rect);
+	_vm->_system->updateScreen();
+}
+
+void MystGraphics::transitionPartialToLeft(Common::Rect rect, uint32 width, uint32 steps)
+{
+	rect.clip(_viewport);
+
+	uint32 stepWidth = width / steps;
+	Common::Rect srcRect = Common::Rect(rect.left, rect.top, rect.left, rect.bottom);
+	Common::Rect dstRect = Common::Rect(rect.right, rect.top, rect.right, rect.bottom);
+
+	for (uint step = 1; step <= steps; step++) {
+		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->_system->updateScreen();
+	}
+
+	copyBackBufferToScreen(rect);
+	_vm->_system->updateScreen();
+}
+
 void MystGraphics::drawRect(Common::Rect rect, RectState state) {
 	rect.clip(_viewport);
 
diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h
index de8fe52..04eb1b9 100644
--- a/engines/mohawk/myst_graphics.h
+++ b/engines/mohawk/myst_graphics.h
@@ -48,7 +48,7 @@ public:
 	void copyImageToScreen(uint16 image, Common::Rect dest);
 	void copyImageToBackBuffer(uint16 image, Common::Rect dest);
 	void copyBackBufferToScreen(Common::Rect r);
-	void runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay);
+	void runTransition(TransitionType type, Common::Rect rect, uint16 steps, uint16 delay);
 	void drawRect(Common::Rect rect, RectState state);
 	void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
 	void enableDrawingTimeSimulation(bool enable);
@@ -60,7 +60,9 @@ protected:
 	MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
 	void simulatePreviousDrawDelay(const Common::Rect &dest);
 	void copyBackBufferToScreenWithSaturation(int16 saturation);
-
+	void transitionDissolve(Common::Rect rect, uint step);
+	void transitionPartialToRight(Common::Rect rect, uint32 width, uint32 steps);
+	void transitionPartialToLeft(Common::Rect rect, uint32 width, uint32 steps);
 private:
 	MohawkEngine_Myst *_vm;
 	MystBitmap *_bmpDecoder;
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 107a8b0..c1b75df 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -100,18 +100,18 @@ void MystScriptParser::setupCommonOpcodes() {
 	// "Standard" Opcodes
 	OPCODE(0, o_toggleVar);
 	OPCODE(1, o_setVar);
-	OPCODE(2, o_changeCardSwitch);
+	OPCODE(2, o_changeCardSwitch4);
 	OPCODE(3, o_takePage);
 	OPCODE(4, o_redrawCard);
 	// Opcode 5 Not Present
-	OPCODE(6, o_goToDest);
-	OPCODE(7, o_goToDest);
-	OPCODE(8, o_goToDest);
+	OPCODE(6, o_goToDestForward);
+	OPCODE(7, o_goToDestLeft);
+	OPCODE(8, o_goToDestRight);
 	OPCODE(9, o_triggerMovie);
 	OPCODE(10, o_toggleVarNoRedraw);
 	// Opcode 11 Not Present
-	OPCODE(12, o_changeCardSwitch);
-	OPCODE(13, o_changeCardSwitch);
+	OPCODE(12, o_changeCardSwitchLtR);
+	OPCODE(13, o_changeCardSwitchRtL);
 	OPCODE(14, o_drawAreaState);
 	OPCODE(15, o_redrawAreaForVar);
 	OPCODE(16, o_changeCardDirectional);
@@ -120,7 +120,7 @@ void MystScriptParser::setupCommonOpcodes() {
 	OPCODE(19, o_enableAreas);
 	OPCODE(20, o_disableAreas);
 	OPCODE(21, o_directionalUpdate);
-	OPCODE(22, o_goToDest);
+	OPCODE(22, o_goToDestUp);
 	OPCODE(23, o_toggleAreasActivation);
 	OPCODE(24, o_playSound);
 	// Opcode 25 is unused; original calls replaceSoundMyst
@@ -145,6 +145,7 @@ void MystScriptParser::setupCommonOpcodes() {
 	OPCODE(44, o_restoreMainCursor);
 	// Opcode 45 Not Present
 	OPCODE(46, o_soundWaitStop);
+	OPCODE(48, o_goToDest);
 	OPCODE(51, o_exitMap);
 	// Opcodes 47 to 99 Not Present
 
@@ -273,7 +274,7 @@ void MystScriptParser::animatedUpdate(uint16 argc, uint16 *argv, uint16 delay) {
 
 	while (argsRead < argc) {
 		Common::Rect rect = Common::Rect(argv[argsRead], argv[argsRead + 1], argv[argsRead + 2], argv[argsRead + 3]);
-		uint16 kind = argv[argsRead + 4];
+		TransitionType kind = static_cast<TransitionType>(argv[argsRead + 4]);
 		uint16 steps = argv[argsRead + 5];
 
 		debugC(kDebugScript, "\trect.left: %d", rect.left);
@@ -323,16 +324,41 @@ void MystScriptParser::o_setVar(uint16 op, uint16 var, uint16 argc, uint16 *argv
 		_vm->redrawArea(var);
 }
 
-void MystScriptParser::o_changeCardSwitch(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	// Opcodes 2, 12, and 13 are the same
+void MystScriptParser::o_changeCardSwitch4(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	uint16 value = getVar(var);
 
 	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
 
 	if (value)
-		_vm->changeToCard(argv[value -1 ], true);
+		_vm->changeToCard(argv[value -1 ], kTransitionDissolve);
 	else if (_invokingResource != NULL)
-		_vm->changeToCard(_invokingResource->getDest(), true);
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionDissolve);
+	else
+		warning("Missing invokingResource in altDest call");
+}
+
+void MystScriptParser::o_changeCardSwitchLtR(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	uint16 value = getVar(var);
+
+	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
+
+	if (value)
+		_vm->changeToCard(argv[value -1 ], kTransitionLeftToRight);
+	else if (_invokingResource != NULL)
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionLeftToRight);
+	else
+		warning("Missing invokingResource in altDest call");
+}
+
+void MystScriptParser::o_changeCardSwitchRtL(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	uint16 value = getVar(var);
+
+	debugC(kDebugScript, "Opcode %d: changeCardSwitch var %d: %d", op, var, value);
+
+	if (value)
+		_vm->changeToCard(argv[value -1 ], kTransitionRightToLeft);
+	else if (_invokingResource != NULL)
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionRightToLeft);
 	else
 		warning("Missing invokingResource in altDest call");
 }
@@ -373,10 +399,47 @@ void MystScriptParser::o_goToDest(uint16 op, uint16 var, uint16 argc, uint16 *ar
 	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
 
 	if (_invokingResource != NULL)
-		_vm->changeToCard(_invokingResource->getDest(), true);
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionCopy);
+	else
+		warning("Opcode %d: Missing invokingResource", op);
+}
+
+void MystScriptParser::o_goToDestForward(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
+
+	if (_invokingResource != NULL)
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionDissolve);
+	else
+		warning("Opcode %d: Missing invokingResource", op);
+}
+
+void MystScriptParser::o_goToDestLeft(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
+
+	if (_invokingResource != NULL)
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionPartToRight);
+	else
+		warning("Opcode %d: Missing invokingResource", op);
+}
+
+void MystScriptParser::o_goToDestRight(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
+
+	if (_invokingResource != NULL)
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionPartToLeft);
 	else
 		warning("Opcode %d: Missing invokingResource", op);
 }
+
+void MystScriptParser::o_goToDestUp(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+	debugC(kDebugScript, "Opcode %d: Change To Dest of Invoking Resource", op);
+
+	if (_invokingResource != NULL)
+		_vm->changeToCard(_invokingResource->getDest(), kTransitionTopToBottom);
+	else
+		warning("Opcode %d: Missing invokingResource", op);
+}
+
 void MystScriptParser::o_triggerMovie(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Trigger Type 6 Resource Movie..", op);
 	// TODO: If movie has sound, pause background music
@@ -427,7 +490,7 @@ void MystScriptParser::o_changeCardDirectional(uint16 op, uint16 var, uint16 arg
 	debugC(kDebugScript, "\tcardId: %d", cardId);
 	debugC(kDebugScript, "\tdirectonal update data size: %d", directionalUpdateDataSize);
 
-	_vm->changeToCard(cardId, false);
+	_vm->changeToCard(cardId, kNoTransition);
 
 	animatedUpdate(directionalUpdateDataSize, &argv[2], 0);
 }
@@ -440,23 +503,23 @@ void MystScriptParser::o_changeCardPush(uint16 op, uint16 var, uint16 argc, uint
 	debugC(kDebugScript, "Opcode %d: Jump to Card Id, Storing Current Card Id", op);
 
 	_savedCardId = _vm->getCurCard();
-	uint16 cardId = argv[0];
 
-	// argv[1] is not used in the original engine
+	uint16 cardId = argv[0];
+	TransitionType transition = static_cast<TransitionType>(argv[1]);
 
 	debugC(kDebugScript, "\tCurrent CardId: %d", _savedCardId);
 	debugC(kDebugScript, "\tJump to CardId: %d", cardId);
 
-	_vm->changeToCard(cardId, true);
+	_vm->changeToCard(cardId, transition);
 }
 
 void MystScriptParser::o_changeCardPop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 	debugC(kDebugScript, "Opcode %d: Return To Stored Card Id", op);
 	debugC(kDebugScript, "\tCardId: %d", _savedCardId);
 
-	// argv[0] is not used in the original engine
+	TransitionType transition = static_cast<TransitionType>(argv[0]);
 
-	_vm->changeToCard(_savedCardId, true);
+	_vm->changeToCard(_savedCardId, transition);
 }
 
 void MystScriptParser::o_enableAreas(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -752,14 +815,11 @@ void MystScriptParser::o_changeCard(uint16 op, uint16 var, uint16 argc, uint16 *
 	debugC(kDebugScript, "Opcode %d: Change Card", op);
 
 	uint16 cardId = argv[0];
-
-	// Argument 1 if present is not used
-	// uint16 u0 = argv[1];
+	TransitionType transition = static_cast<TransitionType>(argv[1]);
 
 	debugC(kDebugScript, "\tTarget Card: %d", cardId);
-	//debugC(kDebugScript, "\tu0: %d", u0); // Unused data
 
-	_vm->changeToCard(cardId, true);
+	_vm->changeToCard(cardId, transition);
 }
 
 void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -767,7 +827,7 @@ void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, uint16 argc,
 
 		uint16 imageId = argv[0];
 		uint16 cardId = argv[1];
-		// argv[2] is not used in the original engine
+		TransitionType transition = static_cast<TransitionType>(argv[2]);
 
 		debugC(kDebugScript, "\timageId: %d", imageId);
 		debugC(kDebugScript, "\tcardId: %d", cardId);
@@ -775,7 +835,7 @@ void MystScriptParser::o_drawImageChangeCard(uint16 op, uint16 var, uint16 argc,
 		_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
 		_vm->_system->updateScreen();
 
-		_vm->changeToCard(cardId, true);
+		_vm->changeToCard(cardId, transition);
 }
 
 void MystScriptParser::o_changeMainCursor(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -850,7 +910,7 @@ void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, u
 	if (soundId)
 		_vm->_sound->replaceSoundMyst(soundId);
 
-	_vm->changeToCard(cardId, false);
+	_vm->changeToCard(cardId, kNoTransition);
 
 	animatedUpdate(dataSize, &argv[4], delayBetweenSteps);
 }
@@ -901,12 +961,12 @@ void MystScriptParser::o_quit(uint16 op, uint16 var, uint16 argc, uint16 *argv)
 void MystScriptParser::showMap() {
 	if (_vm->getCurCard() != getMap()) {
 		_savedMapCardId = _vm->getCurCard();
-		_vm->changeToCard(getMap(), true);
+		_vm->changeToCard(getMap(), kTransitionCopy);
 	}
 }
 
 void MystScriptParser::o_exitMap(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
-	_vm->changeToCard(_savedMapCardId, true);
+	_vm->changeToCard(_savedMapCardId, kTransitionCopy);
 }
 
 } // End of namespace Mohawk
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index ccb76e0..b75da08 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -86,10 +86,16 @@ public:
 	// Common opcodes
 	DECLARE_OPCODE(o_toggleVar);
 	DECLARE_OPCODE(o_setVar);
-	DECLARE_OPCODE(o_changeCardSwitch);
+	DECLARE_OPCODE(o_changeCardSwitch4);
+	DECLARE_OPCODE(o_changeCardSwitchLtR);
+	DECLARE_OPCODE(o_changeCardSwitchRtL);
 	DECLARE_OPCODE(o_takePage);
 	DECLARE_OPCODE(o_redrawCard);
 	DECLARE_OPCODE(o_goToDest);
+	DECLARE_OPCODE(o_goToDestForward);
+	DECLARE_OPCODE(o_goToDestLeft);
+	DECLARE_OPCODE(o_goToDestRight);
+	DECLARE_OPCODE(o_goToDestUp);
 	DECLARE_OPCODE(o_triggerMovie);
 	DECLARE_OPCODE(o_toggleVarNoRedraw);
 	DECLARE_OPCODE(o_drawAreaState);
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index c32ab3a..63ba5f7 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -341,7 +341,7 @@ void Channelwood::o_drawImageChangeCardAndVolume(uint16 op, uint16 var, uint16 a
 	_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
 	_vm->_system->updateScreen();
 
-	_vm->changeToCard(cardId, true);
+	_vm->changeToCard(cardId, kTransitionPartToLeft);
 
 	if (argc == 3) {
 		uint16 volume = argv[2];
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index 29a1257..9f393ea 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -104,14 +104,14 @@ void Demo::returnToMenu_run() {
 	switch (_returnToMenuStep){
 	case 0:
 		_vm->_gfx->fadeToBlack();
-		_vm->changeToCard(2003, false);
+		_vm->changeToCard(2003, kNoTransition);
 		_vm->_gfx->fadeFromBlack();
 
 		_returnToMenuStep++;
 		break;
 	case 1:
 		_vm->_gfx->fadeToBlack();
-		_vm->changeToCard(2001, false);
+		_vm->changeToCard(2001, kNoTransition);
 		_vm->_gfx->fadeFromBlack();
 		_vm->_cursor->showCursor();
 
diff --git a/engines/mohawk/myst_stacks/intro.cpp b/engines/mohawk/myst_stacks/intro.cpp
index 545b97d..7173322 100644
--- a/engines/mohawk/myst_stacks/intro.cpp
+++ b/engines/mohawk/myst_stacks/intro.cpp
@@ -127,9 +127,9 @@ void Intro::introMovies_run() {
 		break;
 	default:
 		if (_vm->getFeatures() & GF_DEMO)
-			_vm->changeToCard(2001, true);
+			_vm->changeToCard(2001, kTransitionRightToLeft);
 		else
-			_vm->changeToCard(2, true);
+			_vm->changeToCard(2, kTransitionRightToLeft);
 	}
 }
 
@@ -148,7 +148,7 @@ void Intro::mystLinkBook_run() {
 			_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
 		}
 	} else if (!_linkBookMovie->isPlaying()) {
-		_vm->changeToCard(5, true);
+		_vm->changeToCard(5, kTransitionRightToLeft);
 	}
 }
 
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 6a925ab..d6069a1 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -616,7 +616,7 @@ void Mechanical::elevatorGoMiddle_run() {
 				_vm->_sound->playSoundBlocking(11120);
 				_vm->_gfx->copyImageToBackBuffer(6118, Common::Rect(544, 333));
 				_vm->_sound->replaceSoundMyst(12120);
-				_vm->_gfx->runTransition(2, Common::Rect(177, 0, 370, 333), 25, 0);
+				_vm->_gfx->runTransition(kTransitionUnk2, Common::Rect(177, 0, 370, 333), 25, 0);
 				_vm->_sound->playSoundBlocking(13120);
 				_vm->_sound->replaceSoundMyst(8120);
 				_vm->_gfx->copyImageToBackBuffer(6327, Common::Rect(544, 333));
@@ -630,7 +630,7 @@ void Mechanical::elevatorGoMiddle_run() {
 
 				_elevatorPosition = 1;
 
-				_vm->changeToCard(6327, true);
+				_vm->changeToCard(6327, kTransitionRightToLeft);
 			}
 		}
 	}
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index f09c992..f404b23 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -1043,7 +1043,7 @@ void Myst::o_bookGivePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 
 	// No page or white page
 	if (!_globals.heldPage || _globals.heldPage == 13) {
-		_vm->changeToCard(cardIdBookCover, true);
+		_vm->changeToCard(cardIdBookCover, kTransitionDissolve);
 		return;
 	}
 
@@ -1085,7 +1085,7 @@ void Myst::o_bookGivePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 
 	// Wrong book
 	if (bookVar != var) {
-		_vm->changeToCard(cardIdBookCover, true);
+		_vm->changeToCard(cardIdBookCover, kTransitionDissolve);
 		return;
 	}
 
@@ -1111,9 +1111,9 @@ void Myst::o_bookGivePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
 		else
 			_globals.currentAge = 10;
 
-		_vm->changeToCard(cardIdLose, true);
+		_vm->changeToCard(cardIdLose, kTransitionDissolve);
 	} else {
-		_vm->changeToCard(cardIdBookCover, true);
+		_vm->changeToCard(cardIdBookCover, kTransitionDissolve);
 	}
 }
 
@@ -1300,7 +1300,7 @@ void Myst::imagerValidation_run() {
 
 		if (_imagerValidationStep == 11) {
 			_imagerValidationStep = 0;
-			_vm->changeToCard(_imagerValidationCard, true);
+			_vm->changeToCard(_imagerValidationCard, kTransitionBottomToTop);
 		} else {
 			_startTime = time + 100;
 		}
@@ -1475,10 +1475,10 @@ void Myst::o_cabinSafeHandleMove(uint16 op, uint16 var, uint16 argc, uint16 *arg
 			if (soundId)
 				_vm->_sound->replaceSoundMyst(soundId);
 
-			_vm->changeToCard(4103, false);
+			_vm->changeToCard(4103, kNoTransition);
 
 			Common::Rect screenRect = Common::Rect(544, 333);
-			_vm->_gfx->runTransition(0, screenRect, 2, 5);
+			_vm->_gfx->runTransition(kTransitionLeftToRight, screenRect, 2, 5);
 		}
 		_tempVar = 1;
 	} else {
@@ -3296,7 +3296,7 @@ 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(6, Common::Rect(0, 72, 106, 153), 5, 10);
+			_vm->_gfx->runTransition(kTransitionBottomToTop, Common::Rect(0, 72, 106, 153), 5, 10);
 			_vm->_sound->playSoundBlocking(7348);
 			_vm->_sound->replaceBackgroundMyst(4348, 16384);
 		} else {
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index 0b8dcf8..608bd0a 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -139,7 +139,7 @@ void Preview::speech_run() {
 		break;
 	case 1: // Open book
 		if (_currentCue >= 1) {
-			_vm->changeToCard(3001, true);
+			_vm->changeToCard(3001, kTransitionDissolve);
 
 			_speechStep++;
 		}
@@ -147,7 +147,7 @@ void Preview::speech_run() {
 	case 2: // Go to Myst
 		if (_currentCue >= 2) {
 			_vm->_gfx->fadeToBlack();
-			_vm->changeToCard(3002, false);
+			_vm->changeToCard(3002, kNoTransition);
 			_vm->_gfx->fadeFromBlack();
 
 			_speechStep++;
@@ -164,7 +164,7 @@ void Preview::speech_run() {
 		if (_currentCue >= 4) {
 			_library->drawConditionalDataToScreen(0);
 
-			_vm->changeToCard(3003, true);
+			_vm->changeToCard(3003, kTransitionDissolve);
 
 			_speechNextTime = time + 2000;
 			_speechStep++;
@@ -181,7 +181,7 @@ void Preview::speech_run() {
 		if (time < _speechNextTime)
 			break;
 
-		_vm->changeToCard(3004, true);
+		_vm->changeToCard(3004, kTransitionDissolve);
 		_speechNextTime = time + 2000;
 		_speechStep++;
 		break;
@@ -190,7 +190,7 @@ void Preview::speech_run() {
 			break;
 
 		_vm->_gfx->fadeToBlack();
-		_vm->changeToCard(3005, false);
+		_vm->changeToCard(3005, kNoTransition);
 		_vm->_gfx->fadeFromBlack();
 		_speechNextTime = time + 1000;
 		_speechStep++;
@@ -205,7 +205,7 @@ void Preview::speech_run() {
 		if (time < _speechNextTime)
 			break;
 
-		_vm->changeToCard(3006 + _speechStep - 7, true);
+		_vm->changeToCard(3006 + _speechStep - 7, kTransitionDissolve);
 		_speechNextTime = time + 2000;
 		_speechStep++;
 		break;
@@ -213,7 +213,7 @@ void Preview::speech_run() {
 		if (time < _speechNextTime)
 			break;
 
-		_vm->changeToCard(4329, true);
+		_vm->changeToCard(4329, kTransitionDissolve);
 
 		_speechRunning = false;
 		_globals.currentAge = 2;
diff --git a/engines/mohawk/myst_stacks/selenitic.cpp b/engines/mohawk/myst_stacks/selenitic.cpp
index 1473742..a941b14 100644
--- a/engines/mohawk/myst_stacks/selenitic.cpp
+++ b/engines/mohawk/myst_stacks/selenitic.cpp
@@ -729,11 +729,11 @@ void Selenitic::o_mazeRunnerDoorButton(uint16 op, uint16 var, uint16 argc, uint1
 	uint16 cardIdEntry = argv[1];
 
 	if (_mazeRunnerPosition == 288) {
-		_vm->changeToCard(cardIdEntry, false);
+		_vm->changeToCard(cardIdEntry, kNoTransition);
 		_vm->_sound->replaceSoundMyst(cardIdEntry);
 		animatedUpdate(argv[2], &argv[3], 10);
 	} else if (_mazeRunnerPosition == 289) {
-		_vm->changeToCard(cardIdExit, false);
+		_vm->changeToCard(cardIdExit, kNoTransition);
 		_vm->_sound->replaceSoundMyst(cardIdExit);
 		animatedUpdate(argv[2], &argv[3], 10);
 	}
@@ -895,9 +895,9 @@ void Selenitic::o_soundLockButton(uint16 op, uint16 var, uint16 argc, uint16 *ar
 		uint16 cardIdClosed = argv[0];
 		uint16 cardIdOpen = argv[1];
 
-		_vm->changeToCard(cardIdClosed, true);
+		_vm->changeToCard(cardIdClosed, kTransitionDissolve);
 
-		_vm->changeToCard(cardIdOpen, false);
+		_vm->changeToCard(cardIdOpen, kNoTransition);
 		_vm->_sound->replaceSoundMyst(argv[2]);
 
 		animatedUpdate(argv[4], &argv[5], argv[3]);
diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp
index c0bb400..7209269 100644
--- a/engines/mohawk/myst_stacks/slides.cpp
+++ b/engines/mohawk/myst_stacks/slides.cpp
@@ -63,7 +63,7 @@ void Slides::runPersistentScripts() {
 		// Used on Cards...
 		if (_vm->_system->getMillis() > _nextCardTime) {
 			_vm->_gfx->fadeToBlack();
-			_vm->changeToCard(_nextCardID, false);
+			_vm->changeToCard(_nextCardID, kNoTransition);
 			_vm->_gfx->fadeFromBlack();
 		}
 	}
diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp
index 595f9db..1359685 100644
--- a/engines/mohawk/myst_stacks/stoneship.cpp
+++ b/engines/mohawk/myst_stacks/stoneship.cpp
@@ -440,9 +440,9 @@ void Stoneship::o_drawerOpenSirius(uint16 op, uint16 var, uint16 argc, uint16 *a
 		drawer->drawConditionalDataToScreen(0, 0);
 	}
 
-	uint16 transition = 5;
+	TransitionType transition = kTransitionTopToBottom;
 	if (argc == 2 && argv[1])
-		transition = 11;
+		transition = kTransitionCopy;
 
 	_vm->_gfx->runTransition(transition, drawer->getRect(), 25, 5);
 }
@@ -579,7 +579,7 @@ void Stoneship::o_drawerOpenAchenar(uint16 op, uint16 var, uint16 argc, uint16 *
 
 	MystResourceType8 *drawer = static_cast<MystResourceType8 *>(_vm->_resources[argv[0]]);
 	drawer->drawConditionalDataToScreen(0, 0);
-	_vm->_gfx->runTransition(5, drawer->getRect(), 25, 5);
+	_vm->_gfx->runTransition(kTransitionTopToBottom, drawer->getRect(), 25, 5);
 }
 
 void Stoneship::o_hologramPlayback(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -777,7 +777,7 @@ void Stoneship::o_cloudOrbLeave(uint16 op, uint16 var, uint16 argc, uint16 *argv
 
 	_cloudOrbMovie->pauseMovie(true);
 	_vm->_sound->replaceSoundMyst(_cloudOrbStopSound);
-	_vm->_gfx->runTransition(5, _invokingResource->getRect(), 4, 0);
+	_vm->_gfx->runTransition(kTransitionTopToBottom, _invokingResource->getRect(), 4, 0);
 }
 
 void Stoneship::o_drawerCloseOpened(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -794,7 +794,7 @@ void Stoneship::drawerClose(uint16 drawer) {
 	_vm->drawResourceImages();
 
 	MystResource *res = _vm->_resources[drawer];
-	_vm->_gfx->runTransition(6, res->getRect(), 25, 5);
+	_vm->_gfx->runTransition(kTransitionBottomToTop, res->getRect(), 25, 5);
 }
 
 void Stoneship::o_hologramDisplay_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {


Commit: 611900d3c36ca9acaecca195f477841b9e8015df
    https://github.com/scummvm/scummvm/commit/611900d3c36ca9acaecca195f477841b9e8015df
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2012-12-15T21:55:07-08:00

Commit Message:
MOHAWK: The cancel button of Myst's dialog was actually saving

Changed paths:
    engines/mohawk/dialogs.cpp



diff --git a/engines/mohawk/dialogs.cpp b/engines/mohawk/dialogs.cpp
index 4461a30..5f5a3b3 100644
--- a/engines/mohawk/dialogs.cpp
+++ b/engines/mohawk/dialogs.cpp
@@ -137,12 +137,6 @@ void MystOptionsDialog::open() {
 
 void MystOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
 	switch (cmd) {
-	case kZipCmd:
-		_vm->_gameState->_globals.zipMode = _zipModeCheckbox->getState();
-		break;
-	case kTransCmd:
-		_vm->_gameState->_globals.transitions = _transitionsCheckbox->getState();
-		break;
 	case kDropCmd:
 		_vm->_needsPageDrop = true;
 		close();
@@ -155,8 +149,10 @@ void MystOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, ui
 		_vm->_needsShowDemoMenu = true;
 		close();
 	break;
-	case GUI::kCloseCmd:
-		close();
+	case GUI::kOKCmd:
+		_vm->_gameState->_globals.zipMode = _zipModeCheckbox->getState();
+		_vm->_gameState->_globals.transitions = _transitionsCheckbox->getState();
+		GUI::OptionsDialog::handleCommand(sender, cmd, data);
 		break;
 	default:
 		GUI::OptionsDialog::handleCommand(sender, cmd, data);






More information about the Scummvm-git-logs mailing list