diff options
Diffstat (limited to 'engines')
-rwxr-xr-x | engines/pegasus/constants.h | 36 | ||||
-rwxr-xr-x | engines/pegasus/menu.cpp | 331 | ||||
-rwxr-xr-x | engines/pegasus/menu.h | 38 | ||||
-rw-r--r-- | engines/pegasus/pegasus.cpp | 92 | ||||
-rw-r--r-- | engines/pegasus/pegasus.h | 13 |
5 files changed, 510 insertions, 0 deletions
diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h index 89fdeefad2..8d2a95bcd2 100755 --- a/engines/pegasus/constants.h +++ b/engines/pegasus/constants.h @@ -519,6 +519,42 @@ const tHotSpotFlags kJMPClickingSpotFlags = kClickSpotFlag | kOpticalBiochipSpotFlag | kAirMaskSpotFlag; +const tMM32BitID kMainMenuID = 1; +const tMM32BitID kPauseMenuID = 2; +const tMM32BitID kCreditsMenuID = 3; +const tMM32BitID kDeathMenuID = 4; + +///////////////////////////////////////////// +// +// Menu commands. + +const tGameMenuCommand kMenuCmdOverview = kMenuCmdNoCommand + 1; +const tGameMenuCommand kMenuCmdStartAdventure = kMenuCmdOverview + 1; +const tGameMenuCommand kMenuCmdStartWalkthrough = kMenuCmdStartAdventure + 1; +const tGameMenuCommand kMenuCmdRestore = kMenuCmdStartWalkthrough + 1; +const tGameMenuCommand kMenuCmdCredits = kMenuCmdRestore + 1; +const tGameMenuCommand kMenuCmdQuit = kMenuCmdCredits + 1; + +const tGameMenuCommand kMenuCmdDeathContinue = kMenuCmdQuit + 1; + +const tGameMenuCommand kMenuCmdDeathQuitDemo = kMenuCmdDeathContinue + 1; +const tGameMenuCommand kMenuCmdDeathMainMenuDemo = kMenuCmdDeathQuitDemo + 1; + +const tGameMenuCommand kMenuCmdDeathRestore = kMenuCmdDeathContinue + 1; +const tGameMenuCommand kMenuCmdDeathMainMenu = kMenuCmdDeathRestore + 1; + +const tGameMenuCommand kMenuCmdPauseSave = kMenuCmdDeathMainMenu + 1; +const tGameMenuCommand kMenuCmdPauseContinue = kMenuCmdPauseSave + 1; +const tGameMenuCommand kMenuCmdPauseRestore = kMenuCmdPauseContinue + 1; +const tGameMenuCommand kMenuCmdPauseQuit = kMenuCmdPauseRestore + 1; + +const tGameMenuCommand kMenuCmdCreditsMainMenu = kMenuCmdPauseQuit + 1; + +const tGameMenuCommand kMenuCmdCancelRestart = kMenuCmdCreditsMainMenu + 1; +const tGameMenuCommand kMenuCmdEjectRestart = kMenuCmdCancelRestart + 1; + +const TimeValue kMenuButtonHiliteTime = 20; +const TimeScale kMenuButtonHiliteScale = kSixtyTicksPerSecond; } // End of namespace Pegasus diff --git a/engines/pegasus/menu.cpp b/engines/pegasus/menu.cpp index f7ffbea15f..335cfea6da 100755 --- a/engines/pegasus/menu.cpp +++ b/engines/pegasus/menu.cpp @@ -41,4 +41,335 @@ void GameMenu::restorePreviousHandler() { InputHandler::setInputHandler(_previousHandler); } +enum { + kMainMenuStartDemo = 0, + kMainMenuCreditsDemo, + kMainMenuQuitDemo, + kFirstSelectionDemo = kMainMenuStartDemo, + kLastSelectionDemo = kMainMenuQuitDemo, + + kMainMenuOverview = 0, + kMainMenuStart, + kMainMenuRestore, + kMainMenuDifficulty, + kMainMenuCredits, + kMainMenuQuit, + kFirstSelection = kMainMenuOverview, + kLastSelection = kMainMenuQuit +}; + +static const tCoordType kStartLeftDemo = 44; +static const tCoordType kStartTopDemo = 336; + +static const tCoordType kStartSelectLeftDemo = 40; +static const tCoordType kStartSelectTopDemo = 331; + +static const tCoordType kCreditsLeftDemo = 44; +static const tCoordType kCreditsTopDemo = 372; + +static const tCoordType kCreditsSelectLeftDemo = 40; +static const tCoordType kCreditsSelectTopDemo = 367; + +static const tCoordType kMainMenuQuitLeftDemo = 32; +static const tCoordType kMainMenuQuitTopDemo = 412; + +static const tCoordType kMainMenuQuitSelectLeftDemo = 28; +static const tCoordType kMainMenuQuitSelectTopDemo = 408; + +static const tCoordType kOverviewLeft = 200; +static const tCoordType kOverviewTop = 208; + +static const tCoordType kOverviewSelectLeft = 152; +static const tCoordType kOverviewSelectTop = 204; + +static const tCoordType kStartLeft = 212; +static const tCoordType kStartTop = 256; + +static const tCoordType kStartSelectLeft = 152; +static const tCoordType kStartSelectTop = 252; + +static const tCoordType kRestoreLeft = 212; +static const tCoordType kRestoreTop = 296; + +static const tCoordType kRestoreSelectLeft = 152; +static const tCoordType kRestoreSelectTop = 292; + +static const tCoordType kDifficultyLeft = 320; +static const tCoordType kDifficultyTop = 340; + +static const tCoordType kDifficultySelectLeft = 152; +static const tCoordType kDifficultySelectTop = 336; + +static const tCoordType kCreditsLeft = 212; +static const tCoordType kCreditsTop = 388; + +static const tCoordType kCreditsSelectLeft = 152; +static const tCoordType kCreditsSelectTop = 384; + +static const tCoordType kMainMenuQuitLeft = 212; +static const tCoordType kMainMenuQuitTop = 428; + +static const tCoordType kMainMenuQuitSelectLeft = 152; +static const tCoordType kMainMenuQuitSelectTop = 424; + +// Never set the current input handler to the MainMenu. +MainMenu::MainMenu() : GameMenu(kMainMenuID), _menuBackground(0), _overviewButton(0), + _restoreButton(0), _adventureButton(0), _walkthroughButton(0), _startButton(0), + _creditsButton(0), _quitButton(0), _largeSelect(0), _smallSelect(0) { + + bool isDemo = ((PegasusEngine *)g_engine)->isDemo(); + + if (isDemo) + _menuBackground.initFromPICTFile("Images/Demo/DemoMenu.pict"); + else + _menuBackground.initFromPICTFile("Images/Main Menu/MainMenu.mac"); + _menuBackground.setDisplayOrder(0); + _menuBackground.startDisplaying(); + _menuBackground.show(); + + if (!isDemo) { + _overviewButton.initFromPICTFile("Images/Main Menu/pbOvervi.pict"); + _overviewButton.setDisplayOrder(1); + _overviewButton.moveElementTo(kOverviewLeft, kOverviewTop); + _overviewButton.startDisplaying(); + + _restoreButton.initFromPICTFile("Images/Main Menu/pbRestor.pict"); + _restoreButton.setDisplayOrder(1); + _restoreButton.moveElementTo(kRestoreLeft, kRestoreTop); + _restoreButton.startDisplaying(); + + _adventureButton.initFromPICTFile("Images/Main Menu/BtnAdv.pict"); + _adventureButton.setDisplayOrder(1); + _adventureButton.moveElementTo(kDifficultyLeft, kDifficultyTop); + _adventureButton.startDisplaying(); + + _walkthroughButton.initFromPICTFile("Images/Main Menu/BtnWlk.pict"); + _walkthroughButton.setDisplayOrder(1); + _walkthroughButton.moveElementTo(kDifficultyLeft, kDifficultyTop); + _walkthroughButton.startDisplaying(); + } + + if (isDemo) + _startButton.initFromPICTFile("Images/Demo/Start.pict"); + else + _startButton.initFromPICTFile("Images/Main Menu/pbStart.pict"); + _startButton.setDisplayOrder(1); + _startButton.moveElementTo(isDemo ? kStartLeftDemo : kStartLeft, isDemo ? kStartTopDemo : kStartTop); + _startButton.startDisplaying(); + + if (isDemo) + _creditsButton.initFromPICTFile("Images/Demo/Credits.pict"); + else + _creditsButton.initFromPICTFile("Images/Main Menu/pbCredit.pict"); + _creditsButton.setDisplayOrder(1); + _creditsButton.moveElementTo(isDemo ? kCreditsLeftDemo : kCreditsLeft, isDemo ? kCreditsTopDemo : kCreditsTop); + _creditsButton.startDisplaying(); + + if (isDemo) + _quitButton.initFromPICTFile("Images/Demo/Quit.pict"); + else + _quitButton.initFromPICTFile("Images/Main Menu/pbQuit.pict"); + _quitButton.setDisplayOrder(1); + _quitButton.moveElementTo(isDemo ? kMainMenuQuitLeftDemo : kMainMenuQuitLeft, isDemo ? kMainMenuQuitTopDemo : kMainMenuQuitTop); + _quitButton.startDisplaying(); + + if (isDemo) + _largeSelect.initFromPICTFile("Images/Demo/SelectL.pict", true); + else + _largeSelect.initFromPICTFile("Images/Main Menu/SelectL.pict", true); + _largeSelect.setDisplayOrder(1); + _largeSelect.startDisplaying(); + + if (isDemo) + _smallSelect.initFromPICTFile("Images/Demo/SelectS.pict", true); + else + _smallSelect.initFromPICTFile("Images/Main Menu/SelectS.pict", true); + _smallSelect.setDisplayOrder(1); + _smallSelect.startDisplaying(); + + _menuSelection = isDemo ? kFirstSelectionDemo : kFirstSelection; + + _adventureMode = true; + + //_menuLoop.attachFader(&_menuFader); + _menuLoop.initFromAIFFFile("Sounds/Main Menu.aiff"); + + updateDisplay(); +} + +MainMenu::~MainMenu() { + if (_menuLoop.isPlaying()) + stopMainMenuLoop(); +} + +void MainMenu::startMainMenuLoop() { + FaderMoveSpec spec; + + _menuLoop.loopSound(); + spec.makeTwoKnotFaderSpec(30, 0, 0, 30, 255); + //_menuFader.startFaderSync(spec); +} + +void MainMenu::stopMainMenuLoop() { + FaderMoveSpec spec; + + spec.makeTwoKnotFaderSpec(30, 0, 255, 30, 0); + //_menuFader.startFaderSync(spec); + _menuLoop.stopSound(); +} + +void MainMenu::handleInput(const Input &input, const Hotspot *cursorSpot) { + PegasusEngine *vm = (PegasusEngine *)g_engine; + bool isDemo = vm->isDemo(); + + if (input.upButtonDown()) { + if (_menuSelection > (isDemo ? kFirstSelectionDemo : kFirstSelection)) { + _menuSelection--; + updateDisplay(); + } + } else if (input.downButtonDown()) { + if (_menuSelection < (isDemo ? kLastSelectionDemo : kLastSelection)) { + _menuSelection++; + updateDisplay(); + } + } else if (!isDemo && (input.leftButtonDown() || input.rightButtonDown())) { + if (_menuSelection == kMainMenuDifficulty) { + _adventureMode = !_adventureMode; + updateDisplay(); + } + } else if (JMPPPInput::isMenuButtonPressInput(input)) { + if (isDemo) { + switch (_menuSelection) { + case kMainMenuCreditsDemo: + _creditsButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _creditsButton.hide(); + setLastCommand(kMenuCmdCredits); + break; + case kMainMenuStartDemo: + _startButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _startButton.hide(); + setLastCommand(kMenuCmdStartAdventure); + break; + case kMainMenuQuitDemo: + _quitButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _quitButton.hide(); + setLastCommand(kMenuCmdQuit); + break; + } + } else { + switch (_menuSelection) { + case kMainMenuOverview: + _overviewButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _overviewButton.hide(); + setLastCommand(kMenuCmdOverview); + break; + case kMainMenuRestore: + _restoreButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _restoreButton.hide(); + setLastCommand(kMenuCmdRestore); + break; + case kMainMenuCredits: + _creditsButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _creditsButton.hide(); + setLastCommand(kMenuCmdCredits); + break; + case kMainMenuStart: + _startButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _startButton.hide(); + if (_adventureMode) + setLastCommand(kMenuCmdStartAdventure); + else + setLastCommand(kMenuCmdStartWalkthrough); + break; + case kMainMenuDifficulty: + _adventureMode = !_adventureMode; + updateDisplay(); + break; + case kMainMenuQuit: + _quitButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _quitButton.hide(); + setLastCommand(kMenuCmdQuit); + break; + } + } + } + + InputHandler::handleInput(input, cursorSpot); +} + +void MainMenu::updateDisplay() { + PegasusEngine *vm = (PegasusEngine *)g_engine; + + if (vm->isDemo()) { + switch (_menuSelection) { + case kMainMenuStartDemo: + _smallSelect.moveElementTo(kStartSelectLeftDemo, kStartSelectTopDemo); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kMainMenuCreditsDemo: + _smallSelect.moveElementTo(kCreditsSelectLeftDemo, kCreditsSelectTopDemo); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kMainMenuQuitDemo: + _largeSelect.moveElementTo(kMainMenuQuitSelectLeftDemo, kMainMenuQuitSelectTopDemo); + _largeSelect.show(); + _smallSelect.hide(); + break; + } + } else { + switch (_menuSelection) { + case kMainMenuOverview: + _largeSelect.moveElementTo(kOverviewSelectLeft, kOverviewSelectTop); + _largeSelect.show(); + _smallSelect.hide(); + break; + case kMainMenuRestore: + _smallSelect.moveElementTo(kRestoreSelectLeft, kRestoreSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kMainMenuDifficulty: + if (_adventureMode) { + _adventureButton.show(); + _walkthroughButton.hide(); + } else { + _walkthroughButton.show(); + _adventureButton.hide(); + } + + _largeSelect.moveElementTo(kDifficultySelectLeft, kDifficultySelectTop); + _largeSelect.show(); + _smallSelect.hide(); + break; + case kMainMenuStart: + _smallSelect.moveElementTo(kStartSelectLeft, kStartSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kMainMenuCredits: + _smallSelect.moveElementTo(kCreditsSelectLeft, kCreditsSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kMainMenuQuit: + _smallSelect.moveElementTo(kMainMenuQuitSelectLeft, kMainMenuQuitSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + } + + vm->resetIntroTimer(); + } +} + } // End of namespace Pegasus diff --git a/engines/pegasus/menu.h b/engines/pegasus/menu.h index ecb751aec9..24e3785c3a 100755 --- a/engines/pegasus/menu.h +++ b/engines/pegasus/menu.h @@ -27,7 +27,10 @@ #define PEGASUS_MENU_H #include "pegasus/constants.h" +#include "pegasus/fader.h" #include "pegasus/input.h" +#include "pegasus/sound.h" +#include "pegasus/surface.h" #include "pegasus/util.h" namespace Pegasus { @@ -50,6 +53,41 @@ protected: tGameMenuCommand _lastCommand; }; +class Hotspot; + +class MainMenu : public GameMenu { +public: + MainMenu(); + virtual ~MainMenu(); + + virtual void handleInput(const Input &input, const Hotspot *); + void startMainMenuLoop(); + void stopMainMenuLoop(); + +protected: + void updateDisplay(); + + uint32 _menuSelection; + + // Full and Demo + Picture _menuBackground; + Picture _startButton; + Picture _creditsButton; + Picture _quitButton; + Picture _largeSelect; + Picture _smallSelect; + + // Full only + bool _adventureMode; + Picture _overviewButton; + Picture _restoreButton; + Picture _adventureButton; + Picture _walkthroughButton; + + Sound _menuLoop; + SoundFader _menuFader; +}; + } // End of namespace Pegasus #endif diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index 08ff821835..c79d519fb5 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -36,6 +36,7 @@ #include "pegasus/console.h" #include "pegasus/cursor.h" #include "pegasus/gamestate.h" +#include "pegasus/menu.h" #include "pegasus/movie.h" #include "pegasus/pegasus.h" #include "pegasus/timers.h" @@ -49,6 +50,7 @@ PegasusEngine::PegasusEngine(OSystem *syst, const PegasusGameDescription *gamede _shellNotification(kJMPDCShellNotificationID, this), _returnHotspot(kInfoReturnSpotID) { _continuePoint = 0; _saveAllowed = _loadAllowed = true; + _gameMenu = 0; } PegasusEngine::~PegasusEngine() { @@ -57,6 +59,7 @@ PegasusEngine::~PegasusEngine() { delete _console; delete _cursor; delete _continuePoint; + delete _gameMenu; } Common::Error PegasusEngine::run() { @@ -483,6 +486,14 @@ void PegasusEngine::receiveNotification(Notification *notification, const tNotif #else if (!isDemo()) runIntro(); + + if (shouldQuit()) + return; + + useMenu(new MainMenu()); + _gfx->invalRect(Common::Rect(0, 0, 640, 480)); + _gfx->updateDisplay(); + ((MainMenu *)_gameMenu)->startMainMenuLoop(); #endif break; } @@ -497,4 +508,85 @@ void PegasusEngine::checkCallBacks() { (*it)->checkCallBacks(); } +void PegasusEngine::resetIntroTimer() { + // TODO +} + +void PegasusEngine::delayShell(TimeValue time, TimeScale scale) { + if (time == 0 || scale == 0) + return; + + uint32 startTime = g_system->getMillis(); + uint32 timeInMillis = time * 1000 / scale; + + while (g_system->getMillis() < startTime + timeInMillis) { + checkCallBacks(); + _gfx->updateDisplay(); + } +} + +void PegasusEngine::useMenu(GameMenu *newMenu) { + if (_gameMenu) { + _gameMenu->restorePreviousHandler(); + delete _gameMenu; + } + + _gameMenu = newMenu; + + if (_gameMenu) + _gameMenu->becomeCurrentHandler(); +} + +bool PegasusEngine::checkGameMenu() { + tGameMenuCommand command = kMenuCmdNoCommand; + + if (_gameMenu) { + command = _gameMenu->getLastCommand(); + if (command != kMenuCmdNoCommand) { + _gameMenu->clearLastCommand(); + doGameMenuCommand(command); + } + } + + return command != kMenuCmdNoCommand; +} + +void PegasusEngine::doGameMenuCommand(const tGameMenuCommand command) { + switch (command) { + case kMenuCmdStartAdventure: + GameState.setWalkthroughMode(false); + error("Start new game (adventure mode)"); + break; + case kMenuCmdCredits: + error("Show credits"); + break; + case kMenuCmdQuit: + _system->quit(); + break; + case kMenuCmdOverview: + error("Show overview"); + break; + case kMenuCmdStartWalkthrough: + GameState.setWalkthroughMode(true); + error("Start new game (walkthrough mode)"); + break; + case kMenuCmdRestore: + error("Load game"); + break; + case kMenuCmdNoCommand: + break; + default: + error("Unknown menu command %d", command); + } +} + +void PegasusEngine::handleInput(const Input &input, const Hotspot *cursorSpot) { + if (!checkGameMenu()) + ; // TODO: Other input + + // TODO: Quit request + // TODO: Save request + // TODO: Load request +} + } // End of namespace Pegasus diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h index 3a99ddb823..e3965e6a75 100644 --- a/engines/pegasus/pegasus.h +++ b/engines/pegasus/pegasus.h @@ -52,6 +52,7 @@ class GraphicsManager; class Idler; class Cursor; class TimeBase; +class GameMenu; class PegasusEngine : public ::Engine, public InputHandler, public NotificationManager { friend class InputHandler; @@ -73,6 +74,10 @@ public: GraphicsManager *_gfx; Common::MacResManager *_resFork; + // Menu + void useMenu(GameMenu *menu); + bool checkGameMenu(); + // Misc. bool isDemo() const; void addIdler(Idler *idler); @@ -81,6 +86,8 @@ public: void removeTimeBase(TimeBase *timeBase); void swapSaveAllowed(bool allow) { _saveAllowed = allow; } void swapLoadAllowed(bool allow) { _loadAllowed = allow; } + void delayShell(TimeValue time, TimeScale scale); + void resetIntroTimer(); protected: Common::Error run(); @@ -90,6 +97,8 @@ protected: Notification _shellNotification; virtual void receiveNotification(Notification *notification, const tNotificationFlags flags); + void handleInput(const Input &input, const Hotspot *cursorSpot); + private: // Console PegasusConsole *_console; @@ -124,6 +133,10 @@ private: // Misc. Hotspot _returnHotspot; void showLoadDialog(); + + // Menu + GameMenu *_gameMenu; + void doGameMenuCommand(const tGameMenuCommand); }; } // End of namespace Pegasus |