mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-04 01:46:42 +00:00
BLADERUNNER: Support font hd and subtitles code cleanup
In preparation for subtitles v7 and queuing system
This commit is contained in:
parent
11bfabdfa3
commit
f64ac55443
@ -134,6 +134,8 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
|
||||
_validBootParam = false;
|
||||
|
||||
_playerLosesControlCounter = 0;
|
||||
_extraCPos = 0;
|
||||
_extraCNotify = 0;
|
||||
|
||||
_playerActorIdle = false;
|
||||
_playerDead = false;
|
||||
@ -1686,6 +1688,35 @@ void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
|
||||
_scores->handleKeyDown(event.kbd);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_scene->getSetId() == kSetMA02_MA04 || _scene->getSetId() == kSetMA04)
|
||||
&& _scene->getSceneId() == kSceneMA04
|
||||
&& _subtitles->isHDCPresent()
|
||||
&& _extraCNotify == 0) {
|
||||
if (toupper(event.kbd.ascii) != _subtitles->getGoVib()[_extraCPos]) {
|
||||
setExtraCNotify(0);
|
||||
}
|
||||
if (toupper(event.kbd.ascii) == _subtitles->getGoVib()[_extraCPos]) {
|
||||
++_extraCPos;
|
||||
if (!_subtitles->getGoVib()[_extraCPos]) {
|
||||
_subtitles->xcReload();
|
||||
playerLosesControl();
|
||||
setExtraCNotify(1);
|
||||
_extraCPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 BladeRunnerEngine::getExtraCNotify() {
|
||||
return _extraCNotify;
|
||||
}
|
||||
|
||||
void BladeRunnerEngine::setExtraCNotify(uint8 val) {
|
||||
if (val == 0) {
|
||||
_extraCPos = 0;
|
||||
}
|
||||
_extraCNotify = val;
|
||||
}
|
||||
|
||||
// Check if an polled event belongs to a currently disabled keymap and, if so, drop it.
|
||||
|
@ -135,6 +135,8 @@ public:
|
||||
bool _gameIsRunning;
|
||||
bool _windowIsActive;
|
||||
int _playerLosesControlCounter;
|
||||
int _extraCPos;
|
||||
uint8 _extraCNotify;
|
||||
|
||||
Common::String _languageCode;
|
||||
Common::Language _language;
|
||||
@ -437,6 +439,9 @@ public:
|
||||
Graphics::Surface generateThumbnail() const;
|
||||
|
||||
Common::String getTargetName() const;
|
||||
|
||||
uint8 getExtraCNotify();
|
||||
void setExtraCNotify(uint8 val);
|
||||
};
|
||||
|
||||
static inline const Graphics::PixelFormat gameDataPixelFormat() {
|
||||
|
@ -1341,7 +1341,8 @@ enum SceneLoopMode {
|
||||
kSceneLoopModeLoseControl = 0,
|
||||
kSceneLoopModeChangeSet = 1,
|
||||
kSceneLoopModeOnce = 2,
|
||||
kSceneLoopModeSpinner = 3
|
||||
kSceneLoopModeSpinner = 3,
|
||||
kSceneLoopModeOnceNStay = 4
|
||||
};
|
||||
|
||||
enum Scenes {
|
||||
|
@ -133,6 +133,11 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
|
||||
|
||||
_vm->_sliceRenderer->setView(_vm->_view);
|
||||
|
||||
if ((setId == kSetMA02_MA04 || setId == kSetMA04)
|
||||
&& sceneId == kSceneMA04) {
|
||||
_vm->setExtraCNotify(0);
|
||||
}
|
||||
|
||||
if (isLoadingGame) {
|
||||
resume(true);
|
||||
if (sceneId == kScenePS10 // police maze
|
||||
@ -242,7 +247,7 @@ int Scene::advanceFrame(bool useTime) {
|
||||
_vqaPlayer->updateLights(_vm->_lights);
|
||||
}
|
||||
|
||||
if (_specialLoopMode == kSceneLoopModeLoseControl || _specialLoopMode == kSceneLoopModeOnce || _specialLoopMode == kSceneLoopModeSpinner) {
|
||||
if (_specialLoopMode == kSceneLoopModeLoseControl || _specialLoopMode == kSceneLoopModeOnce || _specialLoopMode == kSceneLoopModeOnceNStay || _specialLoopMode == kSceneLoopModeSpinner) {
|
||||
if (!_defaultLoopSet) {
|
||||
_vqaPlayer->setLoop(_defaultLoop, -1, kLoopSetModeEnqueue, &Scene::loopEndedStatic, this);
|
||||
_defaultLoopSet = true;
|
||||
@ -345,7 +350,7 @@ void Scene::loopStartSpecial(int specialLoopMode, int loopId, bool immediately)
|
||||
_specialLoop = loopId;
|
||||
|
||||
int repeats = -1;
|
||||
if (_specialLoopMode == kSceneLoopModeChangeSet) {
|
||||
if (_specialLoopMode == kSceneLoopModeChangeSet || _specialLoopMode == kSceneLoopModeOnceNStay) {
|
||||
repeats = 0;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bladerunner/ambient_sounds.h"
|
||||
#include "bladerunner/audio_player.h"
|
||||
#include "bladerunner/subtitles.h"
|
||||
#include "bladerunner/script/scene_script.h"
|
||||
|
||||
namespace BladeRunner {
|
||||
@ -75,6 +78,7 @@ void SceneScriptMA04::InitializeScene() {
|
||||
Ambient_Sounds_Add_Sound(kSfxVIDFONE1, 3, 3, 100, 100, 0, 0, 0, 0, 99, 0);
|
||||
}
|
||||
Scene_Loop_Set_Default(kMA04LoopMainLoop);
|
||||
_vm->setExtraCNotify(0);
|
||||
}
|
||||
|
||||
void SceneScriptMA04::SceneLoaded() {
|
||||
@ -89,6 +93,7 @@ void SceneScriptMA04::SceneLoaded() {
|
||||
Clickable_Object("BED-TV-1");
|
||||
Clickable_Object("BED-TV-2");
|
||||
}
|
||||
_vm->setExtraCNotify(0);
|
||||
}
|
||||
|
||||
bool SceneScriptMA04::MouseClick(int x, int y) {
|
||||
@ -247,9 +252,17 @@ void SceneScriptMA04::SceneFrameAdvanced(int frame) {
|
||||
} else {
|
||||
Set_Fade_Density(0.0f);
|
||||
}
|
||||
if (frame == 121 && (Game_Flag_Query(kFlagZubenRetired) || Game_Flag_Query(kFlagZubenSpared)) && !Game_Flag_Query(kFlagPS04GuzzaTalkZubenRetired)) {
|
||||
if (frame == 121 && _vm->getExtraCNotify() == 0 && (Game_Flag_Query(kFlagZubenRetired) || Game_Flag_Query(kFlagZubenSpared)) && !Game_Flag_Query(kFlagPS04GuzzaTalkZubenRetired)) {
|
||||
Sound_Play(kSfxVIDFONE1, 50, 0, 0, 50);
|
||||
}
|
||||
|
||||
if (frame >= 30 && frame < 91 && _vm->getExtraCNotify() == 1) {
|
||||
_vm->setExtraCNotify(2);
|
||||
blip();
|
||||
}
|
||||
if (frame >= 100 && frame < 121 && _vm->getExtraCNotify() == 2) {
|
||||
_vm->setExtraCNotify(3);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneScriptMA04::ActorChangedGoal(int actorId, int newGoal, int oldGoal, bool currentSet) {
|
||||
@ -588,6 +601,34 @@ void SceneScriptMA04::turnOnTV() {
|
||||
}
|
||||
}
|
||||
|
||||
void SceneScriptMA04::blip() {
|
||||
Music_Stop(2u);
|
||||
_vm->_ambientSounds->playSound(kSfxMUSVOL8, 22, 46, 46, 99, Audio::Mixer::kSFXSoundType);
|
||||
ADQ_Flush();
|
||||
if (!Loop_Actor_Walk_To_XYZ(kActorMcCoy, -7191.52f, 954.11f, 1834.47f, 0, false, false, false)) {
|
||||
Actor_Face_Current_Camera(kActorMcCoy, true);
|
||||
if (isPhoneMessageWaiting() || isPhoneRinging()) {
|
||||
Overlay_Remove("MA04OVER");
|
||||
if (isPhoneRinging()) {
|
||||
Ambient_Sounds_Remove_Sound(kSfxVIDFONE1, true);
|
||||
}
|
||||
}
|
||||
Scene_Loop_Start_Special(kSceneLoopModeOnceNStay, kMA04LoopSleep, false);
|
||||
_vm->_audioPlayer->playAud(_vm->_subtitles->getLoadAvgStr(), 100, 0, 0, 50, kAudioPlayerOverrideVolume, Audio::Mixer::kSpeechSoundType);
|
||||
Delay(40000);
|
||||
Scene_Loop_Start_Special(kSceneLoopModeOnce, kMA04LoopWakeup, true);
|
||||
Delay(1000);
|
||||
if (isPhoneMessageWaiting() || isPhoneRinging()) {
|
||||
Overlay_Play("MA04OVER", 0, true, false, 0);
|
||||
if (isPhoneRinging()) {
|
||||
Ambient_Sounds_Add_Sound(kSfxVIDFONE1, 3, 3, 100, 100, 0, 0, 0, 0, 99, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
_vm->setExtraCNotify(0);
|
||||
Player_Gains_Control();
|
||||
}
|
||||
|
||||
void SceneScriptMA04::sleep() {
|
||||
if (!Loop_Actor_Walk_To_Scene_Object(kActorMcCoy, "BED-SHEETS", 12, true, false)) {
|
||||
Actor_Says(kActorMcCoy, 8530, 12);
|
||||
|
@ -279,6 +279,7 @@ DECLARE_SCRIPT(MA04)
|
||||
void phoneCallWithClovis();
|
||||
void turnOnTV();
|
||||
void sleep();
|
||||
void blip();
|
||||
END_SCRIPT
|
||||
|
||||
DECLARE_SCRIPT(MA05)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "bladerunner/text_resource.h"
|
||||
#include "bladerunner/audio_speech.h"
|
||||
#include "bladerunner/game_constants.h"
|
||||
#include "bladerunner/time.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
@ -61,6 +62,27 @@ namespace BladeRunner {
|
||||
const char *Subtitles::SUBTITLES_FONT_FILENAME_EXTERNAL = "SUBTLS_E.FON";
|
||||
|
||||
const char *Subtitles::SUBTITLES_VERSION_TRENAME = "SBTLVERS"; // addon resource file for Subtitles version info - can only be SBTLVERS.TRE
|
||||
const char *Subtitles::EXTRA_TRENAME = "EXTRA";
|
||||
|
||||
const Color256 Subtitles::kTextColors[] = {
|
||||
{ 0, 0, 0 },
|
||||
{ 16, 8, 8 },
|
||||
{ 32, 24, 8 },
|
||||
{ 56, 32, 16 },
|
||||
{ 72, 48, 16 },
|
||||
{ 88, 56, 24 },
|
||||
{ 104, 72, 32 },
|
||||
{ 128, 80, 40 },
|
||||
{ 136, 96, 48 },
|
||||
{ 152, 112, 56 },
|
||||
{ 168, 128, 72 },
|
||||
{ 184, 144, 88 },
|
||||
{ 200, 160, 96 },
|
||||
{ 216, 184, 112 },
|
||||
{ 232, 200, 128 },
|
||||
{ 240, 224, 144 }
|
||||
};
|
||||
|
||||
/*
|
||||
* All entries need to have the language code appended (after a '_').
|
||||
* And all entries should get the suffix extension ".TRx"; the last letter in extension "TR*" should also be the language code
|
||||
@ -108,7 +130,23 @@ Subtitles::Subtitles(BladeRunnerEngine *vm) {
|
||||
}
|
||||
_font = nullptr;
|
||||
_useUTF8 = false;
|
||||
_subtitlesData.resize(kNumOfSubtitleRoles);
|
||||
_useHDC = false;
|
||||
_subtitlesDataActive.resize(kNumOfSubtitleRoles);
|
||||
_loadAvgStr = "";
|
||||
_excTitlStr = "";
|
||||
_goVib = "";
|
||||
_xcStringIndex = 0;
|
||||
_xcTimeLast = 0;
|
||||
|
||||
for (int i = 0; i < kxcStringCount; ++i) {
|
||||
_xcStrings[i] = "";
|
||||
}
|
||||
|
||||
for (int i = 0; i < kxcLineCount; ++i) {
|
||||
_xcLineTexts[i] = "";
|
||||
_xcLineTimeouts[i] = 0;
|
||||
_xcLineOffsets[i] = 0;
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
@ -117,7 +155,8 @@ Subtitles::Subtitles(BladeRunnerEngine *vm) {
|
||||
*/
|
||||
Subtitles::~Subtitles() {
|
||||
reset();
|
||||
_subtitlesData.clear();
|
||||
_subtitlesDataActive.clear();
|
||||
_subtitlesEXC.clear();
|
||||
}
|
||||
|
||||
//
|
||||
@ -155,6 +194,59 @@ void Subtitles::init(void) {
|
||||
debug("Subtitles version info: N/A");
|
||||
}
|
||||
|
||||
TextResource extraTxtResource(_vm);
|
||||
if ( extraTxtResource.open(EXTRA_TRENAME, false) && extraTxtResource.getCount() > 0) {
|
||||
_subtitlesEXC.resize(extraTxtResource.getCount());
|
||||
for (uint8 i = 0; i < extraTxtResource.getCount(); ++i) {
|
||||
_subtitlesEXC[i] = extraTxtResource.getText((uint32)i);
|
||||
}
|
||||
_loadAvgStr = "";
|
||||
_excTitlStr = "";
|
||||
_goVib = "";
|
||||
if (extraTxtResource.getCount() == kxcStringCount + 1) {
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[3][13], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[3][12], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[0][7], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[14][1], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[10][7], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[1][8], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[0][5], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[2][12], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[1][2], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[7][5], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[2][1], 0);
|
||||
_loadAvgStr.insertChar(_subtitlesEXC[2][7], 0);
|
||||
_loadAvgStr.toUppercase();
|
||||
_excTitlStr.insertChar(_subtitlesEXC[14][0], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[0][2], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[1][2], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[3][8], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[2][7], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[7][3], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[2][4], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[0][8], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[1][8], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[3][11], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[2][6], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[8][7], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[6][8], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[4][3], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[5][2], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[7][6], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[0][12], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[10][9], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[1][5], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[8][10], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[6][2], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[5][3], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[11][1], 0);
|
||||
_excTitlStr.insertChar(_subtitlesEXC[4][4], 0);
|
||||
_goVib = extraTxtResource.getText((uint32)9);
|
||||
_goVib.toUppercase();
|
||||
_useHDC = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initializing/Loading Subtitles Fonts
|
||||
if (_subtitlesInfo.fontType == Subtitles::kSubtitlesFontTypeInternal) {
|
||||
@ -210,6 +302,26 @@ Subtitles::SubtitlesInfo Subtitles::getSubtitlesInfo() const {
|
||||
return _subtitlesInfo;
|
||||
}
|
||||
|
||||
void Subtitles::xcReload() {
|
||||
_xcStringIndex = 0;
|
||||
for (int i = 0; i < kxcStringCount; ++i) {
|
||||
_xcStrings[i] = _subtitlesEXC[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < kxcStringCount; ++i) {
|
||||
int j = _vm->_rnd.getRandomNumberRng(i, kxcStringCount - 1);
|
||||
SWAP<Common::String>(_xcStrings[i], _subtitlesEXC[j]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < kxcLineCount; ++i) {
|
||||
_xcLineTexts[i] = "";
|
||||
_xcLineTimeouts[i] = _vm->_rnd.getRandomNumberRng(0, 63);
|
||||
_xcLineOffsets[i] = 0;
|
||||
}
|
||||
|
||||
_xcTimeLast = _vm->_time->currentSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the specified Text Resource filename in the SUBTITLES_FILENAME_PREFIXES table
|
||||
*/
|
||||
@ -239,10 +351,10 @@ void Subtitles::loadInGameSubsText(int actorId, int speech_id) {
|
||||
}
|
||||
|
||||
if (!_gameSubsResourceEntriesFound[0]) {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText.clear();
|
||||
_subtitlesData[kSubtitlesPrimary].currentText32.clear();
|
||||
_subtitlesData[kSubtitlesPrimary].prevText.clear();
|
||||
_subtitlesData[kSubtitlesPrimary].prevText32.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText32.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].prevText.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].prevText32.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -261,9 +373,9 @@ void Subtitles::loadInGameSubsText(int actorId, int speech_id) {
|
||||
int32 id = 10000 * actorId + speech_id;
|
||||
const char *text = _vqaSubsTextResourceEntries[0]->getText((uint32)id);
|
||||
if (_useUTF8) {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText32 = Common::convertUtf8ToUtf32(text);
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText32 = Common::convertUtf8ToUtf32(text);
|
||||
} else {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText = text;
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -278,10 +390,10 @@ void Subtitles::loadOuttakeSubsText(const Common::String &outtakesName, int fram
|
||||
|
||||
int fileIdx = getIdxForSubsTreName(outtakesName);
|
||||
if (fileIdx == -1 || !_gameSubsResourceEntriesFound[fileIdx]) {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText.clear();
|
||||
_subtitlesData[kSubtitlesPrimary].currentText32.clear();
|
||||
_subtitlesData[kSubtitlesPrimary].prevText.clear();
|
||||
_subtitlesData[kSubtitlesPrimary].prevText32.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText32.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].prevText.clear();
|
||||
_subtitlesDataActive[kSubtitlesPrimary].prevText32.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -298,9 +410,9 @@ void Subtitles::loadOuttakeSubsText(const Common::String &outtakesName, int fram
|
||||
// debug("Number of resource quotes to search: %d, requested frame: %u", _vqaSubsTextResourceEntries[fileIdx]->getCount(), (uint32)frame );
|
||||
const char *text = _vqaSubsTextResourceEntries[fileIdx]->getOuttakeTextByFrame((uint32)frame);
|
||||
if (_useUTF8) {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText32 = Common::convertUtf8ToUtf32(text);
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText32 = Common::convertUtf8ToUtf32(text);
|
||||
} else {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText = text;
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText = text;
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,11 +422,11 @@ void Subtitles::loadOuttakeSubsText(const Common::String &outtakesName, int fram
|
||||
*/
|
||||
void Subtitles::setGameSubsText(int subsRole, Common::String dbgQuote, bool forceShowWhenNoSpeech) {
|
||||
if (_useUTF8) {
|
||||
_subtitlesData[subsRole].currentText32 = Common::convertUtf8ToUtf32(dbgQuote);
|
||||
_subtitlesDataActive[subsRole].currentText32 = Common::convertUtf8ToUtf32(dbgQuote);
|
||||
} else {
|
||||
_subtitlesData[subsRole].currentText = dbgQuote;
|
||||
_subtitlesDataActive[subsRole].currentText = dbgQuote;
|
||||
}
|
||||
_subtitlesData[subsRole].forceShowWhenNoSpeech = forceShowWhenNoSpeech; // overrides not showing subtitles when no one is speaking
|
||||
_subtitlesDataActive[subsRole].forceShowWhenNoSpeech = forceShowWhenNoSpeech; // overrides not showing subtitles when no one is speaking
|
||||
}
|
||||
|
||||
/**
|
||||
@ -326,10 +438,10 @@ bool Subtitles::show(int subsRole) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_subtitlesData[subsRole].isVisible) {
|
||||
if (_subtitlesDataActive[subsRole].isVisible) {
|
||||
return false;
|
||||
} else {
|
||||
_subtitlesData[subsRole].isVisible = true;
|
||||
_subtitlesDataActive[subsRole].isVisible = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -343,10 +455,10 @@ bool Subtitles::hide(int subsRole) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_subtitlesData[subsRole].isVisible) {
|
||||
if (!_subtitlesDataActive[subsRole].isVisible) {
|
||||
return false;
|
||||
} else {
|
||||
_subtitlesData[subsRole].isVisible = false;
|
||||
_subtitlesDataActive[subsRole].isVisible = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -357,58 +469,60 @@ bool Subtitles::hide(int subsRole) {
|
||||
*/
|
||||
bool Subtitles::isVisible(int subsRole) const {
|
||||
return _isSystemActive
|
||||
&& _subtitlesData[subsRole].isVisible;
|
||||
&& _subtitlesDataActive[subsRole].isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tick method specific for outtakes (VQA videos)
|
||||
*/
|
||||
void Subtitles::tickOuttakes(Graphics::Surface &s) {
|
||||
if (!_isSystemActive || !_vm->isSubtitlesEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (_isSystemActive && _vm->isSubtitlesEnabled()) {
|
||||
for (int i = 0; i < kNumOfSubtitleRoles; ++i) {
|
||||
if (isNotEmptyCurrentSubsText(i)) {
|
||||
_vm->_subtitles->show(i);
|
||||
} else {
|
||||
_vm->_subtitles->hide(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < kNumOfSubtitleRoles; ++i) {
|
||||
if (isNotEmptyCurrentSubsText(i)) {
|
||||
_vm->_subtitles->show(i);
|
||||
} else {
|
||||
_vm->_subtitles->hide(i);
|
||||
// keep this as a separate if clause
|
||||
if (isVisible(kSubtitlesPrimary) && isVisible(kSubtitlesSecondary)) {
|
||||
draw(s);
|
||||
}
|
||||
}
|
||||
|
||||
// keep this as a separate if clause
|
||||
if (!isVisible(kSubtitlesPrimary) && !isVisible(kSubtitlesSecondary)) {
|
||||
return;
|
||||
}
|
||||
|
||||
draw(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tick method for in-game subtitles -- Not for outtake cutscenes (VQA videos)
|
||||
*/
|
||||
void Subtitles::tick(Graphics::Surface &s) {
|
||||
if (!_isSystemActive || !_vm->isSubtitlesEnabled()) {
|
||||
return;
|
||||
bool proceedToDraw = false;
|
||||
if (_isSystemActive && _vm->isSubtitlesEnabled()) {
|
||||
if (_subtitlesDataActive[kSubtitlesPrimary].isVisible
|
||||
&& !_subtitlesDataActive[kSubtitlesPrimary].forceShowWhenNoSpeech
|
||||
&& !_vm->_audioSpeech->isPlaying()) {
|
||||
_vm->_subtitles->hide(kSubtitlesPrimary); // TODO might need a better system. Don't call it always.
|
||||
}
|
||||
|
||||
// keep this as a separate if clause
|
||||
if (isVisible(kSubtitlesPrimary) || isVisible(kSubtitlesSecondary)) {
|
||||
proceedToDraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_subtitlesData[kSubtitlesPrimary].isVisible
|
||||
&& !_subtitlesData[kSubtitlesPrimary].forceShowWhenNoSpeech
|
||||
&& !_vm->_audioSpeech->isPlaying()) {
|
||||
_vm->_subtitles->hide(kSubtitlesPrimary); // TODO might need a better system. Don't call it always.
|
||||
if (_vm->getExtraCNotify() == 3) {
|
||||
proceedToDraw = true;
|
||||
}
|
||||
|
||||
// keep this as a separate if clause
|
||||
if (!isVisible(kSubtitlesPrimary) && !isVisible(kSubtitlesSecondary)) {
|
||||
return;
|
||||
if (proceedToDraw) {
|
||||
draw(s);
|
||||
}
|
||||
|
||||
draw(s);
|
||||
}
|
||||
|
||||
bool Subtitles::isNotEmptyCurrentSubsText(int subsRole) {
|
||||
if ((_useUTF8 && !_subtitlesData[subsRole].currentText32.empty())
|
||||
|| (!_useUTF8 && !_subtitlesData[subsRole].currentText.empty())) {
|
||||
if ((_useUTF8 && !_subtitlesDataActive[subsRole].currentText32.empty())
|
||||
|| (!_useUTF8 && !_subtitlesDataActive[subsRole].currentText.empty())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -421,11 +535,11 @@ void Subtitles::mergeSubtitleQuotes(int actorId, int quoteFirst, int quoteSecond
|
||||
const char *textFirst = _vqaSubsTextResourceEntries[0]->getText((uint32)idFirst);
|
||||
const char *textSecond = _vqaSubsTextResourceEntries[0]->getText((uint32)idSecond);
|
||||
if (_useUTF8) {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText32 = Common::convertUtf8ToUtf32(textFirst);
|
||||
_subtitlesData[kSubtitlesPrimary].currentText32 += " " + Common::convertUtf8ToUtf32(textSecond);
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText32 = Common::convertUtf8ToUtf32(textFirst);
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText32 += " " + Common::convertUtf8ToUtf32(textSecond);
|
||||
} else {
|
||||
_subtitlesData[kSubtitlesPrimary].currentText = textFirst;
|
||||
_subtitlesData[kSubtitlesPrimary].currentText += " " + Common::String(textSecond);
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText = textFirst;
|
||||
_subtitlesDataActive[kSubtitlesPrimary].currentText += " " + Common::String(textSecond);
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,6 +547,46 @@ void Subtitles::mergeSubtitleQuotes(int actorId, int quoteFirst, int quoteSecond
|
||||
* Draw method for drawing the subtitles on the display surface
|
||||
*/
|
||||
void Subtitles::draw(Graphics::Surface &s) {
|
||||
if (_isSystemActive && _vm->getExtraCNotify() == 3) {
|
||||
// Timing fixed for 60Hz by ScummVM team
|
||||
uint32 timeNow = _vm->_time->currentSystem();
|
||||
bool updateTimeout = false;
|
||||
// unsigned difference is intentional
|
||||
if (timeNow - _xcTimeLast > (1000u / 60u)) {
|
||||
updateTimeout = true;
|
||||
_xcTimeLast = timeNow;
|
||||
}
|
||||
|
||||
_vm->_mainFont->drawString(&s, _excTitlStr, 313 - _vm->_mainFont->getStringWidth(_excTitlStr) / 2, 143, s.w, s.format.RGBToColor(240, 232, 192));
|
||||
|
||||
int y = 158;
|
||||
int lineTextWidth;
|
||||
for (int i = 0; i < kxcLineCount; ++i) {
|
||||
if (updateTimeout) {
|
||||
if (_xcLineTimeouts[i] > 0) {
|
||||
--_xcLineTimeouts[i];
|
||||
} else {
|
||||
_xcLineTexts[i] = _xcStrings[_xcStringIndex];
|
||||
_xcLineTimeouts[i] = 63;
|
||||
lineTextWidth = _vm->_mainFont->getStringWidth(_xcLineTexts[i]);
|
||||
_xcLineOffsets[i] = _vm->_rnd.getRandomNumberRng(0, (306 - lineTextWidth) > 0 ? (306 - lineTextWidth) : 0) + 155;
|
||||
|
||||
_xcStringIndex = (_xcStringIndex + 1) % kxcStringCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_xcLineTexts[i].empty()) {
|
||||
int colorIndex = _xcLineTimeouts[i];
|
||||
if (colorIndex >= 32) {
|
||||
colorIndex = 63 - colorIndex;
|
||||
}
|
||||
colorIndex /= 2;
|
||||
_vm->_mainFont->drawString(&s, _xcLineTexts[i], _xcLineOffsets[i], y, s.w, s.format.RGBToColor(kTextColors[colorIndex].r, kTextColors[colorIndex].g, kTextColors[colorIndex].b));
|
||||
}
|
||||
y += 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_isSystemActive
|
||||
|| (!isVisible(kSubtitlesPrimary) && !isVisible(kSubtitlesSecondary))
|
||||
|| (!isNotEmptyCurrentSubsText(kSubtitlesPrimary) && !isNotEmptyCurrentSubsText(kSubtitlesSecondary))) {
|
||||
@ -444,20 +598,20 @@ void Subtitles::draw(Graphics::Surface &s) {
|
||||
uint linesNum = 0;
|
||||
if (_useUTF8) {
|
||||
// This check is done so that lines won't be re-calculated multiple times for the same text
|
||||
if (_subtitlesData[i].currentText32 != _subtitlesData[i].prevText32) {
|
||||
_subtitlesData[i].lines32.clear();
|
||||
_subtitlesData[i].prevText32 = _subtitlesData[i].currentText32;
|
||||
_font->wordWrapText(_subtitlesData[i].currentText32, kTextMaxWidth, _subtitlesData[i].lines32, 0, Graphics::kWordWrapEvenWidthLines | Graphics::kWordWrapOnExplicitNewLines);
|
||||
if (_subtitlesDataActive[i].currentText32 != _subtitlesDataActive[i].prevText32) {
|
||||
_subtitlesDataActive[i].lines32.clear();
|
||||
_subtitlesDataActive[i].prevText32 = _subtitlesDataActive[i].currentText32;
|
||||
_font->wordWrapText(_subtitlesDataActive[i].currentText32, kTextMaxWidth, _subtitlesDataActive[i].lines32, 0, Graphics::kWordWrapEvenWidthLines | Graphics::kWordWrapOnExplicitNewLines);
|
||||
}
|
||||
linesNum = _subtitlesData[i].lines32.size();
|
||||
linesNum = _subtitlesDataActive[i].lines32.size();
|
||||
} else {
|
||||
// This check is done so that lines won't be re-calculated multiple times for the same text
|
||||
if (_subtitlesData[i].currentText != _subtitlesData[i].prevText) {
|
||||
_subtitlesData[i].lines.clear();
|
||||
_subtitlesData[i].prevText = _subtitlesData[i].currentText;
|
||||
_font->wordWrapText(_subtitlesData[i].currentText, kTextMaxWidth, _subtitlesData[i].lines, 0, Graphics::kWordWrapEvenWidthLines | Graphics::kWordWrapOnExplicitNewLines);
|
||||
if (_subtitlesDataActive[i].currentText != _subtitlesDataActive[i].prevText) {
|
||||
_subtitlesDataActive[i].lines.clear();
|
||||
_subtitlesDataActive[i].prevText = _subtitlesDataActive[i].currentText;
|
||||
_font->wordWrapText(_subtitlesDataActive[i].currentText, kTextMaxWidth, _subtitlesDataActive[i].lines, 0, Graphics::kWordWrapEvenWidthLines | Graphics::kWordWrapOnExplicitNewLines);
|
||||
}
|
||||
linesNum = _subtitlesData[i].lines.size();
|
||||
linesNum = _subtitlesDataActive[i].lines.size();
|
||||
}
|
||||
|
||||
int y = kMarginTop;
|
||||
@ -470,15 +624,15 @@ void Subtitles::draw(Graphics::Surface &s) {
|
||||
switch (_subtitlesInfo.fontType) {
|
||||
case Subtitles::kSubtitlesFontTypeInternal:
|
||||
// shadow/outline is part of the font color data
|
||||
_font->drawString(&s, _subtitlesData[i].lines[j], 0, y, s.w, 0, Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesDataActive[i].lines[j], 0, y, s.w, 0, Graphics::kTextAlignCenter);
|
||||
break;
|
||||
case Subtitles::kSubtitlesFontTypeTTF:
|
||||
_font->drawString(&s, _subtitlesData[i].lines32[j], -1, y , s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesData[i].lines32[j], 0, y - 1, s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesData[i].lines32[j], 1, y , s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesData[i].lines32[j], 0, y + 1, s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesDataActive[i].lines32[j], -1, y , s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesDataActive[i].lines32[j], 0, y - 1, s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesDataActive[i].lines32[j], 1, y , s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesDataActive[i].lines32[j], 0, y + 1, s.w, s.format.RGBToColor( 0, 0, 0), Graphics::kTextAlignCenter);
|
||||
|
||||
_font->drawString(&s, _subtitlesData[i].lines32[j], 0, y , s.w, s.format.RGBToColor(255, 255, 255), Graphics::kTextAlignCenter);
|
||||
_font->drawString(&s, _subtitlesDataActive[i].lines32[j], 0, y , s.w, s.format.RGBToColor(255, 255, 255), Graphics::kTextAlignCenter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -491,18 +645,22 @@ void Subtitles::draw(Graphics::Surface &s) {
|
||||
*/
|
||||
void Subtitles::clear() {
|
||||
for (uint8 i = 0; i < kNumOfSubtitleRoles; ++i) {
|
||||
_subtitlesData[i].isVisible = false;
|
||||
_subtitlesData[i].forceShowWhenNoSpeech = false;
|
||||
_subtitlesData[i].currentText32.clear();
|
||||
_subtitlesData[i].prevText32.clear();
|
||||
_subtitlesData[i].lines32.clear();
|
||||
_subtitlesDataActive[i].isVisible = false;
|
||||
_subtitlesDataActive[i].forceShowWhenNoSpeech = false;
|
||||
_subtitlesDataActive[i].currentText32.clear();
|
||||
_subtitlesDataActive[i].prevText32.clear();
|
||||
_subtitlesDataActive[i].lines32.clear();
|
||||
|
||||
_subtitlesData[i].currentText.clear();
|
||||
_subtitlesData[i].prevText.clear();
|
||||
_subtitlesData[i].lines.clear();
|
||||
_subtitlesDataActive[i].currentText.clear();
|
||||
_subtitlesDataActive[i].prevText.clear();
|
||||
_subtitlesDataActive[i].lines.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool Subtitles::isHDCPresent() {
|
||||
return _useHDC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize/reset member vars, close open file descriptors and garbage collect subtitle fonts and text resource
|
||||
*/
|
||||
@ -530,6 +688,7 @@ void Subtitles::reset() {
|
||||
}
|
||||
|
||||
_useUTF8 = false;
|
||||
_useHDC = false;
|
||||
}
|
||||
|
||||
} // End of namespace BladeRunner
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "bladerunner/bladerunner.h"
|
||||
|
||||
#include "bladerunner/color.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
@ -52,9 +53,22 @@ class Subtitles {
|
||||
static const char *SUBTITLES_FILENAME_PREFIXES[kMaxTextResourceEntries];
|
||||
static const char *SUBTITLES_FONT_FILENAME_EXTERNAL;
|
||||
static const char *SUBTITLES_VERSION_TRENAME;
|
||||
static const char *EXTRA_TRENAME;
|
||||
|
||||
static const Color256 kTextColors[];
|
||||
|
||||
static const int kNumOfSubtitleRoles = 2;
|
||||
|
||||
static const int kxcLineCount = 22;
|
||||
static const int kxcStringCount = 14; // 15 - 1
|
||||
Common::String _xcStrings[kxcStringCount];
|
||||
int _xcStringIndex;
|
||||
|
||||
Common::String _xcLineTexts[kxcLineCount];
|
||||
int _xcLineTimeouts[kxcLineCount];
|
||||
int _xcLineOffsets[kxcLineCount];
|
||||
uint32 _xcTimeLast;
|
||||
|
||||
BladeRunnerEngine *_vm;
|
||||
|
||||
enum SubtitlesFontType {
|
||||
@ -90,6 +104,8 @@ class Subtitles {
|
||||
Common::String currentText;
|
||||
Common::String prevText;
|
||||
Common::Array<Common::String> lines;
|
||||
|
||||
SubtitlesData() : isVisible(false), forceShowWhenNoSpeech(false) { };
|
||||
};
|
||||
|
||||
SubtitlesInfo _subtitlesInfo;
|
||||
@ -97,8 +113,12 @@ class Subtitles {
|
||||
|
||||
Graphics::Font *_font;
|
||||
bool _useUTF8;
|
||||
|
||||
Common::Array<SubtitlesData> _subtitlesData;
|
||||
bool _useHDC;
|
||||
Common::Array<Common::String> _subtitlesEXC;
|
||||
Common::Array<SubtitlesData> _subtitlesDataActive;
|
||||
Common::String _loadAvgStr;
|
||||
Common::String _excTitlStr;
|
||||
Common::String _goVib;
|
||||
|
||||
bool _gameSubsResourceEntriesFound[kMaxTextResourceEntries]; // false if a TRE file did not open successfully
|
||||
bool _isSystemActive; // true if the whole subtitles subsystem should be disabled (due to missing required resources)
|
||||
@ -119,6 +139,10 @@ public:
|
||||
bool show(int subsRole);
|
||||
bool hide(int subsRole);
|
||||
void clear();
|
||||
bool isHDCPresent();
|
||||
void xcReload();
|
||||
Common::String getLoadAvgStr() const { return _loadAvgStr; }
|
||||
const char *getGoVib() const { return _goVib.c_str(); }
|
||||
|
||||
bool isVisible(int subsRole) const;
|
||||
void tick(Graphics::Surface &s);
|
||||
|
Loading…
x
Reference in New Issue
Block a user