aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rwxr-xr-xengines/pegasus/constants.h36
-rwxr-xr-xengines/pegasus/menu.cpp331
-rwxr-xr-xengines/pegasus/menu.h38
-rw-r--r--engines/pegasus/pegasus.cpp92
-rw-r--r--engines/pegasus/pegasus.h13
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