diff options
Diffstat (limited to 'engines/pegasus/pegasus.cpp')
-rw-r--r-- | engines/pegasus/pegasus.cpp | 112 |
1 files changed, 87 insertions, 25 deletions
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index 463e81e52e..4262ad4c12 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -36,6 +36,7 @@ #include "backends/keymapper/keymapper.h" #include "base/plugins.h" #include "base/version.h" +#include "gui/message.h" #include "gui/saveload.h" #include "video/theora_decoder.h" #include "video/qt_decoder.h" @@ -306,6 +307,7 @@ void PegasusEngine::runIntro() { Video::VideoDecoder *video = new Video::QuickTimeDecoder(); if (video->loadFile(_introDirectory + "/BandaiLogo.movie")) { + video->setVolume(MIN<uint>(getAmbienceLevel(), 0xFF)); video->start(); while (!shouldQuit() && !video->endOfVideo() && !skipped) { @@ -313,7 +315,7 @@ void PegasusEngine::runIntro() { const Graphics::Surface *frame = video->decodeNextFrame(); if (frame) { - _system->copyRectToScreen((byte *)frame->pixels, frame->pitch, 0, 0, frame->w, frame->h); + _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h); _system->updateScreen(); } } @@ -337,6 +339,8 @@ void PegasusEngine::runIntro() { if (!video->loadFile(_introDirectory + "/Big Movie.movie")) error("Could not load intro movie"); + video->setVolume(MIN<uint>(getAmbienceLevel(), 0xFF)); + video->seek(Audio::Timestamp(0, 10 * 600, 600)); video->start(); @@ -379,20 +383,21 @@ Common::Error PegasusEngine::showSaveDialog() { int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); - Common::Error result; + if (slot >= 0) + return saveGameState(slot, slc.getResultString()); - if (slot >= 0) { - if (saveGameState(slot, slc.getResultString()).getCode() == Common::kNoError) - result = Common::kNoError; - else - result = Common::kUnknownError; - } else { - result = Common::kUserCanceled; - } + return Common::kUserCanceled; +} - return result; +void PegasusEngine::showSaveFailedDialog(const Common::Error &status) { + Common::String failMessage = Common::String::format(_("Gamestate save failed (%s)! " + "Please consult the README for basic information, and for " + "instructions on how to obtain further assistance."), status.getDesc().c_str()); + GUI::MessageDialog dialog(failMessage); + dialog.runModal(); } + GUI::Debugger *PegasusEngine::getDebugger() { return _console; } @@ -429,8 +434,10 @@ void PegasusEngine::removeTimeBase(TimeBase *timeBase) { _timeBases.remove(timeBase); } -bool PegasusEngine::loadFromStream(Common::ReadStream *stream) { +bool PegasusEngine::loadFromStream(Common::SeekableReadStream *stream) { // Dispose currently running stuff + lowerInventoryDrawerSync(); + lowerBiochipDrawerSync(); useMenu(0); useNeighborhood(0); removeAllItemsFromInventory(); @@ -520,8 +527,36 @@ bool PegasusEngine::loadFromStream(Common::ReadStream *stream) { performJump(GameState.getCurrentNeighborhood()); // AI rules - if (g_AIArea) - g_AIArea->readAIRules(stream); + if (g_AIArea) { + // HACK: clone2727 accidentally changed some Prehistoric code to output some bad saves + // at one point. That's fixed now, but I don't want to leave the other users high + // and dry. + if (GameState.getCurrentNeighborhood() == kPrehistoricID && !isDemo()) { + uint32 pos = stream->pos(); + stream->seek(0x208); + uint32 roomView = stream->readUint32BE(); + stream->seek(pos); + + if (roomView == 0x30019) { + // This is a bad save -> Let's fix the data + // One byte should be put at the end instead + uint32 size = stream->size() - pos; + byte *data = (byte *)malloc(size); + data[0] = stream->readByte(); + data[1] = stream->readByte(); + data[2] = stream->readByte(); + byte wrongData = stream->readByte(); + stream->read(data + 3, size - 4); + data[size - 1] = wrongData; + Common::MemoryReadStream tempStream(data, size, DisposeAfterUse::YES); + g_AIArea->readAIRules(&tempStream); + } else { + g_AIArea->readAIRules(stream); + } + } else { + g_AIArea->readAIRules(stream); + } + } startNeighborhood(); @@ -762,6 +797,8 @@ void PegasusEngine::introTimerExpired() { if (!video->loadFile(_introDirectory + "/LilMovie.movie")) error("Failed to load little movie"); + video->setVolume(MIN<uint>(getAmbienceLevel(), 0xFF)); + bool saveAllowed = swapSaveAllowed(false); bool openAllowed = swapLoadAllowed(false); @@ -804,6 +841,7 @@ void PegasusEngine::delayShell(TimeValue time, TimeScale scale) { uint32 timeInMillis = time * 1000 / scale; while (g_system->getMillis() < startTime + timeInMillis) { + InputDevice.pumpEvents(); checkCallBacks(); _gfx->updateDisplay(); } @@ -908,6 +946,8 @@ void PegasusEngine::doGameMenuCommand(const GameMenuCommand command) { if (!video->loadFile(_introDirectory + "/Closing.movie")) error("Could not load closing movie"); + video->setVolume(MIN<uint>(getSoundFXLevel(), 0xFF)); + uint16 x = (640 - video->getWidth() * 2) / 2; uint16 y = (480 - video->getHeight() * 2) / 2; @@ -939,8 +979,14 @@ void PegasusEngine::doGameMenuCommand(const GameMenuCommand command) { resetIntroTimer(); break; case kMenuCmdPauseSave: - if (showSaveDialog().getCode() != Common::kUserCanceled) + result = showSaveDialog(); + + if (result.getCode() != Common::kUserCanceled) { + if (result.getCode() != Common::kNoError) + showSaveFailedDialog(result); + pauseMenu(false); + } break; case kMenuCmdPauseContinue: pauseMenu(false); @@ -991,7 +1037,12 @@ void PegasusEngine::handleInput(const Input &input, const Hotspot *cursorSpot) { // Can only save during a game and not in the demo if (g_neighborhood && !isDemo()) { pauseEngine(true); - showSaveDialog(); + + Common::Error result = showSaveDialog(); + + if (result.getCode() != Common::kNoError && result.getCode() != Common::kUserCanceled) + showSaveFailedDialog(result); + pauseEngine(false); } } @@ -1367,7 +1418,7 @@ bool PegasusEngine::playMovieScaled(Video::VideoDecoder *video, uint16 x, uint16 if (frame->w <= 320 && frame->h <= 240) { drawScaledFrame(frame, x, y); } else { - _system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h); + _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, x, y, frame->w, frame->h); _system->updateScreen(); } } @@ -1432,6 +1483,15 @@ void PegasusEngine::throwAwayEverything() { g_interface = 0; } +InputBits PegasusEngine::getInputFilter() { + InputBits filter = InputHandler::getInputFilter(); + + if (isPaused()) + return filter & ~JMPPPInput::getItemPanelsInputFilter(); + + return filter; +} + void PegasusEngine::processShell() { checkCallBacks(); checkNotifications(); @@ -1630,6 +1690,9 @@ void PegasusEngine::startNewGame() { removeAllItemsFromInventory(); removeAllItemsFromBiochips(); + // Properly reset all items to their original state + g_allItems.resetAllItems(); + BiochipItem *biochip = (BiochipItem *)_allItems.findItemByID(kAIBiochip); addItemToBiochips(biochip); @@ -2120,6 +2183,7 @@ void PegasusEngine::autoDragItemIntoRoom(Item *item, Sprite *draggingSprite) { _autoDragger.autoDrag(draggingSprite, start, stop, time, kDefaultTimeScale); while (_autoDragger.isDragging()) { + InputDevice.pumpEvents(); checkCallBacks(); refreshDisplay(); _system->delayMillis(10); @@ -2153,6 +2217,7 @@ void PegasusEngine::autoDragItemIntoInventory(Item *, Sprite *draggingSprite) { _autoDragger.autoDrag(draggingSprite, start, stop, time, kDefaultTimeScale); while (_autoDragger.isDragging()) { + InputDevice.pumpEvents(); checkCallBacks(); refreshDisplay(); _system->delayMillis(10); @@ -2229,10 +2294,7 @@ void PegasusEngine::doSubChase() { drawScaledFrame(frame, 0, 0); } - Common::Event event; - while (_eventMan->pollEvent(event)) - ; - + InputDevice.pumpEvents(); _system->delayMillis(10); } @@ -2270,11 +2332,11 @@ void PegasusEngine::drawScaledFrame(const Graphics::Surface *frame, uint16 x, ui scaledFrame.create(frame->w * 2, frame->h * 2, frame->format); if (frame->format.bytesPerPixel == 2) - scaleFrame<uint16>((uint16 *)frame->pixels, (uint16 *)scaledFrame.pixels, frame->w, frame->h, frame->pitch); + scaleFrame<uint16>((const uint16 *)frame->getPixels(), (uint16 *)scaledFrame.getPixels(), frame->w, frame->h, frame->pitch); else - scaleFrame<uint32>((uint32 *)frame->pixels, (uint32 *)scaledFrame.pixels, frame->w, frame->h, frame->pitch); + scaleFrame<uint32>((const uint32 *)frame->getPixels(), (uint32 *)scaledFrame.getPixels(), frame->w, frame->h, frame->pitch); - _system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h); + _system->copyRectToScreen((byte *)scaledFrame.getPixels(), scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h); _system->updateScreen(); scaledFrame.free(); } @@ -2452,7 +2514,7 @@ void PegasusEngine::initKeymap() { { Common::KEYCODE_t, "TMA", _("Toggle Center Data Display") }, { Common::KEYCODE_i, "TIN", _("Display/Hide Info Screen") }, { Common::KEYCODE_ESCAPE, "PM", _("Display/Hide Pause Menu") }, - { Common::KEYCODE_e, "WTF", _("???") } // easter egg key (without being completely upfront about it) + { Common::KEYCODE_e, "WTF", "???" } // easter egg key (without being completely upfront about it) }; for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) { |