[Scummvm-git-logs] scummvm master -> 5b72fbdcbd7f2c2c8191d6c362e84ec53628516b

dreammaster dreammaster at scummvm.org
Sun Mar 11 02:12:43 CET 2018


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

Summary:
5b72fbdcbd XEEN: Implementing subtitles display logic


Commit: 5b72fbdcbd7f2c2c8191d6c362e84ec53628516b
    https://github.com/scummvm/scummvm/commit/5b72fbdcbd7f2c2c8191d6c362e84ec53628516b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-03-10T20:12:25-05:00

Commit Message:
XEEN: Implementing subtitles display logic

Changed paths:
  A engines/xeen/subtitles.cpp
  A engines/xeen/subtitles.h
    engines/xeen/cutscenes.cpp
    engines/xeen/cutscenes.h
    engines/xeen/detection_tables.h
    engines/xeen/locations.cpp
    engines/xeen/module.mk
    engines/xeen/sound.cpp
    engines/xeen/sound.h
    engines/xeen/worldofxeen/clouds_cutscenes.cpp
    engines/xeen/worldofxeen/clouds_cutscenes.h
    engines/xeen/worldofxeen/darkside_cutscenes.cpp
    engines/xeen/worldofxeen/darkside_cutscenes.h


diff --git a/engines/xeen/cutscenes.cpp b/engines/xeen/cutscenes.cpp
index e7a604f..d799049 100644
--- a/engines/xeen/cutscenes.cpp
+++ b/engines/xeen/cutscenes.cpp
@@ -25,91 +25,6 @@
 
 namespace Xeen {
 
-static const char *SUBTITLE_LINE = "\xC" "35\x3" "c\xB" "190\x9" "000%s";
-
-void Cutscenes::resetSubtitles(uint lineNum, uint defaultSize) {
-	_subtitleLineNum = lineNum;
-	_subtitleSize = defaultSize;
-	recordTime();
-}
-
-void Cutscenes::showSubtitles(uint windowIndex) {
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
-	Windows &windows = *_vm->_windows;
-
-	if (sound._fxOn || _vm->shouldExit()) {
-		// Sound is on, so subtitles aren't needed
-		resetSubtitles(0, 0);
-	} else {
-		if (timeElapsed() > 1) {
-			++_subtitleSize;
-			const Common::String &line = _subtitles[_subtitleLineNum];
-			Common::String lineStr(line.c_str(), line.c_str() + _subtitleSize);
-			_subtitleLine = Common::String::format(SUBTITLE_LINE, lineStr.c_str());
-
-			// If displayed a full line, then move to the next line
-			if (_subtitleSize == line.size()) {
-				_subtitleSize = 0;
-				if (++_subtitleLineNum == _subtitles.size())
-					_subtitleLineNum = 0;
-			}
-		}
-
-		// Draw the box sprite
-		if (!_boxSprites)
-			// Not already loaded, so load it
-			_boxSprites = new SpriteResource("box.vga");
-		_boxSprites->draw(0, 0, Common::Point(36, 189));
-
-		// Write the subtitle line
-		windows[windowIndex].writeString(_subtitleLine);
-	}
-
-	screen.update();
-}
-
-void Cutscenes::freeSubtitles() {
-	delete _boxSprites;
-	_boxSprites = nullptr;
-	_subtitles.clear();
-}
-
-bool Cutscenes::subtitlesWait(uint minTime) {
-	EventsManager &events = *_vm->_events;
-
-	events.updateGameCounter();
-	recordTime();
-	while (events.timeElapsed() < minTime || _subtitleSize != 0) {
-		events.pollEventsAndWait();
-		if (events.isKeyMousePressed())
-			return false;
-
-		showSubtitles();
-	}
-
-	return true;
-}
-
-bool Cutscenes::waitForLineOrSound() {
-	while (_vm->_sound->isSoundPlaying() || _subtitleSize) {
-		showSubtitles();
-		_vm->_events->pollEventsAndWait();
-		if (_vm->_events->isKeyMousePressed())
-			return false;
-	}
-
-	return true;
-}
-
-void Cutscenes::recordTime() {
-	_vm->_events->timeMark1();
-}
-
-uint Cutscenes::timeElapsed() {
-	return _vm->_events->timeElapsed1();
-}
-
 uint Cutscenes::getSpeakingFrame(uint minFrame, uint maxFrame) {
 	uint interval = g_system->getMillis() / 100;
 	return minFrame + interval % (maxFrame + 1 - minFrame);
diff --git a/engines/xeen/cutscenes.h b/engines/xeen/cutscenes.h
index aa55014..b3bc778 100644
--- a/engines/xeen/cutscenes.h
+++ b/engines/xeen/cutscenes.h
@@ -28,62 +28,24 @@
 
 namespace Xeen {
 
-#define WAIT(time) events.updateGameCounter(); \
-	if (events.wait(time)) \
-		return false
+#define WAIT(TIME) \
+	events.timeMark5();             \
+	do {                            \
+		events.updateGameCounter(); \
+		if (events.wait(1))         \
+			return false;           \
+	} while (!g_vm->shouldExit() && events.timeElapsed5() < TIME)
 
 class XeenEngine;
 
 class Cutscenes {
 protected:
 	XeenEngine *_vm;
-	StringArray _subtitles;
-	SpriteResource *_boxSprites;
-	uint _timeElapsed;
-	Common::String _subtitleLine;
-	uint _subtitleLineNum, _subtitleSize;
 protected:
-	Cutscenes(XeenEngine *vm) : _vm(vm), _timeElapsed(0), _boxSprites(nullptr),
-		_subtitleLineNum(0), _subtitleSize(0) {}
+	Cutscenes(XeenEngine *vm) : _vm(vm) {}
 	virtual ~Cutscenes() {}
 
 	/**
-	 * Resets the subtitles position
-	 */
-	void resetSubtitles(uint lineNum, uint defaultSize = 1);
-
-	/**
-	 * Free subtitles
-	 */
-	void freeSubtitles();
-
-	/**
-	 * Shows subtitles
-	 */
-	void showSubtitles(uint windowIndex = 0);
-
-	/**
-	 * Delays either the specified number of frames, or until
-	 * an entire subtitle line is shown if subtitles are on
-	 */
-	bool subtitlesWait(uint minTime = 0);
-
-	/**
-	 * Wait for the end of currently playing sound or subtitles line
-	 */
-	bool waitForLineOrSound();
-
-	/**
-	 * Records the current execution time
-	 */
-	void recordTime();
-
-	/**
-	 * Returns the number of ticks since the last recordTime
-	 */
-	uint timeElapsed();
-
-	/**
 	 * Get a speaking frame from a range
 	 */
 	uint getSpeakingFrame(uint minFrame, uint maxFrame);
diff --git a/engines/xeen/detection_tables.h b/engines/xeen/detection_tables.h
index 220c1f1..4440e11 100644
--- a/engines/xeen/detection_tables.h
+++ b/engines/xeen/detection_tables.h
@@ -36,7 +36,7 @@ static const XeenGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformDOS,
 			ADGF_NO_FLAGS,
-			GUIO1(GUIO_NOSPEECH)
+			GUIO0()
 		},
 		GType_WorldOfXeen,
 		0
@@ -55,7 +55,7 @@ static const XeenGameDescription gameDescriptions[] = {
 			Common::DE_DEU,
 			Common::kPlatformDOS,
 			ADGF_NO_FLAGS,
-			GUIO1(GUIO_NOSPEECH),
+			GUIO0(),
 		},
 		GType_WorldOfXeen,
 		0
@@ -74,7 +74,7 @@ static const XeenGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformDOS,
 			ADGF_NO_FLAGS,
-			GUIO1(GUIO_NOSPEECH)
+			GUIO0()
 		},
 		GType_WorldOfXeen,
 		0
@@ -92,7 +92,7 @@ static const XeenGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformDOS,
 			ADGF_NO_FLAGS,
-			GUIO1(GUIO_NOSPEECH)
+			GUIO0()
 		},
 		GType_Clouds,
 		0
@@ -110,7 +110,7 @@ static const XeenGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformDOS,
 			ADGF_NO_FLAGS,
-			GUIO1(GUIO_NOSPEECH)
+			GUIO0()
 		},
 		GType_DarkSide,
 		0
