aboutsummaryrefslogtreecommitdiff
path: root/engines/mads/menu_views.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mads/menu_views.cpp')
-rw-r--r--engines/mads/menu_views.cpp782
1 files changed, 782 insertions, 0 deletions
diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp
new file mode 100644
index 0000000000..6acf6cdf9f
--- /dev/null
+++ b/engines/mads/menu_views.cpp
@@ -0,0 +1,782 @@
+/* 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/menu_views.h"
+#include "mads/resources.h"
+#include "mads/scene.h"
+#include "mads/screen.h"
+
+namespace MADS {
+
+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) {
+ scene._kernelMessages.update();
+
+ _vm->_game->_scene.drawElements(_vm->_game->_fx, _vm->_game->_fx);
+ _redrawFlag = false;
+ }
+
+ _vm->_events->waitForNextFrame();
+ _vm->_game->_fx = kTransitionNone;
+ doFrame();
+ }
+
+ events.setEventTarget(nullptr);
+ _vm->_sound->stop();
+}
+
+void MenuView::display() {
+ _vm->_palette->resetGamePalette(4, 8);
+
+ FullScreenDialog::display();
+}
+
+bool MenuView::onEvent(Common::Event &event) {
+ if (event.type == Common::EVENT_KEYDOWN || event.type == Common::EVENT_LBUTTONDOWN) {
+ _breakFlag = true;
+ _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU;
+ return true;
+ }
+
+ return false;
+}
+
+/*------------------------------------------------------------------------*/
+
+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);
+ Common::strlcpy(_resourceName, resName.c_str(), sizeof(_resourceName));
+ vm->_dialogs->_pendingDialog = DIALOG_TEXTVIEW;
+}
+
+TextView::TextView(MADSEngine *vm) : MenuView(vm) {
+ _animating = false;
+ _panSpeed = 0;
+ _spareScreen = nullptr;
+ _scrollCount = 0;
+ _lineY = -1;
+ _scrollTimeout = 0;
+ _panCountdown = 0;
+ _translationX = 0;
+ _screenId = -1;
+
+ _font = _vm->_font->getFont(FONT_CONVERSATION);
+ _vm->_palette->resetGamePalette(4, 0);
+
+ load();
+}
+
+TextView::~TextView() {
+}
+
+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
+ Common::strlcpy(_currentLine, cEnd + 1, sizeof(_currentLine));
+
+ 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;
+ resetPalette();
+ int screenId = getParameter(&paramP);
+
+ SceneInfo *sceneInfo = SceneInfo::init(_vm);
+ sceneInfo->load(screenId, 0, "", 0, scene._depthSurface, scene._backgroundSurface);
+ scene._spriteSlots.fullRefresh();
+ _redrawFlag = true;
+
+ } else if (!strncmp(commandStr, "GO", 2)) {
+ _animating = true;
+
+ } else if (!strncmp(commandStr, "PAN", 3)) {
+ // Set panning values
+ paramP = commandStr + 3;
+ int panX = getParameter(&paramP);
+ int panY = getParameter(&paramP);
+ int panSpeed = getParameter(&paramP);
+
+ 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(&paramP);
+ _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 r = getParameter(&paramP);
+ byte g = getParameter(&paramP);
+ byte b = getParameter(&paramP);
+
+ _vm->_palette->setEntry(5 + index, r, g, b);
+
+ } 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';
+ assert(spareIndex < 4);
+ int screenId = getParameter(&paramP);
+
+ // Load the spare background
+ SceneInfo *sceneInfo = SceneInfo::init(_vm);
+ sceneInfo->_width = MADS_SCREEN_WIDTH;
+ sceneInfo->_height = MADS_SCENE_HEIGHT;
+ _spareScreens[spareIndex].setSize(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
+ sceneInfo->loadMadsV1Background(screenId, "", SCENEFLAG_TRANSLATE,
+ _spareScreens[spareIndex]);
+ delete sceneInfo;
+
+ } else if (!strncmp(commandStr, "PAGE", 4)) {
+ // Signals to change to a previous specified secondary background
+ paramP = commandStr + 4;
+ int spareIndex = getParameter(&paramP);
+
+ // Only allow background switches if one isn't currently in progress
+ if (!_spareScreen && _spareScreens[spareIndex].getPixels() != nullptr) {
+ _spareScreen = &_spareScreens[spareIndex];
+ _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 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 {
+ int 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, MADS_SCENE_HEIGHT);
+ tl._line = _currentLine;
+ tl._textDisplayIndex = -1;
+ _textLines.push_back(tl);
+}
+
+void TextView::display() {
+ FullScreenDialog::display();
+}
+
+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 *bgP = scene._backgroundSurface.getBasePtr(_translationX, 0);
+ byte *screenP = (byte *)_vm->_screen.getBasePtr(_translationX, 0);
+
+ for (int y = 0; y < MADS_SCENE_HEIGHT; ++y, srcP += MADS_SCREEN_WIDTH,
+ bgP += MADS_SCREEN_WIDTH, screenP += MADS_SCREEN_WIDTH) {
+ *bgP = *srcP;
+ *screenP = *srcP;
+ }
+
+ // Flag the column of the screen is modified
+ _vm->_screen.copyRectToScreen(Common::Rect(_translationX, 0,
+ _translationX + 1, MADS_SCENE_HEIGHT));
+
+ // Keep moving the column to copy to the right
+ if (++_translationX == MADS_SCREEN_WIDTH) {
+ // Surface transition is complete
+ _spareScreen = 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
+ for (int i = _textLines.size() - 1; i >= 0; --i) {
+ TextLine &tl = _textLines[i];
+ if (tl._textDisplayIndex != -1)
+ // Expire the text line that's already on-screen
+ scene._textDisplay.expire(tl._textDisplayIndex);
+
+ tl._pos.y--;
+ if (tl._pos.y < 0) {
+ _textLines.remove_at(i);
+ } else {
+ tl._textDisplayIndex = 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;
+ _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU;
+}
+
+/*------------------------------------------------------------------------*/
+
+char AnimationView::_resourceName[100];
+
+void AnimationView::execute(MADSEngine *vm, const Common::String &resName) {
+ assert(resName.size() < 100);
+ Common::strlcpy(_resourceName, resName.c_str(), sizeof(_resourceName));
+ vm->_dialogs->_pendingDialog = DIALOG_ANIMVIEW;
+}
+
+AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) {
+ _redrawFlag = false;
+
+ _soundDriverLoaded = false;
+ _previousUpdate = 0;
+ _screenId = -1;
+ _resetPalette = false;
+ _resyncMode = NEVER;
+ _v1 = 0;
+ _v2 = -1;
+ _resourceIndex = -1;
+ _currentAnimation = nullptr;
+ _sfx = 0;
+ _soundFlag = _bgLoadFlag = true;
+ _showWhiteBars = true;
+ _manualFrameNumber = 0;
+ _manualSpriteSet = nullptr;
+ _manualStartFrame = _manualEndFrame = 0;
+ _manualFrame2 = 0;
+ _animFrameNumber = 0;
+ _nextCyclingActive = false;
+ _sceneInfo = SceneInfo::init(_vm);
+
+ load();
+}
+
+AnimationView::~AnimationView() {
+ delete _currentAnimation;
+ delete _sceneInfo;
+}
+
+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 AnimationView::display() {
+ Scene &scene = _vm->_game->_scene;
+ _vm->_palette->initPalette();
+ Common::fill(&_vm->_palette->_cyclingPalette[0], &_vm->_palette->_cyclingPalette[PALETTE_SIZE], 0);
+
+ _vm->_palette->resetGamePalette(1, 8);
+ scene._spriteSlots.reset();
+ scene._paletteCycles.clear();
+
+ MenuView::display();
+}
+
+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;
+
+ if (_resourceIndex == -1 || _currentAnimation->freeFlag()) {
+ if (++_resourceIndex == (int)_resources.size()) {
+ scriptDone();
+ } else {
+ scene._frameStartTime = 0;
+ loadNextResource();
+ }
+ } else if (_currentAnimation->getCurrentFrame() == 1) {
+ scene._cyclingActive = _nextCyclingActive;
+ }
+
+ if (_currentAnimation) {
+ ++scene._frameStartTime;
+ _currentAnimation->update();
+ _redrawFlag = true;
+ }
+}
+
+void AnimationView::loadNextResource() {
+ Scene &scene = _vm->_game->_scene;
+ Palette &palette = *_vm->_palette;
+ ResourceEntry &resEntry = _resources[_resourceIndex];
+ Common::Array<PaletteCycle> paletteCycles;
+
+ if (resEntry._bgFlag)
+ palette.resetGamePalette(1, 8);
+
+ palette._mainPalette[253 * 3] = palette._mainPalette[253 * 3 + 1]
+ = palette._mainPalette[253 * 3 + 2] = 0xb4;
+ palette.setPalette(&palette._mainPalette[253 * 3], 253, 1);
+
+ // Free any previous messages
+ scene._kernelMessages.reset();
+
+ // Handle the bars at the top/bottom
+ if (resEntry._showWhiteBars) {
+ // For animations the screen has been clipped to the middle 156 rows.
+ // So although it's slightly messy, bypass our screen class entirely,
+ // and draw the horizontal lines directly on the physiacl screen surface
+ Graphics::Surface *s = g_system->lockScreen();
+ s->hLine(0, 20, MADS_SCREEN_WIDTH, 253);
+ s->hLine(0, 179, MADS_SCREEN_WIDTH, 253);
+ g_system->unlockScreen();
+ }
+
+ // Load the new animation
+ delete _currentAnimation;
+ _currentAnimation = Animation::init(_vm, &scene);
+ int flags = ANIMFLAG_ANIMVIEW | (resEntry._bgFlag ? ANIMFLAG_LOAD_BACKGROUND : 0);
+ _currentAnimation->load(scene._backgroundSurface, scene._depthSurface,
+ resEntry._resourceName, flags, &paletteCycles, _sceneInfo);
+
+ // Signal for a screen refresh
+ scene._spriteSlots.fullRefresh();
+
+ // If a sound driver has been specified, then load the correct one
+ if (!_currentAnimation->_header._soundName.empty()) {
+ const char *chP = strchr(_currentAnimation->_header._soundName.c_str(), '.');
+ assert(chP);
+
+ // Handle both Rex naming (xxx.009) and naming in later games (e.g. xxx.ph9)
+ int driverNum = atoi(chP + 3);
+ // HACK for Dragon
+ if (_currentAnimation->_header._soundName == "#SOUND.DRG")
+ driverNum = 9;
+ _vm->_sound->init(driverNum);
+ }
+
+ // Handle any manual setup
+ if (_currentAnimation->_header._manualFlag) {
+ _manualFrameNumber = _currentAnimation->_header._spritesIndex;
+ _manualSpriteSet = _currentAnimation->getSpriteSet(_manualFrameNumber);
+ }
+
+ // Set the sound data for the animation
+ _vm->_sound->setEnabled(resEntry._soundFlag);
+
+ Common::String dsrName = _currentAnimation->_header._dsrName;
+ if (!dsrName.empty())
+ _vm->_audio->setSoundGroup(dsrName);
+
+ // Start the new animation
+ _currentAnimation->startAnimation(0);
+
+ // Handle the palette and cycling palette
+ scene._cyclingActive = false;
+ Common::copy(&palette._mainPalette[0], &palette._mainPalette[PALETTE_SIZE],
+ &palette._cyclingPalette[0]);
+
+ _vm->_game->_fx = (ScreenTransition)resEntry._fx;
+ _nextCyclingActive = paletteCycles.size() > 0;
+ if (!_vm->_game->_fx) {
+ palette.setFullPalette(palette._mainPalette);
+ }
+
+ scene.initPaletteAnimation(paletteCycles, _nextCyclingActive && !_vm->_game->_fx);
+}
+
+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()) {
+ // Get in next line
+ _currentLine.clear();
+ char c;
+ while (!_script.eos() && (c = _script.readByte()) != '\n') {
+ if (c != '\r' && c != '\0')
+ _currentLine += c;
+ }
+
+ // Process the line
+ while (!_currentLine.empty()) {
+ if (_currentLine.hasPrefix("-")) {
+ _currentLine.deleteChar(0);
+
+ processCommand();
+ } else {
+ // Get resource name
+ Common::String resName;
+ while (!_currentLine.empty() && (c = _currentLine[0]) != ' ') {
+ _currentLine.deleteChar(0);
+ resName += c;
+ }
+
+ // Add resource into list along with any set state information
+ _resources.push_back(ResourceEntry(resName, _sfx, _soundFlag,
+ _bgLoadFlag, _showWhiteBars));
+
+ // Fx resets between resource entries
+ _sfx = 0;
+ }
+
+ // Skip any spaces
+ while (_currentLine.hasPrefix(" "))
+ _currentLine.deleteChar(0);
+ }
+ }
+}
+
+void AnimationView::processCommand() {
+ // Get the command character
+ char commandChar = toupper(_currentLine[0]);
+ _currentLine.deleteChar(0);
+
+ // Handle the command
+ switch (commandChar) {
+ case 'B':
+ _soundFlag = !_soundFlag;
+ break;
+ case 'H':
+ // -h[:ex] Disable EMS / XMS high memory support
+ if (_currentLine.hasPrefix(":"))
+ _currentLine.deleteChar(0);
+ while (_currentLine.hasPrefix("e") || _currentLine.hasPrefix("x"))
+ _currentLine.deleteChar(0);
+ break;
+ case 'O':
+ // -o:xxx Specify opening special effect
+ assert(_currentLine[0] == ':');
+ _currentLine.deleteChar(0);
+ _sfx = getParameter();
+ break;
+ case 'P':
+ // Switch to CONCAT mode, which is ignored anyway
+ break;
+ case 'R': {
+ // Resynch timer (always, beginning, never)
+ assert(_currentLine[0] == ':');
+ _currentLine.deleteChar(0);
+
+ char v = toupper(_currentLine[0]);
+ _currentLine.deleteChar(0);
+ if (v == 'N')
+ _resyncMode = NEVER;
+ else if (v == 'A')
+ _resyncMode = ALWAYS;
+ else if (v == 'B')
+ _resyncMode = BEGINNING;
+ else
+ error("Unknown parameter");
+ break;
+ }
+ case 'W':
+ // Switch white bars being visible
+ _showWhiteBars = !_showWhiteBars;
+ break;
+ case 'X':
+ // Exit after animation finishes. Ignore
+ break;
+ case 'D':
+ // Unimplemented and ignored in the original. Ignore as well
+ break;
+ case 'Y':
+ // Reset palette on startup
+ _resetPalette = true;
+ break;
+ default:
+ error("Unknown command char: '%c'", commandChar);
+ }
+}
+
+int AnimationView::getParameter() {
+ int result = 0;
+
+ while (!_currentLine.empty()) {
+ char c = _currentLine[0];
+
+ if (c >= '0' && c <= '9') {
+ _currentLine.deleteChar(0);
+ result = result * 10 + (c - '0');
+ } else {
+ break;
+ }
+ }
+
+ return result;
+}
+
+void AnimationView::checkResource(const Common::String &resourceName) {
+ //bool hasSuffix = false;
+
+}
+
+int AnimationView::scanResourceIndex(const Common::String &resourceName) {
+ int foundIndex = -1;
+
+ if (_v1) {
+ const char *chP = strchr(resourceName.c_str(), '\\');
+ if (!chP) {
+ chP = strchr(resourceName.c_str(), '*');
+ }
+
+ Common::String resName = chP ? Common::String(chP + 1) : resourceName;
+
+ if (_v2 != 3) {
+ assert(_resIndex.size() == 0);
+ }
+
+ // Scan for the resource name
+ for (uint resIndex = 0; resIndex < _resIndex.size(); ++resIndex) {
+ ResIndexEntry &resEntry = _resIndex[resIndex];
+ if (resEntry._resourceName.compareToIgnoreCase(resourceName)) {
+ foundIndex = resIndex;
+ break;
+ }
+ }
+ }
+
+ if (foundIndex >= 0) {
+ // TODO
+ }
+ return -1;
+}
+
+} // End of namespace MADS