aboutsummaryrefslogtreecommitdiff
path: root/engines/mads/nebular/menu_nebular.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mads/nebular/menu_nebular.cpp')
-rw-r--r--engines/mads/nebular/menu_nebular.cpp346
1 files changed, 346 insertions, 0 deletions
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