@@ -128,7 +128,7 @@ static const XeenGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformDOS,
 			ADGF_NO_FLAGS,
-			GUIO1(GUIO_NOSPEECH)
+			GUIO0()
 		},
 		GType_Swords,
 		0
diff --git a/engines/xeen/locations.cpp b/engines/xeen/locations.cpp
index bf724ae..73d5b4b 100644
--- a/engines/xeen/locations.cpp
+++ b/engines/xeen/locations.cpp
@@ -1238,7 +1238,6 @@ const char *const CUTSCENE_SUBTITLE = "\xC""35\x3""c\xB""190\t000%s";
 
 CutsceneLocation::CutsceneLocation(LocationAction action) : BaseLocation(action),
 		_subtitleCtr(0), _mazeFlag(false) {
-	EventsManager &events = *g_vm->_events;
 	Party &party = *g_vm->_party;
 	_mazeId = party._mazeId;
 	_mazePos = party._mazePosition;
@@ -1246,7 +1245,6 @@ CutsceneLocation::CutsceneLocation(LocationAction action) : BaseLocation(action)
 
 	loadStrings("special.bin");
 	_boxSprites.load("box.vga");
-	events.timeMark3();
 }
 
 void CutsceneLocation::updateSubtitles() {
diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk
index a988137..0154b85 100644
--- a/engines/xeen/module.mk
+++ b/engines/xeen/module.mk
@@ -54,6 +54,7 @@ MODULE_OBJS := \
 	sound_driver.o \
 	spells.o \
 	sprites.o \
+	subtitles.o \
 	window.o \
 	xeen.o \
 	xsurface.o
diff --git a/engines/xeen/sound.cpp b/engines/xeen/sound.cpp
index 01d65f7..eb7c061 100644
--- a/engines/xeen/sound.cpp
+++ b/engines/xeen/sound.cpp
@@ -28,7 +28,7 @@
 
 namespace Xeen {
 
-Sound::Sound(Audio::Mixer *mixer) : _mixer(mixer), _fxOn(true), _musicOn(true),
+Sound::Sound(Audio::Mixer *mixer) : _mixer(mixer), _fxOn(true), _musicOn(true), _subtitles(false),
 		_songData(nullptr), _effectsData(nullptr), _musicSide(0), _musicPercent(100) {
 	_SoundDriver = new AdlibSoundDriver();
 }
@@ -100,6 +100,8 @@ void Sound::updateSoundSettings() {
 	_musicOn = !ConfMan.getBool("music_mute");
 	if (!_musicOn)
 		stopSong();
+
+	_subtitles = ConfMan.hasKey("subtitles") ? ConfMan.getBool("subtitles") : true;
 }
 
 void Sound::loadEffectsData() {
diff --git a/engines/xeen/sound.h b/engines/xeen/sound.h
index 91a1fa7..274aedb 100644
--- a/engines/xeen/sound.h
+++ b/engines/xeen/sound.h
@@ -55,6 +55,7 @@ public:
 	bool _musicOn;
 	Common::String _currentMusic, _priorMusic;
 	int _musicSide;
+	bool _subtitles;
 public:
 	Sound(Audio::Mixer *mixer);
 	virtual ~Sound();
diff --git a/engines/xeen/subtitles.cpp b/engines/xeen/subtitles.cpp
new file mode 100644
index 0000000..6cebb9c
--- /dev/null
+++ b/engines/xeen/subtitles.cpp
@@ -0,0 +1,142 @@
+/* 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 "xeen/subtitles.h"
+#include "xeen/events.h"
+#include "xeen/files.h"
+#include "xeen/xeen.h"
+
+namespace Xeen {
+
+#define SUBTITLE_FRAME_TIME 10
+
+static const char *SUBTITLE_LINE = "\f35\x3""c\v190\t000%s";
+
+Subtitles::Subtitles() : _lineNum(-1), _boxSprites(nullptr), _lineEnd(0), _lineSize(0), _frameExpiryTime(0) {
+}
+
+Subtitles::~Subtitles() {
+	delete _boxSprites;
+}
+
+void Subtitles::loadSubtitles() {
+	File f("special.bin", 2);
+	while (f.pos() < f.size())
+		_lines.push_back(f.readString());
+	f.close();
+}
+
+void Subtitles::reset() {
+	_lineNum = -1;
+}
+
+void Subtitles::markTime() {
+	_frameExpiryTime = g_system->getMillis() + SUBTITLE_FRAME_TIME;
+	//g_vm->_events->timeMark3();
+}
+
+bool Subtitles::timeElapsed() const {
+	return g_system->getMillis() >= _frameExpiryTime;
+	//return g_vm->_events->timeElapsed3() > 1;
+}
+
+void Subtitles::setLine(int line) {
+	if (_lines.empty())
+		loadSubtitles();
+
+	markTime();
+	_lineNum = line;
+	_lineSize = _lines[_lineNum].size();
+	_lineEnd = 1;
+	_displayLine.clear();
+}
+
+bool Subtitles::active() const {
+	return _lineNum != -1;
+}
+
+bool Subtitles::wait(uint minTime) {
+	EventsManager &events = *g_vm->_events;
+
+	events.updateGameCounter();
+	markTime();
+	while (events.timeElapsed() < minTime || active()) {
+		events.pollEventsAndWait();
+		if (events.isKeyMousePressed())
+			return false;
+
+		show();
+	}
+
+	return true;
+}
+
+bool Subtitles::waitForLineOrSound() {
+	while (g_vm->_sound->isSoundPlaying() || active()) {
+		show();
+		g_vm->_events->pollEventsAndWait();
+		if (g_vm->_events->isKeyMousePressed())
+			return false;
+	}
+
+	return true;
+}
+
+void Subtitles::show(uint windowNum) {
+	Sound &sound = *g_vm->_sound;
+	Windows &windows = *g_vm->_windows;
+
+	if (!sound._subtitles || !active() || g_vm->shouldExit()) {
+		// Subtitles aren't needed
+		reset();
+	} else {
+		if (timeElapsed()) {
+			_lineEnd = (_lineEnd + 1) % _lineSize;
+			int count = MAX(_lineEnd - 40, 0);
+
+			// Get the portion of the line to display
+			char buffer[1000];
+			strncpy(buffer, _lines[_lineNum].c_str() + count, _lineEnd - count);
+			buffer[_lineEnd - count] = '\0';
+
+			// Form the display line
+			_displayLine = Common::String::format(SUBTITLE_LINE, buffer);
+			markTime();
+		}
+
+		// Draw the box sprite
+		if (!_boxSprites)
+			// Not already loaded, so load it
+			_boxSprites = new SpriteResource("box.vga");
+		_boxSprites->draw(0, 0, Common::Point(36, 189));
+
+		// Write the subtitle line
+		windows[windowNum].writeString(_displayLine);
+
+		if (_lineEnd == 0)
+			reset();
+	}
+}
+
+
+} // End of namespace Xeen
diff --git a/engines/xeen/subtitles.h b/engines/xeen/subtitles.h
new file mode 100644
index 0000000..c041db2
--- /dev/null
+++ b/engines/xeen/subtitles.h
@@ -0,0 +1,100 @@
+/* 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 XEEN_SUBTITLES_H
+#define XEEN_SUBTITLES_H
+
+#include "common/str-array.h"
+#include "xeen/sprites.h"
+
+namespace Xeen {
+
+class Subtitles {
+private:
+	Common::StringArray _lines;
+	int _lineNum;
+	SpriteResource *_boxSprites;
+	int _lineEnd, _lineSize;
+	Common::String _displayLine;
+	uint32 _frameExpiryTime;
+private:
+	/**
+	 * Loads the string list of all subtitles
+	 */
+	void loadSubtitles();
+
+	/**
+	 * Mark the current time
+	 */
+	void markTime();
+
+	/**
+	 * Returns true if the time for a subtitle frame has expired
+	 */
+	bool timeElapsed() const;
+public:
+	/**
+	 * Constructor
+	 */
+	Subtitles();
+
+	/**
+	 * Destructor
+	 */
+	~Subtitles();
+
+	/**
+	 * Set which subtitle line to display
+	 */
+	void setLine(int line);
+	
+	/**
+	 * Resets subtitles, stopping any display
+	 */
+	void reset();
+
+	/**
+	 * Returns true if a subtitle is active
+	 */
+	bool active() const;
+
+	/**
+	 * Shows any active subtitle
+	 * @param windowNum		Window to render to
+	 */
+	void show(uint windowNum = 0);
+
+	/**
+	 * Delays either the specified number of frames, or until
+	 * an entire subtitle line is shown if subtitles are on
+	 */
+	bool wait(uint minTime = 0);
+
+	/**
+	 * Wait for the end of currently playing sound or subtitles line
+	 */
+	bool waitForLineOrSound();
+};
+
+} // End of namespace Xeen
+
+#endif /* XEEN_SUBTITLES_H */
diff --git a/engines/xeen/worldofxeen/clouds_cutscenes.cpp b/engines/xeen/worldofxeen/clouds_cutscenes.cpp
index 6662cba..89a54c6 100644
--- a/engines/xeen/worldofxeen/clouds_cutscenes.cpp
+++ b/engines/xeen/worldofxeen/clouds_cutscenes.cpp
@@ -116,7 +116,6 @@ bool CloudsCutscenes::showCloudsIntroInner() {
 		lake("lake.vga"), xeen("xeen.vga"), wizTower("wiztower.vga"),
 		wizTower2("wiztwer2.vga"), lake2("lake2.vga"), lake3("lake3.vga"),
 		xeen1("xeen1.vga");
-	_subtitles.load("special.bin", 0);
 	_vm->_files->_isDarkCc = false;
 
 	// Show the production splash screen
@@ -249,7 +248,7 @@ bool CloudsCutscenes::showCloudsIntroInner() {
 	sound.setMusicPercent(60);
 	screen.restoreBackground();
 	screen.update();
-	resetSubtitles(0, 1);
+	_subtitles.reset();
 
 	// Loop through each spoken line
 	int ctr1 = 0, ctr2 = 0, ctr3 = 0, ctr4 = 0, ctr5 = 0, totalCtr = 0;
@@ -258,7 +257,7 @@ bool CloudsCutscenes::showCloudsIntroInner() {
 			sound.playSound(_INTRO_VOCS[lineCtr]);
 		}
 
-		for (int frameCtr = 0, lookup = 0; sound.isSoundPlaying() || _subtitleSize; ) {
+		for (int frameCtr = 0, lookup = 0; sound.isSoundPlaying() || _subtitles.active(); ) {
 			groupo.draw(0, 0);
 			groupo.draw(0, 1, Common::Point(160, 0));
 
@@ -312,7 +311,7 @@ bool CloudsCutscenes::showCloudsIntroInner() {
 
 				ctr5 = (ctr5 + 1) % 19;
 				WAIT(1);
-				showSubtitles();
+				_subtitles.show();
 				continue;
 			}
 
@@ -325,7 +324,7 @@ bool CloudsCutscenes::showCloudsIntroInner() {
 
 				ctr5 = (ctr5 + 1) % 19;
 				WAIT(1);
-				showSubtitles();
+				_subtitles.show();
 				break;
 			}
 
@@ -562,9 +561,9 @@ bool CloudsCutscenes::showCloudsEnding1() {
 				break;
 			}
 
-			showSubtitles(0);
+			_subtitles.show(0);
 			WAIT(3);
-		} while (sound.isSoundPlaying() || _subtitleSize > 0);
+		} while (sound.isSoundPlaying() || _subtitles.active());
 	}
 
 	// Laugh
@@ -672,7 +671,7 @@ bool CloudsCutscenes::showCloudsEnding2() {
 
 	// Congratulations adventurers
 	const char *const VOC_NAMES[3] = { "king1.voc", "king2.voc", "king3.voc" };
-	_subtitleSize = 0;
+	_subtitles.setLine(0);
 	for (int idx = 0; idx < 3; ++idx) {
 		sound.playSound(VOC_NAMES[idx]);
 
@@ -684,9 +683,9 @@ bool CloudsCutscenes::showCloudsEnding2() {
 			if (frame > 1)
 				king.draw(0, frame);
 
-			showSubtitles();
+			_subtitles.show();
 			WAIT(3);
-		} while (sound.isSoundPlaying() || _subtitleSize);
+		} while (sound.isSoundPlaying() || _subtitles.active());
 
 		king.draw(0, 0, Common::Point(0, 0));
 		king.draw(0, 1, Common::Point(160, 0));
@@ -967,9 +966,9 @@ bool CloudsCutscenes::showCloudsEnding5() {
 		if (frame > 1)
 			king.draw(0, frame);
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
-	} while (sound.isSoundPlaying() || _subtitleSize);
+	} while (sound.isSoundPlaying() || _subtitles.active());
 
 	king.draw(0, 0, Common::Point(0, 0));
 	king.draw(0, 1, Common::Point(160, 0));
diff --git a/engines/xeen/worldofxeen/clouds_cutscenes.h b/engines/xeen/worldofxeen/clouds_cutscenes.h
index afaf3be..39fded6 100644
--- a/engines/xeen/worldofxeen/clouds_cutscenes.h
+++ b/engines/xeen/worldofxeen/clouds_cutscenes.h
@@ -24,6 +24,7 @@
 #define XEEN_WORLDOFXEEN_CLOUDS_CUTSCENES_H
 
 #include "xeen/cutscenes.h"
+#include "xeen/subtitles.h"
 #include "xeen/xeen.h"
 
 namespace Xeen {
@@ -38,6 +39,7 @@ private:
 	static const byte _DECODE_TABLE1[256];
 	static const byte _DECODE_TABLE2[256];
 private:
+	Subtitles _subtitles;
 	SpriteResource _mirror, _mirrBack;
 	int _mergeX;
 private:
diff --git a/engines/xeen/worldofxeen/darkside_cutscenes.cpp b/engines/xeen/worldofxeen/darkside_cutscenes.cpp
index 1fd01d5..8886afe 100644
--- a/engines/xeen/worldofxeen/darkside_cutscenes.cpp
+++ b/engines/xeen/worldofxeen/darkside_cutscenes.cpp
@@ -30,7 +30,7 @@ namespace Xeen {
 	namespace WorldOfXeen {
 
 #define	WAIT_SUBTITLES(time) \
-	showSubtitles(); \
+	_subtitles.show(); \
 	WAIT(time)
 
 static const int PHAROAH_FRAMES[32] = {
@@ -70,10 +70,10 @@ const int LEFT_CLAW_IDLE_Y[32] = {
 
 
 bool DarkSideCutscenes::showDarkSideTitle(bool seenIntro) {
-	EventsManager &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
-	_vm->_files->_isDarkCc = true;
+	EventsManager &events = *g_vm->_events;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
+	g_vm->_files->_isDarkCc = true;
 
 	screen.loadPalette("dark.pal");
 	SpriteResource nwc[4] = {
@@ -100,7 +100,7 @@ bool DarkSideCutscenes::showDarkSideTitle(bool seenIntro) {
 
 	// Initial loop for dragon roaring
 	int nwcIndex = 0, nwcFrame = 0;
-	for (int idx = 0; idx < 55 && !_vm->shouldExit(); ++idx) {
+	for (int idx = 0; idx < 55 && !g_vm->shouldExit(); ++idx) {
 		// Render the next frame
 		screen.vertMerge(0);
 		nwc[nwcIndex].draw(0, nwcFrame);
@@ -125,7 +125,7 @@ bool DarkSideCutscenes::showDarkSideTitle(bool seenIntro) {
 	}
 
 	// Loop for dragon using flyspray
-	for (int idx = 0; idx < 42 && !_vm->shouldExit(); ++idx) {
+	for (int idx = 0; idx < 42 && !g_vm->shouldExit(); ++idx) {
 		screen.vertMerge(SCREEN_HEIGHT);
 		nwc[3].draw(0, idx);
 	
@@ -152,7 +152,7 @@ bool DarkSideCutscenes::showDarkSideTitle(bool seenIntro) {
 
 		WAIT(2);
 	}
-	if (_vm->shouldExit())
+	if (g_vm->shouldExit())
 		return false;
 
 	// Pause for a bit
@@ -211,8 +211,8 @@ bool DarkSideCutscenes::rubCrystalBall(bool fadeIn) {
 		_dragon1.draw(0, PHAROAH_FRAMES[frame], Common::Point(139, PHAROAH_YLIST[frame]), SPRFLAG_800);
 		_claw.draw(0, frame % 5, Common::Point(LEFT_CLAW_RUB_X[frame], LEFT_CLAW_RUB_Y[frame]), SPRFLAG_800);
 
-		if (_subtitleSize)
-			showSubtitles();
+		if (_subtitles.active())
+			_subtitles.show();
 
 		if (fadeIn && frame == 0)
 			screen.fadeIn();
@@ -232,9 +232,9 @@ void DarkSideCutscenes::animatePharoah(int frame, bool showBall) {
 }
 
 bool DarkSideCutscenes::showDarkSideIntro1() {
-	EventsManager &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
+	EventsManager &events = *g_vm->_events;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
 	const int XLIST1[] = {
 		0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 58, 60, 62
 	};
@@ -256,7 +256,6 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 	WAIT(60);
 	screen.fadeOut(8);
 
-	_subtitles.load("special.bin");
 	screen.loadBackground("pyramid2.raw");
 	screen.loadPage(0);
 	screen.loadPage(1);
@@ -275,7 +274,7 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 	// Show Might and Magic Darkside of Xeen title, and gradualy scroll
 	// the background vertically down to show the Pharoah's base
 	bool fadeFlag = true;
-	for (int yp = 0, frameNum = 0, idx1 = 0; yp < SCREEN_HEIGHT && !_vm->shouldExit(); ++yp) {
+	for (int yp = 0, frameNum = 0, idx1 = 0; yp < SCREEN_HEIGHT && !g_vm->shouldExit(); ++yp) {
 		screen.vertMerge(yp);
 
 		title.draw(0, 0);
@@ -302,7 +301,7 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 
 	// Zoom into the Pharoah's base closeup view
 	sound.setMusicPercent(38);
-	for (int idx = 14; idx >= 0 && !_vm->shouldExit(); --idx) {
+	for (int idx = 14; idx >= 0 && !g_vm->shouldExit(); --idx) {
 		pyraTop.draw(0, 0, Common::Point(XLIST1[idx], YLIST1[idx]), 0, idx);
 		pyraTop.draw(0, 1, Common::Point(XLIST2[idx], YLIST1[idx]), 0, idx);
 
@@ -313,15 +312,13 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 	screen.saveBackground();
 	sound.playSound("pharoh1a.voc");
 
-	recordTime();
-	resetSubtitles(0);
-	_subtitleLineNum = 0;
+	_subtitles.setLine(0);
 
 	bool phar2 = false;
-	for (int idx = 0; idx < 19 && !_vm->shouldExit(); ++idx) {
+	for (int idx = 0; idx < 19 && !g_vm->shouldExit(); ++idx) {
 		screen.restoreBackground();
 		pyramid.draw(0, idx, Common::Point(132, 62));
-		showSubtitles();
+		_subtitles.show();
 
 		if (!sound.isSoundPlaying() && !phar2)
 			sound.playSound("pharoh1b.voc");
@@ -329,7 +326,7 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 		WAIT_SUBTITLES(4);
 	}
 
-	waitForLineOrSound();
+	_subtitles.waitForLineOrSound();
 	screen.fadeOut();
 
 	const int XLIST3[10] = { 102, 103, 104, 104, 104, 103, 102, 101, 101, 101 };
@@ -346,10 +343,7 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 	};
 
 	SpriteResource dragon("dragon.int");
-	recordTime();
-	resetSubtitles(0);
-	_subtitleLineNum = 0;
-	_subtitleSize = 25;
+	_subtitles.setLine(1);
 
 	screen.loadBackground("2room.raw");
 	screen.loadPage(1);
@@ -360,7 +354,7 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 	screen.horizMerge(SCREEN_WIDTH);
 	dragon.draw(0, 9, Common::Point(XLIST3[0], YLIST3[0]), SPRFLAG_800);
 
-	showSubtitles();
+	_subtitles.show();
 	screen.fadeIn();
 
 	int posNum = 0, phar2Index = 0, ctr = 0;
@@ -368,7 +362,7 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 		events.updateGameCounter();
 		screen.horizMerge(idx);
 		dragon.draw(0, FRAMES3[frameNum], Common::Point(XLIST3[posNum], YLIST3[posNum]), SPRFLAG_800);
-		showSubtitles();
+		_subtitles.show();
 		events.pollEventsAndWait();
 		if (events.isKeyMousePressed())
 			return false;
@@ -379,7 +373,7 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 			sound.playSound(PHAR_VOC[1 + phar2Index++]);
 
 		if (phar2Index == 4) {
-			if (!sound.isSoundPlaying() && !_subtitleSize)
+			if (!sound.isSoundPlaying() && !_subtitles.active())
 				break;
 		}
 
@@ -408,9 +402,9 @@ bool DarkSideCutscenes::showDarkSideIntro1() {
 	clawCtr = (clawCtr + 1) % 32
 
 bool DarkSideCutscenes::showDarkSideIntro2() {
-	EventsManager &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
+	EventsManager &events = *g_vm->_events;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
 	SpriteResource goon("goon.int"), darkLord("darklord.int"), queen("queen.int"),
 		wizard("wizard.int"), fizzle("fizzle.int"), wizMth("wizmth.int");
 	int idx, clawCtr;
@@ -423,8 +417,7 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		return false;
 
 	// TODO: Subtitle stuff
-	recordTime();
-	_subtitleSize = 1;
+	_subtitles.setLine(1);
 	sound.playFX(42);
 
 	for (idx = 0, clawCtr = 0; idx < 11; ++idx) {
@@ -439,7 +432,7 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		}
 
 		if (idx > 6)
-			showSubtitles();
+			_subtitles.show();
 		WAIT(3);
 	}
 
@@ -449,12 +442,9 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		ANIMATE_PHAROAH;
 
 		if (!sound.isSoundPlaying() && vocIndex < 3) {
-			if (!_subtitleSize) {
-				if (!vocIndex) {
-					// TODO: Subtitle stuff
-					recordTime();
-					_subtitleSize = 1;
-				}
+			if (!_subtitles.active()) {
+				if (!vocIndex)
+					_subtitles.setLine(9 + vocIndex);
 
 				sound.playSound(VOC_NAMES[vocIndex++]);
 				if (vocIndex == 3)
@@ -472,14 +462,12 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 				Common::Point(9, 57));
 		}
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
-	} while (vocIndex < 3 || sound.isSoundPlaying() || _subtitleSize);
+	} while (vocIndex < 3 || sound.isSoundPlaying() || _subtitles.active());
 
-	// TODO: Subtitle stuff
 	sound.playSound(VOC_NAMES[3]);
-	recordTime();
-	_subtitleSize = 1;
+	_subtitles.setLine(10);
 
 	idx = 34;
 	do {
@@ -489,13 +477,12 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		if (++idx <= 37)
 			idx = 34;
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
-	} while (sound.isSoundPlaying() || _subtitleSize);
+	} while (sound.isSoundPlaying() || _subtitles.active());
 
 	// TODO: Subtitle stuff
-	recordTime();
-	_subtitleSize = 1;
+	_subtitles.setLine(0);
 	sound.playSound("dark3.voc");
 
 	const char *const VOC_NAMES2[2] = { "pharoh5a.voc", "pharoh5b.voc" };
@@ -505,15 +492,14 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		ANIMATE_PHAROAH;
 		darkLord.draw(0, vocIndex == 0 ? getSpeakingFrame(0, 3) : 0, Common::Point(9, 57));
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 		if (!sound.isSoundPlaying() && vocIndex < 2)
 			sound.playSound(VOC_NAMES2[vocIndex++]);
-	} while (vocIndex < 2 || sound.isSoundPlaying() || _subtitleSize);
+	} while (vocIndex < 2 || sound.isSoundPlaying() || _subtitles.active());
 
 	// TODO: Subtitle stuff
-	recordTime();
-	_subtitleSize = 1;
+	_subtitles.setLine(0);
 
 	sound.playFX(42);
 	vocIndex = 0;
@@ -530,7 +516,7 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 			darkLord.draw(0, getSpeakingFrame(0, 3), Common::Point(9, 57));
 		fizzle.draw(0, idx, Common::Point(9, 57));
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 	}
 
@@ -539,9 +525,9 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 	do {
 		ANIMATE_PHAROAH;
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
-	} while (sound.isSoundPlaying() || _subtitleSize);
+	} while (sound.isSoundPlaying() || _subtitles.active());
 
 	if (!rubCrystalBall())
 		return false;
@@ -556,7 +542,7 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		if (idx == 6)
 			sound.playSound("pharoh6w.voc");
 		if (idx > 6)
-			showSubtitles();
+			_subtitles.show();
 		WAIT(3);
 	}
 
@@ -567,22 +553,20 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		ANIMATE_PHAROAH;
 		goon.draw(0, (vocIndex == 0) ? 0 : nwcIndex, Common::Point(9, 57));
 
-		if (!sound.isSoundPlaying() && !vocIndex && !_subtitleSize) {
+		if (!sound.isSoundPlaying() && !vocIndex && !_subtitles.active()) {
 			// TODO: Subtitles stuff
-			recordTime();
-			_subtitleSize = 1;
+			_subtitles.setLine(0);
 			sound.playSound(VOC_NAMES3[vocIndex++]);
 			sound.playFX(0);
 		}
 
 		nwcIndex = (nwcIndex + 1) % 17;
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
-	} while (!vocIndex || sound.isSoundPlaying() || _subtitleSize);
+	} while (!vocIndex || sound.isSoundPlaying() || _subtitles.active());
 
 	// TODO: Subtitle stuff
-	recordTime();
-	_subtitleSize = 1;
+	_subtitles.setLine(0);
 	sound.playFX(42);
 
 	for (idx = 10, vocIndex = 0; idx >= 0; --idx) {
@@ -596,7 +580,7 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 			vocIndex = 1;
 		}
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 	}
 
@@ -606,8 +590,7 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		return false;
 
 	// TODO: Subtitle stuff
-	recordTime();
-	_subtitleSize = 1;
+	_subtitles.setLine(0);
 
 	for (idx = 0, clawCtr = 0; idx < 11; ++idx) {
 		ANIMATE_PHAROAH;
@@ -619,7 +602,7 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		if (idx == 5)
 			sound.playSound("pharoh8.voc");
 		if (idx > 6)
-			showSubtitles();
+			_subtitles.show();
 
 		WAIT(3);
 	}
@@ -631,22 +614,21 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 		ANIMATE_PHAROAH;
 		wizard.draw(0, (vocIndex == 1) ? getSpeakingFrame(0, 3) : 0, Common::Point(9, 57));
 
-		if (!sound.isSoundPlaying() && vocIndex < 2 && !_subtitleSize) {
+		if (!sound.isSoundPlaying() && vocIndex < 2 && !_subtitles.active()) {
 			// TODO: Subtitle stuff
 			if (vocIndex == 0) {
-				recordTime();
-				_subtitleSize = 1;
+				_subtitles.setLine(0);
 			} else {
-				_subtitleSize = 0;
+				_subtitles.setLine(0);
 			}
 
 			sound.playSound(VOC_NAMES4[vocIndex++]);
 			sound.playFX(0);
 		}
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
-	} while (vocIndex < 2 || sound.isSoundPlaying() || _subtitleSize);
+	} while (vocIndex < 2 || sound.isSoundPlaying() || _subtitles.active());
 
 	sound.playFX(42);
 
@@ -661,13 +643,12 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 			vocIndex = 1;
 		}
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 	}
 
 	// TODO: Subtitle stuff
-	recordTime();
-	_subtitleSize = 1;
+	_subtitles.setLine(0);
 	vocIndex = 0;
 
 	do {
@@ -678,9 +659,9 @@ bool DarkSideCutscenes::showDarkSideIntro2() {
 			vocIndex = 1;
 		}
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
-	} while (sound.isSoundPlaying() || !vocIndex || _subtitleSize);
+	} while (sound.isSoundPlaying() || !vocIndex || _subtitles.active());
 
 	sound.playFX(0);
 	screen.fadeOut();
@@ -705,8 +686,8 @@ bool DarkSideCutscenes::showDarkSideIntro3() {
 	screen.saveBackground();
 
 	// TODO: Subtitle stuff
-	recordTime();
-	showSubtitles();
+	_subtitles.setLine(0);
+	_subtitles.show();
 
 	screen.fadeIn();
 	sound.playSound("pharoh11.voc", 2, 0);
@@ -813,9 +794,9 @@ bool DarkSideCutscenes::showDarkSideIntro3() {
 }
 
 bool DarkSideCutscenes::showWorldOfXeenLogo() {
-	EventsManager &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
+	EventsManager &events = *g_vm->_events;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
 	SpriteResource fizzle("fizzle.int");
 	SpriteResource wfire[7];
 	for (uint idx = 0; idx < 7; ++idx)
@@ -888,9 +869,9 @@ void DarkSideCutscenes::showDarkSideEnding(uint endingScore) {
 }
 
 bool DarkSideCutscenes::showDarkSideEnding1() {
-	EventsManager &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
+	EventsManager &events = *g_vm->_events;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
 
 	sound.playSong("dngon3.m");
 	screen.loadBackground("scene1.raw");
@@ -913,8 +894,7 @@ bool DarkSideCutscenes::showDarkSideEnding1() {
 	screen.fadeIn();
 	WAIT(1);
 
-	_subtitles.load("special.bin");
-	resetSubtitles(21, 0);
+	_subtitles.setLine(21);
 
 	// Alamar stands up
 	for (int idx = 74; idx > 20; idx -= 2) {
@@ -1008,7 +988,7 @@ bool DarkSideCutscenes::showDarkSideEnding1() {
 
 	// Play landing thud
 	sound.playSound("thud.voc");
-	while (!_vm->shouldExit() && !events.isKeyMousePressed()
+	while (!g_vm->shouldExit() && !events.isKeyMousePressed()
 		&& sound.isSoundPlaying()) {
 		events.pollEventsAndWait();
 	}
@@ -1089,20 +1069,20 @@ bool DarkSideCutscenes::showDarkSideEnding1() {
 	screen.fadeIn();
 	WAIT(2);
 
-	resetSubtitles(22, 0);
+	_subtitles.setLine(22);
 
 	for (int idx = 0; idx < 45; ++idx) {
 		screen.restoreBackground();
 		sc07[idx / 6].draw(0, idx % 6, Common::Point(61, 12));
 
-		if (_subtitleSize == 0)
+		if (_subtitles.active() == 0)
 			screen.update();
 		else
-			showSubtitles();
+			_subtitles.show();
 
 		WAIT(2);
 		if (idx == 40)
-			_subtitleSize = 1;
+			_subtitles.setLine(0);
 		else if (idx == 1 || idx == 19)
 			// Wind storm
 			sound.playSound("windstor.voc");
@@ -1112,17 +1092,17 @@ bool DarkSideCutscenes::showDarkSideEnding1() {
 }
 
 bool DarkSideCutscenes::showDarkSideEnding2() {
-	EventsManager &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
+	EventsManager &events = *g_vm->_events;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
 
 	// Corak?!
 	sound.playSound("corak2.voc");
-	subtitlesWait(30);
+	_subtitles.setLine(0);
 
 	// Yep, that's my name, don't wear it out
 	SpriteResource sc08("sc08.end");
-	resetSubtitles(23);
+	_subtitles.setLine(23);
 	sound.playFX(0);
 
 	for (int idx = 0; idx < 15; ++idx) {
@@ -1131,14 +1111,14 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 
 		// Animate Corak speaking
 		sc08.draw(0, sound.isSoundPlaying() ? getSpeakingFrame(0, 2) : 0);
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 	}
 
 	do {
 		sc08.draw(0, 0);
-		showSubtitles();
-	} while (_subtitleSize);
+		_subtitles.show();
+	} while (_subtitles.active());
 
 	sc08.clear();
 
@@ -1149,7 +1129,7 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 	screen.saveBackground();
 	screen.update();
 
-	resetSubtitles(24);
+	_subtitles.setLine(24);
 
 	for (int idx = 0; idx < 15; ++idx) {
 		if (idx == 2)
@@ -1157,20 +1137,21 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 
 		screen.restoreBackground();
 		sc09.draw(0, getSpeakingFrame(0, 8));
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 	}
 
 	do {
 		screen.restoreBackground();
-		showSubtitles();
-	} while (_subtitleSize);
+		_subtitles.show();
+	} while (_subtitles.active());
 
 	sc09.clear();
 
 	// Nor do you!
 	SpriteResource sc10("sc10.end");
-	resetSubtitles(25);
+	_subtitles.setLine(25);
+
 
 	for (int idx = 0; idx < 15; ++idx) {
 		if (idx == 3)
@@ -1178,14 +1159,14 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 
 		screen.restoreBackground();
 		sc10.draw(0, getSpeakingFrame(0, 1));
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 	}
 
 	do {
 		screen.restoreBackground();
-		showSubtitles();
-	} while (_subtitleSize);
+		_subtitles.show();
+	} while (_subtitles.active());
 
 	sc10.clear();
 
@@ -1238,7 +1219,7 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 
 	// I'm ready for you this time
 	SpriteResource sc13("sc13.end");
-	resetSubtitles(26);
+	_subtitles.setLine(26);
 	sound.setMusicPercent(38);
 
 	for (int idx = 0; idx < 16; ++idx) {
@@ -1246,7 +1227,7 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 			sound.playSound("ready2.voc");
 
 		sc13.draw(0, getSpeakingFrame(0, 3));
-		showSubtitles();
+		_subtitles.show();
 
 		if (idx == 0)
 			screen.fadeIn();
@@ -1255,15 +1236,15 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 
 	do {
 		sc13.draw(0, 0);
-		showSubtitles();
+		_subtitles.show();
 		events.pollEventsAndWait();
-	} while (_subtitleSize);
+	} while (_subtitles.active());
 
 	sc13.clear();
 
 	// This fight will be your last
 	SpriteResource sc14("sc14.end");
-	resetSubtitles(27);
+	_subtitles.setLine(27);
 
 	screen.fadeOut();
 	screen.loadBackground("blank.raw");
@@ -1280,24 +1261,24 @@ bool DarkSideCutscenes::showDarkSideEnding2() {
 
 			screen.restoreBackground();
 			sc14.draw(0, idx, Common::Point(37, 37));
-			showSubtitles();
+			_subtitles.show();
 			WAIT(3);
 		}
 	}
 
-	while (_subtitleSize) {
-		showSubtitles();
+	while (_subtitles.active()) {
+		_subtitles.show();
 		events.pollEventsAndWait();
-		showSubtitles();
+		_subtitles.show();
 	}
 
 	return true;
 }
 
 bool DarkSideCutscenes::showDarkSideEnding3() {
-	EventsManager &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
+	EventsManager &events = *g_vm->_events;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
 
 	// Fighting start
 	SpriteResource sc15("sc15.end");
@@ -1323,7 +1304,7 @@ bool DarkSideCutscenes::showDarkSideEnding3() {
 
 	// I can not fail
 	SpriteResource sc16("sc16.end");
-	resetSubtitles(28);
+	_subtitles.setLine(28);
 
 	screen.loadBackground("scene4.raw");
 	screen.loadPage(0);
@@ -1333,13 +1314,13 @@ bool DarkSideCutscenes::showDarkSideEnding3() {
 	screen.saveBackground();
 	screen.horizMerge(0);
 	sc16.draw(0, 0, Common::Point(7, 29));
-	showSubtitles();
+	_subtitles.show();
 	sound.playSound("fail1.voc");
 
 	for (int idx = 0; idx < 5; ++idx) {
 		screen.horizMerge(0);
 		sc16.draw(0, idx, Common::Point(7, 29));
-		showSubtitles();
+		_subtitles.show();
 		WAIT(4);
 	}
 
@@ -1353,7 +1334,7 @@ bool DarkSideCutscenes::showDarkSideEnding3() {
 		if (val > 10)
 			sc16.draw(0, 12, Common::Point(273, 70));
 
-		showSubtitles();
+		_subtitles.show();
 		WAIT(2);
 
 		if (idx == 48)
@@ -1546,10 +1527,10 @@ bool DarkSideCutscenes::showDarkSideEnding3() {
 }
 
 bool DarkSideCutscenes::showDarkSideEnding4() {
-	EventsManager &events = *_vm->_events;
-	FileManager &files = *_vm->_files;
-	Screen &screen = *_vm->_screen;
-	Sound &sound = *_vm->_sound;
+	EventsManager &events = *g_vm->_events;
+	FileManager &files = *g_vm->_files;
+	Screen &screen = *g_vm->_screen;
+	Sound &sound = *g_vm->_sound;
 
 	// Corak does a ricochet shot on Sheltem
 	SpriteResource sc24[2] = {
@@ -1585,7 +1566,7 @@ bool DarkSideCutscenes::showDarkSideEnding4() {
 	// Corak speaking here. It seems this was ditched in favor of the
 	// following closeup of him speaking "I do"
 	SpriteResource sc25("sc25a.end");
-	resetSubtitles(29);
+	_subtitles.setLine(29);
 
 	screen.loadBackground("sc250001.raw");
 	screen.saveBackground();
@@ -1598,11 +1579,11 @@ bool DarkSideCutscenes::showDarkSideEnding4() {
 				sound.playSound("admit2.voc");
 
 			sc25.draw(0, idx, Common::Point(27, 30));
-			showSubtitles();
+			_subtitles.show();
 			WAIT(3);
 		}
 	}
-	subtitlesWait();
+	_subtitles.wait();
 	sc25.clear();
 
 	// I do. Kamakazi time
@@ -1610,14 +1591,14 @@ bool DarkSideCutscenes::showDarkSideEnding4() {
 		SpriteResource("sc26a.end"), SpriteResource("sc26b.end"),
 		SpriteResource("sc26c.end"), SpriteResource("sc26d.end")
 	};
-	resetSubtitles(30);
+	_subtitles.setLine(30);
 
 	screen.loadBackground("sc260001.raw");
 	screen.saveBackground();
-	showSubtitles();
+	_subtitles.show();
 	sound.playSound("ido2.voc");
 
-	for (int idx = 0; sound.isSoundPlaying() || _subtitleSize; ) {
+	for (int idx = 0; sound.isSoundPlaying() || _subtitles.active(); ) {
 		screen.restoreBackground();
 		sc26[idx / 8].draw(0, idx % 8, Common::Point(58, 25));
 		WAIT(2);
@@ -1628,7 +1609,7 @@ bool DarkSideCutscenes::showDarkSideEnding4() {
 	screen.loadBackground("sc270001.raw");
 	screen.saveBackground();
 
-	while (sound.isSoundPlaying() && !_vm->shouldExit()) {
+	while (sound.isSoundPlaying() && !g_vm->shouldExit()) {
 		events.pollEventsAndWait();
 		if (events.isKeyMousePressed())
 			return false;
@@ -1639,8 +1620,8 @@ bool DarkSideCutscenes::showDarkSideEnding4() {
 
 	// What? No!
 	SpriteResource sc27("sc27.end");
-	resetSubtitles(31);
-	showSubtitles();
+	_subtitles.setLine(31);
+	_subtitles.show();
 
 	for (int idx = 0; idx < 12; ++idx) {
 		if (idx == 1)
@@ -1648,11 +1629,11 @@ bool DarkSideCutscenes::showDarkSideEnding4() {
 
 		screen.restoreBackground();
 		sc27.draw(0, idx, Common::Point(65, 22));
-		showSubtitles();
+		_subtitles.show();
 		WAIT(3);
 	}
 
-	subtitlesWait();
+	_subtitles.wait();
 	sc27.clear();
 
 	// Vortex is opened and the two are sucked in, obliterating them
@@ -1730,24 +1711,22 @@ bool DarkSideCutscenes::showDarkSideEnding4() {
 
 	screen.fadeOut();
 	sound.stopSong();
-	freeSubtitles();
-
 	return true;
 }
 
 void DarkSideCutscenes::showDarkSideScore(uint endingScore) {
-	SavesManager &saves = *_vm->_saves;
-	Sound &sound = *_vm->_sound;
+	SavesManager &saves = *g_vm->_saves;
+	Sound &sound = *g_vm->_sound;
 
 	sound.stopAllAudio();
 
-	if (_vm->shouldExit()) {
+	if (g_vm->shouldExit()) {
 		sound.playSong("outday3.m");
 
 		Common::String str = Common::String::format(Res.DARKSIDE_ENDING1, endingScore);
 		showPharaohEndText(str.c_str(), Res.DARKSIDE_ENDING2);
 
-		if (!_vm->shouldExit())
+		if (!g_vm->shouldExit())
 			saves.saveGame();
 	}
 }
@@ -1765,9 +1744,9 @@ bool DarkSideCutscenes::showPharaohEndText(const char *msg1, const char *msg2, c
 }
 
 bool DarkSideCutscenes::showPharaohEndTextInner(const char *msg1, const char *msg2, const char *msg3) {
-	Screen &screen = *_vm->_screen;
-	EventsManager &events = *_vm->_events;
-	Windows &windows = *_vm->_windows;
+	Screen &screen = *g_vm->_screen;
+	EventsManager &events = *g_vm->_events;
+	Windows &windows = *g_vm->_windows;
 	int numPages = 0 + (msg1 ? 1 : 0) + (msg2 ? 1 : 0) + (msg3 ? 1 : 0);
 	const char *const text[3] = { msg1, msg2, msg3 };
 
@@ -1781,7 +1760,7 @@ bool DarkSideCutscenes::showPharaohEndTextInner(const char *msg1, const char *ms
 	events.clearEvents();
 
 	// Iterate through showing the pages
-	for (int pageNum = 0; !_vm->shouldExit() && pageNum < numPages; ++pageNum) {
+	for (int pageNum = 0; !g_vm->shouldExit() && pageNum < numPages; ++pageNum) {
 		// Show each page until a key is pressed
 		do {
 			events.updateGameCounter();
@@ -1800,7 +1779,7 @@ bool DarkSideCutscenes::showPharaohEndTextInner(const char *msg1, const char *ms
 
 			windows[0].update();
 			events.wait(1);
-		} while (!_vm->shouldExit() && !events.isKeyMousePressed());
+		} while (!g_vm->shouldExit() && !events.isKeyMousePressed());
 
 		events.clearEvents();
 	}
diff --git a/engines/xeen/worldofxeen/darkside_cutscenes.h b/engines/xeen/worldofxeen/darkside_cutscenes.h
index 1808562..e0bd5c0 100644
--- a/engines/xeen/worldofxeen/darkside_cutscenes.h
+++ b/engines/xeen/worldofxeen/darkside_cutscenes.h
@@ -24,6 +24,7 @@
 #define XEEN_WORLDOFXEEN_DARKSIDE_CUTSCENES_H
 
 #include "xeen/cutscenes.h"
+#include "xeen/subtitles.h"
 
 namespace Xeen {
 
@@ -33,6 +34,7 @@ namespace WorldOfXeen {
 
 class DarkSideCutscenes : public Cutscenes {
 private:
+	Subtitles _subtitles;
 	SpriteResource _ball, _claw, _dragon1;
 private:
 	/**





More information about the Scummvm-git-logs mailing list