aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mads/events.cpp6
-rw-r--r--engines/mads/events.h10
-rw-r--r--engines/mads/module.mk1
-rw-r--r--engines/mads/nebular/dialogs_nebular.cpp171
-rw-r--r--engines/mads/nebular/dialogs_nebular.h64
-rw-r--r--engines/mads/nebular/menu_nebular.cpp346
-rw-r--r--engines/mads/nebular/menu_nebular.h80
7 files changed, 598 insertions, 80 deletions
diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp
index c3e6d5c122..41c8255ce8 100644
--- a/engines/mads/events.cpp
+++ b/engines/mads/events.cpp
@@ -191,7 +191,7 @@ void EventsManager::pollEvents() {
}
}
-void EventsManager::checkForNextFrameCounter() {
+bool EventsManager::checkForNextFrameCounter() {
// Check for next game frame
uint32 milli = g_system->getMillis();
if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
@@ -209,7 +209,11 @@ void EventsManager::checkForNextFrameCounter() {
// Signal the ScummVM debugger
_vm->_debugger->onFrame();
+
+ return true;
}
+
+ return false;
}
void EventsManager::delay(int cycles) {
diff --git a/engines/mads/events.h b/engines/mads/events.h
index 3d7504c0bd..f491556e9e 100644
--- a/engines/mads/events.h
+++ b/engines/mads/events.h
@@ -51,11 +51,6 @@ private:
* Updates the cursor image when the current cursor changes
*/
void changeCursor();
-
- /**
- * Checks for whether the next game frame number has been reached.
- */
- void checkForNextFrameCounter();
public:
SpriteAsset *_cursorSprites;
CursorType _cursorId;
@@ -147,6 +142,11 @@ public:
void waitForNextFrame();
/**
+ * Checks for whether the next game frame number has been reached.
+ */
+ bool checkForNextFrameCounter();
+
+ /**
* Gets the current frame counter
*/
uint32 getFrameCounter() const { return _frameCounter; }
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index 61e810e215..96353e9ae5 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS := \
nebular/dialogs_nebular.o \
nebular/game_nebular.o \
nebular/globals_nebular.o \
+ nebular/menu_nebular.o \
nebular/sound_nebular.o \
nebular/nebular_scenes.o \
nebular/nebular_scenes1.o \
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index 80ce6cdad4..1cbb7ea3a6 100644
--- a/engines/mads/nebular/dialogs_nebular.cpp
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -524,48 +524,14 @@ void PictureDialog::restore() {
/*------------------------------------------------------------------------*/
-ScreenDialog::DialogLine::DialogLine() {
- _active = true;
- _state = DLGSTATE_UNSELECTED;
- _textDisplayIndex = -1;
- _font = nullptr;
- _widthAdjust = 0;
- _msg = "";
-}
-
-ScreenDialog::DialogLine::DialogLine(const Common::String &s) {
- _active = true;
- _state = DLGSTATE_UNSELECTED;
- _textDisplayIndex = -1;
- _font = nullptr;
- _widthAdjust = -1;
- _msg = s;
+FullScreenDialog::FullScreenDialog(MADSEngine *vm) : _vm(vm) {
+ _screenId = 990;
}
-/*------------------------------------------------------------------------*/
-
-ScreenDialog::ScreenDialog(MADSEngine *vm) : _vm(vm) {
+void FullScreenDialog::display() {
Game &game = *_vm->_game;
Scene &scene = game._scene;
- _tempLine = 0;
- _movedFlag = false;
- _redrawFlag = false;
- _selectedLine = -1;
- _dirFlag = false;
- _textLineCount = 0;
- _screenId = 920;
-
- chooseBackground();
- game.loadQuoteSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0);
- game._kernelMode = KERNEL_ROOM_PRELOAD;
- _vm->_events->waitCursor();
- scene.clearVocab();
- scene._dynamicHotspots.clear();
- _vm->_dialogs->_defaultPosition = Common::Point(-1, -1);
-
bool palFlag = false;
int nextSceneId = scene._nextSceneId;
int currentSceneId = scene._currentSceneId;
@@ -581,14 +547,11 @@ ScreenDialog::ScreenDialog(MADSEngine *vm) : _vm(vm) {
scene._priorSceneId = priorSceneId;
scene._currentSceneId = currentSceneId;
scene._nextSceneId = nextSceneId;
+
_vm->_screen._offset.y = 22;
- _vm->_sound->pauseNewCommands();
_vm->_events->initVars();
game._kernelMode = KERNEL_ROOM_INIT;
- SpriteAsset *menuSprites = new SpriteAsset(_vm, "*MENU", 0);
- _menuSpritesIndex = scene._sprites.add(menuSprites);
-
byte pal[768];
if (_vm->_screenFade) {
Common::fill(&pal[0], &pal[PALETTE_SIZE], 0);
@@ -603,8 +566,19 @@ ScreenDialog::ScreenDialog(MADSEngine *vm) : _vm(vm) {
_vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kCenterVertTransition;
+ _vm->_screen.copyTo(&_savedSurface);
+ /*
+ _vm->_screen.hLine(0, 0, MADS_SCREEN_WIDTH, 2);
+ _vm->_screen.copyRectToScreen(Common::Rect(0, _vm->_screen._offset.y,
+ MADS_SCREEN_WIDTH, _vm->_screen._offset.y + 1));
+ _vm->_screen.copyRectToScreen(Common::Rect(0, _vm->_screen._offset.y + 157,
+ MADS_SCREEN_WIDTH, _vm->_screen._offset.y + 157));
+ */
+
+ game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ?
+ kCenterVertTransition : kTransitionFadeIn;
+
game._trigger = 0;
- _vm->_events->setCursor(CURSOR_ARROW);
_vm->_palette->setEntry(10, 0, 63, 0);
_vm->_palette->setEntry(11, 0, 45, 0);
@@ -613,21 +587,77 @@ ScreenDialog::ScreenDialog(MADSEngine *vm) : _vm(vm) {
_vm->_palette->setEntry(14, 63, 63, 63);
_vm->_palette->setEntry(15, 45, 45, 45);
+ _vm->_events->setCursor(CURSOR_ARROW);
+}
+
+/*------------------------------------------------------------------------*/
+
+GameDialog::DialogLine::DialogLine() {
+ _active = true;
+ _state = DLGSTATE_UNSELECTED;
+ _textDisplayIndex = -1;
+ _font = nullptr;
+ _widthAdjust = 0;
+ _msg = "";
+}
+
+GameDialog::DialogLine::DialogLine(const Common::String &s) {
+ _active = true;
+ _state = DLGSTATE_UNSELECTED;
+ _textDisplayIndex = -1;
+ _font = nullptr;
+ _widthAdjust = -1;
+ _msg = s;
+}
+
+/*------------------------------------------------------------------------*/
+
+GameDialog::GameDialog(MADSEngine *vm) : FullScreenDialog(vm) {
+ Game &game = *_vm->_game;
+ Scene &scene = game._scene;
+
+ _tempLine = 0;
+ _movedFlag = false;
+ _redrawFlag = false;
+ _selectedLine = -1;
+ _dirFlag = false;
+ _textLineCount = 0;
+ _screenId = 920;
+
+ chooseBackground();
+ game.loadQuoteSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0);
+ game._kernelMode = KERNEL_ROOM_PRELOAD;
+ _vm->_events->waitCursor();
+ scene.clearVocab();
+ scene._dynamicHotspots.clear();
+ _vm->_dialogs->_defaultPosition = Common::Point(-1, -1);
+}
+
+void GameDialog::display() {
+ FullScreenDialog::display();
+
+ Scene &scene = _vm->_game->_scene;
+ SpriteAsset *menuSprites = new SpriteAsset(_vm, "*MENU", 0);
+ _menuSpritesIndex = scene._sprites.add(menuSprites);
+
_lineIndex = -1;
+ setClickableLines();
}
-ScreenDialog::~ScreenDialog() {
+GameDialog::~GameDialog() {
_vm->_screen._offset.y = 0;
}
-void ScreenDialog::clearLines() {
+void GameDialog::clearLines() {
Scene &scene = _vm->_game->_scene;
_movedFlag = false;
_lines.clear();
scene._spriteSlots.fullRefresh(true);
}
-void ScreenDialog::setClickableLines() {
+void GameDialog::setClickableLines() {
ScreenObjects &screenObjects = _vm->_game->_screenObjects;
for (uint idx = 0; idx < _lines.size(); ++idx) {
@@ -648,7 +678,7 @@ void ScreenDialog::setClickableLines() {
}
}
-void ScreenDialog::addQuote(int id1, int id2, DialogTextAlign align,
+void GameDialog::addQuote(int id1, int id2, DialogTextAlign align,
const Common::Point &pt, Font *font) {
Common::String msg = _vm->_game->getQuote(id1).c_str(); // c_str() because we need a copy
@@ -658,7 +688,7 @@ void ScreenDialog::addQuote(int id1, int id2, DialogTextAlign align,
addLine(msg, align, pt, font);
}
-void ScreenDialog::addLine(const Common::String &msg, DialogTextAlign align,
+void GameDialog::addLine(const Common::String &msg, DialogTextAlign align,
const Common::Point &pt, Font *font) {
Scene &scene = _vm->_game->_scene;
DialogLine *line;
@@ -737,14 +767,14 @@ void ScreenDialog::addLine(const Common::String &msg, DialogTextAlign align,
++_lineIndex;
}
-void ScreenDialog::initVars() {
+void GameDialog::initVars() {
_tempLine = -1;
_selectedLine = -1;
_lineIndex = 0;
_textLineCount = 0;
}
-void ScreenDialog::chooseBackground() {
+void GameDialog::chooseBackground() {
switch (_vm->_game->_currentSectionNumber) {
case 1:
case 2:
@@ -768,7 +798,7 @@ void ScreenDialog::chooseBackground() {
}
}
-void ScreenDialog::setFrame(int frameNumber, int depth) {
+void GameDialog::setFrame(int frameNumber, int depth) {
Scene &scene = _vm->_game->_scene;
SpriteAsset *menuSprites = scene._sprites[_menuSpritesIndex];
MSprite *frame = menuSprites->getFrame(frameNumber - 1);
@@ -783,7 +813,9 @@ void ScreenDialog::setFrame(int frameNumber, int depth) {
spriteSlot._scale = 100;
}
-void ScreenDialog::show() {
+void GameDialog::show() {
+ display();
+
Scene &scene = _vm->_game->_scene;
while (_selectedLine < 1 && !_vm->shouldQuit()) {
@@ -802,7 +834,7 @@ void ScreenDialog::show() {
}
}
-void ScreenDialog::handleEvents() {
+void GameDialog::handleEvents() {
ScreenObjects &screenObjects = _vm->_game->_screenObjects;
EventsManager &events = *_vm->_events;
Nebular::DialogsNebular &dialogs = *(Nebular::DialogsNebular *)_vm->_dialogs;
@@ -868,7 +900,7 @@ void ScreenDialog::handleEvents() {
_redrawFlag = true;
}
-void ScreenDialog::refreshText() {
+void GameDialog::refreshText() {
Scene &scene = _vm->_game->_scene;
for (uint i = 0; i < _lines.size(); ++i) {
@@ -908,10 +940,8 @@ void ScreenDialog::refreshText() {
/*------------------------------------------------------------------------*/
-DifficultyDialog::DifficultyDialog(MADSEngine *vm) : ScreenDialog(vm) {
- setFrame(8, 2);
+DifficultyDialog::DifficultyDialog(MADSEngine *vm) : GameDialog(vm) {
setLines();
- setClickableLines();
}
void DifficultyDialog::setLines() {
@@ -927,8 +957,13 @@ void DifficultyDialog::setLines() {
}
}
+void DifficultyDialog::display() {
+ GameDialog::display();
+ setFrame(8, 2);
+}
+
void DifficultyDialog::show() {
- ScreenDialog::show();
+ GameDialog::show();
Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game;
switch (_selectedLine) {
@@ -948,10 +983,8 @@ void DifficultyDialog::show() {
/*------------------------------------------------------------------------*/
-GameMenuDialog::GameMenuDialog(MADSEngine *vm) : ScreenDialog(vm) {
- setFrame(1, 2);
+GameMenuDialog::GameMenuDialog(MADSEngine *vm) : GameDialog(vm) {
setLines();
- setClickableLines();
}
void GameMenuDialog::setLines() {
@@ -968,8 +1001,13 @@ void GameMenuDialog::setLines() {
}
}
+void GameMenuDialog::display() {
+ GameDialog::display();
+ setFrame(1, 2);
+}
+
void GameMenuDialog::show() {
- ScreenDialog::show();
+ GameDialog::show();
switch (_selectedLine) {
case 1:
@@ -995,10 +1033,8 @@ void GameMenuDialog::show() {
/*------------------------------------------------------------------------*/
-OptionsDialog::OptionsDialog(MADSEngine *vm) : ScreenDialog(vm) {
- setFrame(2, 2);
+OptionsDialog::OptionsDialog(MADSEngine *vm) : GameDialog(vm) {
setLines();
- setClickableLines();
}
int OptionsDialog::getOptionQuote(int option) {
@@ -1043,11 +1079,16 @@ void OptionsDialog::setLines() {
addQuote(2, 0, ALIGN_NONE, Common::Point(190, yp));
}
+void OptionsDialog::display() {
+ GameDialog::display();
+ setFrame(2, 2);
+}
+
void OptionsDialog::show() {
Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game;
do {
_selectedLine = 0;
- ScreenDialog::show();
+ GameDialog::show();
switch (_selectedLine) {
case 1: // Music
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index 44412797a1..46973cc497 100644
--- a/engines/mads/nebular/dialogs_nebular.h
+++ b/engines/mads/nebular/dialogs_nebular.h
@@ -107,7 +107,35 @@ enum DialogTextAlign { ALIGN_NONE = 0, ALIGN_CENTER = -1, ALIGN_AT_CENTER = -2,
enum DialogState { DLGSTATE_UNSELECTED = 0, DLGSTATE_SELECTED = 1, DLGSTATE_FOCUSED = 2 };
-class ScreenDialog {
+class FullScreenDialog {
+protected:
+ /**
+ * Engine reference
+ */
+ MADSEngine *_vm;
+
+ /**
+ * Used to store the original screen background
+ */
+ MSurface _savedSurface;
+
+ /**
+ * Screen/scene to show background from
+ */
+ int _screenId;
+
+ /**
+ * Handles displaying the screen background and dialog
+ */
+ virtual void display();
+public:
+ /**
+ * Constructor
+ */
+ FullScreenDialog(MADSEngine *vm);
+};
+
+class GameDialog: public FullScreenDialog {
struct DialogLine {
bool _active;
DialogState _state;
@@ -116,22 +144,25 @@ class ScreenDialog {
Common::String _msg;
Font *_font;
int _widthAdjust;
-
+
DialogLine();
DialogLine(const Common::String &s);
};
protected:
- MADSEngine *_vm;
Common::Array<DialogLine> _lines;
int _tempLine;
bool _movedFlag;
bool _redrawFlag;
int _selectedLine;
bool _dirFlag;
- int _screenId;
int _menuSpritesIndex;
int _lineIndex;
int _textLineCount;
+
+ /**
+ * Display the dialog
+ */
+ virtual void display();
/**
* Reset the lines list for the dialog
@@ -181,12 +212,12 @@ public:
/**
* Constructor
*/
- ScreenDialog(MADSEngine *vm);
+ GameDialog(MADSEngine *vm);
/**
* Destructor
*/
- virtual ~ScreenDialog();
+ virtual ~GameDialog();
/**
* Show the dialog
@@ -194,7 +225,7 @@ public:
virtual void show();
};
-class DifficultyDialog : public ScreenDialog {
+class DifficultyDialog : public GameDialog {
private:
/**
* Set the lines for the dialog
@@ -204,12 +235,17 @@ public:
DifficultyDialog(MADSEngine *vm);
/**
+ * Display the dialog
+ */
+ virtual void display();
+
+ /**
* Show the dialog
*/
virtual void show();
};
-class GameMenuDialog : public ScreenDialog {
+class GameMenuDialog : public GameDialog {
private:
/**
* Set the lines for the dialog
@@ -219,12 +255,17 @@ public:
GameMenuDialog(MADSEngine *vm);
/**
+ * Display the dialog
+ */
+ virtual void display();
+
+ /**
* Show the dialog
*/
virtual void show();
};
-class OptionsDialog : public ScreenDialog {
+class OptionsDialog : public GameDialog {
private:
/**
* Set the lines for the dialog
@@ -239,6 +280,11 @@ public:
OptionsDialog(MADSEngine *vm);
/**
+ * Display the dialog
+ */
+ virtual void display();
+
+ /**
* Show the dialog
*/
virtual void show();
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp
new file mode 100644
index 0000000000..0ed7a93996
--- /dev/null
+++ b/engines/mads/nebular/menu_nebular.cpp
@@ -0,0 +1,346 @@
+/* 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.
+ *
+ * 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 "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/mads.h"
+#include "mads/resources.h"
+#include "mads/screen.h"
+#include "mads/nebular/menu_nebular.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+#define NEBULAR_MENUSCREEN 990
+#define MADS_MENU_Y ((MADS_SCREEN_HEIGHT - MADS_SCENE_HEIGHT) / 2)
+#define MADS_MENU_ANIM_DELAY 70
+
+MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) {
+ _breakFlag = false;
+}
+
+void MenuView::execute() {
+ Common::Event event;
+
+ // Main event loop to show the view
+ while (!_breakFlag) {
+ // Handle events
+ while (g_system->getEventManager()->pollEvent(event)) {
+ onEvent(event);
+ }
+
+ if (_vm->_events->checkForNextFrameCounter()) {
+ // Next frame drawn, so allow view to prepare for following one
+ doFrame();
+ }
+
+ // Slight delay
+ g_system->delayMillis(10);
+ _breakFlag = _vm->shouldQuit();
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) {
+ _itemPosList[0] = Common::Point(12, 68);
+ _itemPosList[1] = Common::Point(12, 87);
+ _itemPosList[2] = Common::Point(12, 107);
+ _itemPosList[3] = Common::Point(184, 75);
+ _itemPosList[4] = Common::Point(245, 75);
+ _itemPosList[5] = Common::Point(184, 99);
+
+ _delayTimeout = 0;
+ _menuItem = NULL;
+ _menuItemIndex = 0;
+ _frameIndex = 0;
+ _highlightedIndex = -1;
+ _skipFlag = false;
+}
+
+MainMenu::~MainMenu() {
+ if (_menuItem)
+ delete _menuItem;
+}
+
+bool MainMenu::onEvent(Common::Event &event) {
+ // Handle keypresses - these can be done at any time, even when the menu items are being drawn
+ if (event.type == Common::EVENT_KEYDOWN) {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_ESCAPE:
+ case Common::KEYCODE_F6:
+ handleAction(EXIT);
+ break;
+
+ case Common::KEYCODE_F1:
+ handleAction(START_GAME);
+ break;
+
+ case Common::KEYCODE_F2:
+ handleAction(RESUME_GAME);
+ break;
+
+ case Common::KEYCODE_F3:
+ handleAction(SHOW_INTRO);
+ break;
+
+ case Common::KEYCODE_F4:
+ handleAction(CREDITS);
+ break;
+
+ case Common::KEYCODE_F5:
+ handleAction(QUOTES);
+ break;
+
+ case Common::KEYCODE_s: {
+ // Goodness knows why, but Rex has a key to restart the menuitem animations
+
+ // Delete the current menu items
+ if (_menuItem)
+ delete _menuItem;
+ /*
+ _vm->_palette->deleteRange(_bgPalData);
+ delete _bgPalData;
+ for (uint i = 0; i < _itemPalData.size(); ++i) {
+ _vm->_palette->deleteRange(_itemPalData[i]);
+ delete _itemPalData[i];
+ }
+ _itemPalData.clear();
+ */
+ // Restart the animation
+ _menuItemIndex = 0;
+ _skipFlag = false;
+ _menuItem = NULL;
+ _vm->_events->hideCursor();
+ break;
+ }
+
+ default:
+ // Any other key skips the menu animation
+ _skipFlag = true;
+ return false;
+ }
+
+ return true;
+ }
+
+ int menuIndex;
+
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ if (_vm->_events->isCursorVisible()) {
+ menuIndex = getHighlightedItem(event.mouse.x, event.mouse.y);
+
+ if (menuIndex != _highlightedIndex) {
+// _bgSurface->copyTo(this, Common::Point(0, MADS_MENU_Y));
+
+ _highlightedIndex = menuIndex;
+ if (_highlightedIndex != -1) {
+ MSprite *spr = _menuItem->getFrame(_highlightedIndex);
+ const Common::Point &pt = _itemPosList[_highlightedIndex];
+ spr->copyTo(&_vm->_screen, Common::Point(pt.x, MADS_MENU_Y + pt.y));
+ }
+ }
+ } else {
+ // Skip the menu animation
+ _skipFlag = true;
+ }
+ return true;
+
+ case Common::EVENT_LBUTTONUP:
+ if (_highlightedIndex != -1)
+ handleAction((MADSGameAction)_highlightedIndex);
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+void MainMenu::doFrame() {
+ int itemSize;
+
+ uint32 currTime = g_system->getMillis();
+ if (currTime < _delayTimeout)
+ return;
+ _delayTimeout = currTime + MADS_MENU_ANIM_DELAY;
+
+ // Rex Nebular handling to cycle through the animated display of the menu items
+ if (_menuItemIndex == 7)
+ return;
+
+ // If the user has chosen to skip the menu animation, show the menu immediately
+ if (_skipFlag && !_vm->_events->isCursorVisible()) {
+ // Clear any pending animation
+ _savedSurface.copyTo(&_vm->_screen, Common::Point(0, MADS_MENU_Y));
+
+ // Quickly loop through all the menuitems to display each's final frame
+ while (_menuItemIndex < 7) {
+
+ if (_menuItem) {
+ // Draw the final frame of the menuitem
+ MSprite *spr = _menuItem->getFrame(0);
+ itemSize = _menuItem->getFrame(0)->h;
+ spr->copyTo(&_vm->_screen, Common::Point(_itemPosList[_menuItemIndex - 1].x,
+ _itemPosList[_menuItemIndex - 1].y + MADS_MENU_Y + (itemSize / 2) - (spr->h / 2)));
+
+ delete _menuItem;
+ //copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SCENE_HEIGHT), 0, 0);
+ }
+
+ // Get the next sprite set
+ Common::String spritesName = Resources::formatName(NEBULAR_MENUSCREEN,
+ 'A', ++_menuItemIndex, EXT_SS, "");
+ _menuItem = new SpriteAsset(_vm, spritesName, 0);
+
+ // Slot it into available palette space
+/*
+ RGBList *palData = _menuItem->getRgbList();
+ _vm->_palette->addRange(palData);
+ _menuItem->translate(palData, true);
+ _itemPalData.push_back(palData);
+*/
+ }
+
+ _vm->_events->showCursor();
+ return;
+ }
+
+ if ((_menuItemIndex == 0) || (_frameIndex == 0)) {
+ // Get the next menu item
+ if (_menuItem) {
+ delete _menuItem;
+
+ // Copy over the current display surface area to the background, so the final frame
+ // of the previous menuitem should be kept on the screen
+// copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SCENE_HEIGHT), 0, 0);
+ }
+
+ // Get the next menuitem resource
+ Common::String spritesName = Resources::formatName(NEBULAR_MENUSCREEN,
+ 'A', ++_menuItemIndex, EXT_SS, "");
+
+ /*
+ //sprintf(resName, "RM%dA%d.SS", REX_MENUSCREEN, ++_menuItemIndex);
+ data = _vm->res()->get(resName);
+ _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
+ _vm->res()->toss(resName);
+ */
+ // Slot it into available palette space
+ /*
+ RGBList *palData = _menuItem->getRgbList();
+ _vm->_palette->addRange(palData);
+ _menuItem->translate(palData, true);
+ _itemPalData.push_back(palData);
+ */
+ _frameIndex = _menuItem->getCount() - 1;
+
+ // If the final resource is now loaded, which contains the highlighted versions of
+ // each menuitem, then the startup animation is complete
+ if (_menuItemIndex == 7) {
+ _vm->_events->showCursor();
+ return;
+ }
+ } else {
+ --_frameIndex;
+ }
+
+ // Move to the next menuitem frame
+
+ itemSize = _menuItem->getFrame(0)->h;
+
+ //_bgSurface->copyTo(this, 0, row);
+ MSprite *spr = _menuItem->getFrame(_frameIndex);
+
+ spr->copyTo(&_vm->_screen,
+ Common::Point(_itemPosList[_menuItemIndex - 1].x,
+ _itemPosList[_menuItemIndex - 1].y + MADS_MENU_Y +
+ (itemSize / 2) - (spr->h / 2)));
+}
+
+int MainMenu::getHighlightedItem(int x, int y) {
+ y -= MADS_MENU_Y;
+
+ for (int index = 0; index < 6; ++index) {
+ const Common::Point &pt = _itemPosList[index];
+ MSprite *spr = _menuItem->getFrame(index);
+
+ if ((x >= pt.x) && (y >= pt.y) && (x < (pt.x + spr->w)) && (y < (pt.y + spr->h)))
+ return index;
+ }
+
+ return -1;
+}
+
+void MainMenu::handleAction(MADSGameAction action) {
+ _vm->_events->hideCursor();
+ /*
+ switch (action) {
+ case START_GAME:
+ case RESUME_GAME:
+ // Load a sample starting scene - note that, currently, calling loadScene automatically
+ // removes this menu screen from being displayed
+ _vm->_mouse->cursorOn();
+ _vm->_viewManager->addView(_vm->_scene);
+ _vm->_scene->loadScene(101);
+ return;
+
+ case SHOW_INTRO:
+ _vm->_viewManager->showAnimView("@rexopen");
+ break;
+
+ case CREDITS:
+ _vm->_viewManager->showTextView("credits");
+ return;
+
+ case QUOTES:
+ _vm->_viewManager->showTextView("quotes");
+ return;
+
+ case EXIT:
+ {
+ // When the Exit action is done from the menu, show one of two possible advertisements
+
+ // Activate the scene display with the specified scene
+ bool altAdvert = _vm->_random->getRandomNumber(1000) >= 500;
+ _vm->_scene->loadScene(altAdvert ? 995 : 996);
+ _vm->_viewManager->addView(_vm->_scene);
+
+ _vm->_viewManager->refreshAll();
+ _vm->delay(10000);
+
+ _vm->_events->quitFlag = true;
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ */
+}
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h
new file mode 100644
index 0000000000..581ebe34e4
--- /dev/null
+++ b/engines/mads/nebular/menu_nebular.h
@@ -0,0 +1,80 @@
+/* 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.
+ *
+ * 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.
+ *
+ */
+
+#ifndef MADS_MENU_NEBULAR_H
+#define MADS_MENU_NEBULAR_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/msurface.h"
+#include "mads/nebular/dialogs_nebular.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+namespace Nebular {
+
+enum MADSGameAction { START_GAME, RESUME_GAME, SHOW_INTRO, CREDITS, QUOTES, EXIT };
+
+class MenuView: public FullScreenDialog {
+protected:
+ MADSEngine *_vm;
+ bool _breakFlag;
+
+ virtual void doFrame() = 0;
+
+ virtual bool onEvent(Common::Event &event) = 0;
+public:
+ MenuView(MADSEngine *vm);
+
+ void execute();
+};
+
+class MainMenu: public MenuView {
+private:
+ Common::Point _itemPosList[6];
+ int _usageIndex;
+ int _menuItemIndex;
+ int _frameIndex;
+ bool _skipFlag;
+ SpriteAsset *_menuItem;
+ //Common::Array<RGBList *> _itemPalData;
+ uint32 _delayTimeout;
+ int _highlightedIndex;
+
+ int getHighlightedItem(int x, int y);
+ void handleAction(MADSGameAction action);
+protected:
+ virtual void doFrame();
+
+ virtual bool onEvent(Common::Event &event);
+public:
+ MainMenu(MADSEngine *vm);
+ ~MainMenu();
+};
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_MENU_NEBULAR_H */