aboutsummaryrefslogtreecommitdiff
path: root/engines/pegasus
diff options
context:
space:
mode:
Diffstat (limited to 'engines/pegasus')
-rw-r--r--engines/pegasus/ai/ai_area.cpp2
-rw-r--r--engines/pegasus/configure.engine3
-rw-r--r--engines/pegasus/console.cpp16
-rw-r--r--engines/pegasus/cursor.cpp6
-rw-r--r--engines/pegasus/energymonitor.cpp1
-rw-r--r--engines/pegasus/fader.cpp1
-rw-r--r--engines/pegasus/input.cpp27
-rw-r--r--engines/pegasus/input.h2
-rw-r--r--engines/pegasus/interface.cpp8
-rw-r--r--engines/pegasus/items/inventorypicture.cpp1
-rw-r--r--engines/pegasus/items/item.cpp14
-rw-r--r--engines/pegasus/items/item.h7
-rw-r--r--engines/pegasus/items/itemlist.cpp5
-rw-r--r--engines/pegasus/items/itemlist.h1
-rw-r--r--engines/pegasus/menu.cpp2
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoria.cpp28
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp15
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoriabomb.h3
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp6
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoriamessages.h2
-rw-r--r--engines/pegasus/neighborhood/mars/mars.cpp22
-rw-r--r--engines/pegasus/neighborhood/neighborhood.cpp15
-rw-r--r--engines/pegasus/neighborhood/neighborhood.h2
-rw-r--r--engines/pegasus/neighborhood/norad/delta/globegame.cpp5
-rw-r--r--engines/pegasus/neighborhood/norad/delta/globegame.h2
-rw-r--r--engines/pegasus/neighborhood/norad/delta/noraddelta.cpp18
-rw-r--r--engines/pegasus/neighborhood/norad/delta/noraddelta.h3
-rw-r--r--engines/pegasus/neighborhood/prehistoric/prehistoric.cpp20
-rw-r--r--engines/pegasus/neighborhood/tsa/fulltsa.cpp27
-rw-r--r--engines/pegasus/neighborhood/tsa/tinytsa.cpp23
-rw-r--r--engines/pegasus/neighborhood/wsc/wsc.cpp3
-rw-r--r--engines/pegasus/pegasus.cpp100
-rw-r--r--engines/pegasus/pegasus.h4
-rw-r--r--engines/pegasus/surface.cpp4
-rw-r--r--engines/pegasus/timers.cpp1
35 files changed, 324 insertions, 75 deletions
diff --git a/engines/pegasus/ai/ai_area.cpp b/engines/pegasus/ai/ai_area.cpp
index 5ac8af8812..9cab568d66 100644
--- a/engines/pegasus/ai/ai_area.cpp
+++ b/engines/pegasus/ai/ai_area.cpp
@@ -234,6 +234,7 @@ void AIArea::playAIAreaSequence(const LowerClientSignature, const LowerAreaSigna
vm->_cursor->hide();
while (_middleAreaMovie.isRunning()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -258,6 +259,7 @@ void AIArea::playAIAreaSequence(const LowerClientSignature, const LowerAreaSigna
vm->_cursor->hide();
while (_rightAreaMovie.isRunning()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
diff --git a/engines/pegasus/configure.engine b/engines/pegasus/configure.engine
new file mode 100644
index 0000000000..ed7e295287
--- /dev/null
+++ b/engines/pegasus/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit"
diff --git a/engines/pegasus/console.cpp b/engines/pegasus/console.cpp
index 64bd0ba5f2..e5a0cfec98 100644
--- a/engines/pegasus/console.cpp
+++ b/engines/pegasus/console.cpp
@@ -28,11 +28,11 @@
namespace Pegasus {
PegasusConsole::PegasusConsole(PegasusEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("die", WRAP_METHOD(PegasusConsole, Cmd_Die));
+ registerCmd("die", WRAP_METHOD(PegasusConsole, Cmd_Die));
// These functions are non-demo specific
if (!_vm->isDemo())
- DCmd_Register("jump", WRAP_METHOD(PegasusConsole, Cmd_Jump));
+ registerCmd("jump", WRAP_METHOD(PegasusConsole, Cmd_Jump));
}
PegasusConsole::~PegasusConsole() {
@@ -40,7 +40,7 @@ PegasusConsole::~PegasusConsole() {
bool PegasusConsole::Cmd_Die(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: die <death reason>\n");
+ debugPrintf("Usage: die <death reason>\n");
return true;
}
@@ -54,7 +54,7 @@ bool PegasusConsole::Cmd_Die(int argc, const char **argv) {
if (invalidReason) {
- DebugPrintf("Invalid death reason %d\n", reason);
+ debugPrintf("Invalid death reason %d\n", reason);
return true;
}
@@ -65,14 +65,14 @@ bool PegasusConsole::Cmd_Die(int argc, const char **argv) {
bool PegasusConsole::Cmd_Jump(int argc, const char **argv) {
if (!g_interface) {
// TODO
- DebugPrintf("Cannot jump without interface set up\n");
+ debugPrintf("Cannot jump without interface set up\n");
return true;
}
// TODO: Default room/direction for each neighborhood
if (argc < 4) {
- DebugPrintf("Usage: jump <neighborhood> <room> <direction>\n");
+ debugPrintf("Usage: jump <neighborhood> <room> <direction>\n");
return true;
}
@@ -82,14 +82,14 @@ bool PegasusConsole::Cmd_Jump(int argc, const char **argv) {
if ((neighborhood < kCaldoriaID || neighborhood > kNoradDeltaID || neighborhood == kFinalTSAID) &&
neighborhood != kNoradSubChaseID) {
- DebugPrintf("Invalid neighborhood %d", neighborhood);
+ debugPrintf("Invalid neighborhood %d", neighborhood);
return true;
}
// No real way to check room validity at this point
if (direction > kWest) {
- DebugPrintf("Invalid direction %d", direction);
+ debugPrintf("Invalid direction %d", direction);
return true;
}
diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp
index ad0d2c2d7d..602ae88068 100644
--- a/engines/pegasus/cursor.cpp
+++ b/engines/pegasus/cursor.cpp
@@ -28,7 +28,7 @@
#include "common/system.h"
#include "graphics/cursorman.h"
#include "graphics/surface.h"
-#include "graphics/decoders/pict.h"
+#include "image/pict.h"
#include "pegasus/cursor.h"
#include "pegasus/graphics.h"
@@ -148,7 +148,7 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) {
Common::SeekableReadStream *pictStream = vm->_resFork->getResource(MKTAG('P', 'I', 'C', 'T'), cursorInfo.tag + 1000);
if (pictStream) {
- Graphics::PICTDecoder pict;
+ Image::PICTDecoder pict;
if (!pict.loadStream(*pictStream))
error("Failed to decode cursor PICT %d", cursorInfo.tag + 1000);
@@ -166,7 +166,7 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) {
error("Failed to find color icon %d", cursorInfo.tag);
// PixMap section
- Graphics::PICTDecoder::PixMap pixMap = Graphics::PICTDecoder::readPixMap(*cicnStream);
+ Image::PICTDecoder::PixMap pixMap = Image::PICTDecoder::readPixMap(*cicnStream);
// Mask section
cicnStream->readUint32BE(); // mask baseAddr
diff --git a/engines/pegasus/energymonitor.cpp b/engines/pegasus/energymonitor.cpp
index be9d205360..40e54afb89 100644
--- a/engines/pegasus/energymonitor.cpp
+++ b/engines/pegasus/energymonitor.cpp
@@ -269,6 +269,7 @@ void EnergyMonitor::calibrateEnergyBar() {
// Make sure warning light is hidden...
_energyLight.hide();
while (getCurrentEnergy() != (int32)kMaxJMPEnergy) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
diff --git a/engines/pegasus/fader.cpp b/engines/pegasus/fader.cpp
index a2bbf22944..80ce8ef5dc 100644
--- a/engines/pegasus/fader.cpp
+++ b/engines/pegasus/fader.cpp
@@ -94,6 +94,7 @@ void Fader::startFaderSync(const FaderMoveSpec &spec) {
start();
while (isFading()) {
+ InputDevice.pumpEvents();
((PegasusEngine *)g_engine)->checkCallBacks();
useIdleTime();
}
diff --git a/engines/pegasus/input.cpp b/engines/pegasus/input.cpp
index b74e4a4c45..e1b7e25cd5 100644
--- a/engines/pegasus/input.cpp
+++ b/engines/pegasus/input.cpp
@@ -57,9 +57,10 @@ InputDeviceManager::InputDeviceManager() {
_keyMap[Common::KEYCODE_p] = false;
_keyMap[Common::KEYCODE_TILDE] = false;
_keyMap[Common::KEYCODE_BACKQUOTE] = false;
- _keyMap[Common::KEYCODE_NUMLOCK] = false;
+ _keyMap[Common::KEYCODE_KP7] = false;
_keyMap[Common::KEYCODE_BACKSPACE] = false;
_keyMap[Common::KEYCODE_KP_MULTIPLY] = false;
+ _keyMap[Common::KEYCODE_KP9] = false;
_keyMap[Common::KEYCODE_LALT] = false;
_keyMap[Common::KEYCODE_RALT] = false;
_keyMap[Common::KEYCODE_e] = false;
@@ -81,9 +82,7 @@ void InputDeviceManager::getInput(Input &input, const InputBits filter) {
// (ie. if one uses enter to access the restore menu, we never receive
// the key up event, which leads to bad things)
// This is to closely emulate what the GetKeys() function did on Mac OS
- Common::Event event;
- while (g_system->getEventManager()->pollEvent(event))
- ;
+ pumpEvents();
// Now create the bitfield
InputBits currentBits = 0;
@@ -115,10 +114,19 @@ void InputDeviceManager::getInput(Input &input, const InputBits filter) {
if (_keyMap[Common::KEYCODE_ESCAPE] || _keyMap[Common::KEYCODE_p])
currentBits |= (kRawButtonDown << kMod3ButtonShift);
- if (_keyMap[Common::KEYCODE_TILDE] || _keyMap[Common::KEYCODE_BACKQUOTE] || _keyMap[Common::KEYCODE_NUMLOCK])
+ // The original also used clear (aka "num lock" on Mac keyboards) here, but it doesn't
+ // work right on most systems. Either SDL or the OS treats num lock specially and the
+ // events don't come as expected. In many cases, the key down event is sent many times
+ // causing the drawer to open and close constantly until pressed again. It only causes
+ // more grief than anything else.
+
+ // The original doesn't use KP7 for inventory, but we're using it as an alternative for
+ // num lock. KP9 is used for the biochip drawer to balance things out.
+
+ if (_keyMap[Common::KEYCODE_TILDE] || _keyMap[Common::KEYCODE_BACKQUOTE] || _keyMap[Common::KEYCODE_KP7])
currentBits |= (kRawButtonDown << kLeftFireButtonShift);
- if (_keyMap[Common::KEYCODE_BACKSPACE] || _keyMap[Common::KEYCODE_KP_MULTIPLY])
+ if (_keyMap[Common::KEYCODE_BACKSPACE] || _keyMap[Common::KEYCODE_KP_MULTIPLY] || _keyMap[Common::KEYCODE_KP9])
currentBits |= (kRawButtonDown << kRightFireButtonShift);
// Update mouse button state
@@ -206,6 +214,13 @@ bool InputDeviceManager::notifyEvent(const Common::Event &event) {
return false;
}
+void InputDeviceManager::pumpEvents() {
+ // Just poll for events. notifyEvent() will pick up on them.
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event))
+ ;
+}
+
int operator==(const Input &arg1, const Input &arg2) {
return arg1._inputState == arg2._inputState;
}
diff --git a/engines/pegasus/input.h b/engines/pegasus/input.h
index 3e938fa42a..ba6f11dba0 100644
--- a/engines/pegasus/input.h
+++ b/engines/pegasus/input.h
@@ -50,6 +50,8 @@ public:
void waitInput(const InputBits);
+ void pumpEvents();
+
protected:
friend class Common::Singleton<SingletonBaseType>;
diff --git a/engines/pegasus/interface.cpp b/engines/pegasus/interface.cpp
index f2429bf36a..f8ae6a0752 100644
--- a/engines/pegasus/interface.cpp
+++ b/engines/pegasus/interface.cpp
@@ -604,6 +604,7 @@ void Interface::raiseInventoryDrawerSync() {
raiseInventoryDrawer(false);
while (_inventoryLid.isRunning()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -613,6 +614,7 @@ void Interface::raiseInventoryDrawerSync() {
inventoryLidOpen(false);
while (_inventoryPush.isFading()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -628,6 +630,7 @@ void Interface::lowerInventoryDrawerSync() {
lowerInventoryDrawer(false);
while (_inventoryPush.isFading()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -637,6 +640,7 @@ void Interface::lowerInventoryDrawerSync() {
inventoryDrawerDown(false);
while (_inventoryLid.isRunning()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -652,6 +656,7 @@ void Interface::raiseBiochipDrawerSync() {
raiseBiochipDrawer(false);
while (_biochipLid.isRunning()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -661,6 +666,7 @@ void Interface::raiseBiochipDrawerSync() {
biochipLidOpen(false);
while (_biochipPush.isFading()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -676,6 +682,7 @@ void Interface::lowerBiochipDrawerSync() {
lowerBiochipDrawer(false);
while (_biochipPush.isFading()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
@@ -685,6 +692,7 @@ void Interface::lowerBiochipDrawerSync() {
biochipDrawerDown(false);
while (_biochipLid.isRunning()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
diff --git a/engines/pegasus/items/inventorypicture.cpp b/engines/pegasus/items/inventorypicture.cpp
index fc812faae2..bfdc382f5d 100644
--- a/engines/pegasus/items/inventorypicture.cpp
+++ b/engines/pegasus/items/inventorypicture.cpp
@@ -331,6 +331,7 @@ void InventoryItemsPicture::playEndMessage(DisplayElement *pushElement) {
endMessage.start();
while (endMessage.isRunning()) {
+ InputDevice.pumpEvents();
vm->checkCallBacks();
vm->refreshDisplay();
g_system->delayMillis(10);
diff --git a/engines/pegasus/items/item.cpp b/engines/pegasus/items/item.cpp
index 8089f2b93d..830d3f2f34 100644
--- a/engines/pegasus/items/item.cpp
+++ b/engines/pegasus/items/item.cpp
@@ -39,9 +39,9 @@
namespace Pegasus {
Item::Item(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) : IDObject(id) {
- _itemNeighborhood = neighborhood;
- _itemRoom = room;
- _itemDirection = direction;
+ _originalNeighborhood = _itemNeighborhood = neighborhood;
+ _originalRoom = _itemRoom = room;
+ _originalDirection = _itemDirection = direction;
_itemWeight = 1;
_itemOwnerID = kNoActorID;
_itemState = 0;
@@ -131,6 +131,14 @@ Item::~Item() {
delete[] _itemExtras.entries;
}
+void Item::reset() {
+ _itemNeighborhood = _originalNeighborhood;
+ _itemRoom = _originalRoom;
+ _itemDirection = _originalDirection;
+ _itemOwnerID = kNoActorID;
+ _itemState = 0;
+}
+
void Item::writeToStream(Common::WriteStream *stream) {
stream->writeUint16BE(_itemNeighborhood);
stream->writeUint16BE(_itemRoom);
diff --git a/engines/pegasus/items/item.h b/engines/pegasus/items/item.h
index a1451b2a58..26cccf043c 100644
--- a/engines/pegasus/items/item.h
+++ b/engines/pegasus/items/item.h
@@ -339,6 +339,9 @@ public:
void findItemExtra(const uint32 extraID, ItemExtraEntry &entry);
+ // Reset to its original state at the beginning of the game
+ void reset();
+
protected:
NeighborhoodID _itemNeighborhood;
RoomID _itemRoom;
@@ -347,6 +350,10 @@ protected:
WeightType _itemWeight;
ItemState _itemState;
+ NeighborhoodID _originalNeighborhood;
+ RoomID _originalRoom;
+ DirectionConstant _originalDirection;
+
JMPItemInfo _itemInfo;
ItemStateInfo _sharedAreaInfo;
ItemExtraInfo _itemExtras;
diff --git a/engines/pegasus/items/itemlist.cpp b/engines/pegasus/items/itemlist.cpp
index ff8cae546b..4b58d9ad78 100644
--- a/engines/pegasus/items/itemlist.cpp
+++ b/engines/pegasus/items/itemlist.cpp
@@ -64,4 +64,9 @@ Item *ItemList::findItemByID(const ItemID id) {
return 0;
}
+void ItemList::resetAllItems() {
+ for (ItemIterator it = begin(); it != end(); it++)
+ (*it)->reset();
+}
+
} // End of namespace Pegasus
diff --git a/engines/pegasus/items/itemlist.h b/engines/pegasus/items/itemlist.h
index 9b59206ab3..22bef2c96e 100644
--- a/engines/pegasus/items/itemlist.h
+++ b/engines/pegasus/items/itemlist.h
@@ -48,6 +48,7 @@ public:
virtual void readFromStream(Common::ReadStream *stream);
Item *findItemByID(const ItemID id);
+ void resetAllItems();
};
typedef ItemList::iterator ItemIterator;
diff --git a/engines/pegasus/menu.cpp b/engines/pegasus/menu.cpp
index e55c006f86..4bbda8fd93 100644
--- a/engines/pegasus/menu.cpp
+++ b/engines/pegasus/menu.cpp
@@ -227,6 +227,7 @@ MainMenu::MainMenu() : GameMenu(kMainMenuID), _menuBackground(0), _overviewButto
_menuLoop.attachFader(&_menuFader);
_menuLoop.initFromAIFFFile("Sounds/Main Menu.aiff");
+ _menuFader.setMasterVolume(((PegasusEngine *)g_engine)->getAmbienceLevel());
updateDisplay();
}
@@ -736,6 +737,7 @@ DeathMenu::DeathMenu(const DeathReason deathReason) : GameMenu(kDeathMenuID), _d
_largeSelect.startDisplaying();
} else {
_triumphSound.initFromQuickTime("Sounds/Caldoria/Galactic Triumph");
+ _triumphSound.setVolume(((PegasusEngine *)g_engine)->getAmbienceLevel());
_triumphSound.playSound();
}
diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.cpp b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
index 0b3e1ee040..9d2d6723a9 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoria.cpp
+++ b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
@@ -196,6 +196,8 @@ void Caldoria::start() {
if (!pullbackMovie->loadFile("Images/Caldoria/Pullback.movie"))
error("Could not load pullback movie");
+ pullbackMovie->setVolume(MIN<uint>(_vm->getSoundFXLevel(), 0xFF));
+
// Draw the first frame so we can fade to it
const Graphics::Surface *frame = pullbackMovie->decodeNextFrame();
assert(frame);
@@ -386,54 +388,72 @@ void Caldoria::startSpotOnceOnly(TimeValue startTime, TimeValue stopTime) {
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen13CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen13CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria14, kEast):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen14CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen14CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria18, kWest):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen18CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen18CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria23, kSouth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen23CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen23CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria33, kSouth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen33CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen33CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria36, kNorth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen36CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen36CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria41, kNorth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41NorthCarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen41NorthCarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria41, kEast):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41EastCarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen41EastCarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria41, kWest):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41WestCarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen41WestCarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
default:
@@ -889,7 +909,7 @@ void Caldoria::arriveAtCaldoria49() {
setCurrentAlternate(kAltCaldoriaNormal);
// Need to force the loop to play.
- if (GameState.getCurrentDirection() == kNorth) {
+ if (GameState.getCurrentDirection() == kNorth && !GameState.getCaldoriaSinclairShot()) {
GameState.setCaldoriaFuseTimeLimit(kSinclairShootsTimeLimit);
startExtraSequence(kCa49NorthVoiceAnalysis, kExtraCompletedFlag, kFilterNoInput);
}
@@ -1898,10 +1918,13 @@ uint Caldoria::getNumHints() {
numHints = 1;
}
break;
+#if 0
+ // The hint file is missing
case MakeRoomView(kCaldoria49, kEast):
case MakeRoomView(kCaldoria54, kEast):
numHints = 1;
break;
+#endif
case MakeRoomView(kCaldoria49, kNorth):
numHints = 1;
break;
@@ -1932,9 +1955,12 @@ Common::String Caldoria::getHintMovie(uint hintNum) {
}
return "Images/AI/Globals/XGLOB1A";
+#if 0
+ // The hint file is missing
case MakeRoomView(kCaldoria49, kEast):
case MakeRoomView(kCaldoria54, kEast):
return "Images/AI/Caldoria/X49E";
+#endif
case MakeRoomView(kCaldoria49, kNorth):
return "Images/AI/Caldoria/X49NB2";
}
diff --git a/engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp b/engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp
index abf34d3863..c964e3458b 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp
+++ b/engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp
@@ -1167,6 +1167,18 @@ CaldoriaBomb::~CaldoriaBomb() {
delete[] _bombLevel[i];
}
+void CaldoriaBomb::setSoundFXLevel(const uint16) {
+ // The transition sounds between levels are ambience, so overwrite what
+ // Neighborhood::setSoundFXLevel does and keep using the ambience volume level
+ if (_timer.isRunning())
+ _owner->_navMovie.setVolume(((PegasusEngine *)g_engine)->getAmbienceLevel());
+}
+
+void CaldoriaBomb::setAmbienceLevel(const uint16 level) {
+ if (_timer.isRunning())
+ _owner->_navMovie.setVolume(level);
+}
+
void CaldoriaBomb::openInteraction() {
_grid.moveElementTo(kCaldoriaBombGridLeft, kCaldoriaBombGridTop);
_grid.setDisplayOrder(kCaldoriaBombGridOrder);
@@ -1234,6 +1246,7 @@ void CaldoriaBomb::receiveNotification(Notification *notification, const Notific
_timer.start();
_currentLevel = 0;
_lastVertex = -1;
+ _owner->_navMovie.setVolume(((PegasusEngine *)g_engine)->getAmbienceLevel());
startBombAmbient("Sounds/Caldoria/BmbLoop1.22K.AIFF");
break;
case kCaldoria56BombStage2:
@@ -1258,6 +1271,7 @@ void CaldoriaBomb::receiveNotification(Notification *notification, const Notific
_grid.hide();
_timer.stop();
_timer.hide();
+ _owner->_navMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
_owner->loadLoopSound1("");
_owner->playDeathExtra(kCaldoria56BombExplodes, kDeathNuclearExplosion);
}
@@ -1411,6 +1425,7 @@ void CaldoriaBomb::handleInput(const Input &input, const Hotspot *hotspot) {
_timer.stop();
_grid.hide();
_timer.hide();
+ _owner->_navMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
_owner->startExtraSequence(kCaldoria56BombStage7, kExtraCompletedFlag, kFilterNoInput);
break;
}
diff --git a/engines/pegasus/neighborhood/caldoria/caldoriabomb.h b/engines/pegasus/neighborhood/caldoria/caldoriabomb.h
index 5bb39b4122..ba6d1e8998 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoriabomb.h
+++ b/engines/pegasus/neighborhood/caldoria/caldoriabomb.h
@@ -122,6 +122,9 @@ public:
CaldoriaBomb(Neighborhood *, NotificationManager *);
virtual ~CaldoriaBomb();
+ void setSoundFXLevel(const uint16);
+ void setAmbienceLevel(const uint16);
+
long getNumHints();
Common::String getHintMovie(uint);
void doSolve();
diff --git a/engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp b/engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp
index a3ce97d438..2ae990d775 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp
+++ b/engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp
@@ -24,6 +24,7 @@
*/
#include "pegasus/gamestate.h"
+#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/neighborhood.h"
#include "pegasus/neighborhood/caldoria/caldoria.h"
#include "pegasus/neighborhood/caldoria/caldoriamessages.h"
@@ -45,6 +46,10 @@ void CaldoriaMessages::openInteraction() {
_messageNumber = 1;
}
+void CaldoriaMessages::setSoundFXLevel(const uint16 fxLevel) {
+ _messageMovie.setVolume(fxLevel);
+}
+
void CaldoriaMessages::initInteraction() {
GameInteraction::_owner->startExtraSequence(kCaBedroomVidPhone, kExtraCompletedFlag, kFilterNoInput);
}
@@ -101,6 +106,7 @@ void CaldoriaMessages::play1Message(uint messageNumber) {
GameState.setCaldoriaSeenMessages(true);
}
+ _messageMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
_messageMovie.moveElementTo(kCaldoriaMessageLeft, kCaldoriaMessageTop);
_messageMovie.setDisplayOrder(kCaldoriaMessagesOrder);
_messageMovie.startDisplaying();
diff --git a/engines/pegasus/neighborhood/caldoria/caldoriamessages.h b/engines/pegasus/neighborhood/caldoria/caldoriamessages.h
index 955fe10ce9..b2fc7c3bf9 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoriamessages.h
+++ b/engines/pegasus/neighborhood/caldoria/caldoriamessages.h
@@ -41,6 +41,8 @@ public:
CaldoriaMessages(Neighborhood *, const NotificationID, NotificationManager *);
virtual ~CaldoriaMessages() {}
+ void setSoundFXLevel(const uint16);
+
protected:
void openInteraction();
void initInteraction();
diff --git a/engines/pegasus/neighborhood/mars/mars.cpp b/engines/pegasus/neighborhood/mars/mars.cpp
index 775221589a..df5a75541c 100644
--- a/engines/pegasus/neighborhood/mars/mars.cpp
+++ b/engines/pegasus/neighborhood/mars/mars.cpp
@@ -535,6 +535,10 @@ void Mars::doorOpened() {
}
void Mars::setUpReactorEnergyDrain() {
+ // If there's no energy monitor, there's nothing to do
+ if (!g_energyMonitor)
+ return;
+
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars51, kEast):
if (GameState.isCurrentDoorOpen()) {
@@ -2011,7 +2015,7 @@ void Mars::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {
void Mars::robotTiredOfWaiting() {
if (GameState.getCurrentRoomAndView() == MakeRoomView(kMars48, kEast)) {
- if (_attackingItem) {
+ if (!_attackingItem) {
startExtraSequence(kMars48RobotKillsPlayer, kExtraCompletedFlag, kFilterNoInput);
loadLoopSound2("");
} else {
@@ -2398,6 +2402,8 @@ void Mars::doCanyonChase() {
if (!video->loadFile("Images/Mars/M44ESA.movie"))
error("Could not load interface->shuttle transition video");
+ video->setVolume(MIN<uint>(_vm->getSoundFXLevel(), 0xFF));
+
video->start();
while (!_vm->shouldQuit() && !video->endOfVideo()) {
@@ -2476,6 +2482,7 @@ void Mars::doCanyonChase() {
_shuttleEnergyMeter.initShuttleEnergyMeter();
_shuttleEnergyMeter.powerUpMeter();
while (_shuttleEnergyMeter.isFading()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
g_system->updateScreen();
@@ -2607,6 +2614,7 @@ void Mars::startUpFromFinishedSpaceChase() {
kShuttleJunkTop, false);
initOneMovie(&_explosions, "Images/Mars/Explosions.movie", kShuttleWeaponFrontOrder, 0, 0, false);
+ _explosions.setVolume(_vm->getSoundFXLevel());
_explosionCallBack.initCallBack(&_explosions, kCallBackAtExtremes);
_energyBeam.initShuttleWeapon();
@@ -2645,6 +2653,7 @@ void Mars::startUpFromFinishedSpaceChase() {
initOneMovie(&_canyonChaseMovie, "Images/Mars/M98EAS.movie", kShuttleTractorBeamMovieOrder,
kShuttleWindowLeft, kShuttleWindowTop, true);
+ _canyonChaseMovie.setVolume(_vm->getSoundFXLevel());
_canyonChaseMovie.setTime(_canyonChaseMovie.getDuration());
_canyonChaseMovie.redrawMovieWorld();
}
@@ -2720,6 +2729,7 @@ void Mars::startUpFromSpaceChase() {
kShuttleJunkTop, false);
initOneMovie(&_explosions, "Images/Mars/Explosions.movie", kShuttleWeaponFrontOrder, 0, 0, false);
+ _explosions.setVolume(_vm->getSoundFXLevel());
_explosionCallBack.initCallBack(&_explosions, kCallBackAtExtremes);
_energyBeam.initShuttleWeapon();
@@ -2783,6 +2793,10 @@ void Mars::startUpFromSpaceChase() {
void Mars::setSoundFXLevel(const uint16 level) {
Neighborhood::setSoundFXLevel(level);
+ if (GameState.getCurrentRoomAndView() == MakeRoomView(kMars48, kEast) &&
+ !GameState.getMarsAvoidedReactorRobot())
+ _loop2Fader.setMasterVolume(level);
+
if (_canyonChaseMovie.isMovieValid())
_canyonChaseMovie.setVolume(level);
@@ -2812,6 +2826,7 @@ void Mars::marsTimerExpired(MarsTimerEvent &event) {
GameState.setScoringEnteredLaunchTube();
while (_canyonChaseMovie.isRunning()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
@@ -2836,6 +2851,7 @@ void Mars::marsTimerExpired(MarsTimerEvent &event) {
initOneMovie(&_junk, "Images/Mars/Junk.movie", kShuttleJunkOrder, kShuttleJunkLeft, kShuttleJunkTop, false);
initOneMovie(&_explosions, "Images/Mars/Explosions.movie", kShuttleWeaponFrontOrder, 0, 0, false);
+ _explosions.setVolume(_vm->getSoundFXLevel());
_explosionCallBack.initCallBack(&_explosions, kCallBackAtExtremes);
_energyBeam.initShuttleWeapon();
@@ -2945,6 +2961,7 @@ void Mars::marsTimerExpired(MarsTimerEvent &event) {
showBigExplosion(r, kShuttleAlienShipOrder);
while (_explosions.isRunning()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
g_system->delayMillis(10);
@@ -3138,6 +3155,7 @@ void Mars::spaceChaseClick(const Input &input, const HotSpotID id) {
_shuttleEnergyMeter.drainForTractorBeam();
while (_shuttleEnergyMeter.isFading()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
@@ -3167,11 +3185,13 @@ void Mars::spaceChaseClick(const Input &input, const HotSpotID id) {
// Shameless reuse of a variable :P
initOneMovie(&_canyonChaseMovie, "Images/Mars/M98EAS.movie", kShuttleTractorBeamMovieOrder,
kShuttleWindowLeft, kShuttleWindowTop, true);
+ _canyonChaseMovie.setVolume(_vm->getSoundFXLevel());
_canyonChaseMovie.redrawMovieWorld();
playMovieSegment(&_canyonChaseMovie, 0, _canyonChaseMovie.getDuration());
// wait here until any junk clears...
while (_junk.junkFlying()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
diff --git a/engines/pegasus/neighborhood/neighborhood.cpp b/engines/pegasus/neighborhood/neighborhood.cpp
index 3116bd7978..c9be349694 100644
--- a/engines/pegasus/neighborhood/neighborhood.cpp
+++ b/engines/pegasus/neighborhood/neighborhood.cpp
@@ -470,6 +470,7 @@ void Neighborhood::requestSpotSound(const TimeValue in, const TimeValue out, con
void Neighborhood::playSpotSoundSync(const TimeValue in, const TimeValue out) {
// Let the action queue play out first...
while (!actionQueueEmpty()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->checkNotifications();
@@ -480,6 +481,7 @@ void Neighborhood::playSpotSoundSync(const TimeValue in, const TimeValue out) {
_spotSounds.playSoundSegment(in, out);
while (_spotSounds.isPlaying()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
@@ -1105,6 +1107,7 @@ void Neighborhood::startTurnPush(const TurnDirection turnDirection, const TimeVa
_turnPush.continueFader();
do {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
@@ -1492,7 +1495,15 @@ void Neighborhood::loadLoopSound2(const Common::String &soundName, uint16 volume
if (!_loop2SoundString.empty()) {
_soundLoop2.initFromAIFFFile(_loop2SoundString);
_soundLoop2.loopSound();
- _loop2Fader.setMasterVolume(_vm->getAmbienceLevel());
+ // HACK: Some ambient loops are actually sound effects, like Ares waiting at
+ // the reactor and Poseidon at the launch console. Detect these and use the
+ // SFX volume instead of ambience.
+ if (soundName == "Sounds/Mars/Robot Loop.aiff" ||
+ soundName == "Sounds/Norad/Breathing Typing.22K.AIFF" ||
+ soundName == "Sounds/Norad/N54NAS.32K.AIFF")
+ _loop2Fader.setMasterVolume(_vm->getSoundFXLevel());
+ else
+ _loop2Fader.setMasterVolume(_vm->getAmbienceLevel());
_loop2Fader.setFaderValue(0);
faderMove.makeTwoKnotFaderSpec(fadeScale, 0, 0, fadeIn, volume);
_loop2Fader.startFaderSync(faderMove);
@@ -1577,6 +1588,7 @@ void Neighborhood::closeCroppedMovie() {
void Neighborhood::playCroppedMovieOnce(const Common::String &movieName, CoordType left, CoordType top, const InputBits interruptionFilter) {
openCroppedMovie(movieName, left, top);
+ _croppedMovie.setVolume(_vm->getSoundFXLevel());
_croppedMovie.redrawMovieWorld();
_croppedMovie.start();
@@ -1616,6 +1628,7 @@ void Neighborhood::playMovieSegment(Movie *movie, TimeValue startTime, TimeValue
movie->start();
while (movie->isRunning()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
diff --git a/engines/pegasus/neighborhood/neighborhood.h b/engines/pegasus/neighborhood/neighborhood.h
index 3c1c5eac92..f7f2b038c6 100644
--- a/engines/pegasus/neighborhood/neighborhood.h
+++ b/engines/pegasus/neighborhood/neighborhood.h
@@ -91,6 +91,7 @@ struct QueueRequest {
bool operator==(const QueueRequest &arg1, const QueueRequest &arg2);
bool operator!=(const QueueRequest &arg1, const QueueRequest &arg2);
+class CaldoriaBomb;
class GameInteraction;
class Item;
class Neighborhood;
@@ -109,6 +110,7 @@ protected:
typedef Common::Queue<QueueRequest> NeighborhoodActionQueue;
class Neighborhood : public IDObject, public NotificationReceiver, public InputHandler, public Idler {
+friend class CaldoriaBomb;
friend class StriderCallBack;
public:
diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.cpp b/engines/pegasus/neighborhood/norad/delta/globegame.cpp
index 0b95e9bc2b..5c321a8e8a 100644
--- a/engines/pegasus/neighborhood/norad/delta/globegame.cpp
+++ b/engines/pegasus/neighborhood/norad/delta/globegame.cpp
@@ -453,8 +453,13 @@ GlobeGame::GlobeGame(Neighborhood *handler) : GameInteraction(kNoradGlobeGameInt
_neighborhoodNotification = handler->getNeighborhoodNotification();
}
+void GlobeGame::setSoundFXLevel(const uint16 fxLevel) {
+ _monitorMovie.setVolume(fxLevel);
+}
+
void GlobeGame::openInteraction() {
_monitorMovie.initFromMovieFile("Images/Norad Delta/N79 Left Monitor");
+ _monitorMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
_monitorMovie.moveElementTo(kGlobeMonitorLeft, kGlobeMonitorTop);
_monitorMovie.setDisplayOrder(kGlobeMonitorLayer);
_monitorMovie.startDisplaying();
diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.h b/engines/pegasus/neighborhood/norad/delta/globegame.h
index 73ed48866f..93235a1784 100644
--- a/engines/pegasus/neighborhood/norad/delta/globegame.h
+++ b/engines/pegasus/neighborhood/norad/delta/globegame.h
@@ -98,6 +98,8 @@ public:
GlobeGame(Neighborhood *);
virtual ~GlobeGame() {}
+ void setSoundFXLevel(const uint16);
+
void handleInput(const Input &, const Hotspot *);
void clickInHotspot(const Input &, const Hotspot *);
void activateHotspots();
diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
index 1eea2f0156..ee047d72b2 100644
--- a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
+++ b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
@@ -514,6 +514,17 @@ void NoradDelta::openDoor() {
}
}
+void NoradDelta::cantMoveThatWay(CanOpenDoorReason reason) {
+ // WORKAROUND: The door outside the launch console room isn't treated as a door,
+ // so play the correct sound.
+ if (reason == kCantMoveBlocked && GameState.getCurrentRoomAndView() == MakeRoomView(kNorad67, kNorth)) {
+ cantOpenDoor(kCantOpenLocked);
+ return;
+ }
+
+ Neighborhood::cantMoveThatWay(reason);
+}
+
void NoradDelta::activateHotspots() {
Norad::activateHotspots();
@@ -863,6 +874,13 @@ void NoradDelta::doSolve() {
}
}
+void NoradDelta::setSoundFXLevel(const uint16 level) {
+ Neighborhood::setSoundFXLevel(level);
+
+ if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad54North, kNorth))
+ _loop2Fader.setMasterVolume(level);
+}
+
Common::String NoradDelta::getSoundSpotsName() {
return "Sounds/Norad/Norad Delta Spots";
}
diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.h b/engines/pegasus/neighborhood/norad/delta/noraddelta.h
index 11065f2c9d..591fd691a2 100644
--- a/engines/pegasus/neighborhood/norad/delta/noraddelta.h
+++ b/engines/pegasus/neighborhood/norad/delta/noraddelta.h
@@ -68,6 +68,8 @@ public:
bool canSolve();
void doSolve();
+ void setSoundFXLevel(const uint16);
+
void doorOpened();
protected:
@@ -90,6 +92,7 @@ protected:
void arriveAtNorad79West();
TimeValue getViewTime(const RoomID, const DirectionConstant);
void openDoor();
+ void cantMoveThatWay(CanMoveForwardReason);
void activateHotspots();
void clickInHotspot(const Input &, const Hotspot *);
void receiveNotification(Notification *, const NotificationFlags);
diff --git a/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp b/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp
index d62b069e46..190984f8bc 100644
--- a/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp
+++ b/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp
@@ -124,11 +124,6 @@ void Prehistoric::setUpAIRules() {
AIHasItemCondition *hasLogCondition = new AIHasItemCondition(kHistoricalLog);
AIRule *rule = new AIRule(hasLogCondition, doneAction);
g_AIArea->addAIRule(rule);
- } else {
- AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Prehistoric/XP25W", false);
- AIHasItemCondition *hasLogCondition = new AIHasItemCondition(kHistoricalLog);
- AIRule *rule = new AIRule(hasLogCondition, messageAction);
- g_AIArea->addAIRule(rule);
}
if (!_vm->isOldDemo()) {
@@ -167,6 +162,13 @@ void Prehistoric::setUpAIRules() {
rule = new AIRule(timerCondition, messageAction);
g_AIArea->addAIRule(rule);
}
+
+ if (!_vm->isDemo()) {
+ AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Prehistoric/XP25W", false);
+ AIHasItemCondition *hasLogCondition = new AIHasItemCondition(kHistoricalLog);
+ AIRule *rule = new AIRule(hasLogCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+ }
}
}
@@ -202,11 +204,11 @@ TimeValue Prehistoric::getViewTime(const RoomID room, const DirectionConstant di
void Prehistoric::findSpotEntry(const RoomID room, const DirectionConstant direction, SpotFlags flags, SpotTable::Entry &entry) {
Neighborhood::findSpotEntry(room, direction, flags, entry);
+ // The original strangely disabled the loop for the two volcano spots:
+ // (kPrehistoric01, kSouth) and (kPrehistoric25, kSouth)
+ // We don't do that here.
+
switch (MakeRoomView(room, direction)) {
- case MakeRoomView(kPrehistoric01, kSouth):
- case MakeRoomView(kPrehistoric25, kSouth):
- entry.clear();
- break;
case MakeRoomView(kPrehistoric01, kEast):
if (GameState.getPrehistoricSeenFlyer1())
entry.clear();
diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
index 99efe10272..92b79c038e 100644
--- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
@@ -1692,7 +1692,9 @@ void FullTSA::initializeTBPMonitor(const int newMode, const ExtraID highlightExt
releaseSprites();
}
- _interruptionFilter = kFilterAllInput;
+ // Only allow input if we're not in the middle of series of queue requests.
+ if (actionQueueEmpty())
+ _interruptionFilter = kFilterAllInput;
}
void FullTSA::startUpComparisonMonitor() {
@@ -2643,6 +2645,7 @@ void FullTSA::receiveNotification(Notification *notification, const Notification
GameState.setMarsReadyForShuttleTransport(false);
GameState.setMarsFinishedCanyonChase(false);
GameState.setMarsThreadedMaze(false);
+ GameState.setMarsSawRobotLeave(false);
break;
case kPlayerOnWayToWSC:
_vm->jumpToNewEnvironment(kWSCID, kWSC01, kWest);
@@ -2691,16 +2694,18 @@ void FullTSA::receiveNotification(Notification *notification, const Notification
}
break;
case kTSA37DownloadToOpMemReview:
- switch (GameState.getTSAState()) {
- case kPlayerOnWayToNorad:
- g_opticalChip->playOpMemMovie(kPoseidonSpotID);
- break;
- case kPlayerOnWayToMars:
- g_opticalChip->playOpMemMovie(kAriesSpotID);
- break;
- case kPlayerOnWayToWSC:
- g_opticalChip->playOpMemMovie(kMercurySpotID);
- break;
+ if (_vm->itemInBiochips(kOpticalBiochip)) {
+ switch (GameState.getTSAState()) {
+ case kPlayerOnWayToNorad:
+ g_opticalChip->playOpMemMovie(kPoseidonSpotID);
+ break;
+ case kPlayerOnWayToMars:
+ g_opticalChip->playOpMemMovie(kAriesSpotID);
+ break;
+ case kPlayerOnWayToWSC:
+ g_opticalChip->playOpMemMovie(kMercurySpotID);
+ break;
+ }
}
if (GameState.allTimeZonesFinished()) {
diff --git a/engines/pegasus/neighborhood/tsa/tinytsa.cpp b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
index 0d11f5d904..c808325b0f 100644
--- a/engines/pegasus/neighborhood/tsa/tinytsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
@@ -327,6 +327,7 @@ void TinyTSA::receiveNotification(Notification *notification, const Notification
GameState.setMarsReadyForShuttleTransport(false);
GameState.setMarsFinishedCanyonChase(false);
GameState.setMarsThreadedMaze(false);
+ GameState.setMarsSawRobotLeave(false);
break;
case kPlayerOnWayToWSC:
_vm->jumpToNewEnvironment(kWSCID, kWSC01, kWest);
@@ -372,16 +373,18 @@ void TinyTSA::receiveNotification(Notification *notification, const Notification
}
break;
case kTinyTSA37DownloadToOpMemReview:
- switch (GameState.getTSAState()) {
- case kPlayerOnWayToNorad:
- g_opticalChip->playOpMemMovie(kPoseidonSpotID);
- break;
- case kPlayerOnWayToMars:
- g_opticalChip->playOpMemMovie(kAriesSpotID);
- break;
- case kPlayerOnWayToWSC:
- g_opticalChip->playOpMemMovie(kMercurySpotID);
- break;
+ if (_vm->itemInBiochips(kOpticalBiochip)) {
+ switch (GameState.getTSAState()) {
+ case kPlayerOnWayToNorad:
+ g_opticalChip->playOpMemMovie(kPoseidonSpotID);
+ break;
+ case kPlayerOnWayToMars:
+ g_opticalChip->playOpMemMovie(kAriesSpotID);
+ break;
+ case kPlayerOnWayToWSC:
+ g_opticalChip->playOpMemMovie(kMercurySpotID);
+ break;
+ }
}
requestExtraSequence(kTinyTSA37OpMemReviewToMainMenu, kExtraCompletedFlag, kFilterNoInput);
diff --git a/engines/pegasus/neighborhood/wsc/wsc.cpp b/engines/pegasus/neighborhood/wsc/wsc.cpp
index 09e2a48a52..f009b35cdc 100644
--- a/engines/pegasus/neighborhood/wsc/wsc.cpp
+++ b/engines/pegasus/neighborhood/wsc/wsc.cpp
@@ -2029,6 +2029,7 @@ void WSC::moleculeGameClick(const HotSpotID id) {
_moleculesMovie.start();
while (_moleculesMovie.isRunning()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
@@ -2063,6 +2064,7 @@ void WSC::moleculeGameClick(const HotSpotID id) {
_moleculesMovie.start();
while (_moleculesMovie.isRunning()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
@@ -2076,6 +2078,7 @@ void WSC::moleculeGameClick(const HotSpotID id) {
while (_moleculesMovie.isRunning()) {
+ InputDevice.pumpEvents();
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
index 3bd29ce8dd..0010180d8d 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) {
@@ -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);
}
}
@@ -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);
}
diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h
index 07e6d8f761..d88545a4d1 100644
--- a/engines/pegasus/pegasus.h
+++ b/engines/pegasus/pegasus.h
@@ -249,7 +249,7 @@ private:
Common::List<TimeBase *> _timeBases;
// Save/Load
- bool loadFromStream(Common::ReadStream *stream);
+ bool loadFromStream(Common::SeekableReadStream *stream);
bool writeToStream(Common::WriteStream *stream, int saveType);
void loadFromContinuePoint();
void writeContinueStream(Common::WriteStream *stream);
@@ -257,6 +257,7 @@ private:
bool _saveAllowed, _loadAllowed; // It's so nice that this was in the original code already :P
Common::Error showLoadDialog();
Common::Error showSaveDialog();
+ void showSaveFailedDialog(const Common::Error &status);
bool _saveRequested, _loadRequested;
// Misc.
@@ -272,6 +273,7 @@ private:
uint getNeighborhoodCD(const NeighborhoodID neighborhood) const;
uint _currentCD;
void initKeymap();
+ InputBits getInputFilter();
// Menu
GameMenu *_gameMenu;
diff --git a/engines/pegasus/surface.cpp b/engines/pegasus/surface.cpp
index cdcb3c6e79..cb1e2e7bcc 100644
--- a/engines/pegasus/surface.cpp
+++ b/engines/pegasus/surface.cpp
@@ -28,7 +28,7 @@
#include "common/stream.h"
#include "common/system.h"
#include "graphics/surface.h"
-#include "graphics/decoders/pict.h"
+#include "image/pict.h"
#include "video/video_decoder.h"
#include "pegasus/pegasus.h"
@@ -101,7 +101,7 @@ void Surface::getImageFromPICTResource(Common::MacResManager *resFork, uint16 id
}
bool Surface::getImageFromPICTStream(Common::SeekableReadStream *stream) {
- Graphics::PICTDecoder pict;
+ Image::PICTDecoder pict;
if (!pict.loadStream(*stream))
return false;
diff --git a/engines/pegasus/timers.cpp b/engines/pegasus/timers.cpp
index 8463d866e8..5fb2551e7a 100644
--- a/engines/pegasus/timers.cpp
+++ b/engines/pegasus/timers.cpp
@@ -333,6 +333,7 @@ void TimeBaseCallBack::releaseCallBack() {
void TimeBaseCallBack::disposeCallBack() {
_timeBase = 0;
+ _trigger = kTriggerNone;
_hasBeenTriggered = false;
}