[Scummvm-cvs-logs] scummvm master -> 33b770ac60354b3a8bea89bc5babe3f5c0ebf4dc

bluegr bluegr at gmail.com
Wed Oct 15 10:46:07 CEST 2014


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
701d43b5c2 MADS: Initial implementation of sound driver handling for V2 games
33b770ac60 MADS: Move all the anim and text view code into a common class


Commit: 701d43b5c208a605465c59e9caf8767df18c3e04
    https://github.com/scummvm/scummvm/commit/701d43b5c208a605465c59e9caf8767df18c3e04
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2014-10-15T11:43:20+03:00

Commit Message:
MADS: Initial implementation of sound driver handling for V2 games

Changed paths:
    engines/mads/nebular/menu_nebular.cpp



diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp
index a9ed6d3..6a13cea 100644
--- a/engines/mads/nebular/menu_nebular.cpp
+++ b/engines/mads/nebular/menu_nebular.cpp
@@ -922,7 +922,11 @@ void AnimationView::loadNextResource() {
 		const char *chP = strchr(_currentAnimation->_header._soundName.c_str(), '.');
 		assert(chP);
 
-		int driverNum = atoi(chP + 1);
+		// 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);
 	}
 


Commit: 33b770ac60354b3a8bea89bc5babe3f5c0ebf4dc
    https://github.com/scummvm/scummvm/commit/33b770ac60354b3a8bea89bc5babe3f5c0ebf4dc
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2014-10-15T11:43:30+03:00

Commit Message:
MADS: Move all the anim and text view code into a common class

The animation and text players are more or less common among all MADS
games

Changed paths:
  A engines/mads/menu_views.cpp
  A engines/mads/menu_views.h
    engines/mads/debugger.cpp
    engines/mads/dialogs.cpp
    engines/mads/dialogs.h
    engines/mads/module.mk
    engines/mads/nebular/dialogs_nebular.cpp
    engines/mads/nebular/dialogs_nebular.h
    engines/mads/nebular/menu_nebular.cpp
    engines/mads/nebular/menu_nebular.h



