diff options
Diffstat (limited to 'engines/mads/nebular/menu_nebular.cpp')
-rw-r--r-- | engines/mads/nebular/menu_nebular.cpp | 559 |
1 files changed, 33 insertions, 526 deletions
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index 88453ecdba..f2f90e2291 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -21,8 +21,10 @@ */ #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" @@ -36,45 +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; - _vm->_screenFade = SCREEN_FADE_FAST; - - scene._spriteSlots.reset(true); - display(); - - events.setEventTarget(this); - events.hideCursor(); - - while (!_breakFlag && !_vm->shouldQuit()) { - if (_redrawFlag) { - _vm->_game->_scene.drawElements(_vm->_game->_fx, _vm->_game->_fx); - _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); @@ -91,6 +54,17 @@ MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) { } 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() { @@ -132,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(); } @@ -151,6 +128,9 @@ void MainMenu::doFrame() { if (_skipFlag && _menuItemIndex >= 0) { // 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(); @@ -160,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; @@ -340,7 +323,7 @@ void MainMenu::handleAction(MADSGameAction action) { return; case SHOW_INTRO: - AnimationView::execute(_vm, "@rexopen"); + AnimationView::execute(_vm, "rexopen"); break; case CREDITS: @@ -394,6 +377,7 @@ void AdvertView::show() { events.setEventTarget(nullptr); _vm->quitGame(); + events.pollEvents(); } bool AdvertView::onEvent(Common::Event &event) { @@ -407,493 +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); - strncpy(_resourceName, resName.c_str(), sizeof(_resourceName)); - vm->_dialogs->_pendingDialog = DIALOG_TEXTVIEW; -} - -TextView::TextView(MADSEngine *vm) : MenuView(vm) { - _animating = false; - _panSpeed = 0; - Common::fill(&_spareScreens[0], &_spareScreens[10], 0); - _spareScreen = nullptr; - _scrollCount = 0; - _lineY = -1; - _scrollTimeout = 0; - _panCountdown = 0; - _translationX = 0; - - _font = _vm->_font->getFont(FONT_CONVERSATION); - _vm->_palette->resetGamePalette(4, 0); - load(); -} - -TextView::~TextView() { - delete _spareScreen; -} - -void TextView::load() { - Common::String scriptName(_resourceName); - scriptName += ".txr"; - - if (!_script.open(scriptName)) - 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()) { - // Read in the next line - _script.readLine(_currentLine, 79); - char *p = _currentLine + strlen(_currentLine) - 1; - if (*p == '\n') - *p = '\0'; - - // 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 - strncpy(_currentLine, cEnd + 1, sizeof(_currentLine)); - - cStart = strchr(_currentLine, '['); - } - - if (_currentLine[0]) { - processText(); - break; - } - - } else { - processText(); - break; - } - } -} - -void TextView::processCommand() { - 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; - _screenId = getParameter(¶mP); - - } else if (!strncmp(commandStr, "GO", 2)) { - _animating = true; - - } 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 + 7; - - if (!strncmp(paramP, "#SOUND.00", 9)) { - int driverNum = paramP[9] - '0'; - _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 = _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) - _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 = _font->getWidth(_currentLine); - xStart = (MADS_SCREEN_WIDTH - lineWidth) / 2; - } - - // Add the new line to the list of pending lines - TextLine tl; - tl._pos = Common::Point(xStart, 155); - tl._line = _currentLine; - _textLines.push_back(tl); -} - -void TextView::display() { - resetPalette(); - - FullScreenDialog::display(); - _sceneChanged = true; -} - -void TextView::resetPalette() { - _vm->_palette->resetGamePalette(8, 8); - _vm->_palette->setEntry(5, 0, 63, 63); - _vm->_palette->setEntry(6, 0, 45, 45); -} - -void TextView::doFrame() { - Scene &scene = _vm->_game->_scene; - if (!_animating) - return; - - // Only update state if wait period has expired - uint32 currTime = g_system->getMillis(); - - // If a screen transition is in progress and it's time for another column, handle it - if (_spareScreen) { - byte *srcP = _spareScreen->getBasePtr(_translationX, 0); - byte *destP = scene._backgroundSurface.getBasePtr(_translationX, 0); - - for (int y = 0; y < MADS_SCENE_HEIGHT; ++y, srcP += _spareScreen->w, - destP += MADS_SCREEN_WIDTH) { - *destP = *srcP; - } - - if (++_translationX >= MADS_SCREEN_WIDTH) { - // Surface transition is complete - /* - delete _spareScreen; - _spareScreen = nullptr; - -// _vm->_palette->deleteRange(_bgCurrent); - delete _bgCurrent; - _bgCurrent = _bgSpare; - _bgSpare = nullptr; - */ - } - } - - // Make sure it's time for an update - if (currTime < _scrollTimeout) - return; - _scrollTimeout = g_system->getMillis() + TEXT_ANIMATION_DELAY; - _redrawFlag = true; - - // If any panning values are set, pan the background surface - if ((_pan.x != 0) || (_pan.y != 0)) { - if (_panCountdown > 0) { - --_panCountdown; - return; - } - - // Handle horizontal panning - if (_pan.x != 0) { - byte *lineTemp = new byte[_pan.x]; - for (int y = 0; y < MADS_SCENE_HEIGHT; ++y) { - byte *pixelsP = (byte *)scene._backgroundSurface.getBasePtr(0, y); - - // Copy the first X pixels into temp buffer, move the rest of the line - // to the start of the line, and then move temp buffer pixels to end of line - Common::copy(pixelsP, pixelsP + _pan.x, lineTemp); - Common::copy(pixelsP + _pan.x, pixelsP + MADS_SCREEN_WIDTH, pixelsP); - Common::copy(lineTemp, lineTemp + _pan.x, pixelsP + MADS_SCREEN_WIDTH - _pan.x); - } - - delete[] lineTemp; - } - - // Handle vertical panning - if (_pan.y != 0) { - // Store the bottom Y lines into a temp buffer, move the rest of the lines down, - // and then copy the stored lines back to the top of the screen - byte *linesTemp = new byte[_pan.y * MADS_SCREEN_WIDTH]; - byte *pixelsP = (byte *)scene._backgroundSurface.getBasePtr(0, MADS_SCENE_HEIGHT - _pan.y); - Common::copy(pixelsP, pixelsP + MADS_SCREEN_WIDTH * _pan.y, linesTemp); - - for (int y = MADS_SCENE_HEIGHT - 1; y >= _pan.y; --y) { - byte *destP = (byte *)scene._backgroundSurface.getBasePtr(0, y); - byte *srcP = (byte *)scene._backgroundSurface.getBasePtr(0, y - _pan.y); - Common::copy(srcP, srcP + MADS_SCREEN_WIDTH, destP); - } - - Common::copy(linesTemp, linesTemp + _pan.y * MADS_SCREEN_WIDTH, - (byte *)scene._backgroundSurface.getPixels()); - delete[] linesTemp; - } - - // Flag for a full screen refresh - scene._spriteSlots.fullRefresh(); - } - - // Scroll all active text lines up - scene._textDisplay.reset(); - for (int i = _textLines.size() - 1; i >= 0; --i) { - TextLine &tl = _textLines[i]; - tl._pos.y--; - if (tl._pos.y < 0) { - _textLines.remove_at(i); - } else { - scene._textDisplay.add(tl._pos.x, tl._pos.y, 0x605, -1, tl._line, _font); - } - } - - if (_scrollCount > 0) { - // Handling final scrolling of text off of screen - if (--_scrollCount == 0) { - scriptDone(); - return; - } - } else { - // Handling a text row - if (++_lineY == (_font->getHeight() + TEXTVIEW_LINE_SPACING)) - processLines(); - } -} - -void TextView::scriptDone() { - _breakFlag = true; -} - -/*------------------------------------------------------------------------*/ - -char AnimationView::_resourceName[100]; - -void AnimationView::execute(MADSEngine *vm, const Common::String &resName) { - assert(resName.size() < 100); - strncpy(_resourceName, resName.c_str(), sizeof(_resourceName)); - vm->_dialogs->_pendingDialog = DIALOG_ANIMVIEW; -} - -AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) { - _soundDriverLoaded = false; - _previousUpdate = 0; -} - -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(); -} - -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 RexAnimationView::scriptDone() { + AnimationView::scriptDone(); -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"); } } |