aboutsummaryrefslogtreecommitdiff
path: root/engines/pegasus/pegasus.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/pegasus/pegasus.cpp')
-rw-r--r--engines/pegasus/pegasus.cpp112
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++) {