aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/myst_stacks/mechanical.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk/myst_stacks/mechanical.cpp')
-rw-r--r--engines/mohawk/myst_stacks/mechanical.cpp94
1 files changed, 65 insertions, 29 deletions
diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp
index ffcaa226c6..3324c9a22d 100644
--- a/engines/mohawk/myst_stacks/mechanical.cpp
+++ b/engines/mohawk/myst_stacks/mechanical.cpp
@@ -40,6 +40,9 @@ Mechanical::Mechanical(MohawkEngine_Myst *vm) :
setupOpcodes();
_elevatorGoingMiddle = false;
+ _elevatorPosition = 0;
+
+ _crystalLit = 0;
_mystStaircaseState = false;
_fortressPosition = 0;
@@ -277,7 +280,7 @@ void Mechanical::o_throneEnablePassage(uint16 op, uint16 var, uint16 argc, uint1
void Mechanical::o_birdCrankStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Mechanical bird crank start", op);
- MystResourceType11 *crank = static_cast<MystResourceType11 *>(_invokingResource);
+ MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
uint16 crankSoundId = crank->getList2(0);
_vm->_sound->replaceSoundMyst(crankSoundId, Audio::Mixer::kMaxChannelVolume, true);
@@ -285,16 +288,16 @@ void Mechanical::o_birdCrankStart(uint16 op, uint16 var, uint16 argc, uint16 *ar
_birdSingEndTime = 0;
_birdCrankStartTime = _vm->_system->getMillis();
- MystResourceType6 *crankMovie = static_cast<MystResourceType6 *>(crank->getSubResource(0));
+ MystAreaVideo *crankMovie = static_cast<MystAreaVideo *>(crank->getSubResource(0));
crankMovie->playMovie();
}
void Mechanical::o_birdCrankStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Mechanical bird crank stop", op);
- MystResourceType11 *crank = static_cast<MystResourceType11 *>(_invokingResource);
+ MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
- MystResourceType6 *crankMovie = static_cast<MystResourceType6 *>(crank->getSubResource(0));
+ MystAreaVideo *crankMovie = static_cast<MystAreaVideo *>(crank->getSubResource(0));
crankMovie->pauseMovie(true);
uint16 crankSoundId = crank->getList2(1);
@@ -334,7 +337,7 @@ void Mechanical::o_fortressStaircaseMovie(uint16 op, uint16 var, uint16 argc, ui
void Mechanical::o_elevatorRotationStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Elevator rotation lever start", op);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
lever->drawFrame(0);
_elevatorRotationLeverMoving = true;
@@ -349,7 +352,7 @@ void Mechanical::o_elevatorRotationMove(uint16 op, uint16 var, uint16 argc, uint
debugC(kDebugScript, "Opcode %d: Elevator rotation lever move", op);
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Make the handle follow the mouse
int16 maxStep = lever->getNumFrames() - 1;
@@ -367,7 +370,7 @@ void Mechanical::o_elevatorRotationStop(uint16 op, uint16 var, uint16 argc, uint
debugC(kDebugScript, "Opcode %d: Elevator rotation lever stop", op);
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Get current lever frame
int16 maxStep = lever->getNumFrames() - 1;
@@ -416,7 +419,7 @@ void Mechanical::o_fortressRotationSpeedStart(uint16 op, uint16 var, uint16 argc
_vm->_cursor->setCursor(700);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
lever->drawFrame(0);
}
@@ -424,7 +427,7 @@ void Mechanical::o_fortressRotationSpeedMove(uint16 op, uint16 var, uint16 argc,
debugC(kDebugScript, "Opcode %d Fortress rotation speed lever move", op);
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Make the handle follow the mouse
int16 maxStep = lever->getNumFrames() - 1;
@@ -441,7 +444,7 @@ void Mechanical::o_fortressRotationSpeedMove(uint16 op, uint16 var, uint16 argc,
void Mechanical::o_fortressRotationSpeedStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d Fortress rotation speed lever stop", op);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Release lever
for (int i = _fortressRotationSpeed; i >= 0; i--) {
@@ -459,7 +462,7 @@ void Mechanical::o_fortressRotationBrakeStart(uint16 op, uint16 var, uint16 argc
_vm->_cursor->setCursor(700);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
lever->drawFrame(_fortressRotationBrake);
}
@@ -467,7 +470,7 @@ void Mechanical::o_fortressRotationBrakeMove(uint16 op, uint16 var, uint16 argc,
debugC(kDebugScript, "Opcode %d Fortress rotation brake lever move", op);
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Make the handle follow the mouse
int16 maxStep = lever->getNumFrames() - 1;
@@ -484,7 +487,7 @@ void Mechanical::o_fortressRotationBrakeMove(uint16 op, uint16 var, uint16 argc,
void Mechanical::o_fortressRotationBrakeStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d Fortress rotation brake lever stop", op);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
lever->drawFrame(_fortressRotationBrake);
_vm->checkCursorHints();
@@ -495,7 +498,7 @@ void Mechanical::o_fortressSimulationSpeedStart(uint16 op, uint16 var, uint16 ar
_vm->_cursor->setCursor(700);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
lever->drawFrame(0);
}
@@ -503,7 +506,7 @@ void Mechanical::o_fortressSimulationSpeedMove(uint16 op, uint16 var, uint16 arg
debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever move", op);
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Make the handle follow the mouse
int16 maxStep = lever->getNumFrames() - 1;
@@ -520,7 +523,7 @@ void Mechanical::o_fortressSimulationSpeedMove(uint16 op, uint16 var, uint16 arg
void Mechanical::o_fortressSimulationSpeedStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d Fortress rotation simulator speed lever stop", op);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Release lever
for (int i = _fortressSimulationSpeed; i >= 0; i--) {
@@ -538,7 +541,7 @@ void Mechanical::o_fortressSimulationBrakeStart(uint16 op, uint16 var, uint16 ar
_vm->_cursor->setCursor(700);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
lever->drawFrame(_fortressSimulationBrake);
}
@@ -546,7 +549,7 @@ void Mechanical::o_fortressSimulationBrakeMove(uint16 op, uint16 var, uint16 arg
debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever move", op);
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
// Make the handle follow the mouse
int16 maxStep = lever->getNumFrames() - 1;
@@ -563,7 +566,7 @@ void Mechanical::o_fortressSimulationBrakeMove(uint16 op, uint16 var, uint16 arg
void Mechanical::o_fortressSimulationBrakeStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d Fortress rotation simulator brake lever stop", op);
- MystResourceType12 *lever = static_cast<MystResourceType12 *>(_invokingResource);
+ MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
lever->drawFrame(_fortressSimulationBrake);
_vm->checkCursorHints();
@@ -664,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->playMovie();
+ VideoHandle gears = _fortressRotationGears->getMovieHandle();
uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
// Myst ME short movie workaround, explained in o_fortressRotation_init
@@ -737,7 +740,7 @@ void Mechanical::o_throne_init(uint16 op, uint16 var, uint16 argc, uint16 *argv)
// Used on Card 6238 (Sirrus' Throne) and Card 6027 (Achenar's Throne)
debugC(kDebugScript, "Opcode %d: Brother throne init", op);
- _invokingResource->setEnabled(getVar(var));
+ getInvokingResource<MystArea>()->setEnabled(getVar(var));
}
void Mechanical::o_fortressStaircase_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -763,13 +766,13 @@ void Mechanical::o_bird_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
_birdSinging = false;
_birdSingEndTime = 0;
- _bird = static_cast<MystResourceType6 *>(_invokingResource);
+ _bird = getInvokingResource<MystAreaVideo>();
}
void Mechanical::o_snakeBox_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Snake box init", op);
- _snakeBox = static_cast<MystResourceType6 *>(_invokingResource);
+ _snakeBox = getInvokingResource<MystAreaVideo>();
}
void Mechanical::elevatorRotation_run() {
@@ -798,7 +801,7 @@ void Mechanical::o_elevatorRotation_init(uint16 op, uint16 var, uint16 argc, uin
}
void Mechanical::fortressRotation_run() {
- VideoHandle gears = _fortressRotationGears->playMovie();
+ VideoHandle gears = _fortressRotationGears->getMovieHandle();
double oldRate = gears->getRate().toDouble();
uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
@@ -872,7 +875,7 @@ void Mechanical::fortressRotation_run() {
void Mechanical::o_fortressRotation_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Fortress rotation init", op);
- _fortressRotationGears = static_cast<MystResourceType6 *>(_invokingResource);
+ _fortressRotationGears = getInvokingResource<MystAreaVideo>();
VideoHandle gears = _fortressRotationGears->playMovie();
gears->setLooping(true);
@@ -938,13 +941,22 @@ void Mechanical::fortressSimulation_run() {
holo->setLooping(true);
holo->setRate(0);
+ // HACK: Support negative rates with edit lists
+ _fortressSimulationHoloRate = 0;
+ // END HACK
+
_vm->_cursor->showCursor();
_fortressSimulationInit = false;
} else {
- VideoHandle holo = _fortressSimulationHolo->playMovie();
+ VideoHandle holo = _fortressSimulationHolo->getMovieHandle();
double oldRate = holo->getRate().toDouble();
+
+ // HACK: Support negative rates with edit lists
+ oldRate = _fortressSimulationHoloRate;
+ // END HACK
+
uint32 moviePosition = Audio::Timestamp(holo->getTime(), 600).totalNumberOfFrames();
int32 positionInQuarter = 900 - (moviePosition + 900) % 1800;
@@ -978,7 +990,26 @@ void Mechanical::fortressSimulation_run() {
newRate = CLIP<double>(newRate, -2.5, 2.5);
- holo->setRate(Common::Rational((int)(newRate * 1000.0), 1000));
+ // HACK: Support negative rates with edit lists
+
+ // Our current QuickTime implementation does not support negative
+ // playback rates for movies using edit lists.
+ // The fortress rotation simulator movie this code handles is the
+ // only movie in the game requiring that feature.
+
+ // This hack approximates the next frame to display when the rate
+ // is negative, and seeks to it. It's not intended to be precise.
+
+ _fortressSimulationHoloRate = newRate;
+
+ if (_fortressSimulationHoloRate < 0) {
+ double newMoviePosition = moviePosition + _fortressSimulationHoloRate * 10;
+ holo->setRate(0);
+ holo->seek(Audio::Timestamp(0, (uint)newMoviePosition, 600));
+ } else {
+ holo->setRate(Common::Rational((int)(newRate * 1000.0), 1000));
+ }
+ // END HACK
_gearsWereRunning = true;
} else if (_gearsWereRunning) {
@@ -986,6 +1017,11 @@ void Mechanical::fortressSimulation_run() {
uint16 simulationPosition = (moviePosition + 900) / 1800 % 4;
holo->setRate(0);
+
+ // HACK: Support negative rates with edit lists
+ _fortressSimulationHoloRate = 0;
+ // END HACK
+
holo->seek(Audio::Timestamp(0, 1800 * simulationPosition, 600));
_vm->_sound->playSoundBlocking( _fortressRotationSounds[simulationPosition]);
@@ -997,7 +1033,7 @@ void Mechanical::fortressSimulation_run() {
void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Fortress rotation simulator init", op);
- _fortressSimulationHolo = static_cast<MystResourceType6 *>(_invokingResource);
+ _fortressSimulationHolo = getInvokingResource<MystAreaVideo>();
_fortressSimulationStartSound1 = argv[0];
_fortressSimulationStartSound2 = argv[1];
@@ -1019,7 +1055,7 @@ void Mechanical::o_fortressSimulation_init(uint16 op, uint16 var, uint16 argc, u
void Mechanical::o_fortressSimulationStartup_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Fortress rotation simulator startup init", op);
- _fortressSimulationStartup = static_cast<MystResourceType6 *>(_invokingResource);
+ _fortressSimulationStartup = getInvokingResource<MystAreaVideo>();
}
} // End of namespace MystStacks