diff options
Diffstat (limited to 'engines/mads/nebular/menu_nebular.cpp')
-rw-r--r-- | engines/mads/nebular/menu_nebular.cpp | 463 |
1 files changed, 48 insertions, 415 deletions
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index cb8f56bd05..28de4e5650 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -21,9 +21,12 @@ */ #include "common/scummsys.h" +#include "common/config-manager.h" #include "mads/game.h" #include "mads/mads.h" +#include "mads/menu_views.h" #include "mads/resources.h" +#include "mads/scene.h" #include "mads/screen.h" #include "mads/nebular/menu_nebular.h" @@ -35,44 +38,6 @@ namespace Nebular { #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; - _redrawFlag = true; - _palFlag = false; -} - -void MenuView::show() { - Scene &scene = _vm->_game->_scene; - EventsManager &events = *_vm->_events; - display(); - - events.setEventTarget(this); - events.hideCursor(); - - while (!_breakFlag && !_vm->shouldQuit()) { - if (_redrawFlag) { - scene.drawElements(_vm->_game->_fx, _vm->_game->_fx); - - _vm->_screen.copyRectToScreen(Common::Rect(0, 0, 320, 200)); - _redrawFlag = false; - } - - _vm->_events->waitForNextFrame(); - _vm->_game->_fx = kTransitionNone; - doFrame(); - } - - events.setEventTarget(nullptr); -} - -void MenuView::display() { - _vm->_palette->resetGamePalette(4, 8); - - FullScreenDialog::display(); -} - -/*------------------------------------------------------------------------*/ - MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) { Common::fill(&_menuItems[0], &_menuItems[7], (SpriteAsset *)nullptr); Common::fill(&_menuItemIndexes[0], &_menuItemIndexes[7], -1); @@ -83,9 +48,23 @@ MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) { _highlightedIndex = -1; _selectedIndex = -1; _buttonDown = false; + + for (int i = 0; i < 7; ++i) + _menuItems[i] = nullptr; } MainMenu::~MainMenu() { + Scene &scene = _vm->_game->_scene; + for (int i = 0; i < 7; ++i) { + if (_menuItemIndexes[i] != -1) + scene._sprites.remove(_menuItemIndexes[i]); + } + + scene._spriteSlots.reset(); +} + +bool MainMenu::shouldShowQuotes() { + return ConfMan.hasKey("ShowQuotes") && ConfMan.getBool("ShowQuotes"); } void MainMenu::display() { @@ -104,10 +83,10 @@ void MainMenu::display() { // Register the menu item area in the screen objects MSprite *frame0 = _menuItems[i]->getFrame(0); Common::Point pt(frame0->_offset.x - (frame0->w / 2), - frame0->_offset.y - frame0->h + _vm->_screen._offset.y); + frame0->_offset.y - frame0->h); screenObjects.add( - Common::Rect(pt.x, pt.y, pt.x + frame0->w, pt.y + frame0->h), - LAYER_GUI, CAT_COMMAND, i); + Common::Rect(pt.x, pt.y + DIALOG_TOP, pt.x + frame0->w, + pt.y + frame0->h + DIALOG_TOP), LAYER_GUI, CAT_COMMAND, i); } // Set the cursor for when it's shown @@ -127,6 +106,9 @@ void MainMenu::doFrame() { handleAction((MADSGameAction)_selectedIndex); } else { for (_menuItemIndex = 0; _menuItemIndex < 6; ++_menuItemIndex) { + if (_menuItemIndex == 4 && !shouldShowQuotes()) + continue; + if (_menuItemIndex != _selectedIndex) { addSpriteSlot(); } @@ -144,8 +126,11 @@ void MainMenu::doFrame() { // If the user has chosen to skip the animation, show the full menu immediately if (_skipFlag && _menuItemIndex >= 0) { - // Quickly loop through all the menu items to display each's final frame + // Quickly loop through all the menu items to display each's final frame for (; _menuItemIndex < 6; ++_menuItemIndex) { + if (_menuItemIndex == 4 && !shouldShowQuotes()) + continue; + // Draw the final frame of the menuitem _frameIndex = 0; addSpriteSlot(); @@ -155,9 +140,12 @@ void MainMenu::doFrame() { } else { if ((_menuItemIndex == -1) || (_frameIndex == 0)) { if (++_menuItemIndex == 6) { + // Reached end of display animation _vm->_events->showCursor(); return; + } else if (_menuItemIndex == 4 && !shouldShowQuotes()) { + ++_menuItemIndex; } _frameIndex = _menuItems[_menuItemIndex]->getCount() - 1; @@ -173,7 +161,7 @@ void MainMenu::doFrame() { void MainMenu::addSpriteSlot() { Scene &scene = _vm->_game->_scene; SpriteSlots &spriteSlots = scene._spriteSlots; - + int seqIndex = (_menuItemIndex < 6) ? _menuItemIndex : _frameIndex; spriteSlots.deleteTimer(seqIndex); @@ -267,7 +255,7 @@ bool MainMenu::onEvent(Common::Event &event) { } return true; - case Common::EVENT_MOUSEMOVE: + case Common::EVENT_MOUSEMOVE: if (_buttonDown) { int menuIndex = getHighlightedItem(event.mouse); if (menuIndex != _highlightedIndex) { @@ -299,7 +287,7 @@ bool MainMenu::onEvent(Common::Event &event) { default: break; } - + return false; } @@ -329,13 +317,13 @@ void MainMenu::handleAction(MADSGameAction action) { break; case RESUME_GAME: - // The original resumed the most recently saved game. Instead, + // The original resumed the most recently saved game. Instead, // just show the load game scren _vm->_dialogs->_pendingDialog = DIALOG_RESTORE; return; case SHOW_INTRO: - AnimationView::execute(_vm, "@rexopen"); + AnimationView::execute(_vm, "rexopen"); break; case CREDITS: @@ -366,12 +354,14 @@ void AdvertView::show() { uint32 expiryTime = g_system->getMillis() + 10 * 1000; _vm->_palette->resetGamePalette(4, 8); - + // Load the advert background onto the screen SceneInfo *sceneInfo = SceneInfo::init(_vm); sceneInfo->load(screenId, 0, Common::String(), 0, _vm->_game->_scene._depthSurface, _vm->_screen); _vm->_screen.copyRectToScreen(_vm->_screen.getBounds()); + _vm->_palette->setFullPalette(_vm->_palette->_mainPalette); + delete sceneInfo; EventsManager &events = *_vm->_events; @@ -387,6 +377,7 @@ void AdvertView::show() { events.setEventTarget(nullptr); _vm->quitGame(); + events.pollEvents(); } bool AdvertView::onEvent(Common::Event &event) { @@ -400,374 +391,16 @@ bool AdvertView::onEvent(Common::Event &event) { /*------------------------------------------------------------------------*/ -char TextView::_resourceName[100]; -#define TEXTVIEW_LINE_SPACING 2 -#define TEXT_ANIMATION_DELAY 100 -#define TV_NUM_FADE_STEPS 40 -#define TV_FADE_DELAY_MILLI 50 - -void TextView::execute(MADSEngine *vm, const Common::String &resName) { - assert(resName.size() < 100); - strcpy(_resourceName, resName.c_str()); - vm->_dialogs->_pendingDialog = DIALOG_TEXTVIEW; -} - -TextView::TextView(MADSEngine *vm) : MenuView(vm), - _textSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT + _vm->_font->getHeight()) { - _animating = false; - _panSpeed = 0; - Common::fill(&_spareScreens[0], &_spareScreens[10], 0); - _spareScreen = nullptr; - _scrollCount = 0; - _lineY = -1; - _scrollTimeout = 0; - _panCountdown = 0; - _translationX = 0; -} - -TextView::~TextView() { - delete _spareScreen; -} - -void TextView::load() { - if (!_script.open(_resourceName)) - error("Could not open resource %s", _resourceName); - - processLines(); -} - -void TextView::processLines() { - if (_script.eos()) - error("Attempted to read past end of response file"); - - while (!_script.eos()) { - _script.readLine(_currentLine, 79); - - // Commented out line, so go loop for another - if (_currentLine[0] == '#') - continue; - - // Process the line - char *cStart = strchr(_currentLine, '['); - if (cStart) { - while (cStart) { - // Loop for possible multiple commands on one line - char *cEnd = strchr(_currentLine, ']'); - if (!cEnd) - error("Unterminated command '%s' in response file", _currentLine); - - *cEnd = '\0'; - processCommand(); - - // Copy rest of line (if any) to start of buffer - strcpy(_currentLine, cEnd + 1); - - cStart = strchr(_currentLine, '['); - } - - if (_currentLine[0]) { - processText(); - break; - } - - } else { - processText(); - break; - } - } -} - -void TextView::processCommand() { - Scene &scene = _vm->_game->_scene; - Common::String scriptLine(_currentLine + 1); - scriptLine.toUppercase(); - const char *paramP; - const char *commandStr = scriptLine.c_str(); - - if (!strncmp(commandStr, "BACKGROUND", 10)) { - // Set the background - paramP = commandStr + 10; - int screenId = getParameter(¶mP); - - SceneInfo *sceneInfo = SceneInfo::init(_vm); - sceneInfo->load(screenId, 0, Common::String(), 0, scene._depthSurface, - scene._backgroundSurface); - - } else if (!strncmp(commandStr, "GO", 2)) { - _animating = true; - - // Grab what the final palete will be - byte destPalette[PALETTE_SIZE]; - _vm->_palette->grabPalette(destPalette, 0, 256); - - // Copy the loaded background, if any, to the view surface - //int yp = 22; - //scene._backgroundSurface.copyTo(this, 0, 22); - - // Handle fade-in - //byte srcPalette[768]; - //Common::fill(&srcPalette[0], &srcPalette[PALETTE_SIZE], 0); - //_vm->_palette->fadeIn(srcPalette, destPalette, 0, PALETTE_COUNT, 0, 0, - // TV_FADE_DELAY_MILLI, TV_NUM_FADE_STEPS); - _vm->_game->_fx = kTransitionFadeIn; - - } else if (!strncmp(commandStr, "PAN", 3)) { - // Set panning values - paramP = commandStr + 3; - int panX = getParameter(¶mP); - int panY = getParameter(¶mP); - int panSpeed = getParameter(¶mP); - - if ((panX != 0) || (panY != 0)) { - _pan = Common::Point(panX, panY); - _panSpeed = panSpeed; - } - - } else if (!strncmp(commandStr, "DRIVER", 6)) { - // Set the driver to use - paramP = commandStr + 6; - int driverNum = getParameter(¶mP); - _vm->_sound->init(driverNum); - - } else if (!strncmp(commandStr, "SOUND", 5)) { - // Set sound number - paramP = commandStr + 5; - int soundId = getParameter(¶mP); - _vm->_sound->command(soundId); - - } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') || - (commandStr[5] == '1'))) { - // Set the text colors - int index = commandStr[5] - '0'; - paramP = commandStr + 6; - - byte palEntry[3]; - palEntry[0] = getParameter(¶mP) << 2; - palEntry[1] = getParameter(¶mP) << 2; - palEntry[2] = getParameter(¶mP) << 2; - _vm->_palette->setPalette(&palEntry[0], 5 + index, 1); - - } else if (!strncmp(commandStr, "SPARE", 5)) { - // Sets a secondary background number that can be later switched in with a PAGE command - paramP = commandStr + 6; - int spareIndex = commandStr[5] - '0'; - if ((spareIndex >= 0) && (spareIndex <= 9)) { - int screenId = getParameter(¶mP); - - _spareScreens[spareIndex] = screenId; - } - - } else if (!strncmp(commandStr, "PAGE", 4)) { - // Signals to change to a previous specified secondary background - paramP = commandStr + 4; - int spareIndex = getParameter(¶mP); - - // Only allow background switches if one isn't currently in progress - if (!_spareScreen && (_spareScreens[spareIndex] != 0)) { - _spareScreen = new MSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT); - //_spareScreen->loadBackground(_spareScreens[spareIndex], &_bgSpare); - - _translationX = 0; - } - - } else { - error("Unknown response command: '%s'", commandStr); - } -} - -int TextView::getParameter(const char **paramP) { - if ((**paramP != '=') && (**paramP != ',')) - return 0; - - int result = 0; - ++*paramP; - while ((**paramP >= '0') && (**paramP <= '9')) { - result = result * 10 + (**paramP - '0'); - ++*paramP; - } - - return result; -} - -void TextView::processText() { - int lineWidth, xStart; - - if (!strcmp(_currentLine, "***")) { - // Special signifier for end of script - _scrollCount = _vm->_font->getHeight() * 13; - _lineY = -1; - return; - } - - _lineY = 0; - - // Lines are always centered, except if line contains a '@', in which case the - // '@' marks the position that must be horizontally centered - char *centerP = strchr(_currentLine, '@'); - if (centerP) { - *centerP = '\0'; - xStart = (MADS_SCREEN_WIDTH / 2) - _vm->_font->getWidth(_currentLine); - - // Delete the @ character and shift back the remainder of the string - char *p = centerP + 1; - if (*p == ' ') ++p; - strcpy(centerP, p); - - } else { - lineWidth = _vm->_font->getWidth(_currentLine); - xStart = (MADS_SCREEN_WIDTH - lineWidth) / 2; - } - - // Copy the text line onto the bottom of the textSurface surface, which will allow it - // to gradually scroll onto the screen - int yp = _textSurface.h - _vm->_font->getHeight() - TEXTVIEW_LINE_SPACING; - _textSurface.fillRect(Common::Rect(0, yp, MADS_SCREEN_WIDTH, _textSurface.h), 0); - _vm->_font->writeString(&_textSurface, _currentLine, Common::Point(xStart, yp)); -} - -/*------------------------------------------------------------------------*/ - -char AnimationView::_resourceName[100]; - -void AnimationView::execute(MADSEngine *vm, const Common::String &resName) { - assert(resName.size() < 100); - strcpy(_resourceName, resName.c_str()); - vm->_dialogs->_pendingDialog = DIALOG_ANIMVIEW; -} - -AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) { - _soundDriverLoaded = false; -} - -void AnimationView::load() { - Common::String resName(_resourceName); - if (!resName.hasSuffix(".")) - resName += ".res"; - - if (!_script.open(resName)) - error("Could not open resource %s", resName.c_str()); - - processLines(); -} +void RexAnimationView::scriptDone() { + AnimationView::scriptDone(); -bool AnimationView::onEvent(Common::Event &event) { - // Wait for the Escape key or a mouse press - if (((event.type == Common::EVENT_KEYDOWN) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) || - (event.type == Common::EVENT_RBUTTONUP)) { - scriptDone(); - return true; - } - - return false; -} - -void AnimationView::doFrame() { - Scene &scene = _vm->_game->_scene; - int bgNumber = 0; - - // Only update state if wait period has expired - if (_previousUpdate > 0) { - if (g_system->getMillis() - _previousUpdate < 3000) { - return; - } else { - // time for an update - _previousUpdate = g_system->getMillis(); - } - } else { - _previousUpdate = g_system->getMillis(); - return; - } - - char bgFile[10]; - strncpy(bgFile, _currentFile, 5); - bgFile[0] = bgFile[2]; - bgFile[1] = bgFile[3]; - bgFile[2] = bgFile[4]; - bgFile[3] = '\0'; - bgNumber = atoi(bgFile); - sprintf(bgFile, "rm%i.art", bgNumber); - - // Not all scenes have a background. If there is one, refresh it - if (Common::File::exists(bgFile)) { - _vm->_palette->resetGamePalette(4, 8); - SceneInfo *sceneInfo = SceneInfo::init(_vm); - sceneInfo->load(bgNumber, 0, Common::String(), 0, scene._depthSurface, - scene._backgroundSurface); - } - - // Read next line - processLines(); -} - -void AnimationView::scriptDone() { - _breakFlag = true; - _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU; -} - -void AnimationView::processLines() { - if (_script.eos()) { - // end of script, end animation - scriptDone(); - return; - } - - while (!_script.eos()) { - _script.readLine(_currentLine, 79); - - // Process the line - char *cStart = strchr(_currentLine, '-'); - if (cStart) { - while (cStart) { - // Loop for possible multiple commands on one line - char *cEnd = strchr(_currentLine, ' '); - if (!cEnd) - error("Unterminated command '%s' in response file", _currentLine); - - *cEnd = '\0'; - processCommand(); - - // Copy rest of line (if any) to start of buffer - // Don't use strcpy() here, because if the - // rest of the line is the longer of the two - // strings, the memory areas will overlap. - memmove(_currentLine, cEnd + 1, strlen(cEnd + 1) + 1); - - cStart = strchr(_currentLine, '-'); - } - - if (_currentLine[0]) { - sprintf(_currentFile, "%s", _currentLine); - //printf("File: %s\n", _currentLine); - break; - } - - } else { - sprintf(_currentFile, "%s", _currentLine); - warning("File: %s\n", _currentLine); - break; - } - } -} - -void AnimationView::processCommand() { - Common::String commandLine(_currentLine + 1); - commandLine.toUppercase(); - const char *commandStr = commandLine.c_str(); - const char *param = commandStr; - - if (!strncmp(commandStr, "X", 1)) { - //printf("X "); - } else if (!strncmp(commandStr, "W", 1)) { - //printf("W "); - } else if (!strncmp(commandStr, "R", 1)) { - param = param + 2; - //printf("R:%s ", param); - } else if (!strncmp(commandStr, "O", 1)) { - // Set the transition effect - param = param + 2; - _vm->_game->_fx = (ScreenTransition)atoi(param); - } else { - error("Unknown response command: '%s'", commandStr); + Common::String s = getResourceName(); + if (s == "rexend1") { + TextView::execute(_vm, "ending1"); + } else if (s == "rexend2") { + TextView::execute(_vm, "ending2"); + } else if (s == "rexend3") { + TextView::execute(_vm, "credits"); } } |