diff --git a/engines/mads/debugger.cpp b/engines/mads/debugger.cpp
index 3b77d53..99251f9 100644
--- a/engines/mads/debugger.cpp
+++ b/engines/mads/debugger.cpp
@@ -362,7 +362,7 @@ bool Debugger::Cmd_PlayAnim(int argc, const char **argv) {
 
 		Common::File f;
 		if (f.exists(resName) || f.exists(resName + ".res")) {
-			Nebular::AnimationView::execute(_vm, resName);
+			AnimationView::execute(_vm, resName);
 			return false;
 		} else {
 			debugPrintf("Could not find resource file\n");
@@ -382,7 +382,7 @@ bool Debugger::Cmd_PlayText(int argc, const char **argv) {
 
 		Common::File f;
 		if (f.exists(resName) || f.exists(resName + ".txr")) {
-			Nebular::TextView::execute(_vm, resName);
+			TextView::execute(_vm, resName);
 			return false;
 		} else {
 			debugPrintf("Could not find resource file\n");
diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp
index 7e6909d..5ea8fb1 100644
--- a/engines/mads/dialogs.cpp
+++ b/engines/mads/dialogs.cpp
@@ -395,4 +395,77 @@ Dialogs::Dialogs(MADSEngine *vm)
 	_pendingDialog = DIALOG_NONE;
 }
 
+/*------------------------------------------------------------------------*/
+
+FullScreenDialog::FullScreenDialog(MADSEngine *vm) : _vm(vm) {
+	switch (_vm->getGameID()) {
+	case GType_RexNebular:
+		_screenId = 990;
+		break;
+	case GType_Phantom:
+		_screenId = 920;
+		break;
+	case GType_Dragonsphere:
+		_screenId = 922;
+		break;
+	default:
+		error("FullScreenDialog:Unknown game");
+	}
+	_palFlag = true;
+}
+
+FullScreenDialog::~FullScreenDialog() {
+	_vm->_screen.resetClipBounds();
+	_vm->_game->_scene.restrictScene();
+}
+
+void FullScreenDialog::display() {
+	Game &game = *_vm->_game;
+	Scene &scene = game._scene;
+
+	int nextSceneId = scene._nextSceneId;
+	int currentSceneId = scene._currentSceneId;
+	int priorSceneId = scene._priorSceneId;
+
+	if (_screenId > 0) {
+		SceneInfo *sceneInfo = SceneInfo::init(_vm);
+		sceneInfo->load(_screenId, 0, "", 0, scene._depthSurface, scene._backgroundSurface);
+	}
+
+	scene._priorSceneId = priorSceneId;
+	scene._currentSceneId = currentSceneId;
+	scene._nextSceneId = nextSceneId;
+
+	_vm->_events->initVars();
+	game._kernelMode = KERNEL_ROOM_INIT;
+
+	byte pal[768];
+	if (_vm->_screenFade) {
+		Common::fill(&pal[0], &pal[PALETTE_SIZE], 0);
+		_vm->_palette->setFullPalette(pal);
+	} else {
+		_vm->_palette->getFullPalette(pal);
+		_vm->_palette->fadeOut(pal, nullptr, 0, PALETTE_COUNT, 0, 1, 1, 16);
+	}
+
+	// Set Fx state and palette entries
+	game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kCenterVertTransition;
+	game._trigger = 0;
+
+	// Clear the screen and draw the upper and lower horizontal lines
+	_vm->_screen.empty();
+	_vm->_palette->setLowRange();
+	_vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
+	_vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
+	_vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+
+	// Restrict the screen to the area between the two lines
+	_vm->_screen.setClipBounds(Common::Rect(0, DIALOG_TOP, MADS_SCREEN_WIDTH,
+		DIALOG_TOP + MADS_SCENE_HEIGHT));
+	_vm->_game->_scene.restrictScene();
+
+	if (_screenId > 0)
+		scene._spriteSlots.fullRefresh();
+}
+
 } // End of namespace MADS
diff --git a/engines/mads/dialogs.h b/engines/mads/dialogs.h
index c586a6f..317c7bd 100644
--- a/engines/mads/dialogs.h
+++ b/engines/mads/dialogs.h
@@ -30,6 +30,8 @@
 
 namespace MADS {
 
+#define DIALOG_TOP 22
+
 class Dialog {
 private:
 	void setDialogPalette();
@@ -226,6 +228,36 @@ public:
 	virtual bool show(int messageId, int objectId = -1) = 0;
 };
 
+class FullScreenDialog: public EventTarget {
+protected:
+	/**
+	 * Engine reference
+	 */
+	MADSEngine *_vm;
+
+	/**
+	 * Screen/scene to show background from
+	 */
+	int _screenId;
+
+	/**
+	 * Flag for palette initialization
+	 */
+	bool _palFlag;
+
+	/**
+	 * Handles displaying the screen background and dialog
+	 */
+	virtual void display();
+public:
+	/**
+	 * Constructor
+	 */
+	FullScreenDialog(MADSEngine *vm);
+
+	virtual ~FullScreenDialog();
+};
+
 } // End of namespace MADS
 
 #endif /* MADS_DIALOGS_H */
diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp
new file mode 100644
index 0000000..6acf6cd
--- /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
diff --git a/engines/mads/menu_views.h b/engines/mads/menu_views.h
new file mode 100644
index 0000000..6faa665
--- /dev/null
+++ b/engines/mads/menu_views.h
@@ -0,0 +1,226 @@
+/* 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.
+ *
+ */
+
+#ifndef MADS_MENU_VIEWS_H
+#define MADS_MENU_VIEWS_H
+
+#include "common/scummsys.h"
+#include "mads/dialogs.h"
+#include "mads/game.h"
+#include "mads/msurface.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+class MenuView: public FullScreenDialog {
+protected:
+	bool _breakFlag;
+	bool _redrawFlag;
+
+	virtual void doFrame() = 0;
+
+	virtual void display();
+
+	/**
+	* Event handler
+	*/
+	virtual bool onEvent(Common::Event &event);
+public:
+	MenuView(MADSEngine *vm);
+
+	virtual ~MenuView() {}
+
+	virtual void show();
+};
+
+struct TextLine {
+	Common::Point _pos;
+	Common::String _line;
+	int _textDisplayIndex;
+};
+
+/**
+ * Scrolling text view
+ */
+class TextView : public MenuView {
+private:
+	static char _resourceName[100];
+
+	bool _animating;
+	Common::Array<TextLine> _textLines;
+	Common::Point _pan;
+	int _panSpeed;
+	MSurface _spareScreens[4];
+	int _scrollCount;
+	int _lineY;
+	uint32 _scrollTimeout;
+	int _panCountdown;
+	int _translationX;
+	Common::File _script;
+	char _currentLine[80];
+	MSurface *_spareScreen;
+	Font *_font;
+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);
+
+	/**
+	 * Called when the script is finished
+	 */
+	void scriptDone();
+
+	/**
+	 * Reset the game palette
+	 */
+	void resetPalette();
+protected:
+	virtual void display();
+
+	virtual void doFrame();
+public:
+	/**
+	 * Queue the given text resource for display
+	 */
+	static void execute(MADSEngine *vm, const Common::String &resName);
+
+	TextView(MADSEngine *vm);
+
+	virtual ~TextView();
+};
+
+enum ResyncMode { NEVER, ALWAYS, BEGINNING };
+
+struct ResourceEntry {
+	Common::String _resourceName;
+	int _fx;
+	bool _soundFlag;
+	bool _bgFlag;
+	bool _showWhiteBars;
+
+	ResourceEntry() {}
+	ResourceEntry(const Common::String &resName, int fx, bool soundFlag,
+			bool bgFlag, bool showWhiteBars) {
+		_resourceName = resName;
+		_fx = fx;
+		_soundFlag = soundFlag;
+		_bgFlag = bgFlag;
+		_showWhiteBars = showWhiteBars;
+	}
+};
+
+struct ResIndexEntry {
+	int _id;
+	int _v;
+	Common::String _resourceName;
+
+	ResIndexEntry() {}
+};
+
+/**
+* Animation cutscene view
+*/
+class AnimationView : public MenuView {
+private:
+	static char _resourceName[100];
+
+	Common::File _script;
+	uint32 _previousUpdate;
+	Common::String _currentLine;
+	bool _soundDriverLoaded;
+	bool _resetPalette;
+	ResyncMode _resyncMode;
+	int _sfx;
+	bool _soundFlag;
+	bool _bgLoadFlag;
+	bool _showWhiteBars;
+	Common::Array<ResourceEntry> _resources;
+	Common::Array<ResIndexEntry> _resIndex;
+	int _v1;
+	int _v2;
+	int _resourceIndex;
+	SceneInfo *_sceneInfo;
+	Animation *_currentAnimation;
+	int _manualFrameNumber;
+	SpriteAsset *_manualSpriteSet;
+	int _manualStartFrame, _manualEndFrame;
+	int _manualFrame2;
+	int _animFrameNumber;
+	bool _nextCyclingActive;
+private:
+	void checkResource(const Common::String &resourceName);
+
+	int scanResourceIndex(const Common::String &resourceName);
+
+	void load();
+
+	void processLines();
+
+	void processCommand();
+
+	int getParameter();
+
+	void scriptDone();
+
+	void loadNextResource();
+protected:
+	virtual void display();
+
+	virtual void doFrame();
+
+	virtual bool onEvent(Common::Event &event);
+public:
+	/**
+	* Queue the given text resource for display
+	*/
+	static void execute(MADSEngine *vm, const Common::String &resName);
+
+	AnimationView(MADSEngine *vm);
+
+	virtual ~AnimationView();
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_MENU_VIEWS_H */
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index 96353e9..fc04a2f 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -35,6 +35,7 @@ MODULE_OBJS := \
 	hotspots.o \
 	inventory.o \
 	mads.o \
+	menu_views.o \
 	messages.o \
 	msurface.o \
 	palette.o \
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index 35a7d3b..86244bd 100644
--- a/engines/mads/nebular/dialogs_nebular.cpp
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -553,67 +553,6 @@ void PictureDialog::restore() {
 
 /*------------------------------------------------------------------------*/
 
-FullScreenDialog::FullScreenDialog(MADSEngine *vm) : _vm(vm) {
-	_screenId = 990;
-	_palFlag = true;
-}
-
-FullScreenDialog::~FullScreenDialog() {
-	_vm->_screen.resetClipBounds();
-	_vm->_game->_scene.restrictScene();
-}
-
-void FullScreenDialog::display() {
-	Game &game = *_vm->_game;
-	Scene &scene = game._scene;
-
-	int nextSceneId = scene._nextSceneId;
-	int currentSceneId = scene._currentSceneId;
-	int priorSceneId = scene._priorSceneId;
-
-	if (_screenId > 0) {
-		SceneInfo *sceneInfo = SceneInfo::init(_vm);
-		sceneInfo->load(_screenId, 0, "", 0, scene._depthSurface, scene._backgroundSurface);
-	}
-
-	scene._priorSceneId = priorSceneId;
-	scene._currentSceneId = currentSceneId;
-	scene._nextSceneId = nextSceneId;
-
-	_vm->_events->initVars();
-	game._kernelMode = KERNEL_ROOM_INIT;
-
-	byte pal[768];
-	if (_vm->_screenFade) {
-		Common::fill(&pal[0], &pal[PALETTE_SIZE], 0);
-		_vm->_palette->setFullPalette(pal);
-	} else {
-		_vm->_palette->getFullPalette(pal);
-		_vm->_palette->fadeOut(pal, nullptr, 0, PALETTE_COUNT, 0, 1, 1, 16);
-	}
-
-	// Set Fx state and palette entries
-	game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kCenterVertTransition;
-	game._trigger = 0;
-
-	// Clear the screen and draw the upper and lower horizontal lines
-	_vm->_screen.empty();
-	_vm->_palette->setLowRange();
-	_vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
-	_vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
-	_vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
-
-	// Restrict the screen to the area between the two lines
-	_vm->_screen.setClipBounds(Common::Rect(0, DIALOG_TOP, MADS_SCREEN_WIDTH,
-		DIALOG_TOP + MADS_SCENE_HEIGHT));
-	_vm->_game->_scene.restrictScene();
-
-	if (_screenId > 0)
-		scene._spriteSlots.fullRefresh();
-}
-
-/*------------------------------------------------------------------------*/
-
 GameDialog::DialogLine::DialogLine() {
 	_active = true;
 	_state = DLGSTATE_UNSELECTED;
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index f64f992..d00cd87 100644
--- a/engines/mads/nebular/dialogs_nebular.h
+++ b/engines/mads/nebular/dialogs_nebular.h
@@ -31,8 +31,6 @@ namespace MADS {
 
 namespace Nebular {
 
-#define DIALOG_TOP 22
-
 enum CapitalizationMode { kUppercase = 0, kLowercase = 1, kUpperAndLower = 2 };
 
 class DialogsNebular : public Dialogs {
@@ -109,36 +107,6 @@ enum DialogTextAlign { ALIGN_NONE = 0, ALIGN_CENTER = -1, ALIGN_AT_CENTER = -2,
 
 enum DialogState { DLGSTATE_UNSELECTED = 0, DLGSTATE_SELECTED = 1, DLGSTATE_FOCUSED = 2 };
 
-class FullScreenDialog: public EventTarget {
-protected:
-	/**
-	 * Engine reference
-	 */
-	MADSEngine *_vm;
-
-	/**
-	 * Screen/scene to show background from
-	 */
-	int _screenId;
-
-	/**
-	 * Flag for palette initialization
-	 */
-	bool _palFlag;
-
-	/**
-	 * Handles displaying the screen background and dialog
-	 */
-	virtual void display();
-public:
-	/**
-	 * Constructor
-	 */
-	FullScreenDialog(MADSEngine *vm);
-
-	virtual ~FullScreenDialog();
-};
-
 class GameDialog: public FullScreenDialog {
 	struct DialogLine {
 		bool _active;
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp
index 6a13cea..717e3f6 100644
--- a/engines/mads/nebular/menu_nebular.cpp
+++ b/engines/mads/nebular/menu_nebular.cpp
@@ -23,6 +23,7 @@
 #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"
@@ -36,58 +37,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) {
-			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;
-}
-
-/*------------------------------------------------------------------------*/
-
 MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) {
 	Common::fill(&_menuItems[0], &_menuItems[7], (SpriteAsset *)nullptr);
 	Common::fill(&_menuItemIndexes[0], &_menuItemIndexes[7], -1);
@@ -426,706 +375,6 @@ bool AdvertView::onEvent(Common::Event &event) {
 	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 Nebular
 
 } // End of namespace MADS
diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h
index c05c872..29777a7 100644
--- a/engines/mads/nebular/menu_nebular.h
+++ b/engines/mads/nebular/menu_nebular.h
@@ -25,6 +25,7 @@
 
 #include "common/scummsys.h"
 #include "mads/game.h"
+#include "mads/menu_views.h"
 #include "mads/msurface.h"
 #include "mads/nebular/dialogs_nebular.h"
 
@@ -36,27 +37,6 @@ namespace Nebular {
 
 enum MADSGameAction { START_GAME, RESUME_GAME, SHOW_INTRO, CREDITS, QUOTES, EXIT };
 
-class MenuView: public FullScreenDialog {
-protected:
-	bool _breakFlag;
-	bool _redrawFlag;
-
-	virtual void doFrame() = 0;
-
-	virtual void display();
-
-	/**
-	* Event handler
-	*/
-	virtual bool onEvent(Common::Event &event);
-public:
-	MenuView(MADSEngine *vm);
-
-	virtual ~MenuView() {}
-
-	virtual void show();
-};
-
 class MainMenu: public MenuView {
 private:
 	SpriteAsset *_menuItems[7];
@@ -148,174 +128,6 @@ public:
 	void show();
 };
 
-struct TextLine {
-	Common::Point _pos;
-	Common::String _line;
-	int _textDisplayIndex;
-};
-
-/**
- * Scrolling text view
- */
-class TextView : public MenuView {
-private:
-	static char _resourceName[100];
-
-	bool _animating;
-	Common::Array<TextLine> _textLines;
-	Common::Point _pan;
-	int _panSpeed;
-	MSurface _spareScreens[4];
-	int _scrollCount;
-	int _lineY;
-	uint32 _scrollTimeout;
-	int _panCountdown;
-	int _translationX;
-	Common::File _script;
-	char _currentLine[80];
-	MSurface *_spareScreen;
-	Font *_font;
-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);
-
-	/**
-	 * Called when the script is finished
-	 */
-	void scriptDone();
-
-	/**
-	 * Reset the game palette
-	 */
-	void resetPalette();
-protected:
-	virtual void display();
-
-	virtual void doFrame();
-public:
-	/**
-	 * Queue the given text resource for display
-	 */
-	static void execute(MADSEngine *vm, const Common::String &resName);
-
-	TextView(MADSEngine *vm);
-
-	virtual ~TextView();
-};
-
-enum ResyncMode { NEVER, ALWAYS, BEGINNING };
-
-struct ResourceEntry {
-	Common::String _resourceName;
-	int _fx;
-	bool _soundFlag;
-	bool _bgFlag;
-	bool _showWhiteBars;
-
-	ResourceEntry() {}
-	ResourceEntry(const Common::String &resName, int fx, bool soundFlag,
-			bool bgFlag, bool showWhiteBars) {
-		_resourceName = resName;
-		_fx = fx;
-		_soundFlag = soundFlag;
-		_bgFlag = bgFlag;
-		_showWhiteBars = showWhiteBars;
-	}
-};
-
-struct ResIndexEntry {
-	int _id;
-	int _v;
-	Common::String _resourceName;
-
-	ResIndexEntry() {}
-};
-
-/**
-* Animation cutscene view
-*/
-class AnimationView : public MenuView {
-private:
-	static char _resourceName[100];
-
-	Common::File _script;
-	uint32 _previousUpdate;
-	Common::String _currentLine;
-	bool _soundDriverLoaded;
-	bool _resetPalette;
-	ResyncMode _resyncMode;
-	int _sfx;
-	bool _soundFlag;
-	bool _bgLoadFlag;
-	bool _showWhiteBars;
-	Common::Array<ResourceEntry> _resources;
-	Common::Array<ResIndexEntry> _resIndex;
-	int _v1;
-	int _v2;
-	int _resourceIndex;
-	SceneInfo *_sceneInfo;
-	Animation *_currentAnimation;
-	int _manualFrameNumber;
-	SpriteAsset *_manualSpriteSet;
-	int _manualStartFrame, _manualEndFrame;
-	int _manualFrame2;
-	int _animFrameNumber;
-	bool _nextCyclingActive;
-private:
-	void checkResource(const Common::String &resourceName);
-
-	int scanResourceIndex(const Common::String &resourceName);
-
-	void load();
-
-	void processLines();
-
-	void processCommand();
-
-	int getParameter();
-
-	void scriptDone();
-
-	void loadNextResource();
-protected:
-	virtual void display();
-
-	virtual void doFrame();
-
-	virtual bool onEvent(Common::Event &event);
-public:
-	/**
-	* Queue the given text resource for display
-	*/
-	static void execute(MADSEngine *vm, const Common::String &resName);
-
-	AnimationView(MADSEngine *vm);
-
-	virtual ~AnimationView();
-};
-
 } // End of namespace Nebular
 
 } // End of namespace MADS






More information about the Scummvm-git-logs mailing list