BLADERUNNER: SUBTITLES.MIX pack support

This commit is contained in:
antoniou79 2018-08-01 18:05:28 +03:00 committed by Eugene Sandulenko
parent bf46900c7c
commit 6f55071c57
10 changed files with 98 additions and 389 deletions

View File

@ -56,7 +56,7 @@ bool MIXArchive::open(const Common::String &filename) {
_entries[i].length = _fd.readUint32LE();
#if BLADERUNNER_DEBUG_CONSOLE
debug("%08x %-12d %-12d", _entries[i].id, _entries[i].offset, _entries[i].length);
debug("%08x %-12d %-12d", _entries[i].hash, _entries[i].offset, _entries[i].length);
#endif
// Verify that the entries are sorted by id. Note that id is signed.

View File

@ -505,6 +505,11 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
_mainFont->setSpacing(1, 0);
_subtitles = new Subtitles(this);
r = openArchive("SUBTITLES.MIX");
if (!r) {
_subtitles->setSubtitlesSystemInactive(true); // no subtitles support
}
_subtitles->init();
for (int i = 0; i != 43; ++i) {
Shape *shape = new Shape(this);
@ -678,6 +683,9 @@ void BladeRunnerEngine::shutdown() {
_mainFont = nullptr;
}
if(isArchiveOpen("SUBTITLES.MIX")) {
closeArchive("SUBTITLES.MIX");
}
if (_subtitles) {
delete _subtitles;
_subtitles = nullptr;

View File

@ -106,7 +106,7 @@ public:
#if BLADERUNNER_DEBUG_GAME
static const int kArchiveCount = 100;
#else
static const int kArchiveCount = 10;
static const int kArchiveCount = 11; // +1 to original value (10) to accommodate for SUBTITLES.MIX resource
#endif
static const int kActorCount = 100;
static const int kActorVoiceOver = kActorCount - 1;

View File

@ -37,46 +37,6 @@ Font::~Font() {
close();
}
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
// for external FON font file / subtitles support
bool Font::openFromStream(Common::ScopedPtr<Common::SeekableReadStream> &stream, int screenWidth, int screenHeight, int spacing1, int spacing2, uint16 color) {
reset();
_screenWidth = screenWidth;
_screenHeight = screenHeight;
_spacing1 = spacing1;
_spacing2 = spacing2;
_color = color;
if (!stream) {
return false;
}
_characterCount = stream->readUint32LE();
debug("Font's character count: %d", _characterCount);
_maxWidth = stream->readUint32LE();
_maxHeight = stream->readUint32LE();
_dataSize = stream->readUint32LE();
_data = new uint16[_dataSize];
if (!_data) {
debug("Font::open failed to allocate font buffer");
return false;
}
for (int i = 0; i < _characterCount; i++) {
_characters[i].x = stream->readUint32LE();
_characters[i].y = stream->readUint32LE();
_characters[i].width = stream->readUint32LE();
_characters[i].height = stream->readUint32LE();
_characters[i].dataOffset = stream->readUint32LE();
debug("char::%d character x: %d, y: %d, w: %d, h:%d, do: %d", i, _characters[i].x, _characters[i].y, _characters[i].width, _characters[i].height, _characters[i].dataOffset);
}
for (int i = 0; i < _dataSize; i++) {
_data[i] = stream->readUint16LE();
}
return true;
}
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
bool Font::open(const Common::String &fileName, int screenWidth, int screenHeight, int spacing1, int spacing2, uint16 color) {
reset();

View File

@ -63,9 +63,6 @@ public:
Font(BladeRunnerEngine *vm);
~Font();
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
bool openFromStream(Common::ScopedPtr<Common::SeekableReadStream> &s, int screenWidth, int screenHeight, int spacing1, int spacing2, uint16 color);
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
bool open(const Common::String &fileName, int screenWidth, int screenHeight, int spacing1, int spacing2, uint16 color);
void close();

View File

@ -42,7 +42,7 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co
if (!noLocalization) {
resName = resName + "_" + _vm->_languageCode;
}
Common::String resNameNoVQASuffix = resName;
resName = resName + ".VQA";
VQAPlayer vqa_player(_vm, &_vm->_surfaceBack); // surfaceBack is needed here for subtitles rendering properly, original was _surfaceFront here
@ -62,7 +62,7 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co
break;
if (frame >= 0) {
_vm->_subtitles->getOuttakeSubsText(resName + ".TRE" , frame);
_vm->_subtitles->getOuttakeSubsText(resNameNoVQASuffix, frame);
_vm->_subtitles->tickOuttakes(_vm->_surfaceFront);
_vm->blitToScreen(_vm->_surfaceFront);
}

View File

@ -39,10 +39,9 @@ namespace BladeRunner {
*
* TODO in python script (FON from png glyphs) check if you can have semi-transparent pixels to better outline the fringe points of the glyphs - check what happens when MSB is set (transparency) and the rest of the color value is not all 0s.
* TODO Catch error for bad symbol in a quote (one that causes the font to crash) - this could happen with the corrupted internal font (TAHOMA18) -> font crash or bad font display / garbage character
* TODO add a keyboard shortcut key to enable / disable subtitles?
* TODO have a debug script to detect/report problematic lines (too long)
*
* TODO? put external FON and TRE in a new folder "SUBS" - case insensitive (?)
* TODO? add a keyboard shortcut key to enable / disable subtitles?
* TODO? Use another escape sequence to progressively display text in a line (like in SCUMM games) <-- this could be very useful with very long lines - might also need an extra manual time or ticks parameter to determine when during the display of the first segment we should switch to the second.
* TODO? A more advanced subtitles system
* TODO: subtitles could be independent from sound playing (but should disappear when switching between UI screens)
@ -66,19 +65,18 @@ namespace BladeRunner {
*/
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
const Common::String Subtitles::SUBTITLES_FONT_FILENAME = "SUBTITLES.FON";
const Common::String Subtitles::SUBTITLES_FONT_FILENAME = "SUBTLS_E.FON";
#else
const Common::String Subtitles::SUBTITLES_FONT_FILENAME = "TAHOMA18.FON";
#endif
/*
* All entries need to have the language code appended (after a '_').
* The outtakes then need a substring ".VQA"
* And all entries should have the suffix extension ".TRE"
* And all entries should get the suffix extension ".TRE" (or FUTURE: the last letter in extension "TR*" should also be the language code)
* If/When adding new TRE resources here --> Update kMaxTextResourceEntries and also update method getIdxForSubsTreName()
*/
const Common::String Subtitles::SUBTITLES_FILENAME_PREFIXES[kMaxTextResourceEntries] = {
"outQuotes", // 0 // (in-game subtitles, not VQA subtitles)
"INGQUO", // 0 // (in-game subtitles, not VQA subtitles)
"WSTLGO", // 1
"BRLOGO", // 2
"INTRO", // 3
@ -97,14 +95,13 @@ const Common::String Subtitles::SUBTITLES_FILENAME_PREFIXES[kMaxTextResourceEntr
"END04B", // 16
"END04C", // 17
"END06", // 18
"END07", // 19
"END01A", // 20
"END01B", // 21
"END01C", // 22
"END01D", // 23
"END01E", // 24
"END01F", // 25
"END03" // 26
"END01A", // 19
"END01B", // 20
"END01C", // 21
"END01D", // 22
"END01E", // 23
"END01F", // 24
"END03" // 25
};
/**
@ -112,56 +109,83 @@ const Common::String Subtitles::SUBTITLES_FILENAME_PREFIXES[kMaxTextResourceEntr
*/
Subtitles::Subtitles(BladeRunnerEngine *vm) {
_vm = vm;
_subtitlesSystemInactive = false;
// Initializing and reseting Subtitles
for (int i = 0; i < kMaxTextResourceEntries; i++) {
_gameSubsFdEntries[i] = nullptr;
_vqaSubsTextResourceEntries[i] = nullptr;
}
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
_gameSubsFontsFd = nullptr;
_subsFont = nullptr;
#else
_subsFont = nullptr;
_subsBgFont = nullptr;
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
reset();
// Done - Subtitles Reset
}
/**
* Subtitles Destructor
*/
Subtitles::~Subtitles() {
// delete any resource entries in the _vqaSubsTextResourceEntries table
// and close any open text resource files
for (int i = 0; i != kMaxTextResourceEntries; ++i) {
if (_vqaSubsTextResourceEntries[i] != nullptr) {
delete _vqaSubsTextResourceEntries[i];
_vqaSubsTextResourceEntries[i] = nullptr;
}
}
if (_subsFont != nullptr) {
_subsFont->close();
delete _subsFont;
_subsFont = nullptr;
}
#if !BLADERUNNER_SUBTITLES_EXTERNAL_FONT
if (_subsBgFont != nullptr) {
_subsBgFont->close();
delete _subsBgFont;
_subsBgFont = nullptr;
}
#endif // !BLADERUNNER_SUBTITLES_EXTERNAL_FONT
}
//
// Init is kept separated from constructor to allow not loading up resources if subtitles system is disabled
//
void Subtitles::init(void) {
if (_subtitlesSystemInactive) {
return;
}
//
// Loading text resources
for (int i = 0; i < kMaxTextResourceEntries; i++) {
_gameSubsFdEntries[i] = new Common::File();
_vqaSubsTextResourceEntries[i] = new TextResource(_vm);
Common::String tmpConstructedFileName = "";
tmpConstructedFileName = SUBTITLES_FILENAME_PREFIXES[i] + "_" + _vm->_languageCode;
if (i > 0) {
tmpConstructedFileName += ".VQA";
}
tmpConstructedFileName += ".TRE";
if (openGameSubs(tmpConstructedFileName) && loadGameSubsText(i)) {
_gameSubsFdEntriesFound[i] = true;
//tmpConstructedFileName += ".TRE"; // = Common::String::format("%s.TR%s", tmpConstructedFileName.c_str(), _vm->_languageCode.c_str());
if ( _vqaSubsTextResourceEntries[i]->open(tmpConstructedFileName)) {
_gameSubsResourceEntriesFound[i] = true;
}
}
// Done - Loading text resources
//
// Initializing/Loading Subtitles' Fonts
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
// Open external fonts file (FON file) and load fonts
_gameSubsFontsFd = new Common::File();
_subsFont = new Font(_vm);
if (openSubsFontFile() && loadSubsFont()) {
_subsFontsLoaded = true;
}
#else
_subsFont = new Font(_vm);
// Use TAHOMA18.FON (is corrupted in places)
// 10PT or TAHOMA24 or KIA6PT have all caps glyphs (and also are too big or too small) so they are not appropriate.
if (_subsFont ->open(SUBTITLES_FONT_FILENAME, 640, 480, -1, 0, 0)) { // Color setting does not seem to affect the TAHOMA fonts or does it affect the black outline since we give 0 here?
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
_subsFont->setSpacing(-1, 0);
#else
_subsFont->setSpacing(1, 0);
_subsFont->setWhiteColor();
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
_subsFontsLoaded = true;
} else {
_subsFontsLoaded = false;
}
#if !BLADERUNNER_SUBTITLES_EXTERNAL_FONT
_subsBgFont = new Font(_vm);
if (_subsFontsLoaded && _subsBgFont ->open(SUBTITLES_FONT_FILENAME, 640, 480, -1, 0, 0)) { // TODO dark color? --- color does not seem to affect the TAHOMA fonts or does it affect the black outline since we give 0 here? ?? - we should give the original color here. What is it for TAHOMA?
_subsBgFont ->setSpacing(1, 0);
@ -182,51 +206,8 @@ Subtitles::Subtitles(BladeRunnerEngine *vm) {
}
}
/**
* Subtitles Destructor
*/
Subtitles::~Subtitles() {
// delete any resource entries in the _vqaSubsTextResourceEntries table
// and close any open text resource files
for (int i = 0; i != kMaxTextResourceEntries; ++i) {
if (_vqaSubsTextResourceEntries[i] != nullptr) {
delete _vqaSubsTextResourceEntries[i];
_vqaSubsTextResourceEntries[i] = nullptr;
}
if (_gameSubsFdEntries[i] != nullptr) {
if (isOpenGameSubs(i)) {
closeGameSubs(i);
}
delete _gameSubsFdEntries[i];
_gameSubsFdEntries[i] = nullptr;
}
}
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
if (_subsFont != nullptr) {
_subsFont->close();
delete _subsFont;
_subsFont = nullptr;
}
if (_gameSubsFontsFd != nullptr) {
if (isOpenSubsFontFile()) {
closeSubsFontFile();
}
delete _gameSubsFontsFd;
_gameSubsFontsFd = nullptr;
}
#else
if (_subsFont != nullptr) {
_subsFont->close();
delete _subsFont;
_subsFont = nullptr;
}
if (_subsBgFont != nullptr) {
_subsBgFont->close();
delete _subsBgFont;
_subsBgFont = nullptr;
}
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
void Subtitles::setSubtitlesSystemInactive(bool flag) {
_subtitlesSystemInactive = flag;
}
/**
@ -237,10 +218,6 @@ int Subtitles::getIdxForSubsTreName(const Common::String &treName) const {
Common::String tmpConstructedFileName = "";
for (int i = 0; i < kMaxTextResourceEntries; ++i) {
tmpConstructedFileName = SUBTITLES_FILENAME_PREFIXES[i] + "_" + _vm->_languageCode;
if (i > 0) {
tmpConstructedFileName += ".VQA";
}
tmpConstructedFileName += ".TRE";
if (tmpConstructedFileName == treName) {
return i;
}
@ -249,178 +226,18 @@ int Subtitles::getIdxForSubsTreName(const Common::String &treName) const {
return -1;
}
/**
* Open an external subtitles File and store its file descriptor
* @return true if successful, false otherwise
*/
bool Subtitles::openGameSubs(const Common::String &filename) {
uint32 gameSubsEntryCount = 0;
int subTreIdx = getIdxForSubsTreName(filename);
if (subTreIdx < 0 || _gameSubsFdEntries[subTreIdx] == nullptr) {
debug("Subtitles::open(): Could not open %s", filename.c_str());
return false;
}
// debug("Now opening subs file: %s", filename.c_str());
if (!_gameSubsFdEntries[subTreIdx]->open(filename)) {
debug("Subtitles::open(): Could not open %s", filename.c_str());
return false;
}
gameSubsEntryCount = _gameSubsFdEntries[subTreIdx]->readUint32LE();
if (_gameSubsFdEntries[subTreIdx]->err()) {
error("Subtitles::open(): Error reading entries in %s", filename.c_str());
_gameSubsFdEntries[subTreIdx]->close();
return false;
}
debug("Subtitles::open: Opened in-game external subs file %s with %d entries", filename.c_str(), gameSubsEntryCount);
return true;
}
/**
* Close an open external subtitles File
*/
void Subtitles::closeGameSubs(int subTreIdx) {
if (subTreIdx < 0 || _gameSubsFdEntries[subTreIdx] == nullptr) {
debug("Subtitles::close(): Could not close file with Idx %d", subTreIdx);
return;
}
return _gameSubsFdEntries[subTreIdx]->close();
}
/**
* Check whether an external subtitles File is open
*/
bool Subtitles::isOpenGameSubs(int subTreIdx) const {
if (subTreIdx < 0 || _gameSubsFdEntries[subTreIdx] == nullptr) {
return false;
}
return _gameSubsFdEntries[subTreIdx]->isOpen();
}
/**
* Load the game subs as a TRE resource and store them in a specific entry in _vqaSubsTextResourceEntries table
*/
bool Subtitles::loadGameSubsText(int subTreIdx) {
bool r = false;
Common::SeekableReadStream *stream = createReadStreamForGameSubs(subTreIdx);
if (stream != nullptr) {
Common::ScopedPtr<Common::SeekableReadStream> s(stream);
r = _vqaSubsTextResourceEntries[subTreIdx]->openFromStream(s);
if (!r) {
error("Failed to load subtitle text");
}
closeGameSubs(subTreIdx);
}
return r;
}
/**
* Auxiliary method for loadGameSubsText
* @return nullptr if failure, otherwise return a pointer to a new SafeSeekableSubReadStream
*/
Common::SeekableReadStream *Subtitles::createReadStreamForGameSubs(int subTreIdx) {
if (subTreIdx < 0 || _gameSubsFdEntries[subTreIdx] == nullptr) {
return nullptr;
}
if (!isOpenGameSubs(subTreIdx)) {
return nullptr;
}
return new Common::SafeSeekableSubReadStream(_gameSubsFdEntries[subTreIdx], 0, _gameSubsFdEntries[subTreIdx]->size(), DisposeAfterUse::YES); // TODO changed to YES from NO is this ok?
}
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
//
// EXTERN FONT MANAGEMENT - Font Open/ Create Read Stream / Load / Close methods
//
/**
* @return true if successfully opened the external fonts (FON) file, false otherwise
*/
bool Subtitles::openSubsFontFile() {
uint32 subFontsTableEntryCount = 0;
// debug("Now opening subs file: %s", SUBTITLES_FONT_FILENAME.c_str());
if (_gameSubsFontsFd == nullptr || !_gameSubsFontsFd->open(SUBTITLES_FONT_FILENAME)) {
debug("Subtitles FONT::open(): Could not open %s", SUBTITLES_FONT_FILENAME.c_str());
return false;
}
subFontsTableEntryCount = _gameSubsFontsFd->readUint32LE(); // only for debug report purposes
if (_gameSubsFontsFd->err()) {
error("Subtitles FONT::open(): Error reading entries in %s", SUBTITLES_FONT_FILENAME.c_str());
_gameSubsFontsFd->close();
return false;
}
debug("Subtitles FONT::open: Opened in-game external subs FONT file %s with %d entries", SUBTITLES_FONT_FILENAME.c_str(), subFontsTableEntryCount);
return true;
}
/**
* Close the external Fonts (FON) file
*/
void Subtitles::closeSubsFontFile() {
if (_gameSubsFontsFd != nullptr) {
_gameSubsFontsFd->close();
}
}
/**
* Checks whether the external fonts (FON) file has been opened
*/
bool Subtitles::isOpenSubsFontFile() const {
return _gameSubsFontsFd != nullptr && _gameSubsFontsFd->isOpen();
}
/**
* Auxiliary function to create a read stream fro the external fonts file
* @return a pointer to the stream if successful, or nullptr otherwise
*/
Common::SeekableReadStream *Subtitles::createReadStreamForSubFonts() {
if (_gameSubsFontsFd == nullptr || !isOpenSubsFontFile()) {
return nullptr;
}
return new Common::SafeSeekableSubReadStream(_gameSubsFontsFd, 0, _gameSubsFontsFd->size(), DisposeAfterUse::YES); // TODO changed to YES from NO is this ok?
}
/**
* Loads the font from the external font file
* @return true if successful, or false otherwise
*/
bool Subtitles::loadSubsFont() {
bool r = false;
Common::SeekableReadStream *stream = createReadStreamForSubFonts();
if (stream != nullptr) {
Common::ScopedPtr<Common::SeekableReadStream> s(stream);
r = _subsFont->openFromStream(s, 640, 480, -1, 0, 0);
if (!r) {
error("Failed to load subtitle FONT");
} else {
_subsFont->setSpacing(-1, 0);
}
//_subsFont->setSpacing(0, 0);
closeSubsFontFile();
}
return r;
}
//
// END OF EXTERNAL FONT MANAGEMENT
//
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
/**
* Get the active subtitle text by searching with actor ID and speech ID
* Use this method for in-game dialogue - Not dialogue during a VQA cutscene
* Returns the dialogue quote, but also sets the private _currentSubtitleTextFull member
*/
const char *Subtitles::getInGameSubsText(int actorId, int speech_id) {
if (_subtitlesSystemInactive) {
return "";
}
int32 id = 10000 * actorId + speech_id;
if (!_gameSubsFdEntriesFound[0]) {
if (!_gameSubsResourceEntriesFound[0]) {
if (_currentSubtitleTextFull != "") {
_currentSubtitleTextFull = "";
_subtitlesQuoteChanged = true;
@ -439,8 +256,12 @@ const char *Subtitles::getInGameSubsText(int actorId, int speech_id) {
* Returns the dialogue quote, but also sets the private _currentSubtitleTextFull member
*/
const char *Subtitles::getOuttakeSubsText(const Common::String &outtakesName, int frame) {
if (_subtitlesSystemInactive) {
return "";
}
int fileIdx = getIdxForSubsTreName(outtakesName);
if (fileIdx == -1 || !_gameSubsFdEntriesFound[fileIdx]) {
if (fileIdx == -1 || !_gameSubsResourceEntriesFound[fileIdx]) {
if (_currentSubtitleTextFull != "") {
_currentSubtitleTextFull = "";
_subtitlesQuoteChanged = true;
@ -476,6 +297,9 @@ void Subtitles::setGameSubsText(Common::String dbgQuote) {
* @return true if the member was set now, false if the member was already set
*/
bool Subtitles::show() {
if (_subtitlesSystemInactive) {
return false;
}
if (_isVisible) {
return false;
@ -489,6 +313,10 @@ bool Subtitles::show() {
* @return true if the member was cleared, false if it was already clear.
*/
bool Subtitles::hide() {
if (_subtitlesSystemInactive) {
return false;
}
if (!_isVisible) {
return false;
}
@ -502,7 +330,7 @@ bool Subtitles::hide() {
* @return the value of the _isVisible member boolean var
*/
bool Subtitles::isVisible() const {
return _isVisible;
return _subtitlesSystemInactive || _isVisible;
}
/**
@ -514,7 +342,7 @@ void Subtitles::tickOuttakes(Graphics::Surface &s) {
} else {
_vm->_subtitles->show();
}
if (!_vm->isSubtitlesEnabled()) {
if (_subtitlesSystemInactive || !_vm->isSubtitlesEnabled()) {
return;
}
if (!_isVisible) { // keep it as a separate if
@ -530,7 +358,7 @@ void Subtitles::tick(Graphics::Surface &s) {
if (!_vm->_audioSpeech->isPlaying()) {
_vm->_subtitles->hide(); // TODO might need a better system. Don't call it always.
}
if (!_vm->isSubtitlesEnabled()) {
if (_subtitlesSystemInactive || !_vm->isSubtitlesEnabled()) {
return;
}
if (!_isVisible) { // keep it as a separate if
@ -726,37 +554,15 @@ void Subtitles::reset() {
delete _vqaSubsTextResourceEntries[i];
_vqaSubsTextResourceEntries[i] = nullptr;
}
_gameSubsFdEntriesFound[i] = false;
if (_gameSubsFdEntries[i] != nullptr) {
if (isOpenGameSubs(i)) {
closeGameSubs(i);
}
delete _gameSubsFdEntries[i];
_gameSubsFdEntries[i] = nullptr;
}
_gameSubsResourceEntriesFound[i] = false;
}
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
if (_subsFont != nullptr) {
_subsFont->close();
delete _subsFont;
_subsFont = nullptr;
}
if (_gameSubsFontsFd != nullptr) {
if (isOpenSubsFontFile()) {
closeSubsFontFile();
}
delete _gameSubsFontsFd;
_gameSubsFontsFd = nullptr;
}
#else
if (_subsFont != nullptr) {
if (_subsFont != nullptr) {
_subsFont->close();
delete _subsFont;
_subsFont = nullptr;
}
#if !BLADERUNNER_SUBTITLES_EXTERNAL_FONT
if (_subsBgFont != nullptr) {
_subsBgFont->close();
delete _subsBgFont;

View File

@ -48,7 +48,7 @@ class Subtitles {
// TODO Or just support the current _vm->_languageCode ? [current implementation]
static const int kMaxNumOfSubtitlesLines = 3;
static const int kMaxWidthPerLineToAutoSplitThresholdPx = 610;
static const int kMaxTextResourceEntries = 1 + 26; // Support in-game subs (1) and all possible VQAs (26) with spoken dialogue!
static const int kMaxTextResourceEntries = 1 + 25; // Support in-game subs (1) and all possible VQAs (26) with spoken dialogue!
static const Common::String SUBTITLES_FILENAME_PREFIXES[kMaxTextResourceEntries];
static const Common::String SUBTITLES_FONT_FILENAME;
@ -70,17 +70,16 @@ class Subtitles {
int _currentSubtitleLines;
bool _subtitlesQuoteChanged;
Common::File *_gameSubsFdEntries[kMaxTextResourceEntries]; // an array of pointers to TRE FILEs
bool _gameSubsFdEntriesFound[kMaxTextResourceEntries]; // false if a TRE file did not open successfully
bool _gameSubsResourceEntriesFound[kMaxTextResourceEntries]; // false if a TRE file did not open successfully
bool _subsFontsLoaded; // false if external fonts did not load, or internal fonts (fore and background) did not load
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
Common::File *_gameSubsFontsFd; // the file for the external FONT for subtitles
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
bool _subtitlesSystemInactive; // true if the whole subtitles subsystem should be disabled (due to missing required resources)
public:
Subtitles(BladeRunnerEngine *vm);
~Subtitles();
void init();
void setSubtitlesSystemInactive(bool flag); // disable subtitles system (possibly due to missing important resources like SUBTITLES.MIX file)
const char *getInGameSubsText(int actorId, int speech_id) ; // get the text for actorId, quoteId (in-game subs)
const char *getOuttakeSubsText(const Common::String &outtakesName, int frame); // get the text for this frame if any
@ -92,24 +91,6 @@ public:
void tickOuttakes(Graphics::Surface &s);
private:
Common::SeekableReadStream *createReadStreamForGameSubs(int subTreIdx);
bool openGameSubs(const Common::String &filename);
void closeGameSubs(int subTreIdx);
bool isOpenGameSubs(int subTreIdx) const;
bool loadGameSubsText(int subTreIdx); // populate a GAME SUBS TextResource with subtitles
//
//
#if BLADERUNNER_SUBTITLES_EXTERNAL_FONT
Common::SeekableReadStream *createReadStreamForSubFonts();
bool openSubsFontFile();
void closeSubsFontFile();
bool isOpenSubsFontFile() const; //
bool loadSubsFont(); // create a the font object from a FON file (external)
#endif // BLADERUNNER_SUBTITLES_EXTERNAL_FONT
void draw(Graphics::Surface &s);
// bool showAt(int x, int y); // TODO maybe future use (?)
void calculatePosition();

View File

@ -43,48 +43,6 @@ TextResource::~TextResource() {
delete[] _strings;
}
// for TRE subtitles support
bool TextResource::openFromStream(Common::ScopedPtr<Common::SeekableReadStream> &s) {
if (!s) {
return false;
}
_count = s->readUint32LE();
_ids = new uint32[_count];
_offsets = new uint32[_count + 1];
for (uint32 i = 0; i != _count; ++i) {
_ids[i] = s->readUint32LE();
}
for (uint32 i = 0; i != _count + 1; ++i) {
_offsets[i] = s->readUint32LE();
}
uint32 stringsStart = s->pos() - 4;
for (uint32 i = 0; i != _count + 1; ++i) {
_offsets[i] -= stringsStart;
}
uint32 remain = s->size() - s->pos();
_strings = new char[remain];
assert(remain >= _offsets[_count]);
s->read(_strings, remain);
#if BLADERUNNER_DEBUG_CONSOLE
// debug("\nRESOURCE:: from Stream\n----------------");
// for (uint32 i = 0; i != (uint32)_count; ++i) {
// debug("%3d: %s", _ids[i], getText(_ids[i]));
// }
#endif
return true;
}
bool TextResource::open(const Common::String &name) {
assert(name.size() <= 8);

View File

@ -45,7 +45,6 @@ public:
~TextResource();
bool open(const Common::String &name);
bool openFromStream(Common::ScopedPtr<Common::SeekableReadStream> &s);
const char *getText(uint32 id) const;
const char *getOuttakeTextByFrame(uint32 frame) const;