diff options
Diffstat (limited to 'engines/mohawk')
-rw-r--r-- | engines/mohawk/detection.cpp | 36 | ||||
-rw-r--r-- | engines/mohawk/riven.cpp | 16 | ||||
-rw-r--r-- | engines/mohawk/riven.h | 8 | ||||
-rw-r--r-- | engines/mohawk/riven_external.cpp | 56 | ||||
-rw-r--r-- | engines/mohawk/riven_external.h | 2 | ||||
-rw-r--r-- | engines/mohawk/riven_scripts.cpp | 16 | ||||
-rw-r--r-- | engines/mohawk/video.cpp | 58 | ||||
-rw-r--r-- | engines/mohawk/video.h | 11 |
8 files changed, 161 insertions, 42 deletions
diff --git a/engines/mohawk/detection.cpp b/engines/mohawk/detection.cpp index a7b1fe7fae..7f2e0cb312 100644 --- a/engines/mohawk/detection.cpp +++ b/engines/mohawk/detection.cpp @@ -341,6 +341,24 @@ static const MohawkGameDescription gameDescriptions[] = { 0, }, + // Myst Masterpiece Edition + // French Windows + // From gamin (Included in "Myst: La Trilogie") + { + { + "myst", + "Masterpiece Edition", + AD_ENTRY1("MYST.DAT", "aea81633b2d2ae498f09072fb87263b6"), + Common::FR_FRA, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_MYST, + GF_ME, + 0, + }, + // Riven: The Sequel to Myst // Version 1.0 (5CD) // From clone2727 @@ -432,6 +450,24 @@ static const MohawkGameDescription gameDescriptions[] = { }, // Riven: The Sequel to Myst + // Version ? (DVD, From "Myst: La Trilogie") + // From gamin + { + { + "riven", + "", + AD_ENTRY1("a_Data.MHK", "aff2a384aaa9a0e0ec51010f708c5c04"), + Common::FR_FRA, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_RIVEN, + GF_DVD, + 0, + }, + + // Riven: The Sequel to Myst // Version ? (Demo, From "Prince of Persia Collector's Edition") // From Clone2727 { diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 744b3f2d2c..c646855bc7 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -47,6 +47,7 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio _cardData.hasData = false; _gameOver = false; _activatedSLST = false; + _ignoreNextMouseUp = false; _extrasFile = NULL; // Attempt to let game run from the CDs @@ -147,10 +148,15 @@ Common::Error MohawkEngine_Riven::run() { runHotspotScript(_curHotspot, kMouseDownScript); break; case Common::EVENT_LBUTTONUP: - if (_curHotspot >= 0) - runHotspotScript(_curHotspot, kMouseUpScript); - else - checkInventoryClick(); + // See RivenScript::switchCard() for more information on why we sometimes + // disable the next up event. + if (!_ignoreNextMouseUp) { + if (_curHotspot >= 0) + runHotspotScript(_curHotspot, kMouseUpScript); + else + checkInventoryClick(); + } + _ignoreNextMouseUp = false; break; case Common::EVENT_KEYDOWN: switch (event.kbd.keycode) { @@ -233,6 +239,7 @@ void MohawkEngine_Riven::changeToStack(uint16 n) { // Stop any videos playing _video->stopVideos(); + _video->clearMLST(); // Clear the old stack files out for (uint32 i = 0; i < _mhk.size(); i++) @@ -310,7 +317,6 @@ void MohawkEngine_Riven::refreshCard() { _gfx->clearWaterEffects(); _gfx->_activatedPLSTs.clear(); _video->stopVideos(); - _video->_mlstRecords.clear(); _gfx->drawPLST(1); _activatedSLST = false; diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index f014b76fb8..11c3a4c0cb 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -113,7 +113,6 @@ public: Common::RandomSource *_rnd; Card _cardData; - bool _gameOver; GUI::Debugger *getDebugger(); @@ -147,6 +146,10 @@ private: uint32 *_vars; uint32 _varCount; + // Miscellaneous + bool _gameOver; + bool _ignoreNextMouseUp; + public: Common::SeekableReadStream *getExtrasResource(uint32 tag, uint16 id); bool _activatedSLST; @@ -180,6 +183,9 @@ public: uint32 *getLocalVar(uint32 index); uint32 *matchVarToString(Common::String varName); uint32 *matchVarToString(const char *varName); + + void setGameOver() { _gameOver = true; } + void ignoreNextMouseUp() { _ignoreNextMouseUp = true; } }; } // End of namespace Mohawk diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp index 8b1ff45a66..4e6bba1c2a 100644 --- a/engines/mohawk/riven_external.cpp +++ b/engines/mohawk/riven_external.cpp @@ -210,7 +210,28 @@ void RivenExternal::runEndGame(uint16 video) { _vm->_video->playMovieBlocking(video); // TODO: Play until the last frame and then run the credits - _vm->_gameOver = true; + _vm->setGameOver(); +} + +void RivenExternal::runDomeButtonMovie() { + // This command just plays the video of the button moving down and up. + _vm->_video->playMovieBlocking(2); +} + +void RivenExternal::runDomeCheck() { + // Check if we clicked while the golden frame was showing + + VideoHandle video = _vm->_video->findVideoHandle(1); + assert(video != NULL_VID_HANDLE); + + int32 curFrame = _vm->_video->getCurFrame(video); + int32 frameCount = _vm->_video->getFrameCount(video); + + // The final frame of the video is the 'golden' frame (double meaning: the + // frame that is the magic one is the one with the golden symbol) but we + // give a 3 frame leeway in either direction. + if (frameCount - curFrame < 3 || curFrame < 3) + *_vm->matchVarToString("domecheck") = 1; } // ------------------------------------------------------------------------------------ @@ -218,11 +239,13 @@ void RivenExternal::runEndGame(uint16 video) { // ------------------------------------------------------------------------------------ void RivenExternal::xastartupbtnhide(uint16 argc, uint16 *argv) { - // The original game hides the start/setup buttons depending on an ini entry. It's safe to ignore this command. + // The original game hides the start/setup buttons depending on an ini entry. + // It's safe to ignore this command. } void RivenExternal::xasetupcomplete(uint16 argc, uint16 *argv) { - // The original game sets an ini entry to disable the setup button and use the start button only. It's safe to ignore this part of the command. + // The original game sets an ini entry to disable the setup button and use the + // start button only. It's safe to ignore this part of the command. _vm->_sound->stopSound(); _vm->changeToCard(1); } @@ -514,13 +537,14 @@ void RivenExternal::xbupdateboiler(uint16 argc, uint16 *argv) { if (heat) { if (platform == 0) { _vm->_video->activateMLST(7, _vm->getCurCard()); - // TODO: Play video (non-blocking) + _vm->_video->playMovie(7); } else { _vm->_video->activateMLST(8, _vm->getCurCard()); - // TODO: Play video (non-blocking) + _vm->_video->playMovie(8); } } else { - // TODO: Stop MLST's 7 and 8 + _vm->_video->stopMovie(7); + _vm->_video->stopMovie(8); } _vm->refreshCard(); @@ -627,11 +651,11 @@ void RivenExternal::xbisland190_slidermw(uint16 argc, uint16 *argv) { } void RivenExternal::xbscpbtn(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeButtonMovie(); } void RivenExternal::xbisland_domecheck(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeCheck(); } void RivenExternal::xvalvecontrol(uint16 argc, uint16 *argv) { @@ -723,11 +747,11 @@ void RivenExternal::xgisland25_slidermw(uint16 argc, uint16 *argv) { } void RivenExternal::xgscpbtn(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeButtonMovie(); } void RivenExternal::xgisland1490_domecheck(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeCheck(); } void RivenExternal::xgplateau3160_dopools(uint16 argc, uint16 *argv) { @@ -978,11 +1002,11 @@ void RivenExternal::xjdome25_slidermw(uint16 argc, uint16 *argv) { } void RivenExternal::xjscpbtn(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeButtonMovie(); } void RivenExternal::xjisland3500_domecheck(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeCheck(); } int RivenExternal::jspitElevatorLoop() { @@ -1258,11 +1282,11 @@ void RivenExternal::xpisland990_elevcombo(uint16 argc, uint16 *argv) { } void RivenExternal::xpscpbtn(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeButtonMovie(); } void RivenExternal::xpisland290_domecheck(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeCheck(); } void RivenExternal::xpisland25_opencard(uint16 argc, uint16 *argv) { @@ -1457,11 +1481,11 @@ void RivenExternal::xtakeit(uint16 argc, uint16 *argv) { } void RivenExternal::xtscpbtn(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeButtonMovie(); } void RivenExternal::xtisland4990_domecheck(uint16 argc, uint16 *argv) { - // TODO: Dome related + runDomeCheck(); } void RivenExternal::xtisland5056_opencard(uint16 argc, uint16 *argv) { diff --git a/engines/mohawk/riven_external.h b/engines/mohawk/riven_external.h index 8270a00854..14bb51340c 100644 --- a/engines/mohawk/riven_external.h +++ b/engines/mohawk/riven_external.h @@ -57,6 +57,8 @@ private: int jspitElevatorLoop(); void runDemoBoundaryDialog(); void runEndGame(uint16 video); + void runDomeCheck(); + void runDomeButtonMovie(); // ----------------------------------------------------- // aspit (Main Menu, Books, Setup) external commands diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp index fa6f336542..d574a455c6 100644 --- a/engines/mohawk/riven_scripts.cpp +++ b/engines/mohawk/riven_scripts.cpp @@ -298,13 +298,10 @@ void RivenScript::processCommands(bool runCommands) { // Command 1: draw tBMP resource (tbmp_id, left, top, right, bottom, u0, u1, u2, u3) void RivenScript::drawBitmap(uint16 op, uint16 argc, uint16 *argv) { - if (argc < 5) { - // Copy the image to the whole screen, ignoring the rest of the parameters + if (argc < 5) // Copy the image to the whole screen, ignoring the rest of the parameters _vm->_gfx->copyImageToScreen(argv[0], 0, 0, 608, 392); - } else { - // Copy the image to a certain part of the screen + else // Copy the image to a certain part of the screen _vm->_gfx->copyImageToScreen(argv[0], argv[1], argv[2], argv[3], argv[4]); - } // Now, update the screen _vm->_gfx->updateScreen(); @@ -313,6 +310,12 @@ void RivenScript::drawBitmap(uint16 op, uint16 argc, uint16 *argv) { // Command 2: go to card (card id) void RivenScript::switchCard(uint16 op, uint16 argc, uint16 *argv) { _vm->changeToCard(argv[0]); + + // WORKAROUND: If we changed card on a mouse down event, + // we want to ignore the next mouse up event so we don't + // change card when lifting the mouse on the next card. + if (_scriptType == kMouseDownScript) + _vm->ignoreNextMouseUp(); } // Command 3: play an SLST from the script @@ -547,9 +550,8 @@ void RivenScript::activateSLST(uint16 op, uint16 argc, uint16 *argv) { // Command 41: activate MLST record and play void RivenScript::activateMLSTAndPlay(uint16 op, uint16 argc, uint16 *argv) { - _vm->_video->enableMovie(argv[0] - 1); _vm->_video->activateMLST(argv[0], _vm->getCurCard()); - // TODO: Play movie (blocking?) + _vm->_video->playMovie(argv[0]); } // Command 43: activate BLST record (card hotspot enabling lists) diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp index adca805763..a45a4294c8 100644 --- a/engines/mohawk/video.cpp +++ b/engines/mohawk/video.cpp @@ -35,18 +35,19 @@ VideoManager::VideoManager(MohawkEngine* vm) : _vm(vm) { } VideoManager::~VideoManager() { - _mlstRecords.clear(); stopVideos(); } void VideoManager::pauseVideos() { for (uint16 i = 0; i < _videoStreams.size(); i++) - _videoStreams[i]->pauseVideo(true); + if (_videoStreams[i].video) + _videoStreams[i]->pauseVideo(true); } void VideoManager::resumeVideos() { for (uint16 i = 0; i < _videoStreams.size(); i++) - _videoStreams[i]->pauseVideo(false); + if (_videoStreams[i].video) + _videoStreams[i]->pauseVideo(false); } void VideoManager::stopVideos() { @@ -89,7 +90,7 @@ void VideoManager::playMovieCentered(Common::String filename, bool clearScreen) void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) { bool continuePlaying = true; - while (!_videoStreams[videoHandle]->endOfVideo() && !_vm->shouldQuit() && continuePlaying) { + while (_videoStreams[videoHandle].video && !_videoStreams[videoHandle]->endOfVideo() && !_vm->shouldQuit() && continuePlaying) { if (updateBackgroundMovies()) _vm->_system->updateScreen(); @@ -120,8 +121,10 @@ void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) { _vm->_system->delayMillis(10); } - _videoStreams[videoHandle]->close(); - _videoStreams.clear(); + delete _videoStreams[videoHandle].video; + _videoStreams[videoHandle].video = 0; + _videoStreams[videoHandle].id = 0; + _videoStreams[videoHandle].filename.clear(); } void VideoManager::playBackgroundMovie(Common::String filename, int16 x, int16 y, bool loop) { @@ -152,8 +155,9 @@ bool VideoManager::updateBackgroundMovies() { _videoStreams[i]->rewind(); } else { delete _videoStreams[i].video; - memset(&_videoStreams[i], 0, sizeof(VideoEntry)); - _videoStreams[i].video = NULL; + _videoStreams[i].video = 0; + _videoStreams[i].id = 0; + _videoStreams[i].filename.clear(); continue; } } @@ -240,7 +244,15 @@ void VideoManager::activateMLST(uint16 mlstId, uint16 card) { if (mlstRecord.u1 != 1) warning("mlstRecord.u1 not 1"); + // We've found a match, add it if (mlstRecord.index == mlstId) { + // Make sure we don't have any duplicates + for (uint32 j = 0; j < _mlstRecords.size(); j++) + if (_mlstRecords[j].index == mlstRecord.index || _mlstRecords[j].code == mlstRecord.code) { + _mlstRecords.remove_at(j); + j--; + } + _mlstRecords.push_back(mlstRecord); break; } @@ -249,6 +261,10 @@ void VideoManager::activateMLST(uint16 mlstId, uint16 card) { delete mlstStream; } +void VideoManager::clearMLST() { + _mlstRecords.clear(); +} + void VideoManager::playMovie(uint16 id) { for (uint16 i = 0; i < _mlstRecords.size(); i++) if (_mlstRecords[i].code == id) { @@ -274,8 +290,10 @@ void VideoManager::stopMovie(uint16 id) { if (_mlstRecords[i].code == id) for (uint16 j = 0; j < _videoStreams.size(); j++) if (_mlstRecords[i].movieID == _videoStreams[j].id) { - delete _videoStreams[i].video; - memset(&_videoStreams[i].video, 0, sizeof(VideoEntry)); + delete _videoStreams[j].video; + _videoStreams[j].video = 0; + _videoStreams[j].id = 0; + _videoStreams[j].filename.clear(); return; } } @@ -374,4 +392,24 @@ VideoHandle VideoManager::createVideoHandle(Common::String filename, uint16 x, u return _videoStreams.size() - 1; } +VideoHandle VideoManager::findVideoHandle(uint16 id) { + for (uint16 i = 0; i < _mlstRecords.size(); i++) + if (_mlstRecords[i].code == id) + for (uint16 j = 0; j < _videoStreams.size(); j++) + if (_videoStreams[j].video && _mlstRecords[i].movieID == _videoStreams[j].id) + return j; + + return NULL_VID_HANDLE; +} + +int32 VideoManager::getCurFrame(const VideoHandle &handle) { + assert(handle != NULL_VID_HANDLE); + return _videoStreams[handle]->getCurFrame(); +} + +uint32 VideoManager::getFrameCount(const VideoHandle &handle) { + assert(handle != NULL_VID_HANDLE); + return _videoStreams[handle]->getFrameCount(); +} + } // End of namespace Mohawk diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h index 8cfe1527fb..6aa553e26b 100644 --- a/engines/mohawk/video.h +++ b/engines/mohawk/video.h @@ -82,6 +82,7 @@ public: // Riven-related functions void activateMLST(uint16 mlstId, uint16 card); + void clearMLST(); void enableMovie(uint16 id); void disableMovie(uint16 id); void disableAllMovies(); @@ -89,19 +90,23 @@ public: void stopMovie(uint16 id); void playMovieBlocking(uint16 id); - // Riven-related variables - Common::Array<MLSTRecord> _mlstRecords; + // Handle functions + VideoHandle findVideoHandle(uint16 id); + int32 getCurFrame(const VideoHandle &handle); + uint32 getFrameCount(const VideoHandle &handle); private: MohawkEngine *_vm; - void waitUntilMovieEnds(VideoHandle videoHandle); + // Riven-related variables + Common::Array<MLSTRecord> _mlstRecords; // Keep tabs on any videos playing Common::Array<VideoEntry> _videoStreams; VideoHandle createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop); VideoHandle createVideoHandle(Common::String filename, uint16 x, uint16 y, bool loop); + void waitUntilMovieEnds(VideoHandle videoHandle); }; } // End of namespace Mohawk |