diff options
Diffstat (limited to 'engines/mohawk/riven.cpp')
-rw-r--r-- | engines/mohawk/riven.cpp | 306 |
1 files changed, 175 insertions, 131 deletions
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 07b08dc220..f2f4a42f0e 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -27,6 +27,7 @@ #include "common/events.h" #include "common/EventRecorder.h" #include "common/keyboard.h" +#include "common/translation.h" #include "mohawk/graphics.h" #include "mohawk/resource.h" @@ -44,6 +45,7 @@ Common::Rect *g_cathJournalRect2; Common::Rect *g_atrusJournalRect3; Common::Rect *g_cathJournalRect3; Common::Rect *g_trapBookRect3; +Common::Rect *g_demoExitRect; MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescription *gamedesc) : MohawkEngine(syst, gamedesc) { _showHotspots = false; @@ -73,6 +75,7 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio g_atrusJournalRect3 = new Common::Rect(222, 402, 240, 426); g_cathJournalRect3 = new Common::Rect(291, 408, 311, 419); g_trapBookRect3 = new Common::Rect(363, 396, 386, 432); + g_demoExitRect = new Common::Rect(291, 408, 317, 419); } MohawkEngine_Riven::~MohawkEngine_Riven() { @@ -92,13 +95,13 @@ MohawkEngine_Riven::~MohawkEngine_Riven() { delete g_atrusJournalRect3; delete g_cathJournalRect3; delete g_trapBookRect3; + delete g_demoExitRect; } GUI::Debugger *MohawkEngine_Riven::getDebugger() { return _console; } - Common::Error MohawkEngine_Riven::run() { MohawkEngine::run(); @@ -114,124 +117,133 @@ Common::Error MohawkEngine_Riven::run() { initVars(); - // Open extras.mhk for common images (non-existant in the demo) - if (!(getFeatures() & GF_DEMO)) { - _extrasFile = new MohawkArchive(); - _extrasFile->open("extras.mhk"); - } + // Open extras.mhk for common images + _extrasFile = new MohawkArchive(); + _extrasFile->open("extras.mhk"); // Start at main cursor _gfx->changeCursor(kRivenMainCursor); - // Load game from launcher/command line if requested - if (ConfMan.hasKey("save_slot") && !(getFeatures() & GF_DEMO)) { + // Let's begin, shall we? + if (getFeatures() & GF_DEMO) { + // Start the demo off with the videos + changeToStack(aspit); + changeToCard(6); + } else if (ConfMan.hasKey("save_slot")) { + // Load game from launcher/command line if requested uint32 gameToLoad = ConfMan.getInt("save_slot"); Common::StringArray savedGamesList = _saveLoad->generateSaveGameList(); if (gameToLoad > savedGamesList.size()) error ("Could not find saved game"); _saveLoad->loadGame(savedGamesList[gameToLoad]); - } else { // Otherwise, start us off at aspit's card 1 + } else { + // Otherwise, start us off at aspit's card 1 (the main menu) changeToStack(aspit); changeToCard(1); } + + while (!_gameOver && !shouldQuit()) + handleEvents(); + + return Common::kNoError; +} + +void MohawkEngine_Riven::handleEvents() { Common::Event event; - while (!_gameOver) { - bool needsUpdate = _gfx->runScheduledWaterEffects(); - needsUpdate |= _video->updateBackgroundMovies(); - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_MOUSEMOVE: - _mousePos = event.mouse; - checkHotspotChange(); + // Update background videos and the water effect + bool needsUpdate = _gfx->runScheduledWaterEffects(); + needsUpdate |= _video->updateBackgroundMovies(); + + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + checkHotspotChange(); - // Check to show the inventory - if (_mousePos.y >= 392) + if (!(getFeatures() & GF_DEMO)) { + // Check to show the inventory, but it is always "showing" in the demo + if (_eventMan->getMousePos().y >= 392) _gfx->showInventory(); else _gfx->hideInventory(); + } - needsUpdate = true; - break; - case Common::EVENT_LBUTTONDOWN: + needsUpdate = true; + break; + case Common::EVENT_LBUTTONDOWN: + if (_curHotspot >= 0) + runHotspotScript(_curHotspot, kMouseDownScript); + break; + case Common::EVENT_LBUTTONUP: + // See RivenScript::switchCard() for more information on why we sometimes + // disable the next up event. + if (!_ignoreNextMouseUp) { if (_curHotspot >= 0) - runHotspotScript(_curHotspot, kMouseDownScript); + runHotspotScript(_curHotspot, kMouseUpScript); + else + checkInventoryClick(); + } + _ignoreNextMouseUp = false; + break; + case Common::EVENT_KEYDOWN: + switch (event.kbd.keycode) { + case Common::KEYCODE_d: + if (event.kbd.flags & Common::KBD_CTRL) { + _console->attach(); + _console->onFrame(); + } break; - case Common::EVENT_LBUTTONUP: - // 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(); + case Common::KEYCODE_SPACE: + pauseGame(); + break; + case Common::KEYCODE_F4: + _showHotspots = !_showHotspots; + if (_showHotspots) { + for (uint16 i = 0; i < _hotspotCount; i++) + _gfx->drawRect(_hotspots[i].rect, _hotspots[i].enabled); + needsUpdate = true; + } else + refreshCard(); + break; + case Common::KEYCODE_F5: + runDialog(*_optionsDialog); + updateZipMode(); + break; + case Common::KEYCODE_r: + // Return to the main menu in the demo on ctrl+r + if (event.kbd.flags & Common::KBD_CTRL && getFeatures() & GF_DEMO) { + if (_curStack != aspit) + changeToStack(aspit); + changeToCard(1); } - _ignoreNextMouseUp = false; break; - case Common::EVENT_KEYDOWN: - switch (event.kbd.keycode) { - case Common::KEYCODE_d: - if (event.kbd.flags & Common::KBD_CTRL) { - _console->attach(); - _console->onFrame(); - } - break; - case Common::KEYCODE_SPACE: - pauseGame(); - break; - case Common::KEYCODE_F4: - _showHotspots = !_showHotspots; - if (_showHotspots) { - for (uint16 i = 0; i < _hotspotCount; i++) - _gfx->drawRect(_hotspots[i].rect, _hotspots[i].enabled); - needsUpdate = true; - } else - refreshCard(); - break; - case Common::KEYCODE_F5: - runDialog(*_optionsDialog); - updateZipMode(); - break; - case Common::KEYCODE_ESCAPE: - if (getFeatures() & GF_DEMO) { - if (_curStack != aspit) - changeToStack(aspit); - changeToCard(1); - } - break; - default: - break; + case Common::KEYCODE_p: + // Play the intro videos in the demo on ctrl+p + if (event.kbd.flags & Common::KBD_CTRL && getFeatures() & GF_DEMO) { + if (_curStack != aspit) + changeToStack(aspit); + changeToCard(6); } break; default: break; } + break; + default: + break; } + } - if (_curHotspot >= 0) - runHotspotScript(_curHotspot, kMouseInsideScript); - - if (shouldQuit()) { - if (_eventMan->shouldRTL() && (getFeatures() & GF_DEMO) && !(_curStack == aspit && _curCard == 12)) { - if (_curStack != aspit) - changeToStack(aspit); - changeToCard(12); - _eventMan->resetRTL(); - continue; - } - return Common::kNoError; - } - - // Update the screen if we need to - if (needsUpdate) - _system->updateScreen(); + if (_curHotspot >= 0) + runHotspotScript(_curHotspot, kMouseInsideScript); - // Cut down on CPU usage - _system->delayMillis(10); - } + // Update the screen if we need to + if (needsUpdate) + _system->updateScreen(); - return Common::kNoError; + // Cut down on CPU usage + _system->delayMillis(10); } // Stack/Card-Related Functions @@ -240,7 +252,7 @@ void MohawkEngine_Riven::changeToStack(uint16 n) { // The endings are in reverse order because of the way the 1.02 patch works. // The only "Data3" file is j_Data3.mhk from that patch. Patch files have higher // priorities over the regular files and are therefore loaded and checked first. - static const char *endings[] = { "_Data3.mhk", "_Data2.mhk", "_Data1.mhk", "_Data.mhk" }; + static const char *endings[] = { "_Data3.mhk", "_Data2.mhk", "_Data1.mhk", "_Data.mhk", "_Sounds.mhk" }; // Don't change stack to the current stack (if the files are loaded) if (_curStack == n && !_mhk.empty()) @@ -274,9 +286,8 @@ void MohawkEngine_Riven::changeToStack(uint16 n) { if (_mhk.empty()) error("Could not load stack %s", getStackName(_curStack).c_str()); - // Stop any currently playing sounds and load the new sound file too + // Stop any currently playing sounds _sound->stopAllSLST(); - _sound->loadRivenSounds(_curStack); } // Riven uses some hacks to change stacks for linking books @@ -379,12 +390,11 @@ void MohawkEngine_Riven::loadHotspots(uint16 id) { // NOTE: The hotspot scripts are cleared by the RivenScriptManager automatically. - Common::SeekableReadStream* inStream = getRawData(ID_HSPT, id); + Common::SeekableReadStream *inStream = getRawData(ID_HSPT, id); _hotspotCount = inStream->readUint16BE(); _hotspots = new RivenHotspot[_hotspotCount]; - for (uint16 i = 0; i < _hotspotCount; i++) { _hotspots[i].enabled = true; @@ -396,26 +406,21 @@ void MohawkEngine_Riven::loadHotspots(uint16 id) { int16 right = inStream->readSint16BE(); int16 bottom = inStream->readSint16BE(); - // Riven has some weird hotspots, disable them here + // Riven has some invalid rects, disable them here + // Known weird hotspots: + // - tspit 371 (DVD: 377), hotspot 4 if (left >= right || top >= bottom) { - left = top = right = bottom = 0; - _hotspots[i].enabled = 0; + warning("%s %d hotspot %d is invalid: (%d, %d, %d, %d)", getStackName(_curStack).c_str(), _curCard, i, left, top, right, bottom); + left = top = right = bottom = 0; + _hotspots[i].enabled = 0; } _hotspots[i].rect = Common::Rect(left, top, right, bottom); _hotspots[i].u0 = inStream->readUint16BE(); - - if (_hotspots[i].u0 != 0) - warning("Hotspot %d u0 non-zero", i); - _hotspots[i].mouse_cursor = inStream->readUint16BE(); _hotspots[i].index = inStream->readUint16BE(); _hotspots[i].u1 = inStream->readSint16BE(); - - if (_hotspots[i].u1 != -1) - warning("Hotspot %d u1 not -1", i); - _hotspots[i].zipModeHotspot = inStream->readUint16BE(); // Read in the scripts now @@ -431,7 +436,7 @@ void MohawkEngine_Riven::updateZipMode() { for (uint32 i = 0; i < _hotspotCount; i++) { if (_hotspots[i].zipModeHotspot) { - if (*matchVarToString("azip") != 0) { + if (*getVar("azip") != 0) { // Check if a zip mode hotspot is enabled by checking the name/id against the ZIPS records. Common::String hotspotName = getName(HotspotNames, _hotspots[i].name_resource); @@ -455,7 +460,7 @@ void MohawkEngine_Riven::checkHotspotChange() { uint16 hotspotIndex = 0; bool foundHotspot = false; for (uint16 i = 0; i < _hotspotCount; i++) - if (_hotspots[i].enabled && _hotspots[i].rect.contains(_mousePos)) { + if (_hotspots[i].enabled && _hotspots[i].rect.contains(_eventMan->getMousePos())) { foundHotspot = true; hotspotIndex = i; } @@ -481,50 +486,71 @@ Common::String MohawkEngine_Riven::getHotspotName(uint16 hotspot) { } void MohawkEngine_Riven::checkInventoryClick() { + Common::Point mousePos = _eventMan->getMousePos(); + // Don't even bother. We're not in the inventory portion of the screen. - if (_mousePos.y < 392) + if (mousePos.y < 392) + return; + + // In the demo, check if we've clicked the exit button + if (getFeatures() & GF_DEMO) { + if (g_demoExitRect->contains(mousePos)) { + if (_curStack == aspit && _curCard == 1) { + // From the main menu, go to the "quit" screen + changeToCard(12); + } else if (_curStack == aspit && _curCard == 12) { + // From the "quit" screen, just quit + _gameOver = true; + } else { + // Otherwise, return to the main menu + if (_curStack != aspit) + changeToStack(aspit); + changeToCard(1); + } + } return; + } - // No inventory in the demo or opening screens. - if (getFeatures() & GF_DEMO || _curStack == aspit) + // No inventory shown on aspit + if (_curStack == aspit) return; // Set the return stack/card id's. - *matchVarToString("returnstackid") = _curStack; - *matchVarToString("returncardid") = _curCard; + *getVar("returnstackid") = _curStack; + *getVar("returncardid") = _curCard; // See RivenGraphics::showInventory() for an explanation // of the variables' meanings. - bool hasCathBook = *matchVarToString("acathbook") != 0; - bool hasTrapBook = *matchVarToString("atrapbook") != 0; + bool hasCathBook = *getVar("acathbook") != 0; + bool hasTrapBook = *getVar("atrapbook") != 0; // Go to the book if a hotspot contains the mouse if (!hasCathBook) { - if (g_atrusJournalRect1->contains(_mousePos)) { + if (g_atrusJournalRect1->contains(mousePos)) { _gfx->hideInventory(); changeToStack(aspit); changeToCard(5); } } else if (!hasTrapBook) { - if (g_atrusJournalRect2->contains(_mousePos)) { + if (g_atrusJournalRect2->contains(mousePos)) { _gfx->hideInventory(); changeToStack(aspit); changeToCard(5); - } else if (g_cathJournalRect2->contains(_mousePos)) { + } else if (g_cathJournalRect2->contains(mousePos)) { _gfx->hideInventory(); changeToStack(aspit); changeToCard(6); } } else { - if (g_atrusJournalRect3->contains(_mousePos)) { + if (g_atrusJournalRect3->contains(mousePos)) { _gfx->hideInventory(); changeToStack(aspit); changeToCard(5); - } else if (g_cathJournalRect3->contains(_mousePos)) { + } else if (g_cathJournalRect3->contains(mousePos)) { _gfx->hideInventory(); changeToStack(aspit); changeToCard(6); - } else if (g_trapBookRect3->contains(_mousePos)) { + } else if (g_trapBookRect3->contains(mousePos)) { _gfx->hideInventory(); changeToStack(aspit); changeToCard(7); @@ -607,8 +633,26 @@ void MohawkEngine_Riven::runHotspotScript(uint16 hotspot, uint16 scriptType) { } } +void MohawkEngine_Riven::delayAndUpdate(uint32 ms) { + uint32 startTime = _system->getMillis(); + + while (_system->getMillis() < startTime + ms && !shouldQuit()) { + bool needsUpdate = _gfx->runScheduledWaterEffects(); + needsUpdate |= _video->updateBackgroundMovies(); + + Common::Event event; + while (_system->getEventManager()->pollEvent(event)) + ; + + if (needsUpdate) + _system->updateScreen(); + + _system->delayMillis(10); // Ease off the CPU + } +} + void MohawkEngine_Riven::runLoadDialog() { - GUI::SaveLoadChooser slc("Load Game:", "Load"); + GUI::SaveLoadChooser slc(_("Load game:"), _("Load")); slc.setSaveMode(false); Common::String gameId = ConfMan.get("gameid"); @@ -636,19 +680,19 @@ Common::Error MohawkEngine_Riven::saveGameState(int slot, const char *desc) { return _saveLoad->saveGame(Common::String(desc)) ? Common::kNoError : Common::kUnknownError; } -static const char *rivenStackNames[] = { - "aspit", - "bspit", - "gspit", - "jspit", - "ospit", - "pspit", - "rspit", - "tspit" -}; - -Common::String MohawkEngine_Riven::getStackName(uint16 stack) { - return Common::String(rivenStackNames[stack]); +Common::String MohawkEngine_Riven::getStackName(uint16 stack) const { + static const char *rivenStackNames[] = { + "aspit", + "bspit", + "gspit", + "jspit", + "ospit", + "pspit", + "rspit", + "tspit" + }; + + return rivenStackNames[stack]; } bool ZipMode::operator== (const ZipMode &z) const { |