aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk')
-rw-r--r--engines/mohawk/detection.cpp36
-rw-r--r--engines/mohawk/riven.cpp16
-rw-r--r--engines/mohawk/riven.h8
-rw-r--r--engines/mohawk/riven_external.cpp56
-rw-r--r--engines/mohawk/riven_external.h2
-rw-r--r--engines/mohawk/riven_scripts.cpp16
-rw-r--r--engines/mohawk/video.cpp58
-rw-r--r--engines/mohawk/video.h11
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