From 73dfbc70acfdf883237dbb5e961f19a92ff00ded Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 27 Jul 2014 16:48:23 -0400 Subject: MADS: Beginnings of re-implementing text view class --- engines/mads/nebular/dialogs_nebular.cpp | 1 + engines/mads/nebular/menu_nebular.cpp | 219 ++++++++++++++++++++++++++++++- engines/mads/nebular/menu_nebular.h | 45 ++++++- 3 files changed, 262 insertions(+), 3 deletions(-) (limited to 'engines') diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 17c27b44f7..a3cc1b754a 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -542,6 +542,7 @@ FullScreenDialog::FullScreenDialog(MADSEngine *vm) : _vm(vm) { } FullScreenDialog::~FullScreenDialog() { + _vm->_screen._offset.y = 0; } void FullScreenDialog::display() { diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index 363ec06d02..e3f68862a4 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -371,12 +371,230 @@ void MainMenu::handleAction(MADSGameAction action) { /*------------------------------------------------------------------------*/ 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(const Common::String &resName) { assert(resName.size() < 100); strcpy(_resourceName, resName.c_str()); } +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, yp); + + // 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); + + } 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]; @@ -386,7 +604,6 @@ void AnimationView::execute(const Common::String &resName) { strcpy(_resourceName, resName.c_str()); } - } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h index 04ac60fb0d..7e11e78e27 100644 --- a/engines/mads/nebular/menu_nebular.h +++ b/engines/mads/nebular/menu_nebular.h @@ -122,15 +122,54 @@ public: class TextView : public MenuView { private: static char _resourceName[100]; + + bool _animating; + Common::Point _pan; + int _panSpeed; + int _spareScreens[10]; + int _scrollCount; + int _lineY; + uint32 _scrollTimeout; + int _panCountdown; + int _translationX; + Common::File _script; + char _currentLine[80]; + MSurface _textSurface; + MSurface *_spareScreen; +private: + /** + * Load the text resource + */ + void load(); + + /** + * Process the lines + */ + void processLines(); + + /** + * Process a command from the script file + */ + void processCommand(); + + /** + * Process text from the script file + */ + void processText(); + + /** + * Get a parameter from line + */ + int getParameter(const char **paramP); public: /** * Queue the given text resource for display */ static void execute(const Common::String &resName); - TextView(MADSEngine *vm) : MenuView(vm) {} + TextView(MADSEngine *vm); - virtual ~TextView() {} + virtual ~TextView(); }; /** @@ -139,6 +178,8 @@ public: class AnimationView : public MenuView { private: static char _resourceName[100]; + + public: /** * Queue the given text resource for display -- cgit v1.2.3