diff options
Diffstat (limited to 'engines/mohawk/myst_stacks/mechanical.cpp')
-rw-r--r-- | engines/mohawk/myst_stacks/mechanical.cpp | 94 |
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 |