aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/myst_stacks
diff options
context:
space:
mode:
authorBastien Bouclet2012-12-09 14:33:24 +0100
committerBastien Bouclet2012-12-16 06:51:01 +0100
commitbbc760c51c9961e9ed65bb43901face1579d5b47 (patch)
tree7fc77dd97e4e32a37ee46947cd113184dfc10bd0 /engines/mohawk/myst_stacks
parentadf3a8d7dde028422e0340a5c6995ce9b93376cb (diff)
downloadscummvm-rg350-bbc760c51c9961e9ed65bb43901face1579d5b47.tar.gz
scummvm-rg350-bbc760c51c9961e9ed65bb43901face1579d5b47.tar.bz2
scummvm-rg350-bbc760c51c9961e9ed65bb43901face1579d5b47.zip
MOHAWK: Implement Mechanical fortress rotation
Both the simulation and the actual rotation.
Diffstat (limited to 'engines/mohawk/myst_stacks')
-rw-r--r--engines/mohawk/myst_stacks/mechanical.cpp153
-rw-r--r--engines/mohawk/myst_stacks/mechanical.h2
2 files changed, 151 insertions, 4 deletions
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index 79de03308c..2d84207ef8 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 3bd7f2d71b..ab8b60cf31 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