diff options
author | Strangerke | 2013-06-26 23:11:34 +0200 |
---|---|---|
committer | Strangerke | 2013-06-26 23:11:34 +0200 |
commit | 6e2d567bca53b6ffee771b4105e2e73dbd73f5b4 (patch) | |
tree | 9880f0c496263ffb6928248d495ce4172dabed18 /engines/pegasus | |
parent | ac387835e4527c1814919093b4e4bc9798d5742d (diff) | |
parent | 6716fa39a6fb2a3925576288c256688c5aadd7e9 (diff) | |
download | scummvm-rg350-6e2d567bca53b6ffee771b4105e2e73dbd73f5b4.tar.gz scummvm-rg350-6e2d567bca53b6ffee771b4105e2e73dbd73f5b4.tar.bz2 scummvm-rg350-6e2d567bca53b6ffee771b4105e2e73dbd73f5b4.zip |
Merge branch 'master' of https://github.com/scummvm/scummvm into mortevielle
Conflicts:
engines/engines.mk
Diffstat (limited to 'engines/pegasus')
25 files changed, 390 insertions, 101 deletions
diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp index 5babdf34af..897d31d7bd 100644 --- a/engines/pegasus/cursor.cpp +++ b/engines/pegasus/cursor.cpp @@ -82,8 +82,14 @@ void Cursor::setCurrentFrameIndex(int32 index) { _index = index; if (index != -1) { loadCursorImage(_info[index]); - CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount); - CursorMan.replaceCursor((byte *)_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0); + + if (_info[index].surface->format.bytesPerPixel == 1) { + CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount); + CursorMan.replaceCursor(_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0); + } else { + CursorMan.replaceCursor(_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, _info[index].surface->format.RGBToColor(0xFF, 0xFF, 0xFF), false, &_info[index].surface->format); + } + ((PegasusEngine *)g_engine)->_gfx->markCursorAsDirty(); } } @@ -135,9 +141,25 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) { if (cursorInfo.surface) return; + PegasusEngine *vm = (PegasusEngine *)g_engine; + + if (vm->isDVD()) { + // The DVD version has some higher color PICT images for its cursors + Common::SeekableReadStream *pictStream = vm->_resFork->getResource(MKTAG('P', 'I', 'C', 'T'), cursorInfo.tag + 1000); + + if (pictStream) { + Graphics::PICTDecoder pict; + if (!pict.loadStream(*pictStream)) + error("Failed to decode cursor PICT %d", cursorInfo.tag + 1000); + + cursorInfo.surface = pict.getSurface()->convertTo(g_system->getScreenFormat()); + delete pictStream; + return; + } + } + cursorInfo.surface = new Graphics::Surface(); - PegasusEngine *vm = (PegasusEngine *)g_engine; Common::SeekableReadStream *cicnStream = vm->_resFork->getResource(MKTAG('c', 'i', 'c', 'n'), cursorInfo.tag); if (!cicnStream) diff --git a/engines/pegasus/detection.cpp b/engines/pegasus/detection.cpp index 908005b665..721c382d4f 100644 --- a/engines/pegasus/detection.cpp +++ b/engines/pegasus/detection.cpp @@ -35,6 +35,10 @@ struct PegasusGameDescription { ADGameDescription desc; }; +enum { + GF_DVD = (1 << 1) +}; + bool PegasusEngine::hasFeature(EngineFeature f) const { return (f == kSupportsRTL) @@ -46,6 +50,22 @@ bool PegasusEngine::isDemo() const { return (_gameDescription->desc.flags & ADGF_DEMO) != 0; } +bool PegasusEngine::isDVD() const { + return (_gameDescription->desc.flags & GF_DVD) != 0; +} + +bool PegasusEngine::isDVDDemo() const { + return isDemo() && isDVD(); +} + +bool PegasusEngine::isOldDemo() const { + return isDemo() && !isDVD(); +} + +bool PegasusEngine::isWindows() const { + return _gameDescription->desc.platform == Common::kPlatformWindows; +} + } // End of namespace Pegasus static const PlainGameDescriptor pegasusGames[] = { @@ -76,7 +96,31 @@ static const PegasusGameDescription gameDescriptions[] = { AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 360129), Common::EN_ANY, Common::kPlatformMacintosh, - ADGF_MACRESFORK|ADGF_DEMO, + ADGF_MACRESFORK | ADGF_DEMO, + GUIO1(GUIO_NOLAUNCHLOAD) + }, + }, + + { + { + "pegasus", + "DVD Demo", + AD_ENTRY1s("JMP PP Resources", "d0fcda50dc75c7a81ae314e6a813f4d2", 93495), + Common::EN_ANY, + Common::kPlatformMacintosh, + ADGF_MACRESFORK | ADGF_DEMO | GF_DVD, + GUIO1(GUIO_NOLAUNCHLOAD) + }, + }, + + { + { + "pegasus", + "DVD Demo", + AD_ENTRY1s("JMP PP Resources", "d0fcda50dc75c7a81ae314e6a813f4d2", 93495), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_MACRESFORK | ADGF_DEMO | GF_DVD, GUIO1(GUIO_NOLAUNCHLOAD) }, }, @@ -119,12 +163,12 @@ SaveStateList PegasusMetaEngine::listSaves(const char *target) const { // The original had no pattern, so the user must rename theirs // Note that we ignore the target because saves are compatible between // all versions - Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles("pegasus-*.sav"); + Common::StringArray fileNames = Pegasus::PegasusEngine::listSaveFiles(); SaveStateList saveList; - for (uint32 i = 0; i < filenames.size(); i++) { + for (uint32 i = 0; i < fileNames.size(); i++) { // Isolate the description from the file name - Common::String desc = filenames[i].c_str() + 8; + Common::String desc = fileNames[i].c_str() + 8; for (int j = 0; j < 4; j++) desc.deleteLastChar(); @@ -136,8 +180,8 @@ SaveStateList PegasusMetaEngine::listSaves(const char *target) const { void PegasusMetaEngine::removeSaveState(const char *target, int slot) const { // See listSaves() for info on the pattern - Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles("pegasus-*.sav"); - g_system->getSavefileManager()->removeSavefile(filenames[slot].c_str()); + Common::StringArray fileNames = Pegasus::PegasusEngine::listSaveFiles(); + g_system->getSavefileManager()->removeSavefile(fileNames[slot].c_str()); } bool PegasusMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { diff --git a/engines/pegasus/elements.cpp b/engines/pegasus/elements.cpp index c84d555444..87fb69a557 100644 --- a/engines/pegasus/elements.cpp +++ b/engines/pegasus/elements.cpp @@ -259,8 +259,8 @@ void FrameSequence::openFrameSequence() { _frameTimes.clear(); for (uint32 i = 0; i < _numFrames; i++) { TimeValue time = res->readUint32BE(); - _duration += time; _frameTimes.push_back(_duration); + _duration += time; } setScale(scale); diff --git a/engines/pegasus/energymonitor.cpp b/engines/pegasus/energymonitor.cpp index 8aa77eb341..be9d205360 100644 --- a/engines/pegasus/energymonitor.cpp +++ b/engines/pegasus/energymonitor.cpp @@ -262,9 +262,9 @@ void EnergyMonitor::calibrateEnergyBar() { _energyLight.setCurrentFrameIndex(0); _energyLight.hide(); - show(); setEnergyValue(0); setEnergyDrainRate(-(int32)kMaxJMPEnergy / 2); + show(); // Make sure warning light is hidden... _energyLight.hide(); diff --git a/engines/pegasus/interface.cpp b/engines/pegasus/interface.cpp index d9d3865192..f2429bf36a 100644 --- a/engines/pegasus/interface.cpp +++ b/engines/pegasus/interface.cpp @@ -186,6 +186,11 @@ void Interface::validateInventoryPanel() { _inventoryLid.setDisplayOrder(kInventoryLidOrder); _inventoryLid.startDisplaying(); + if (((PegasusEngine *)g_engine)->isDVD()) { + _inventoryOpenSound.initFromAIFFFile("Sounds/Items/Inventory Panel Open.aif"); + _inventoryCloseSound.initFromAIFFFile("Sounds/Items/Inventory Panel Close.aif"); + } + _inventoryPushCallBack.initCallBack(&_inventoryPush, kCallBackAtExtremes); _inventoryLidCallBack.initCallBack(&_inventoryLid, kCallBackAtExtremes); @@ -231,6 +236,11 @@ void Interface::validateBiochipPanel() { _biochipLid.setDisplayOrder(kBiochipLidOrder); _biochipLid.startDisplaying(); + if (((PegasusEngine *)g_engine)->isDVD()) { + _biochipOpenSound.initFromAIFFFile("Sounds/Items/Biochip Panel Open.aif"); + _biochipCloseSound.initFromAIFFFile("Sounds/Items/Biochip Panel Close.aif"); + } + _biochipPushCallBack.initCallBack(&_biochipPush, kCallBackAtExtremes); _biochipLidCallBack.initCallBack(&_biochipLid, kCallBackAtExtremes); @@ -385,6 +395,11 @@ void Interface::raiseInventoryDrawer(const bool doCallBacks) { _inventoryLid.show(); _inventoryPush.show(); _inventoryLid.start(); + + if (((PegasusEngine *)g_engine)->isDVD()) { + _inventoryCloseSound.stopSound(); + _inventoryOpenSound.playSound(); + } } void Interface::playEndMessage() { @@ -446,6 +461,11 @@ void Interface::lowerInventoryDrawer(const bool doCallBacks) { FaderMoveSpec moveSpec; moveSpec.makeTwoKnotFaderSpec(60, 0, 1000, 15, 0); _inventoryPush.startFader(moveSpec); + + if (((PegasusEngine *)g_engine)->isDVD()) { + _inventoryOpenSound.stopSound(); + _inventoryCloseSound.playSound(); + } } } @@ -487,6 +507,11 @@ void Interface::raiseBiochipDrawer(const bool doCallBacks) { _biochipLid.show(); _biochipPush.show(); _biochipLid.start(); + + if (((PegasusEngine *)g_engine)->isDVD()) { + _biochipCloseSound.stopSound(); + _biochipOpenSound.playSound(); + } } void Interface::biochipLidOpen(const bool doCallBacks) { @@ -521,6 +546,11 @@ void Interface::lowerBiochipDrawer(const bool doCallBacks) { FaderMoveSpec moveSpec; moveSpec.makeTwoKnotFaderSpec(60, 0, 1000, 9, 0); _biochipPush.startFader(moveSpec); + + if (((PegasusEngine *)g_engine)->isDVD()) { + _biochipOpenSound.stopSound(); + _biochipCloseSound.playSound(); + } } } diff --git a/engines/pegasus/interface.h b/engines/pegasus/interface.h index a65d9a595a..5f04f98df0 100644 --- a/engines/pegasus/interface.h +++ b/engines/pegasus/interface.h @@ -29,6 +29,7 @@ #include "pegasus/hotspot.h" #include "pegasus/input.h" #include "pegasus/notification.h" +#include "pegasus/sound.h" #include "pegasus/surface.h" #include "pegasus/transition.h" #include "pegasus/items/inventorypicture.h" @@ -125,6 +126,7 @@ protected: NotificationCallBack _inventoryLidCallBack; InventoryItemsPicture _inventoryPanel; bool _inventoryUp, _inventoryRaised; + Sound _inventoryOpenSound, _inventoryCloseSound; Push _biochipPush; SpriteSequence _biochipLid; @@ -132,6 +134,7 @@ protected: NotificationCallBack _biochipLidCallBack; BiochipPicture _biochipPanel; bool _biochipUp, _biochipRaised; + Sound _biochipOpenSound, _biochipCloseSound; Hotspot _currentItemSpot; Hotspot _currentBiochipSpot; diff --git a/engines/pegasus/items/inventorypicture.h b/engines/pegasus/items/inventorypicture.h index 88a4a4ba75..9eba25bc3a 100644 --- a/engines/pegasus/items/inventorypicture.h +++ b/engines/pegasus/items/inventorypicture.h @@ -106,7 +106,6 @@ protected: virtual TimeValue getItemPanelTime(Item *); void loopCurrentItem(); - InputHandler *_previousHandler; bool _isLooping; }; diff --git a/engines/pegasus/menu.cpp b/engines/pegasus/menu.cpp index deaa460188..e55c006f86 100644 --- a/engines/pegasus/menu.cpp +++ b/engines/pegasus/menu.cpp @@ -149,10 +149,14 @@ MainMenu::MainMenu() : GameMenu(kMainMenuID), _menuBackground(0), _overviewButto bool isDemo = ((PegasusEngine *)g_engine)->isDemo(); - if (isDemo) - _menuBackground.initFromPICTFile("Images/Demo/DemoMenu.pict"); - else + if (isDemo) { + if (((PegasusEngine *)g_engine)->isWindows()) + _menuBackground.initFromPICTFile("Images/Demo/DemoMenuPC.pict"); + else + _menuBackground.initFromPICTFile("Images/Demo/DemoMenu.pict"); + } else { _menuBackground.initFromPICTFile("Images/Main Menu/MainMenu.mac"); + } _menuBackground.setDisplayOrder(0); _menuBackground.startDisplaying(); _menuBackground.show(); diff --git a/engines/pegasus/movie.cpp b/engines/pegasus/movie.cpp index 75c287c7a6..59814a753d 100644 --- a/engines/pegasus/movie.cpp +++ b/engines/pegasus/movie.cpp @@ -161,9 +161,10 @@ void Movie::setTime(const TimeValue time, const TimeScale scale) { } void Movie::setRate(const Common::Rational rate) { - if (rate != 1 && rate != 0) { - warning("Cannot set movie rate"); - start(); + if (_video) { + _video->setRate(rate); + + TimeBase::setRate(_video->getRate()); return; } diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.cpp b/engines/pegasus/neighborhood/caldoria/caldoria.cpp index 140e6e8093..9a378a6728 100644 --- a/engines/pegasus/neighborhood/caldoria/caldoria.cpp +++ b/engines/pegasus/neighborhood/caldoria/caldoria.cpp @@ -1291,6 +1291,7 @@ void Caldoria::activateHotspots() { _vm->getAllHotspots().deactivateOneHotspot(kCaldoriaRightDrawerNoKeysCloseSpotID); } } + break; case kCaldoriaReplicator: if (GameState.getCaldoriaMadeOJ()) _vm->getAllHotspots().deactivateOneHotspot(kCaldoriaMakeOJSpotID); @@ -1640,10 +1641,12 @@ void Caldoria::takeElevator(uint startFloor, uint endFloor) { break; case 2: _croppedMovie.setTime(k1To2Time); + _croppedMovie.redrawMovieWorld(); requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag); break; case 3: _croppedMovie.setTime(k1To3Time); + _croppedMovie.redrawMovieWorld(); requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag); break; case 4: @@ -1670,10 +1673,12 @@ void Caldoria::takeElevator(uint startFloor, uint endFloor) { break; case 2: _croppedMovie.setTime(k4To2Time); + _croppedMovie.redrawMovieWorld(); requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag); break; case 3: _croppedMovie.setTime(k4To3Time); + _croppedMovie.redrawMovieWorld(); requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag); break; case 4: @@ -1697,10 +1702,12 @@ void Caldoria::takeElevator(uint startFloor, uint endFloor) { break; case 2: _croppedMovie.setTime(k5To2Time); + _croppedMovie.redrawMovieWorld(); requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag); break; case 3: _croppedMovie.setTime(k5To3Time); + _croppedMovie.redrawMovieWorld(); requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag); break; case 4: diff --git a/engines/pegasus/neighborhood/mars/mars.cpp b/engines/pegasus/neighborhood/mars/mars.cpp index 34c9e3d0f8..775221589a 100644 --- a/engines/pegasus/neighborhood/mars/mars.cpp +++ b/engines/pegasus/neighborhood/mars/mars.cpp @@ -1035,7 +1035,6 @@ void Mars::checkContinuePoint(const RoomID room, const DirectionConstant directi case MakeRoomView(kMars51, kEast): case MakeRoomView(kMars56, kEast): case MakeRoomView(kMars60, kWest): - case MakeRoomView(kMarsMaze004, kWest): case MakeRoomView(kMarsMaze009, kWest): case MakeRoomView(kMarsMaze012, kWest): case MakeRoomView(kMarsMaze037, kWest): @@ -1059,6 +1058,11 @@ void Mars::checkContinuePoint(const RoomID room, const DirectionConstant directi case MakeRoomView(kMarsMaze199, kWest): makeContinuePoint(); break; + case MakeRoomView(kMarsMaze004, kWest): + // WORKAROUND: See Mars::arriveAt() for more details. + if (GameState.isTakenItemID(kCardBomb)) + makeContinuePoint(); + break; case MakeRoomView(kMars05, kEast): case MakeRoomView(kMars06, kEast): case MakeRoomView(kMars07, kEast): @@ -1393,6 +1397,13 @@ void Mars::arriveAt(const RoomID room, const DirectionConstant direction) { case MakeRoomView(kMarsRobotShuttle, kEast): setCurrentActivation(kActivationRobotHeadClosed); break; + case MakeRoomView(kMarsMaze004, kWest): + // WORKAROUND: You're not supposed to continue through the maze without the + // bomb or the game will not be completable. We're using the previously unused + // bomb death here to prevent progress (you didn't find the bomb, after all). + if (!GameState.isTakenItemID(kCardBomb)) + didntFindBomb(); + break; case MakeRoomView(kMarsMaze007, kNorth): launchMaze007Robot(); break; @@ -2459,6 +2470,7 @@ void Mars::doCanyonChase() { playSpotSoundSync(kShuttleCockpitIn, kShuttleCockpitOut); _centerShuttleMovie.setTime(kShuttleCenterCheckTime); + _centerShuttleMovie.redrawMovieWorld(); playSpotSoundSync(kShuttleOnboardIn, kShuttleOnboardOut); _shuttleEnergyMeter.initShuttleEnergyMeter(); @@ -2643,7 +2655,7 @@ void Mars::startUpFromSpaceChase() { // Open the spot sounds movie again... _spotSounds.initFromQuickTime(getSoundSpotsName()); - _spotSounds.setVolume(_vm->getSoundFXLevel());; + _spotSounds.setVolume(_vm->getSoundFXLevel()); initOnePicture(&_shuttleInterface1, "Images/Mars/MCmain1.pict", kShuttleBackgroundOrder, kShuttle1Left, kShuttle1Top, true); diff --git a/engines/pegasus/neighborhood/mars/reactor.cpp b/engines/pegasus/neighborhood/mars/reactor.cpp index 334fb98879..3a7ef9d7eb 100644 --- a/engines/pegasus/neighborhood/mars/reactor.cpp +++ b/engines/pegasus/neighborhood/mars/reactor.cpp @@ -244,9 +244,9 @@ void ReactorHistory::draw(const Common::Rect &) { static const CoordType kColorTops[5] = { 0, kColorHeights[0], - kColorHeights[0] + kColorHeights[1], - kColorHeights[0] + kColorHeights[1] + kColorHeights[2], - kColorHeights[0] + kColorHeights[1] + kColorHeights[2] + kColorHeights[3], + (CoordType)(kColorHeights[0] + kColorHeights[1]), + (CoordType)(kColorHeights[0] + kColorHeights[1] + kColorHeights[2]), + (CoordType)(kColorHeights[0] + kColorHeights[1] + kColorHeights[2] + kColorHeights[3]), }; if (_colors.isSurfaceValid() && _digits.isSurfaceValid()) { diff --git a/engines/pegasus/neighborhood/neighborhood.cpp b/engines/pegasus/neighborhood/neighborhood.cpp index 07be62c957..38366c4ba2 100644 --- a/engines/pegasus/neighborhood/neighborhood.cpp +++ b/engines/pegasus/neighborhood/neighborhood.cpp @@ -1761,10 +1761,10 @@ void Neighborhood::pauseTimer() { } void Neighborhood::resumeTimer() { - // NOTE: Yes, this function calls pauseFuse! - // Looks like an original game bug, will need - // to investigate how this affects gameplay. - _eventTimer.pauseFuse(); + // NOTE: The original calls pauseFuse() here, which causes a bug with the robot + // in WSC on the catwalk, causing him never to come after you if you don't act + // against him. + _eventTimer.resumeFuse(); } bool Neighborhood::timerPaused() { diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.cpp b/engines/pegasus/neighborhood/norad/delta/globegame.cpp index 06e40c2b3a..1416c51c8d 100644 --- a/engines/pegasus/neighborhood/norad/delta/globegame.cpp +++ b/engines/pegasus/neighborhood/norad/delta/globegame.cpp @@ -64,6 +64,10 @@ void GlobeTracker::setTrackParameters(const Hotspot *trackSpot, GlobeTrackDirect _globeMovie->setSegment(start, start + kDurationPerRow); + // Clip new time so we don't go past the end of the segment + if (newTime >= start + kDurationPerRow) + newTime = start + kDurationPerRow - 1; + if (newTime != time) { _globeMovie->setTime(newTime); _globeMovie->redrawMovieWorld(); @@ -84,6 +88,10 @@ void GlobeTracker::setTrackParameters(const Hotspot *trackSpot, GlobeTrackDirect _globeMovie->setSegment(start, start + kDurationPerRow); + // Clip new time so we don't go past the end of the segment + if (newTime >= start + kDurationPerRow) + newTime = start + kDurationPerRow - 1; + if (newTime != time) { _globeMovie->setTime(newTime); _globeMovie->redrawMovieWorld(); @@ -621,6 +629,7 @@ void GlobeGame::receiveNotification(Notification *notification, const Notificati _monitorMovie.stop(); _monitorMovie.setSegment(0, _monitorMovie.getDuration()); _monitorMovie.setTime(kSplash2End * scale - 1); + _monitorMovie.redrawMovieWorld(); _monitorMovie.setFlags(0); _owner->requestDelay(1, 2, kFilterNoInput, 0); @@ -643,6 +652,7 @@ void GlobeGame::receiveNotification(Notification *notification, const Notificati _monitorMovie.stop(); _monitorMovie.setSegment(0, _monitorMovie.getDuration()); _monitorMovie.setTime(kNewLaunchSiloTime * scale); + _monitorMovie.redrawMovieWorld(); _owner->requestSpotSound(kNewLaunchSiloIn, kNewLaunchSiloOut, kFilterNoInput, kSpotSoundCompletedFlag); _gameState = kPlayingNewSilo1; diff --git a/engines/pegasus/neighborhood/norad/pressuredoor.cpp b/engines/pegasus/neighborhood/norad/pressuredoor.cpp index d1378567d3..a12e971d10 100644 --- a/engines/pegasus/neighborhood/norad/pressuredoor.cpp +++ b/engines/pegasus/neighborhood/norad/pressuredoor.cpp @@ -323,7 +323,8 @@ void PressureDoor::receiveNotification(Notification *notification, const Notific _robotState = kRobotDead; _levelsMovie.stop(); _levelsMovie.setSegment((kNormalSubRoomPressure + kPressureBase) * _levelsScale, - (GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale); + (GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale + 1); + _levelsMovie.setTime((GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale); _pressureCallBack.setCallBackFlag(kPressureDroppingFlag); _pressureCallBack.scheduleCallBack(kTriggerAtStart, 0, 0); _typeMovie.stop(); @@ -335,7 +336,7 @@ void PressureDoor::receiveNotification(Notification *notification, const Notific _downButton.setCurrentFrameIndex(1); _gameState = kGameOver; allowInput(false); - _levelsMovie.setRate(Common::Rational(0x5555, 0x10000) - 1); // Should match door tracker. + _levelsMovie.setRate(Common::Rational(-4, 3)); // Should match door tracker. break; case kRobotDead: allowInput(true); diff --git a/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp b/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp index 814d7717de..d62b069e46 100644 --- a/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp +++ b/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp @@ -125,6 +125,13 @@ void Prehistoric::setUpAIRules() { 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()) { AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Prehistoric/XP1NB", false); AILocationCondition *locCondition = new AILocationCondition(1); locCondition->addLocation(MakeRoomView(kPrehistoric16, kNorth)); @@ -159,11 +166,6 @@ void Prehistoric::setUpAIRules() { AITimerCondition *timerCondition = new AITimerCondition(kPrehistoricWarningTimeLimit, 1, true); rule = new AIRule(timerCondition, messageAction); g_AIArea->addAIRule(rule); - - messageAction = new AIPlayMessageAction("Images/AI/Prehistoric/XP25W", false); - AIHasItemCondition *hasLogCondition = new AIHasItemCondition(kHistoricalLog); - rule = new AIRule(hasLogCondition, messageAction); - g_AIArea->addAIRule(rule); } } } @@ -402,9 +404,10 @@ void Prehistoric::loadAmbientLoops() { switch (room) { case kPrehistoric02: // 1/4 volume. - if (GameState.getPrehistoricSeenTimeStream()) - loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 64); - break; + if (!GameState.getPrehistoricSeenTimeStream()) + break; + + // Fall through case kPrehistoric01: case kPrehistoric03: case kPrehistoric04: @@ -419,7 +422,10 @@ void Prehistoric::loadAmbientLoops() { case kPrehistoric19: case kPrehistoric20: // 1/4 volume. - loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 64); + if (_vm->isDVD()) // Updated sound for the DVD version + loadLoopSound1("Sounds/Prehistoric/P02SAL00.32k.AIFF", 64); + else + loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 64); break; case kPrehistoric08: case kPrehistoric10: @@ -429,11 +435,17 @@ void Prehistoric::loadAmbientLoops() { case kPrehistoric18: case kPrehistoric21: // 3/16 volume. - loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 48); + if (_vm->isDVD()) // Updated sound for the DVD version + loadLoopSound1("Sounds/Prehistoric/P02SAL00.32k.AIFF", 48); + else + loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 48); break; case kPrehistoric25: // 1/8 volume. - loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 32); + if (_vm->isDVD()) // Updated sound for the DVD version + loadLoopSound1("Sounds/Prehistoric/P02SAL00.32k.AIFF", 32); + else + loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 32); break; case kPrehistoric22: case kPrehistoric22North: @@ -470,19 +482,29 @@ void Prehistoric::loadAmbientLoops() { break; case kPrehistoric01: case kPrehistoric25: - loadLoopSound2("Sounds/Prehistoric/VolcLoop.22K.AIFF", 64); + if (_vm->isDVD()) + loadLoopSound2("Sounds/Prehistoric/VolcLoop.32K.AIFF", 64); + else + loadLoopSound2("Sounds/Prehistoric/VolcLoop.22K.AIFF", 64); break; case kPrehistoric18: - if (_privateFlags.getFlag(kPrehistoricPrivateExtendedBridgeFlag)) - loadLoopSound2("Sounds/Prehistoric/P18EAL00.22k.AIFF", 0x100, 0, 0); - else + if (_privateFlags.getFlag(kPrehistoricPrivateExtendedBridgeFlag)) { + if (_vm->isDVD()) // Updated sound for the DVD version + loadLoopSound2("Sounds/Prehistoric/P18EAL00.44K.aiff", 0x100, 0, 0); + else + loadLoopSound2("Sounds/Prehistoric/P18EAL00.22k.AIFF", 0x100, 0, 0); + } else { loadLoopSound2(""); + } break; case kPrehistoric23: case kPrehistoric24: case kPrehistoric22: case kPrehistoric22North: - loadLoopSound2("Sounds/Prehistoric/P24NAL00.22k.AIFF", 64); + if (_vm->isDVD()) // Updated sound for the DVD version + loadLoopSound2("Sounds/Prehistoric/P24NAL00.32k.AIFF", 64); + else + loadLoopSound2("Sounds/Prehistoric/P24NAL00.22k.AIFF", 64); break; } } @@ -575,7 +597,7 @@ Common::String Prehistoric::getEnvScanMovie() { Common::String movieName = Neighborhood::getEnvScanMovie(); if (movieName.empty()) { - if (!_vm->isDemo()) { + if (!_vm->isOldDemo()) { switch (GameState.getCurrentRoom()) { case kPrehistoric16: case kPrehistoric23: diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp index b598841b45..9b843da5d6 100644 --- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp +++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp @@ -622,6 +622,13 @@ void RipTimer::draw(const Common::Rect &updateRect) { } void RipTimer::timeChanged(const TimeValue newTime) { + // WORKAROUND: If the timer isn't running, don't run the following code. + // Fixes use of the code when it shouldn't be running (since this is an + // IdlerAnimation, this is called on useIdleTime() but this specific + // timer only makes sense when used as an actual timer). + if (!isRunning()) + return; + Common::Rect bounds; getBounds(bounds); diff --git a/engines/pegasus/neighborhood/wsc/wsc.cpp b/engines/pegasus/neighborhood/wsc/wsc.cpp index f3bf113333..50b7774da4 100644 --- a/engines/pegasus/neighborhood/wsc/wsc.cpp +++ b/engines/pegasus/neighborhood/wsc/wsc.cpp @@ -646,11 +646,13 @@ uint WSC::getNumHints() { return 1; break; case MakeRoomView(kWSC03, kNorth): - if (inSynthesizerGame() || (_vm->getEnergyDeathReason() == kDeathDidntStopPoison && - !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) && - !GameState.getWSCDesignedAntidote())) - return 3; - break; + // WORKAROUND: The original game is missing the first two hint movies and + // just plays nothing in its stead. We'll just return that we have one + // hint available. + if (inSynthesizerGame()) + return 1; + + // fall through case MakeRoomView(kWSC01, kNorth): case MakeRoomView(kWSC01, kSouth): case MakeRoomView(kWSC01, kEast): @@ -779,10 +781,12 @@ Common::String WSC::getHintMovie(uint hintNum) { } break; case MakeRoomView(kWSC03, kNorth): + // WORKAROUND: The original game is missing the first two hint movies and + // just plays nothing in its stead. We just make it the first hint. if (inSynthesizerGame()) - return Common::String::format("Images/AI/WSC/XW03NH%d", hintNum); + return "Images/AI/WSC/XW03NH3"; - return Common::String::format("Images/AI/WSC/XWPH%d", hintNum); + // fall through case MakeRoomView(kWSC01, kNorth): case MakeRoomView(kWSC01, kSouth): case MakeRoomView(kWSC01, kEast): diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index 81e8058628..463e81e52e 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -33,9 +33,11 @@ #include "common/textconsole.h" #include "common/translation.h" #include "common/random.h" +#include "backends/keymapper/keymapper.h" #include "base/plugins.h" #include "base/version.h" #include "gui/saveload.h" +#include "video/theora_decoder.h" #include "video/qt_decoder.h" #include "pegasus/console.h" @@ -151,6 +153,7 @@ Common::Error PegasusEngine::run() { } // Set up input + initKeymap(); InputHandler::setInputHandler(this); allowInput(true); @@ -237,6 +240,9 @@ bool PegasusEngine::detectOpeningClosingDirectory() { void PegasusEngine::createItems() { Common::SeekableReadStream *res = _resFork->getResource(MKTAG('N', 'I', 't', 'm'), 0x80); + if (!res) + error("Couldn't find neighborhood items resource"); + uint16 entryCount = res->readUint16BE(); for (uint16 i = 0; i < entryCount; i++) { @@ -614,7 +620,7 @@ void PegasusEngine::loadFromContinuePoint() { // Failure to load a continue point is fatal if (!_continuePoint) - error("Attempting to load from non-existant continue point"); + error("Attempting to load from non-existent continue point"); _continuePoint->seek(0); @@ -637,9 +643,15 @@ void PegasusEngine::writeContinueStream(Common::WriteStream *stream) { delete[] data; } +Common::StringArray PegasusEngine::listSaveFiles() { + Common::StringArray fileNames = g_system->getSavefileManager()->listSavefiles("pegasus-*.sav"); + Common::sort(fileNames.begin(), fileNames.end()); + return fileNames; +} + Common::Error PegasusEngine::loadGameState(int slot) { - Common::StringArray filenames = _saveFileMan->listSavefiles("pegasus-*.sav"); - Common::InSaveFile *loadFile = _saveFileMan->openForLoading(filenames[slot]); + Common::StringArray fileNames = listSaveFiles(); + Common::InSaveFile *loadFile = _saveFileMan->openForLoading(fileNames[slot]); if (!loadFile) return Common::kUnknownError; @@ -649,7 +661,23 @@ Common::Error PegasusEngine::loadGameState(int slot) { return valid ? Common::kNoError : Common::kUnknownError; } +static bool isValidSaveFileChar(char c) { + // Limit it to letters, digits, and a few other characters that should be safe + return Common::isAlnum(c) || c == ' ' || c == '_' || c == '+' || c == '-' || c == '.'; +} + +static bool isValidSaveFileName(const Common::String &desc) { + for (uint32 i = 0; i < desc.size(); i++) + if (!isValidSaveFileChar(desc[i])) + return false; + + return true; +} + Common::Error PegasusEngine::saveGameState(int slot, const Common::String &desc) { + if (!isValidSaveFileName(desc)) + return Common::Error(Common::kCreatingFileFailed, _("Invalid save file name")); + Common::String output = Common::String::format("pegasus-%s.sav", desc.c_str()); Common::OutSaveFile *saveFile = _saveFileMan->openForSaving(output, false); if (!saveFile) @@ -667,19 +695,35 @@ void PegasusEngine::receiveNotification(Notification *notification, const Notifi case kGameStartingFlag: { useMenu(new MainMenu()); - if (!isDemo()) { + if (isDemo()) { + // Start playing the music earlier here + ((MainMenu *)_gameMenu)->startMainMenuLoop(); + + // Show the intro splash screen + showTempScreen("Images/Demo/NGsplashScrn.pict"); + + if (shouldQuit()) { + useMenu(0); + return; + } + + // Fade out and then back in with the main menu + _gfx->doFadeOutSync(); + _gfx->updateDisplay(); + _gfx->doFadeInSync(); + } else { + // Display the intro runIntro(); resetIntroTimer(); - } else { - showTempScreen("Images/Demo/NGsplashScrn.pict"); - } - if (shouldQuit()) - return; + if (shouldQuit()) + return; - _gfx->invalRect(Common::Rect(0, 0, 640, 480)); - _gfx->updateDisplay(); - ((MainMenu *)_gameMenu)->startMainMenuLoop(); + // Now display the main menu + _gfx->invalRect(Common::Rect(0, 0, 640, 480)); + _gfx->updateDisplay(); + ((MainMenu *)_gameMenu)->startMainMenuLoop(); + } break; } case kPlayerDiedFlag: @@ -818,7 +862,8 @@ void PegasusEngine::doGameMenuCommand(const GameMenuCommand command) { case kMenuCmdDeathQuitDemo: if (isDemo()) showTempScreen("Images/Demo/NGquitScrn.pict"); - _system->quit(); + _gfx->doFadeOutSync(); + quitGame(); break; case kMenuCmdOverview: stopIntroTimer(); @@ -1132,10 +1177,15 @@ void PegasusEngine::doInterfaceOverview() { controllerHighlight.hide(); } - overviewText.setTime(time * 3 + 2, 15); - overviewText.redrawMovieWorld(); + // The original just constantly redraws the frame, but that + // doesn't actually need to be done. + if ((time * 3 + 2) * 40 != overviewText.getTime()) { + overviewText.setTime(time * 3 + 2, 15); + overviewText.redrawMovieWorld(); + } refreshDisplay(); + _system->delayMillis(10); } if (shouldQuit()) @@ -1313,8 +1363,14 @@ bool PegasusEngine::playMovieScaled(Video::VideoDecoder *video, uint16 x, uint16 if (video->needsUpdate()) { const Graphics::Surface *frame = video->decodeNextFrame(); - if (frame) - drawScaledFrame(frame, x, y); + if (frame) { + 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->updateScreen(); + } + } } Input input; @@ -1338,6 +1394,19 @@ void PegasusEngine::die(const DeathReason reason) { } void PegasusEngine::doDeath() { +#ifdef USE_THEORADEC + // The updated demo has a new Theora video for the closing + if (isDVDDemo() && _deathReason == kPlayerWonGame) { + Video::TheoraDecoder decoder; + + if (decoder.loadFile("Images/Demo TSA/DemoClosing.ogg")) { + throwAwayEverything(); + decoder.start(); + playMovieScaled(&decoder, 0, 0); + } + } +#endif + _gfx->doFadeOutSync(); throwAwayEverything(); useMenu(new DeathMenu(_deathReason)); @@ -1420,6 +1489,10 @@ void PegasusEngine::switchGameMode(const GameMode newMode, const GameMode oldMod } bool PegasusEngine::canSwitchGameMode(const GameMode newMode, const GameMode oldMode) { + // WORKAROUND: Don't allow game mode switches when the interface is not set up. + // Prevents segfaults when pressing 'i' when in the space chase. + if (!g_interface) + return false; if (newMode == kModeInventoryPick && oldMode == kModeBiochipPick) return false; if (newMode == kModeBiochipPick && oldMode == kModeInventoryPick) @@ -1538,6 +1611,18 @@ void PegasusEngine::startNewGame() { GameState.setPrehistoricSeenFlyer2(false); GameState.setPrehistoricSeenBridgeZoom(false); GameState.setPrehistoricBreakerThrown(false); + +#ifdef USE_THEORADEC + if (isDVD()) { + // The updated demo has a new Theora video for the closing + Video::TheoraDecoder decoder; + + if (decoder.loadFile("Images/Demo TSA/DemoOpening.ogg")) { + decoder.start(); + playMovieScaled(&decoder, 0, 0); + } + } +#endif } else { jumpToNewEnvironment(kCaldoriaID, kCaldoria00, kEast); } @@ -2343,4 +2428,41 @@ uint PegasusEngine::getNeighborhoodCD(const NeighborhoodID neighborhood) const { return 1; } +void PegasusEngine::initKeymap() { +#ifdef ENABLE_KEYMAPPER + static const char *const kKeymapName = "pegasus"; + Common::Keymapper *const mapper = _eventMan->getKeymapper(); + + // Do not try to recreate same keymap over again + if (mapper->getKeymap(kKeymapName) != 0) + return; + + Common::Keymap *const engineKeyMap = new Common::Keymap(kKeymapName); + + // Since the game has multiple built-in keys for each of these anyway, + // this just attempts to remap one of them. + const Common::KeyActionEntry keyActionEntries[] = { + { Common::KEYCODE_UP, "UP", _("Up/Zoom In/Move Forward/Open Doors") }, + { Common::KEYCODE_DOWN, "DWN", _("Down/Zoom Out") }, + { Common::KEYCODE_LEFT, "TL", _("Turn Left") }, + { Common::KEYCODE_RIGHT, "TR", _("Turn Right") }, + { Common::KEYCODE_BACKQUOTE, "TIV", _("Display/Hide Inventory Tray") }, + { Common::KEYCODE_BACKSPACE, "TBI", _("Display/Hide Biochip Tray") }, + { Common::KEYCODE_RETURN, "ENT", _("Action/Select") }, + { 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) + }; + + for (uint i = 0; i < ARRAYSIZE(keyActionEntries); i++) { + Common::Action *const act = new Common::Action(engineKeyMap, keyActionEntries[i].id, keyActionEntries[i].description); + act->addKeyEvent(keyActionEntries[i].ks); + } + + mapper->addGameKeymap(engineKeyMap); + mapper->pushKeymap(kKeymapName, true); +#endif +} + } // End of namespace Pegasus diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h index 2a8ba22470..07e6d8f761 100644 --- a/engines/pegasus/pegasus.h +++ b/engines/pegasus/pegasus.h @@ -30,6 +30,7 @@ #include "common/macresman.h" #include "common/rect.h" #include "common/scummsys.h" +#include "common/str-array.h" #include "common/system.h" #include "common/util.h" @@ -94,6 +95,10 @@ public: // Misc. bool isDemo() const; + bool isDVD() const; + bool isDVDDemo() const; + bool isOldDemo() const; + bool isWindows() const; void addIdler(Idler *idler); void removeIdler(Idler *idler); void addTimeBase(TimeBase *timeBase); @@ -195,6 +200,7 @@ public: bool saveRequested() const { return _saveRequested; } void requestLoad() { _loadRequested = true; } bool loadRequested() const { return _loadRequested; } + static Common::StringArray listSaveFiles(); protected: Common::Error run(); @@ -265,6 +271,7 @@ private: void doSubChase(); uint getNeighborhoodCD(const NeighborhoodID neighborhood) const; uint _currentCD; + void initKeymap(); // Menu GameMenu *_gameMenu; diff --git a/engines/pegasus/sound.cpp b/engines/pegasus/sound.cpp index bf15858e80..5b437b81d4 100644 --- a/engines/pegasus/sound.cpp +++ b/engines/pegasus/sound.cpp @@ -87,6 +87,9 @@ void Sound::playSound() { stopSound(); + // Make sure the sound is back at the beginning before we play it + _stream->rewind(); + if (_fader) setVolume(_fader->getFaderValue()); diff --git a/engines/pegasus/surface.cpp b/engines/pegasus/surface.cpp index e9e0958f9d..cdcb3c6e79 100644 --- a/engines/pegasus/surface.cpp +++ b/engines/pegasus/surface.cpp @@ -85,7 +85,8 @@ void Surface::getImageFromPICTFile(const Common::String &fileName) { if (!pict.open(fileName)) error("Could not open picture '%s'", fileName.c_str()); - getImageFromPICTStream(&pict); + if (!getImageFromPICTStream(&pict)) + error("Failed to load PICT '%s'", fileName.c_str()); } void Surface::getImageFromPICTResource(Common::MacResManager *resFork, uint16 id) { @@ -93,19 +94,22 @@ void Surface::getImageFromPICTResource(Common::MacResManager *resFork, uint16 id if (!res) error("Could not open PICT resource %d from '%s'", id, resFork->getBaseFileName().c_str()); - getImageFromPICTStream(res); + if (!getImageFromPICTStream(res)) + error("Failed to load PICT resource %d from '%s'", id, resFork->getBaseFileName().c_str()); + delete res; } -void Surface::getImageFromPICTStream(Common::SeekableReadStream *stream) { +bool Surface::getImageFromPICTStream(Common::SeekableReadStream *stream) { Graphics::PICTDecoder pict; if (!pict.loadStream(*stream)) - error("Failed to load PICT image"); + return false; _surface = pict.getSurface()->convertTo(g_system->getScreenFormat(), pict.getPalette()); _ownsSurface = true; _bounds = Common::Rect(0, 0, _surface->w, _surface->h); + return true; } void Surface::getImageFromMovieFrame(Video::VideoDecoder *video, TimeValue time) { diff --git a/engines/pegasus/surface.h b/engines/pegasus/surface.h index 4588146fb4..47e3ef538c 100644 --- a/engines/pegasus/surface.h +++ b/engines/pegasus/surface.h @@ -84,7 +84,7 @@ protected: Common::Rect _bounds; private: - void getImageFromPICTStream(Common::SeekableReadStream *stream); + bool getImageFromPICTStream(Common::SeekableReadStream *stream); uint32 getGlowColor(uint32 color) const; bool isTransparent(uint32 color) const; diff --git a/engines/pegasus/timers.cpp b/engines/pegasus/timers.cpp index 3b875038cc..50cc9bc6d8 100644 --- a/engines/pegasus/timers.cpp +++ b/engines/pegasus/timers.cpp @@ -73,13 +73,8 @@ TimeBase::TimeBase(const TimeScale preferredScale) { } TimeBase::~TimeBase() { - if (_master) - _master->_slaves.remove(this); - ((PegasusEngine *)g_engine)->removeTimeBase(this); disposeAllCallBacks(); - - // TODO: Remove slaves? Make them remove themselves? } void TimeBase::setTime(const TimeValue time, const TimeScale scale) { @@ -88,20 +83,23 @@ void TimeBase::setTime(const TimeValue time, const TimeScale scale) { } TimeValue TimeBase::getTime(const TimeScale scale) { + // HACK: Emulate the master TimeBase code here for the one case that needs it in the + // game. Note that none of the master TimeBase code in this file should actually be + // used as a reference for anything ever. + if (_master) + return _master->getTime(scale); + return _time.getNumerator() * ((scale == 0) ? _preferredScale : scale) / _time.getDenominator(); } void TimeBase::setRate(const Common::Rational rate) { _rate = rate; + _lastMillis = 0; if (_rate == 0) _paused = false; } -Common::Rational TimeBase::getEffectiveRate() const { - return _rate * ((_master == 0) ? 1 : _master->getEffectiveRate()); -} - void TimeBase::start() { if (_paused) _pausedRate = 1; @@ -192,18 +190,15 @@ TimeValue TimeBase::getDuration(const TimeScale scale) const { } void TimeBase::setMasterTimeBase(TimeBase *tb) { - // TODO: We're just ignoring the master (except for effective rate) - // for now to simplify things - if (_master) - _master->_slaves.remove(this); - _master = tb; - - if (_master) - _master->_slaves.push_back(this); } void TimeBase::updateTime() { + if (_master) { + _master->updateTime(); + return; + } + if (_lastMillis == 0) { _lastMillis = g_system->getMillis(); } else { @@ -211,7 +206,7 @@ void TimeBase::updateTime() { if (_lastMillis == curTime) // No change return; - _time += Common::Rational(curTime - _lastMillis, 1000) * getEffectiveRate(); + _time += Common::Rational(curTime - _lastMillis, 1000) * getRate(); _lastMillis = curTime; } } @@ -233,8 +228,6 @@ void TimeBase::checkCallBacks() { else if (_time <= startTime) _time = startTime; - // TODO: Update the slaves? - Common::Rational time = Common::Rational(getTime(), getScale()); // Check if we've triggered any callbacks diff --git a/engines/pegasus/timers.h b/engines/pegasus/timers.h index bcdca6e860..944930d21b 100644 --- a/engines/pegasus/timers.h +++ b/engines/pegasus/timers.h @@ -26,7 +26,6 @@ #ifndef PEGASUS_TIMERS_H #define PEGASUS_TIMERS_H -#include "common/list.h" #include "common/rational.h" #include "common/func.h" @@ -122,11 +121,6 @@ protected: Common::Rational _time; uint32 _lastMillis, _pauseStart; - -private: - Common::Rational getEffectiveRate() const; - - Common::List<TimeBase *> _slaves; }; // Type passed to initCallBack() |