diff options
Diffstat (limited to 'engines/pegasus/menu.cpp')
-rw-r--r-- | engines/pegasus/menu.cpp | 1219 |
1 files changed, 1219 insertions, 0 deletions
diff --git a/engines/pegasus/menu.cpp b/engines/pegasus/menu.cpp new file mode 100644 index 0000000000..deaa460188 --- /dev/null +++ b/engines/pegasus/menu.cpp @@ -0,0 +1,1219 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "pegasus/gamestate.h" +#include "pegasus/menu.h" +#include "pegasus/pegasus.h" +#include "pegasus/scoring.h" + +namespace Pegasus { + +GameMenu::GameMenu(const uint32 id) : IDObject(id), InputHandler((InputHandler *)((PegasusEngine *)g_engine)) { + _previousHandler = 0; + _lastCommand = kMenuCmdNoCommand; +} + +void GameMenu::becomeCurrentHandler() { + _previousHandler = InputHandler::setInputHandler(this); +} + +void GameMenu::restorePreviousHandler() { + InputHandler::setInputHandler(_previousHandler); +} + +void GameMenu::drawScore(GameScoreType score, GameScoreType total, const Common::Rect &scoreBounds, Surface *numbers) { + CoordType x = scoreBounds.right; + drawNumber(total, x, scoreBounds.top, numbers); + + x -= 12; + Common::Rect r1(120, 0, 132, 12); // The slash. + Common::Rect r2 = r1; + r2.moveTo(x, scoreBounds.top); + numbers->copyToCurrentPort(r1, r2); + drawNumber(score, x, scoreBounds.top, numbers); +} + +void GameMenu::drawNumber(GameScoreType number, CoordType &x, CoordType y, Surface *numbers) { + Common::Rect r1(0, 0, 12, 12); // Width, height of one digit + Common::Rect r2 = r1; + r2.moveTo(x - 12, y); + + do { + uint16 digit = number % 10; + number /= 10; + r1.moveTo(digit * 12, 0); + numbers->copyToCurrentPort(r1, r2); + r2.translate(-12, 0); + } while (number != 0); + + x = r2.right; +} + +enum { + kMainMenuStartDemo = 0, + kMainMenuCreditsDemo, + kMainMenuQuitDemo, + kFirstSelectionDemo = kMainMenuStartDemo, + kLastSelectionDemo = kMainMenuQuitDemo, + + kMainMenuOverview = 0, + kMainMenuStart, + kMainMenuRestore, + kMainMenuDifficulty, + kMainMenuCredits, + kMainMenuQuit, + kFirstSelection = kMainMenuOverview, + kLastSelection = kMainMenuQuit +}; + +static const CoordType kStartLeftDemo = 44; +static const CoordType kStartTopDemo = 336; + +static const CoordType kStartSelectLeftDemo = 40; +static const CoordType kStartSelectTopDemo = 331; + +static const CoordType kCreditsLeftDemo = 44; +static const CoordType kCreditsTopDemo = 372; + +static const CoordType kCreditsSelectLeftDemo = 40; +static const CoordType kCreditsSelectTopDemo = 367; + +static const CoordType kMainMenuQuitLeftDemo = 32; +static const CoordType kMainMenuQuitTopDemo = 412; + +static const CoordType kMainMenuQuitSelectLeftDemo = 28; +static const CoordType kMainMenuQuitSelectTopDemo = 408; + +static const CoordType kOverviewLeft = 200; +static const CoordType kOverviewTop = 208; + +static const CoordType kOverviewSelectLeft = 152; +static const CoordType kOverviewSelectTop = 204; + +static const CoordType kStartLeft = 212; +static const CoordType kStartTop = 256; + +static const CoordType kStartSelectLeft = 152; +static const CoordType kStartSelectTop = 252; + +static const CoordType kRestoreLeft = 212; +static const CoordType kRestoreTop = 296; + +static const CoordType kRestoreSelectLeft = 152; +static const CoordType kRestoreSelectTop = 292; + +static const CoordType kDifficultyLeft = 320; +static const CoordType kDifficultyTop = 340; + +static const CoordType kDifficultySelectLeft = 152; +static const CoordType kDifficultySelectTop = 336; + +static const CoordType kCreditsLeft = 212; +static const CoordType kCreditsTop = 388; + +static const CoordType kCreditsSelectLeft = 152; +static const CoordType kCreditsSelectTop = 384; + +static const CoordType kMainMenuQuitLeft = 212; +static const CoordType kMainMenuQuitTop = 428; + +static const CoordType kMainMenuQuitSelectLeft = 152; +static const CoordType 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(); + } +} + +enum { + kCreditsMenuCoreTeam, + kCreditsMenuSupportTeam, + kCreditsMenuOriginalTeam, + kCreditsMenuTalent, + kCreditsMenuOtherTitles, + kCreditsMenuMainMenu, + + kCreditsFirstSelection = kCreditsMenuCoreTeam, + kCreditsLastSelection = kCreditsMenuMainMenu +}; + +static const CoordType kCreditsMovieLeft = 288; +static const CoordType kCreditsMovieTop = 0; + +static const CoordType kCoreTeamSelectLeft = 40; +static const CoordType kCoreTeamSelectTop = 223; + +static const CoordType kSupportTeamSelectLeft = 40; +static const CoordType kSupportTeamSelectTop = 259; + +static const CoordType kOriginalTeamSelectLeft = 40; +static const CoordType kOriginalTeamSelectTop = 295; + +static const CoordType kTalentSelectLeft = 40; +static const CoordType kTalentSelectTop = 331; + +static const CoordType kOtherTitlesSelectLeft = 40; +static const CoordType kOtherTitlesSelectTop = 367; + +static const CoordType kCreditsMainMenuLeft = 32; +static const CoordType kCreditsMainMenuTop = 412; + +static const CoordType kCreditsMainMenuSelectLeft = 30; +static const CoordType kCreditsMainMenuSelectTop = 408; + +static const TimeValue kCoreTeamTime = 0; +static const TimeValue kSupportTeamTime = 1920; +static const TimeValue kOriginalTeamTime = 3000; +static const TimeValue kTalentTime = 4440; +static const TimeValue kOtherTitlesTime = 4680; + +static const TimeValue kFrameIncrement = 120; // Three frames... + +// Never set the current input handler to the CreditsMenu. +CreditsMenu::CreditsMenu() : GameMenu(kCreditsMenuID), _menuBackground(0), _creditsMovie(0), + _mainMenuButton(0), _largeSelect(0), _smallSelect(0) { + + _menuBackground.initFromPICTFile("Images/Credits/CredScrn.pict"); + _menuBackground.setDisplayOrder(0); + _menuBackground.startDisplaying(); + _menuBackground.show(); + + _creditsMovie.initFromMovieFile("Images/Credits/Credits.movie"); + _creditsMovie.setDisplayOrder(1); + _creditsMovie.moveElementTo(kCreditsMovieLeft, kCreditsMovieTop); + _creditsMovie.startDisplaying(); + _creditsMovie.show(); + _creditsMovie.redrawMovieWorld(); + + _mainMenuButton.initFromPICTFile("Images/Credits/MainMenu.pict"); + _mainMenuButton.setDisplayOrder(1); + _mainMenuButton.moveElementTo(kCreditsMainMenuLeft, kCreditsMainMenuTop); + _mainMenuButton.startDisplaying(); + + _largeSelect.initFromPICTFile("Images/Credits/SelectL.pict", true); + _largeSelect.setDisplayOrder(2); + _largeSelect.moveElementTo(kCreditsMainMenuSelectLeft, kCreditsMainMenuSelectTop); + _largeSelect.startDisplaying(); + + _smallSelect.initFromPICTFile("Images/Credits/SelectS.pict", true); + _smallSelect.setDisplayOrder(2); + _smallSelect.show(); + _smallSelect.startDisplaying(); + + _menuSelection = -1; + + newMenuSelection(kCreditsMenuCoreTeam); +} + +// Assumes the new selection is never more than one away from the old... +void CreditsMenu::newMenuSelection(const int newSelection) { + if (newSelection != _menuSelection) { + switch (newSelection) { + case kCreditsMenuCoreTeam: + _smallSelect.moveElementTo(kCoreTeamSelectLeft, kCoreTeamSelectTop); + _creditsMovie.setTime(kCoreTeamTime); + _creditsMovie.redrawMovieWorld(); + break; + case kCreditsMenuSupportTeam: + _smallSelect.moveElementTo(kSupportTeamSelectLeft, kSupportTeamSelectTop); + _creditsMovie.setTime(kSupportTeamTime); + _creditsMovie.redrawMovieWorld(); + break; + case kCreditsMenuOriginalTeam: + _smallSelect.moveElementTo(kOriginalTeamSelectLeft, kOriginalTeamSelectTop); + _creditsMovie.setTime(kOriginalTeamTime); + _creditsMovie.redrawMovieWorld(); + break; + case kCreditsMenuTalent: + _smallSelect.moveElementTo(kTalentSelectLeft, kTalentSelectTop); + _creditsMovie.setTime(kTalentTime); + _creditsMovie.redrawMovieWorld(); + break; + case kCreditsMenuOtherTitles: + _smallSelect.moveElementTo(kOtherTitlesSelectLeft, kOtherTitlesSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + _creditsMovie.setTime(kOtherTitlesTime); + _creditsMovie.redrawMovieWorld(); + break; + case kCreditsMenuMainMenu: + _smallSelect.hide(); + _largeSelect.show(); + break; + } + + _menuSelection = newSelection; + } +} + +void CreditsMenu::newMovieTime(const TimeValue newTime) { + if (newTime < kSupportTeamTime) { + _smallSelect.moveElementTo(kCoreTeamSelectLeft, kCoreTeamSelectTop); + _menuSelection = kCreditsMenuCoreTeam; + } else if (newTime < kOriginalTeamTime) { + _smallSelect.moveElementTo(kSupportTeamSelectLeft, kSupportTeamSelectTop); + _menuSelection = kCreditsMenuSupportTeam; + } else if (newTime < kTalentTime) { + _smallSelect.moveElementTo(kOriginalTeamSelectLeft, kOriginalTeamSelectTop); + _menuSelection = kCreditsMenuOriginalTeam; + } else if (newTime < kOtherTitlesTime) { + _smallSelect.moveElementTo(kTalentSelectLeft, kTalentSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + _menuSelection = kCreditsMenuTalent; + } else if ((int)newTime == -120) { + // HACK: Avoid getting sent to the bottom button in the default case + return; + } else { + _smallSelect.moveElementTo(kOtherTitlesSelectLeft, kOtherTitlesSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + _menuSelection = kCreditsMenuOtherTitles; + } + + _creditsMovie.setTime(newTime); + _creditsMovie.redrawMovieWorld(); +} + +void CreditsMenu::handleInput(const Input &input, const Hotspot *cursorSpot) { + if (input.upButtonDown()) { + if (_menuSelection > kCreditsFirstSelection) + newMenuSelection(_menuSelection - 1); + } else if (input.downButtonDown()) { + if (_menuSelection < kCreditsLastSelection) + newMenuSelection(_menuSelection + 1); + } else if (input.leftButtonDown()) { + newMovieTime(_creditsMovie.getTime() - kFrameIncrement); + } else if (input.rightButtonDown()) { + newMovieTime(_creditsMovie.getTime() + kFrameIncrement); + } else if (JMPPPInput::isMenuButtonPressInput(input)) { + if (_menuSelection == kCreditsMenuMainMenu) { + _mainMenuButton.show(); + ((PegasusEngine *)g_engine)->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _mainMenuButton.hide(); + setLastCommand(kMenuCmdCreditsMainMenu); + } + } + + InputHandler::handleInput(input, cursorSpot); +} + +static const CoordType kContinueLeft = 44; +static const CoordType kContinueTop = 336; + +static const CoordType kContinueSelectLeft = 40; +static const CoordType kContinueSelectTopDemo = 331; +static const CoordType kContinueSelectTop = 332; + +static const CoordType kMainMenuLeftDemo = 44; +static const CoordType kMainMenuTopDemo = 372; + +static const CoordType kMainMenuSelectLeftDemo = 40; +static const CoordType kMainMenuSelectTopDemo = 367; + +static const CoordType kQuitLeftDemo = 32; +static const CoordType kQuitTopDemo = 412; + +static const CoordType kQuitSelectLeftDemo = 28; +static const CoordType kQuitSelectTopDemo = 408; + +static const CoordType kRestoreLeftDeath = 44; +static const CoordType kRestoreTopDeath = 372; + +static const CoordType kRestoreSelectLeftDeath = 40; +static const CoordType kRestoreSelectTopDeath = 368; + +static const CoordType kMainMenuLeft = 32; +static const CoordType kMainMenuTop = 412; + +static const CoordType kMainMenuSelectLeft = 28; +static const CoordType kMainMenuSelectTop = 408; + +enum { + kDeathScreenContinueDemo = 0, + kDeathScreenMainMenuDemo, + kDeathScreenQuitDemo, + + kFirstDeathSelectionDemo = kDeathScreenContinueDemo, + kLastDeathSelectionDemo = kDeathScreenQuitDemo, + + kDeathScreenContinue = 0, + kDeathScreenRestore, + kDeathScreenMainMenu, + + kFirstDeathSelection = kDeathScreenContinue, + kLastDeathSelection = kDeathScreenMainMenu +}; + +// Never set the current input handler to the DeathMenu. +DeathMenu::DeathMenu(const DeathReason deathReason) : GameMenu(kDeathMenuID), _deathBackground(0), _continueButton(0), + _mainMenuButton(0), _quitButton(0), _restoreButton(0), _largeSelect(0), _smallSelect(0) { + PegasusEngine *vm = (PegasusEngine *)g_engine; + bool isDemo = vm->isDemo(); + + _playerWon = (deathReason == kPlayerWonGame); + + Common::String prefix = "Images/"; + Common::String imageName; + if (isDemo) { + prefix += "Demo/"; + imageName = prefix; + + switch (deathReason) { + case kDeathFallOffCliff: + imageName += "dPfall"; + break; + case kDeathEatenByDinosaur: + imageName += "dPdino"; + break; + case kDeathStranded: + imageName += "dPstuck"; + break; + default: + imageName += "dPdemowin"; + break; + } + + imageName += ".pict"; + } else { + prefix += "Death Screens/"; + imageName = prefix; + + static const char *fileNames[] = { + "dAunmade", "dAbombed", "dAshot", "dAassass", "dAnuked", + "dTunmade", "dTshot", "dPfall", "dPdino", "dPstuck", + "dNchoke", "dNcaught", "dNcaught", "dNsub", "dNrobot1", + "dNrobot2", "dMfall", "dMcaught", "dMtracks", "dMrobot", + "dMtoast", "dMexplo1", "dMexplo2", "dMchoke1", "dMchoke2", + "dMdroid", "dMfall", "dMgears", "dMshutt1", "dMshutt2", + "dWpoison", "dWcaught", "dWplasma", "dWshot", "dAfinale" + }; + + imageName += fileNames[deathReason - 1]; + imageName += ".pict"; + } + + _deathBackground.initFromPICTFile(imageName); + _deathReason = deathReason; + + if (!isDemo) { + vm->_gfx->setCurSurface(_deathBackground.getSurface()); + drawAllScores(); + vm->_gfx->setCurSurface(vm->_gfx->getWorkArea()); + } + + _deathBackground.setDisplayOrder(0); + _deathBackground.startDisplaying(); + _deathBackground.show(); + + if (isDemo) { + if (_playerWon) // Make credits button... + _continueButton.initFromPICTFile(prefix + "Credits.pict"); + else // Make continue button... + _continueButton.initFromPICTFile(prefix + "Continue.pict"); + + _mainMenuButton.initFromPICTFile(prefix + "MainMenu.pict"); + _mainMenuButton.setDisplayOrder(1); + _mainMenuButton.moveElementTo(kMainMenuLeftDemo, kMainMenuTopDemo); + _mainMenuButton.startDisplaying(); + + _quitButton.initFromPICTFile(prefix + "Quit.pict"); + _quitButton.setDisplayOrder(1); + _quitButton.moveElementTo(kQuitLeftDemo, kQuitTopDemo); + _quitButton.startDisplaying(); + + _menuSelection = kDeathScreenContinueDemo; + } else { + if (!_playerWon) { + _mainMenuButton.initFromPICTFile(prefix + "MainMenu.pict"); + _mainMenuButton.setDisplayOrder(1); + _mainMenuButton.moveElementTo(kMainMenuLeft, kMainMenuTop); + _mainMenuButton.startDisplaying(); + + _restoreButton.initFromPICTFile(prefix + "Restore.pict"); + _restoreButton.setDisplayOrder(1); + _restoreButton.moveElementTo(kRestoreLeftDeath, kRestoreTopDeath); + _restoreButton.startDisplaying(); + } + + _continueButton.initFromPICTFile(prefix + "Continue.pict"); + + _menuSelection = kDeathScreenContinue; + } + + _smallSelect.initFromPICTFile(prefix + "SelectS.pict", true); + _smallSelect.setDisplayOrder(2); + _smallSelect.startDisplaying(); + + _continueButton.setDisplayOrder(1); + _continueButton.moveElementTo(kContinueLeft, kContinueTop); + _continueButton.startDisplaying(); + + if (isDemo || !_playerWon) { + _largeSelect.initFromPICTFile(prefix + "SelectL.pict", true); + _largeSelect.setDisplayOrder(2); + _largeSelect.startDisplaying(); + } else { + _triumphSound.initFromQuickTime("Sounds/Caldoria/Galactic Triumph"); + _triumphSound.playSound(); + } + + updateDisplay(); +} + +void DeathMenu::handleInput(const Input &input, const Hotspot *cursorSpot) { + PegasusEngine *vm = (PegasusEngine *)g_engine; + + if (input.upButtonDown()) { + if (_menuSelection > (vm->isDemo() ? kFirstDeathSelectionDemo : kFirstDeathSelection)) { + _menuSelection--; + updateDisplay(); + } + } else if (input.downButtonDown() && (vm->isDemo() || !_playerWon)) { + if (_menuSelection < (vm->isDemo() ? kLastDeathSelectionDemo : kLastDeathSelection)) { + _menuSelection++; + updateDisplay(); + } + } else if (JMPPPInput::isMenuButtonPressInput(input)) { + if (vm->isDemo()) { + switch (_menuSelection) { + case kDeathScreenContinueDemo: + _continueButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _continueButton.hide(); + setLastCommand(kMenuCmdDeathContinue); + break; + case kDeathScreenQuitDemo: + _quitButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _quitButton.hide(); + setLastCommand(kMenuCmdDeathQuitDemo); + break; + case kDeathScreenMainMenuDemo: + _mainMenuButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _mainMenuButton.hide(); + setLastCommand(kMenuCmdDeathMainMenuDemo); + break; + } + } else { + switch (_menuSelection) { + case kDeathScreenContinue: + _continueButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _continueButton.hide(); + setLastCommand(kMenuCmdDeathContinue); + break; + case kDeathScreenRestore: + _restoreButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _restoreButton.hide(); + setLastCommand(kMenuCmdDeathRestore); + break; + case kDeathScreenMainMenu: + _mainMenuButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _mainMenuButton.hide(); + setLastCommand(kMenuCmdDeathMainMenu); + break; + } + } + } + + InputHandler::handleInput(input, cursorSpot); +} + +void DeathMenu::updateDisplay() { + if (((PegasusEngine *)g_engine)->isDemo()) { + switch (_menuSelection) { + case kDeathScreenContinueDemo: + _smallSelect.moveElementTo(kContinueSelectLeft, kContinueSelectTopDemo); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kDeathScreenQuitDemo: + _largeSelect.moveElementTo(kQuitSelectLeftDemo, kQuitSelectTopDemo); + _largeSelect.show(); + _smallSelect.hide(); + break; + case kDeathScreenMainMenuDemo: + _smallSelect.moveElementTo(kMainMenuSelectLeftDemo, kMainMenuSelectTopDemo); + _smallSelect.show(); + _largeSelect.hide(); + break; + } + } else { + switch (_menuSelection) { + case kDeathScreenContinue: + _smallSelect.moveElementTo(kContinueSelectLeft, kContinueSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kDeathScreenRestore: + _smallSelect.moveElementTo(kRestoreSelectLeftDeath, kRestoreSelectTopDeath); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kDeathScreenMainMenu: + _largeSelect.moveElementTo(kMainMenuSelectLeft, kMainMenuSelectTop); + _largeSelect.show(); + _smallSelect.hide(); + break; + } + } +} + +void DeathMenu::drawAllScores() { + Surface numbers; + numbers.getImageFromPICTFile("Images/Death Screens/Numbers.pict"); + + Common::Rect scoreBounds; + GameScoreType caldoriaTotal = 0; + + switch (_deathReason) { + case kDeathCardBomb: + case kDeathShotBySinclair: + case kDeathSinclairShotDelegate: + case kDeathNuclearExplosion: + case kDeathGassedInNorad: + case kDeathWokeUpNorad: + case kDeathArrestedInNorad: + case kDeathSubDestroyed: + case kDeathRobotThroughNoradDoor: + case kDeathRobotSubControlRoom: + case kDeathWrongShuttleLock: + case kDeathArrestedInMars: + case kDeathRunOverByPod: + case kDeathDidntGetOutOfWay: + case kDeathReactorBurn: + case kDeathDidntFindMarsBomb: + case kDeathDidntDisarmMarsBomb: + case kDeathNoMaskInMaze: + case kDeathNoAirInMaze: + case kDeathGroundByMazebot: + case kDeathMissedOreBucket: + case kDeathDidntLeaveBucket: + case kDeathRanIntoCanyonWall: + case kDeathRanIntoSpaceJunk: + case kDeathDidntStopPoison: + case kDeathArrestedInWSC: + case kDeathHitByPlasma: + case kDeathShotOnCatwalk: + case kPlayerWonGame: + caldoriaTotal += kMaxCaldoriaTSAScoreAfter; + scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 5, + kDeathScreenScoreLeft + kDeathScreenScoreWidth, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 5 + kDeathScreenScoreHeight); + drawScore(GameState.getGandhiScore(), kMaxGandhiScore, scoreBounds, &numbers); + + scoreBounds.translate(0, kDeathScreenScoreSkipVert); + drawScore(GameState.getWSCScore(), kMaxWSCScore, scoreBounds, &numbers); + + scoreBounds.translate(0, kDeathScreenScoreSkipVert); + drawScore(GameState.getNoradScore(), kMaxNoradScore, scoreBounds, &numbers); + + scoreBounds.translate(0, kDeathScreenScoreSkipVert); + drawScore(GameState.getMarsScore(), kMaxMarsScore, scoreBounds, &numbers); + // fall through + case kDeathFallOffCliff: + case kDeathEatenByDinosaur: + case kDeathStranded: + case kDeathShotByTSARobots: + scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop - kDeathScreenScoreSkipVert, + kDeathScreenScoreLeft + kDeathScreenScoreWidth, kDeathScreenScoreTop - kDeathScreenScoreSkipVert + kDeathScreenScoreHeight); + drawScore(GameState.getPrehistoricScore(), kMaxPrehistoricScore, scoreBounds, &numbers); + // fall through + case kDeathUncreatedInCaldoria: + case kDeathUncreatedInTSA: + scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop, kDeathScreenScoreLeft + kDeathScreenScoreWidth, + kDeathScreenScoreTop + kDeathScreenScoreHeight); + caldoriaTotal += kMaxCaldoriaTSAScoreBefore; + drawScore(GameState.getCaldoriaTSAScore(), caldoriaTotal, scoreBounds, &numbers); + + scoreBounds = Common::Rect(kDeathScreenScoreLeft, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 6, + kDeathScreenScoreLeft + kDeathScreenScoreWidth, kDeathScreenScoreTop - kDeathScreenScoreSkipVert * 6 + kDeathScreenScoreHeight); + + drawScore(GameState.getTotalScore(), kMaxTotalScore, scoreBounds, &numbers); + break; + } +} + +enum { + kPauseMenuSave, + kPauseMenuContinue, + kPauseMenuRestore, + kPauseMenuSoundFX, + kPauseMenuAmbience, + kPauseMenuWalkthru, + kPauseMenuQuitToMainMenu, + + kFirstPauseSelection = kPauseMenuSave, + kLastPauseSelection = kPauseMenuQuitToMainMenu +}; + +static const CoordType kPauseLeft = 194; +static const CoordType kPauseTop = 68; + +static const CoordType kSaveGameLeft = kPauseLeft + 6; +static const CoordType kSaveGameTop = kPauseTop + 56; + +static const CoordType kSaveGameSelectLeft = kPauseLeft - 44; +static const CoordType kSaveGameSelectTop = kPauseTop + 52; + +static const CoordType kPauseContinueLeft = kPauseLeft + 18; +static const CoordType kPauseContinueTop = kPauseTop + 100; + +static const CoordType kPauseContinueSelectLeft = kPauseLeft - 44; +static const CoordType kPauseContinueSelectTop = kPauseTop + 95; + +static const CoordType kPauseRestoreLeft = kPauseLeft + 18; +static const CoordType kPauseRestoreTop = kPauseTop + 136; + +static const CoordType kPauseRestoreSelectLeft = kPauseLeft - 44; +static const CoordType kPauseRestoreSelectTop = kPauseTop + 131; + +static const CoordType kSoundFXLeft = kPauseLeft + 128; +static const CoordType kSoundFXTop = kPauseTop + 187; +static const CoordType kSoundFXRight = kSoundFXLeft + 96; +static const CoordType kSoundFXBottom = kSoundFXTop + 14; + +static const CoordType kSoundFXSelectLeft = kPauseLeft - 44; +static const CoordType kSoundFXSelectTop = kPauseTop + 172; + +static const CoordType kAmbienceLeft = kPauseLeft + 128; +static const CoordType kAmbienceTop = kPauseTop + 227; +static const CoordType kAmbienceRight = kAmbienceLeft + 96; +static const CoordType kAmbienceBottom = kAmbienceTop + 14; + +static const CoordType kAmbienceSelectLeft = kPauseLeft - 44; +static const CoordType kAmbienceSelectTop = kPauseTop + 212; + +static const CoordType kWalkthruLeft = kPauseLeft + 128; +static const CoordType kWalkthruTop = kPauseTop + 264; + +static const CoordType kWalkthruSelectLeft = kPauseLeft - 44; +static const CoordType kWalkthruSelectTop = kPauseTop + 255; + +static const CoordType kQuitLeft = kPauseLeft + 18; +static const CoordType kQuitTop = kPauseTop + 302; + +static const CoordType kQuitSelectLeft = kPauseLeft - 44; +static const CoordType kQuitSelectTop = kPauseTop + 297; + +// These are relative to the pause background. +static const CoordType kPauseScoreLeft = 130; +static const CoordType kPauseScoreTop = 34; +static const CoordType kPauseScoreRight = kPauseScoreLeft + 108; +static const CoordType kPauseScoreBottom = kPauseScoreTop + 12; + +// Never set the current input handler to the CPauseMenu. +PauseMenu::PauseMenu() : GameMenu(kPauseMenuID), _pauseBackground(0), _saveButton(0), _restoreButton(0), + _walkthroughButton(0), _continueButton(0), _soundFXLevel(0), _ambienceLevel(0), _quitButton(0), + _largeSelect(0), _smallSelect(0) { + PegasusEngine *vm = (PegasusEngine *)g_engine; + + _pauseBackground.initFromPICTFile("Images/Pause Screen/PausScrn.pict", true); + + if (!vm->isDemo()) { + Surface numbers; + numbers.getImageFromPICTFile("Images/Pause Screen/Numbers.pict"); + vm->_gfx->setCurSurface(_pauseBackground.getSurface()); + drawScore(GameState.getTotalScore(), kMaxTotalScore, + Common::Rect(kPauseScoreLeft, kPauseScoreTop, kPauseScoreRight, kPauseScoreBottom), &numbers); + vm->_gfx->setCurSurface(vm->_gfx->getWorkArea()); + } + + _pauseBackground.setDisplayOrder(kPauseMenuOrder); + _pauseBackground.moveElementTo(kPauseLeft, kPauseTop); + _pauseBackground.startDisplaying(); + _pauseBackground.show(); + + if (!vm->isDemo()) { + _saveButton.initFromPICTFile("Images/Pause Screen/SaveGame.pict"); + _saveButton.setDisplayOrder(kSaveGameOrder); + _saveButton.moveElementTo(kSaveGameLeft, kSaveGameTop); + _saveButton.startDisplaying(); + + _restoreButton.initFromPICTFile("Images/Pause Screen/Restore.pict"); + _restoreButton.setDisplayOrder(kRestoreOrder); + _restoreButton.moveElementTo(kPauseRestoreLeft, kPauseRestoreTop); + _restoreButton.startDisplaying(); + + _walkthroughButton.initFromPICTFile("Images/Pause Screen/Walkthru.pict"); + _walkthroughButton.setDisplayOrder(kWalkthruOrder); + _walkthroughButton.moveElementTo(kWalkthruLeft, kWalkthruTop); + _walkthroughButton.startDisplaying(); + + if (GameState.getWalkthroughMode()) + _walkthroughButton.show(); + } + + _continueButton.initFromPICTFile("Images/Pause Screen/Continue.pict"); + _continueButton.setDisplayOrder(kContinueOrder); + _continueButton.moveElementTo(kPauseContinueLeft, kPauseContinueTop); + _continueButton.startDisplaying(); + + _soundFXLevel.setDisplayOrder(kSoundFXOrder); + _soundFXLevel.setBounds(Common::Rect(kSoundFXLeft, kSoundFXTop, kSoundFXRight, kSoundFXBottom)); + _soundFXLevel.startDisplaying(); + _soundFXLevel.show(); + _soundFXLevel.setSoundLevel(vm->getSoundFXLevel()); + + _ambienceLevel.setDisplayOrder(kAmbienceOrder); + _ambienceLevel.setBounds(Common::Rect(kAmbienceLeft, kAmbienceTop, kAmbienceRight, kAmbienceBottom)); + _ambienceLevel.startDisplaying(); + _ambienceLevel.show(); + _ambienceLevel.setSoundLevel(vm->getAmbienceLevel()); + + _quitButton.initFromPICTFile("Images/Pause Screen/Quit2MM.pict"); + _quitButton.setDisplayOrder(kQuitToMainMenuOrder); + _quitButton.moveElementTo(kQuitLeft, kQuitTop); + _quitButton.startDisplaying(); + + _largeSelect.initFromPICTFile("Images/Pause Screen/SelectL.pict", true); + _largeSelect.setDisplayOrder(kPauseLargeHiliteOrder); + _largeSelect.startDisplaying(); + + _smallSelect.initFromPICTFile("Images/Pause Screen/SelectS.pict", true); + _smallSelect.setDisplayOrder(kPauseSmallHiliteOrder); + _smallSelect.startDisplaying(); + + _menuSelection = (vm->isDemo()) ? kPauseMenuContinue : kPauseMenuSave; + + updateDisplay(); +} + +void PauseMenu::handleInput(const Input &input, const Hotspot *cursorSpot) { + PegasusEngine *vm = (PegasusEngine *)g_engine; + + if (input.upButtonDown()) { + if (vm->isDemo()) { + if (_menuSelection > kPauseMenuContinue) { + switch (_menuSelection) { + case kPauseMenuSoundFX: + _menuSelection = kPauseMenuContinue; + break; + case kPauseMenuAmbience: + _menuSelection = kPauseMenuSoundFX; + break; + case kPauseMenuQuitToMainMenu: + _menuSelection = kPauseMenuAmbience; + break; + } + updateDisplay(); + } + } else { + if (_menuSelection > kFirstPauseSelection) { + _menuSelection--; + updateDisplay(); + } + } + } else if (input.downButtonDown()) { + if (vm->isDemo()) { + if (_menuSelection < kPauseMenuQuitToMainMenu) { + switch (_menuSelection) { + case kPauseMenuContinue: + _menuSelection = kPauseMenuSoundFX; + break; + case kPauseMenuSoundFX: + _menuSelection = kPauseMenuAmbience; + break; + case kPauseMenuAmbience: + _menuSelection = kPauseMenuQuitToMainMenu; + break; + } + updateDisplay(); + } + } else { + if (_menuSelection < kLastPauseSelection) { + _menuSelection++; + updateDisplay(); + } + } + } else if (input.leftButtonDown()) { + if (_menuSelection == kPauseMenuSoundFX) { + _soundFXLevel.decrementLevel(); + vm->setSoundFXLevel(_soundFXLevel.getSoundLevel()); + } else if (_menuSelection == kPauseMenuAmbience) { + _ambienceLevel.decrementLevel(); + vm->setAmbienceLevel(_ambienceLevel.getSoundLevel()); + } else if (!vm->isDemo() && _menuSelection == kPauseMenuWalkthru) { + GameState.setWalkthroughMode(!GameState.getWalkthroughMode()); + if (GameState.getWalkthroughMode()) + _walkthroughButton.show(); + else + _walkthroughButton.hide(); + } + } else if (input.rightButtonDown()) { + if (_menuSelection == kPauseMenuSoundFX) { + _soundFXLevel.incrementLevel(); + vm->setSoundFXLevel(_soundFXLevel.getSoundLevel()); + } else if (_menuSelection == kPauseMenuAmbience) { + _ambienceLevel.incrementLevel(); + vm->setAmbienceLevel(_ambienceLevel.getSoundLevel()); + } else if (!vm->isDemo() && _menuSelection == kPauseMenuWalkthru) { + GameState.setWalkthroughMode(!GameState.getWalkthroughMode()); + if (GameState.getWalkthroughMode()) + _walkthroughButton.show(); + else + _walkthroughButton.hide(); + } + } else if (JMPPPInput::isMenuButtonPressInput(input)) { + switch (_menuSelection) { + case kPauseMenuSave: + _saveButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _saveButton.hide(); + setLastCommand(kMenuCmdPauseSave); + break; + case kPauseMenuRestore: + _restoreButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _restoreButton.hide(); + setLastCommand(kMenuCmdPauseRestore); + break; + case kPauseMenuContinue: + _continueButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _continueButton.hide(); + setLastCommand(kMenuCmdPauseContinue); + break; + case kPauseMenuWalkthru: + GameState.setWalkthroughMode(!GameState.getWalkthroughMode()); + if (GameState.getWalkthroughMode()) + _walkthroughButton.show(); + else + _walkthroughButton.hide(); + break; + case kPauseMenuQuitToMainMenu: + _quitButton.show(); + vm->delayShell(kMenuButtonHiliteTime, kMenuButtonHiliteScale); + _quitButton.hide(); + setLastCommand(kMenuCmdPauseQuit); + break; + } + } + + InputHandler::handleInput(input, cursorSpot); +} + +void PauseMenu::updateDisplay() { + switch (_menuSelection) { + case kPauseMenuSave: + _largeSelect.moveElementTo(kSaveGameSelectLeft, kSaveGameSelectTop); + _largeSelect.show(); + _smallSelect.hide(); + break; + case kPauseMenuContinue: + _smallSelect.moveElementTo(kPauseContinueSelectLeft, kPauseContinueSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kPauseMenuRestore: + _smallSelect.moveElementTo(kPauseRestoreSelectLeft, kPauseRestoreSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + case kPauseMenuSoundFX: + _largeSelect.moveElementTo(kSoundFXSelectLeft, kSoundFXSelectTop); + _largeSelect.show(); + _smallSelect.hide(); + break; + case kPauseMenuAmbience: + _largeSelect.moveElementTo(kAmbienceSelectLeft, kAmbienceSelectTop); + _largeSelect.show(); + _smallSelect.hide(); + break; + case kPauseMenuWalkthru: + _largeSelect.moveElementTo(kWalkthruSelectLeft, kWalkthruSelectTop); + _largeSelect.show(); + _smallSelect.hide(); + break; + case kPauseMenuQuitToMainMenu: + _smallSelect.moveElementTo(kQuitSelectLeft, kQuitSelectTop); + _smallSelect.show(); + _largeSelect.hide(); + break; + } + + ((PegasusEngine *)g_engine)->resetIntroTimer(); +} + + +} // End of namespace Pegasus |