diff options
| author | Einar Johan Trøan Sømåen | 2014-11-05 20:22:34 +0100 | 
|---|---|---|
| committer | Einar Johan Trøan Sømåen | 2014-11-05 20:22:34 +0100 | 
| commit | 784241c17b57c31af0722d3d98d89314c40743cd (patch) | |
| tree | 249e87f5e89acf7cf934b83b23c7e6d4be31e5ad | |
| parent | eff78c442474185ecb1bde59bfc54c276178c480 (diff) | |
| parent | 9787fc5768fdc7338433fa5bcbc606f7d8ffe1d2 (diff) | |
| download | scummvm-rg350-784241c17b57c31af0722d3d98d89314c40743cd.tar.gz scummvm-rg350-784241c17b57c31af0722d3d98d89314c40743cd.tar.bz2 scummvm-rg350-784241c17b57c31af0722d3d98d89314c40743cd.zip | |
Merge pull request #437 from tobiatesan/wme_subtitles
WME Subtitles
| -rw-r--r-- | engines/wintermute/base/base_game.cpp | 5 | ||||
| -rw-r--r-- | engines/wintermute/base/base_game.h | 2 | ||||
| -rw-r--r-- | engines/wintermute/base/base_game_settings.cpp | 5 | ||||
| -rw-r--r-- | engines/wintermute/base/base_game_settings.h | 1 | ||||
| -rw-r--r-- | engines/wintermute/base/base_string_table.cpp | 9 | ||||
| -rw-r--r-- | engines/wintermute/base/base_string_table.h | 1 | ||||
| -rw-r--r-- | engines/wintermute/module.mk | 2 | ||||
| -rw-r--r-- | engines/wintermute/video/subtitle_card.cpp | 56 | ||||
| -rw-r--r-- | engines/wintermute/video/subtitle_card.h | 53 | ||||
| -rw-r--r-- | engines/wintermute/video/video_subtitler.cpp | 266 | ||||
| -rw-r--r-- | engines/wintermute/video/video_subtitler.h | 53 | ||||
| -rw-r--r-- | engines/wintermute/video/video_theora_player.cpp | 27 | ||||
| -rw-r--r-- | engines/wintermute/video/video_theora_player.h | 6 | 
13 files changed, 475 insertions, 11 deletions
| diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp index 8df39c825a..668053bb3a 100644 --- a/engines/wintermute/base/base_game.cpp +++ b/engines/wintermute/base/base_game.cpp @@ -3896,6 +3896,11 @@ void BaseGame::expandStringByStringTable(char **str) const {  	_settings->expandStringByStringTable(str);  } +////////////////////////////////////////////////////////////////////////// +void BaseGame::expandStringByStringTable(Common::String &str) const { +	_settings->expandStringByStringTable(str); +} +  char *BaseGame::getKeyFromStringTable(const char *str) const {  	return _settings->getKeyFromStringTable(str);  } diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index cdbbff6c93..e535cc9618 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -123,6 +123,7 @@ public:  	inline BaseObject *getMainObject() { return _mainObject; }  	inline BaseFont *getSystemFont() { return _systemFont; } +	inline BaseFont *getVideoFont() { return _videoFont; }  	bool initInput();  	bool initLoop(); @@ -140,6 +141,7 @@ public:  	// String Table  	void expandStringByStringTable(char **str) const; +	void expandStringByStringTable(Common::String &str) const;  	char *getKeyFromStringTable(const char *str) const;  	void LOG(bool res, const char *fmt, ...); diff --git a/engines/wintermute/base/base_game_settings.cpp b/engines/wintermute/base/base_game_settings.cpp index 61c5894be3..996bada997 100644 --- a/engines/wintermute/base/base_game_settings.cpp +++ b/engines/wintermute/base/base_game_settings.cpp @@ -215,6 +215,11 @@ void BaseGameSettings::expandStringByStringTable(char **str) const {  	_stringTable->expand(str);  } +////////////////////////////////////////////////////////////////////////// +void BaseGameSettings::expandStringByStringTable(Common::String &str) const { +	_stringTable->expand(str); +} +  char *BaseGameSettings::getKeyFromStringTable(const char *str) const {  	return _stringTable->getKey(str);  } diff --git a/engines/wintermute/base/base_game_settings.h b/engines/wintermute/base/base_game_settings.h index 2059cb075e..15afb06450 100644 --- a/engines/wintermute/base/base_game_settings.h +++ b/engines/wintermute/base/base_game_settings.h @@ -46,6 +46,7 @@ public:  	bool loadSettings(const char *filename);  	bool loadStringTable(const char *filename, bool clearOld);  	void expandStringByStringTable(char **str) const; +	void expandStringByStringTable(Common::String &str) const;  	char *getKeyFromStringTable(const char *str) const;  	bool persist(BasePersistenceManager *persistMgr); diff --git a/engines/wintermute/base/base_string_table.cpp b/engines/wintermute/base/base_string_table.cpp index 89407a7b0e..4c750ebc93 100644 --- a/engines/wintermute/base/base_string_table.cpp +++ b/engines/wintermute/base/base_string_table.cpp @@ -147,6 +147,15 @@ void BaseStringTable::expand(char **str) const {  	}  } +////////////////////////////////////////////////////////////////////////// +void BaseStringTable::expand(Common::String &str) const { +	char *tmp = new char[str.size()+1]; +	strcpy(tmp, str.c_str()); +	expand(&tmp); +	str = tmp; +	delete[] tmp; +} +  //////////////////////////////////////////////////////////////////////////  const char *BaseStringTable::expandStatic(const char *string) const { diff --git a/engines/wintermute/base/base_string_table.h b/engines/wintermute/base/base_string_table.h index cdcf11917d..cfa3eeb226 100644 --- a/engines/wintermute/base/base_string_table.h +++ b/engines/wintermute/base/base_string_table.h @@ -41,6 +41,7 @@ class BaseStringTable : public BaseClass {  public:  	bool loadFile(const char *filename, bool deleteAll = true);  	void expand(char **str) const; +	void expand(Common::String &str) const;  	const char *expandStatic(const char *string) const;  	bool addString(const char *key, const char *val, bool reportDuplicities = true);  	BaseStringTable(BaseGame *inGame); diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk index 1b6c52e0b7..4c95314a02 100644 --- a/engines/wintermute/module.mk +++ b/engines/wintermute/module.mk @@ -108,7 +108,9 @@ MODULE_OBJS := \  	utils/path_util.o \  	utils/string_util.o \  	utils/utils.o \ +	video/subtitle_card.o \  	video/video_player.o \ +	video/video_subtitler.o \  	video/video_theora_player.o \  	debugger.o \  	wintermute.o \ diff --git a/engines/wintermute/video/subtitle_card.cpp b/engines/wintermute/video/subtitle_card.cpp new file mode 100644 index 0000000000..5d882502fd --- /dev/null +++ b/engines/wintermute/video/subtitle_card.cpp @@ -0,0 +1,56 @@ +/* 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. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#include "engines/wintermute/video/subtitle_card.h" +#include "engines/wintermute/base/base_game.h" + +namespace Wintermute { + +SubtitleCard::SubtitleCard(BaseGame *inGame, +                           const Common::String &text, +                           const uint &startFrame, +                           const uint &endFrame) : _gameRef(inGame), +	_startFrame(startFrame), +	_endFrame(endFrame) { +	_text = text; +	_gameRef->expandStringByStringTable(_text); +} + +uint32 SubtitleCard::getStartFrame() const { +	return _startFrame; +} + +uint32 SubtitleCard::getEndFrame() const { +	return _endFrame; +} + +Common::String SubtitleCard::getText() const { +	return _text; +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/video/subtitle_card.h b/engines/wintermute/video/subtitle_card.h new file mode 100644 index 0000000000..629df77287 --- /dev/null +++ b/engines/wintermute/video/subtitle_card.h @@ -0,0 +1,53 @@ +/* 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. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#ifndef WINTERMUTE_SUBTITLECARD_H +#define WINTERMUTE_SUBTITLECARD_H + +#include "common/str.h" + +namespace Wintermute { + +class BaseGame; + +class SubtitleCard { +public: +	SubtitleCard(BaseGame *inGame, const Common::String &text, const uint &startFrame, const uint &endFrame); +	uint32 getEndFrame() const; +	uint32 getStartFrame() const; +	Common::String getText() const; +private: +	BaseGame *_gameRef; +	uint32 _endFrame; +	uint32 _startFrame; +	Common::String _text; +}; + +} // End of namespace Wintermute + +#endif diff --git a/engines/wintermute/video/video_subtitler.cpp b/engines/wintermute/video/video_subtitler.cpp new file mode 100644 index 0000000000..95d938574b --- /dev/null +++ b/engines/wintermute/video/video_subtitler.cpp @@ -0,0 +1,266 @@ +/* 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. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#include "engines/wintermute/video/video_subtitler.h" +#include "engines/wintermute/base/base_file_manager.h" +#include "engines/wintermute/utils/path_util.h" +#include "engines/wintermute/base/font/base_font.h" +#include "engines/wintermute/base/base_game.h" +#include "engines/wintermute/base/gfx/base_renderer.h" + +namespace Wintermute { + +VideoSubtitler::VideoSubtitler(BaseGame *inGame): BaseClass(inGame) { +	_lastSample = -1; +	_currentSubtitle = 0; +	_showSubtitle = false; +} + +VideoSubtitler::~VideoSubtitler(void) { +	_subtitles.clear(); +} + +bool VideoSubtitler::loadSubtitles(const Common::String &filename, const Common::String &subtitleFile) { +	if (filename.size() == 0) { +		return false; +	} + +	_subtitles.clear(); + +	_lastSample = -1; +	_currentSubtitle = 0; +	_showSubtitle = false; + +	Common::String newFile; + +	/* +	 * Okay, the expected behaviour is this: either we are +	 * provided with a subtitle file to use by the script when +	 * calling PlayTheora(), or we try to autodetect a suitable +	 * one which, for /some/path/movie/ogg is to be called +	 * /some/path/movie.sub +	 */ +	if (subtitleFile.size() != 0) { +		newFile = subtitleFile; +	} else { +		Common::String path = PathUtil::getDirectoryName(filename); +		Common::String name = PathUtil::getFileNameWithoutExtension(filename); +		Common::String ext = ".SUB"; +		newFile = PathUtil::combine(path, name + ext); +	} + +	Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(newFile, true, false); + +	if (file == nullptr) { +		return false; // no subtitles +	} + +	int fileSize = file->size(); +	char *buffer = new char[fileSize]; + +	file->read(buffer, fileSize); + +	/* This is where we parse .sub files. +	 * Subtitles cards are in the form +	 * {StartFrame}{EndFrame} FirstLine | SecondLine \n +	 */ +	int pos = 0; + +	while (pos < fileSize) { +		char *tokenStart = 0; +		int tokenLength = 0; +		int tokenPos = -1; +		int lineLength = 0; +		int start = -1; +		int end = -1; +		bool inToken = false; + +		while (pos + lineLength < fileSize && +				buffer[pos + lineLength] != '\n' && +				buffer[pos + lineLength] != '\0') { +			// Measure the line until we hit EOL, EOS or just hit the boundary +			lineLength++; +		} + +		int realLength; + +		if (pos + lineLength >= fileSize) { +			realLength = lineLength - 0; +		} else { +			// If we got here the above loop exited after hitting "\0" "\n" +			realLength = lineLength - 1; +		} + +		Common::String cardText; +		char *fileLine = (char *)&buffer[pos]; + +		for (int i = 0; i < realLength; i++) { +			if (fileLine[i] == '{') { +				if (!inToken) { +					// We've hit the start of a Start/EndFrame token +					inToken = true; +					tokenStart = fileLine + i + 1; +					tokenLength = 0; +					tokenPos++; +				} else { +					// Actually, we were already inside an (invalid) one. +					tokenLength++; +				} +			} else if (fileLine[i] == '}') { +				if (inToken) { +					// we were /inside/ a {.*} token, so this is the end of the block +					inToken = false; +					char *token = new char[tokenLength + 1]; +					strncpy(token, tokenStart, tokenLength); +					token[tokenLength] = '\0'; +					if (tokenPos == 0) { +						// Was this StartFrame... +						start = atoi(token); +					} else if (tokenPos == 1) { +						// Or the EndFrame? +						end = atoi(token); +					} +					delete[] token; +				} else { +					// This char is part of the plain text, just append it +					cardText += fileLine[i]; +				} +			} else { +				if (inToken) { +					tokenLength++; +				} else { +					if (fileLine[i] == '|') { +						// The pipe character signals a linebreak in the text +						cardText += '\n'; +					} else { +						// This char is part of the plain text, just append it +						cardText += fileLine[i]; +					} +				} +			} +		} + +		if (start != -1 && cardText.size() > 0 && (start != 1 || end != 1)){ +			// Add a subtitlecard based on the line we have just parsed +			_subtitles.push_back(SubtitleCard(_gameRef, cardText, start, end)); +		} + +		pos += lineLength + 1; +	} + +	delete[] buffer; +	// Succeeded loading subtitles! + +	return true; +} + +void VideoSubtitler::display() { +	if (_showSubtitle) { + +		BaseFont *font; + +		if (_gameRef->getVideoFont() == nullptr) { +			font = _gameRef->getSystemFont(); +		} else { +			font = _gameRef->getVideoFont(); +		} + +		int textHeight = font->getTextHeight( +		                     (const byte *)_subtitles[_currentSubtitle].getText().c_str(), +		                     _gameRef->_renderer->getWidth()); + +		font->drawText( +		    (const byte *)_subtitles[_currentSubtitle].getText().c_str(), +		    0, +		    (_gameRef->_renderer->getHeight() - textHeight - 5), +		    (_gameRef->_renderer->getWidth()), +		    TAL_CENTER); +	} +} + +void VideoSubtitler::update(uint32 frame) { +	if (_subtitles.size() == 0) { +		// Edge case: we have loaded subtitles early on... from a blank file. +		return; +	} + +	if ((int32)frame != _lastSample) { +		/* +		 * If the frame count hasn't advanced the previous state still matches +		 * the current frame (obviously). +		 */ + +		_lastSample = frame; +		// Otherwise, we update _lastSample; see above. + +		_showSubtitle = false; + +		bool overdue = (frame > _subtitles[_currentSubtitle].getEndFrame()); +		bool hasNext = (_currentSubtitle + 1 < _subtitles.size()); +		bool nextStarted = false; +		if (hasNext) { +			nextStarted = (_subtitles[_currentSubtitle + 1].getStartFrame() <= frame); +		} + +		while (_currentSubtitle < _subtitles.size() && +		        overdue && hasNext && nextStarted) { +			/* +			 *  We advance until we get past all overdue subtitles. +			 *  We should exit the cycle when we either reach the first +			 *  subtitle which is not overdue whose subsequent subtitle +			 *  has not started yet (aka the one we must display now or +			 *  the one which WILL be displayed when its time comes) +			 *  and / or when we reach the last one. +			 */ + +			_currentSubtitle++; + +			overdue = (frame > _subtitles[_currentSubtitle].getEndFrame()); +			hasNext = (_currentSubtitle + 1 < _subtitles.size()); +			if (hasNext) { +				nextStarted = (_subtitles[_currentSubtitle + 1].getStartFrame() <= frame); +			} else { +				nextStarted = false; +			} +		} + +		bool currentValid = (_subtitles[_currentSubtitle].getEndFrame() != 0); +		/* +		 * No idea why we do this check, carried over from Mnemonic's code. +		 * Possibly a workaround for buggy subtitles or some kind of sentinel? :-\ +		 */ + +		bool currentStarted = frame >= _subtitles[_currentSubtitle].getStartFrame(); + +		if (currentStarted && !overdue && currentValid) { +			_showSubtitle = true; +		} +	} +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/video/video_subtitler.h b/engines/wintermute/video/video_subtitler.h new file mode 100644 index 0000000000..94f22909a1 --- /dev/null +++ b/engines/wintermute/video/video_subtitler.h @@ -0,0 +1,53 @@ +/* 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. + * + */ + +/* + * This file is based on Wintermute Engine + * http://dead-code.org/redir.php?target=wme + * Copyright (c) 2011 Jan Nedoma + */ + +#ifndef WINTERMUTE_VIDSUBTITLER_H +#define WINTERMUTE_VIDSUBTITLER_H + +#include "engines/wintermute/base/base.h" +#include "engines/wintermute/video/subtitle_card.h" + +namespace Wintermute { + +class VideoSubtitler : public BaseClass { +public: +	VideoSubtitler(BaseGame *inGame); +	virtual ~VideoSubtitler(void); +	bool loadSubtitles(const Common::String &filename, const Common::String &subtitleFile); +	void display(); +	void update(uint32 frame); +private: +	Common::Array<SubtitleCard> _subtitles; +	int32 _lastSample; +	bool _showSubtitle; +	uint32 _currentSubtitle; +}; + +} // End of namespace Wintermute + +#endif diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp index e1553580ec..22c235c848 100644 --- a/engines/wintermute/video/video_theora_player.cpp +++ b/engines/wintermute/video/video_theora_player.cpp @@ -85,14 +85,14 @@ void VideoTheoraPlayer::SetDefaults() {  	_volume = 100;  	_theoraDecoder = nullptr; -	// TODO: Add subtitles-support -	//_subtitler = nullptr; +	_subtitler = new VideoSubtitler(_gameRef); +	_foundSubtitles = false;  }  //////////////////////////////////////////////////////////////////////////  VideoTheoraPlayer::~VideoTheoraPlayer(void) {  	cleanup(); -//	SAFE_DELETE(_subtitler); +	delete _subtitler;  }  ////////////////////////////////////////////////////////////////////////// @@ -130,6 +130,9 @@ bool VideoTheoraPlayer::initialize(const Common::String &filename, const Common:  	warning("VideoTheoraPlayer::initialize - Theora support not compiled in, video will be skipped: %s", filename.c_str());  	return STATUS_FAILED;  #endif + +	_foundSubtitles = _subtitler->loadSubtitles(_filename, subtitleFile); +  	_theoraDecoder->loadStream(_file);  	if (!_theoraDecoder->isVideoLoaded()) { @@ -214,7 +217,10 @@ bool VideoTheoraPlayer::play(TVideoPlayback type, int x, int y, bool freezeGame,  		_state = THEORA_STATE_PLAYING;  		_looping = looping;  		_playbackType = type; - +		if (_subtitler && _foundSubtitles && _gameRef->_subtitles) { +			_subtitler->update(_theoraDecoder->getFrameCount()); +			_subtitler->display(); +		}  		_startTime = startTime;  		_volume = volume;  		_posX = x; @@ -256,7 +262,7 @@ bool VideoTheoraPlayer::play(TVideoPlayback type, int x, int y, bool freezeGame,  #if 0 // Stubbed for now as theora isn't seekable  	if (StartTime) SeekToTime(StartTime); -	Update(); +	update();  #endif  	return STATUS_FAILED;  } @@ -289,6 +295,10 @@ bool VideoTheoraPlayer::update() {  	}  	if (_theoraDecoder) { +		if (_subtitler && _foundSubtitles && _gameRef->_subtitles) { +			_subtitler->update(_theoraDecoder->getCurFrame()); +		} +  		if (_theoraDecoder->endOfVideo() && _looping) {  			warning("Should loop movie %s, hacked for now", _filename.c_str());  			_theoraDecoder->rewind(); @@ -412,11 +422,10 @@ bool VideoTheoraPlayer::display(uint32 alpha) {  	} else {  		res = STATUS_FAILED;  	} -	// TODO: Add subtitles-support -/*	if (m_Subtitler && _gameRef->m_VideoSubtitles) { -		m_Subtitler->display(); -	}*/ +	if (_subtitler && _foundSubtitles && _gameRef->_subtitles) { +		_subtitler->display(); +	}  	return res;  } diff --git a/engines/wintermute/video/video_theora_player.h b/engines/wintermute/video/video_theora_player.h index 8274a1444f..0b9b3d487a 100644 --- a/engines/wintermute/video/video_theora_player.h +++ b/engines/wintermute/video/video_theora_player.h @@ -31,6 +31,7 @@  #include "engines/wintermute/base/base.h"  #include "engines/wintermute/persistent.h" +#include "engines/wintermute/video/video_subtitler.h"  #include "video/video_decoder.h"  #include "common/stream.h"  #include "graphics/surface.h" @@ -59,7 +60,7 @@ public:  	Common::String _filename;  	BaseSurface *_texture; -	//CVidSubtitler *_subtitler; +	VideoSubtitler *_subtitler;  	// control methods  	bool initialize(const Common::String &filename, const Common::String &subtitleFile = Common::String()); @@ -137,9 +138,10 @@ private:  	bool _playbackStarted; +	bool _foundSubtitles; +  	// helpers  	void SetDefaults(); -  };  } // End of namespace Wintermute | 
