[Scummvm-git-logs] scummvm master -> 1dc8f2fb03781bd676bbebbcbbef5b3fdcdcdae1
criezy
noreply at scummvm.org
Mon Aug 11 22:51:34 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
1dc8f2fb03 TEENAGENT: Update TTS support for Czech and Polish versions
Commit: 1dc8f2fb03781bd676bbebbcbbef5b3fdcdcdae1
https://github.com/scummvm/scummvm/commit/1dc8f2fb03781bd676bbebbcbbef5b3fdcdcdae1
Author: ellm135 (ellm13531 at gmail.com)
Date: 2025-08-11T23:51:30+01:00
Commit Message:
TEENAGENT: Update TTS support for Czech and Polish versions
Changed paths:
engines/teenagent/detection.cpp
engines/teenagent/detection.h
engines/teenagent/metaengine.cpp
engines/teenagent/scene.cpp
engines/teenagent/teenagent.cpp
engines/teenagent/teenagent.h
diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp
index a1f615cd8a3..402328c46dc 100644
--- a/engines/teenagent/detection.cpp
+++ b/engines/teenagent/detection.cpp
@@ -68,7 +68,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS, GAMEOPTION_TTS_SPEECH)
},
{
"teenagent",
@@ -89,7 +89,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS, GAMEOPTION_TTS_SPEECH)
},
{ // Russian fan translation
"teenagent",
@@ -111,7 +111,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS, GAMEOPTION_TTS_SPEECH)
},
{ // Czech Floppy
"teenagent",
@@ -132,7 +132,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::CS_CZE,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS, GAMEOPTION_TTS_SPEECH)
},
{ // Polish CD
"teenagent",
@@ -153,7 +153,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::PL_POL,
Common::kPlatformDOS,
ADGF_CD,
- GUIO2(GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO2(GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS)
},
{ // Polish Floppy
"teenagent",
@@ -174,7 +174,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::PL_POL,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO2(GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS)
},
{ // Demo
"teenagent",
@@ -195,7 +195,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO,
- GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS, GAMEOPTION_TTS_SPEECH)
},
{ // Demo alt
"teenagent",
@@ -216,7 +216,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO,
- GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS)
+ GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GAMEOPTION_TTS_OBJECTS, GAMEOPTION_TTS_SPEECH)
},
AD_TABLE_END_MARKER,
diff --git a/engines/teenagent/detection.h b/engines/teenagent/detection.h
index 80704802544..261d069f044 100644
--- a/engines/teenagent/detection.h
+++ b/engines/teenagent/detection.h
@@ -22,6 +22,7 @@
#ifndef TEENAGENT_DETECTION_H
#define TEENAGENT_DETECTION_H
-#define GAMEOPTION_TTS GUIO_GAMEOPTIONS1
+#define GAMEOPTION_TTS_OBJECTS GUIO_GAMEOPTIONS1
+#define GAMEOPTION_TTS_SPEECH GUIO_GAMEOPTIONS2
#endif // TEENAGENT_DETECTION_H
diff --git a/engines/teenagent/metaengine.cpp b/engines/teenagent/metaengine.cpp
index 99d0cebc0b7..3ecabf4aed8 100644
--- a/engines/teenagent/metaengine.cpp
+++ b/engines/teenagent/metaengine.cpp
@@ -44,11 +44,23 @@ enum {
static const ADExtraGuiOptionsMap optionsList[] = {
{
- GAMEOPTION_TTS,
+ GAMEOPTION_TTS_OBJECTS,
{
- _s("Enable Text to Speech"),
- _s("Use TTS to read text in the game (if TTS is available)"),
- "tts_enabled",
+ _s("Enable Text to Speech for Objects and Options"),
+ _s("Use TTS to read the descriptions (if TTS is available)"),
+ "tts_enabled_objects",
+ false,
+ 0,
+ 0
+ }
+ },
+
+ {
+ GAMEOPTION_TTS_SPEECH,
+ {
+ _s("Enable Text to Speech for Subtitles"),
+ _s("Use TTS to read the subtitles (if TTS is available)"),
+ "tts_enabled_speech",
false,
0,
0
diff --git a/engines/teenagent/scene.cpp b/engines/teenagent/scene.cpp
index 5c87a81df75..4a23646a9d3 100644
--- a/engines/teenagent/scene.cpp
+++ b/engines/teenagent/scene.cpp
@@ -860,7 +860,7 @@ bool Scene::render(bool tickGame, bool tickMark, uint32 messageDelta) {
ttsMessage.replace(endOfItemName, 1, "\n");
}
}
- _vm->sayText(ttsMessage);
+ _vm->sayText(ttsMessage, true);
_vm->playVoiceNow(&_vm->res->voices, _voiceId);
}
}
diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp
index 3934bc35637..ebcc42c4689 100644
--- a/engines/teenagent/teenagent.cpp
+++ b/engines/teenagent/teenagent.cpp
@@ -52,6 +52,24 @@
namespace TeenAgent {
+#ifdef USE_TTS
+
+static const uint16 polishConversionTable[] = {
+ 0x23, 0xc499, 0x24, 0xc59b, 0x25, 0xc582, 0x2a, 0xc3b3, 0x2b, 0xc484, 0x3b, 0xc583,
+ 0x3c, 0xc5bc, 0x3d, 0xc584, 0x3e, 0xc5ba, 0x40, 0xc485, 0x5b, 0xc498, 0x5c, 0xc486,
+ 0x5d, 0xc581, 0x5e, 0xc487, 0x7b, 0xc393, 0x7c, 0xc59a, 0x7d, 0xc5bb, 0x7e, 0xc5b9,
+ 0
+};
+
+static const uint16 czechConversionTable[] = {
+ 0x23, 0xc3a1, 0x24, 0xc48d, 0x25, 0xc48f, 0x2a, 0xc3a9, 0x2b, 0xc49b, 0x3b, 0xc3ad,
+ 0x3c, 0xc588, 0x3d, 0xc3b3, 0x3e, 0xc599, 0x40, 0xc5a1, 0x5b, 0xc5a5, 0x5c, 0xc3ba,
+ 0x5d, 0xc5af, 0x5e, 0xc3bd, 0x7b, 0xc5be, 0x7c, 0xc48c, 0x7d, 0xc598, 0x7e, 0xc5bd,
+ 0
+};
+
+#endif
+
TeenAgentEngine *g_engine = nullptr;
TeenAgentEngine::TeenAgentEngine(OSystem *system, const ADGameDescription *gd)
@@ -600,16 +618,8 @@ Common::Error TeenAgentEngine::run() {
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
if (ttsMan != nullptr) {
- // Currently, the Polish and Czech versions have all text in English
- // Therefore, the TTS language should be English to match the text
- // The Polish CD/Floppy versions also have no working voiceover, so they need full TTS
- if (_gameDescription->language == Common::PL_POL || _gameDescription->language == Common::CS_CZE) {
- ttsMan->setLanguage("en");
- } else {
- ttsMan->setLanguage(ConfMan.get("language"));
- }
-
- ttsMan->enable(ConfMan.getBool("tts_enabled"));
+ ttsMan->setLanguage(ConfMan.get("language"));
+ ttsMan->enable(ConfMan.getBool("tts_enabled_objects") || ConfMan.getBool("tts_enabled_speech"));
}
// Initialize CD audio
@@ -1164,23 +1174,26 @@ bool TeenAgentEngine::hasFeature(EngineFeature f) const {
}
}
-void TeenAgentEngine::sayText(const Common::String &text) {
+void TeenAgentEngine::sayText(const Common::String &text, bool isSubtitle) {
+#ifdef USE_TTS
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
+ bool voice = (!isSubtitle && ConfMan.getBool("tts_enabled_objects")) || (isSubtitle && ConfMan.getBool("tts_enabled_speech"));
// _previousSaid is used to prevent the TTS from looping when sayText calls are inside loops
- if (ttsMan && ConfMan.getBool("tts_enabled") && _previousSaid != text) {
- if (_gameDescription->language == Common::RU_RUS) {
- ttsMan->say(convertCyrillic(text));
+ if (ttsMan && voice && _previousSaid != text) {
+ if (_gameDescription->language != Common::EN_ANY) {
+ ttsMan->say(convertText(text));
} else {
ttsMan->say(text, Common::CodePage::kDos850);
}
_previousSaid = text;
}
+#endif
}
void TeenAgentEngine::stopTextToSpeech() {
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
- if (ttsMan && ConfMan.getBool("tts_enabled") && ttsMan->isSpeaking()) {
+ if (ttsMan && (ConfMan.getBool("tts_enabled_objects") || ConfMan.getBool("tts_enabled_speech")) && ttsMan->isSpeaking()) {
ttsMan->stop();
_previousSaid.clear();
}
@@ -1188,7 +1201,7 @@ void TeenAgentEngine::stopTextToSpeech() {
void TeenAgentEngine::setTTSVoice(CharacterID characterID) const {
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
- if (ttsMan && ConfMan.getBool("tts_enabled")) {
+ if (ttsMan && (ConfMan.getBool("tts_enabled_objects") || ConfMan.getBool("tts_enabled_speech"))) {
Common::Array<int> voices;
int pitch = 0;
Common::TTSVoice::Gender gender;
@@ -1223,41 +1236,82 @@ void TeenAgentEngine::setTTSVoice(CharacterID characterID) const {
}
}
-Common::U32String TeenAgentEngine::convertCyrillic(const Common::String &text) const {
+#ifdef USE_TTS
+
+Common::U32String TeenAgentEngine::convertText(const Common::String &text) const {
const byte *bytes = (const byte *)text.c_str();
- byte *convertedBytes = new byte[text.size() * 2 + 1];
+ byte *convertedBytes = new byte[text.size() * 3 + 1];
+ const uint16 *conversionTable = nullptr;
+
+ if (_gameDescription->language == Common::PL_POL) {
+ conversionTable = polishConversionTable;
+ } else if (_gameDescription->language == Common::CS_CZE) {
+ conversionTable = czechConversionTable;
+ }
int i = 0;
for (const byte *b = bytes; *b; ++b) {
- if (*b == 0x26) { // & needs to be converted to и
- convertedBytes[i] = 0xd0;
- convertedBytes[i + 1] = 0xb8;
- i += 2;
- continue;
- }
+ if (_gameDescription->language == Common::RU_RUS) {
+ if (*b == 0x26) { // & needs to be converted to и
+ convertedBytes[i] = 0xd0;
+ convertedBytes[i + 1] = 0xb8;
+ i += 2;
+ continue;
+ }
- if (*b == 0x3e) { // For Ñ
- convertedBytes[i] = 0xd1;
- convertedBytes[i + 1] = 0x91;
- i += 2;
- continue;
- }
+ if (*b == 0x3e) { // For Ñ
+ convertedBytes[i] = 0xd1;
+ convertedBytes[i + 1] = 0x91;
+ i += 2;
+ continue;
+ }
- if (*b > 0x3f) {
- int translated = *b;
+ if (*b > 0x3f) {
+ int translated = *b;
- if (*b > 0x70) {
- translated += 0xd10f;
+ if (*b > 0x70) {
+ translated += 0xd10f;
+ } else {
+ translated += 0xd04f;
+ }
+
+ convertedBytes[i] = (translated >> 8) & 0xff;
+ convertedBytes[i + 1] = translated & 0xff;
+ i += 2;
} else {
- translated += 0xd04f;
+ convertedBytes[i] = *b;
+ i++;
}
-
- convertedBytes[i] = (translated >> 8) & 0xff;
- convertedBytes[i + 1] = translated & 0xff;
- i += 2;
} else {
- convertedBytes[i] = *b;
- i++;
+ if (*b == 0x60) { // TM
+ convertedBytes[i] = 0xe2;
+ convertedBytes[i + 1] = 0x84;
+ convertedBytes[i + 2] = 0xa2;
+ i += 3;
+ continue;
+ }
+
+ if (*b == 0x80) { // %
+ convertedBytes[i] = 0x25;
+ i++;
+ continue;
+ }
+
+ bool inTable = false;
+ for (uint j = 0; conversionTable[j]; j += 2) {
+ if (*b == conversionTable[j]) {
+ convertedBytes[i] = (conversionTable[j + 1] >> 8) & 0xff;
+ convertedBytes[i + 1] = conversionTable[j + 1] & 0xff;
+ i += 2;
+ inTable = true;
+ break;
+ }
+ }
+
+ if (!inTable) {
+ convertedBytes[i] = *b;
+ i++;
+ }
}
}
@@ -1269,4 +1323,6 @@ Common::U32String TeenAgentEngine::convertCyrillic(const Common::String &text) c
return result;
}
+#endif
+
} // End of namespace TeenAgent
diff --git a/engines/teenagent/teenagent.h b/engines/teenagent/teenagent.h
index 07394d7be7e..e76ff8818b9 100644
--- a/engines/teenagent/teenagent.h
+++ b/engines/teenagent/teenagent.h
@@ -174,10 +174,12 @@ public:
void setMusic(byte id);
- void sayText(const Common::String &text);
+ void sayText(const Common::String &text, bool isSubtitle = false);
void stopTextToSpeech();
void setTTSVoice(CharacterID characterID) const;
- Common::U32String convertCyrillic(const Common::String &text) const;
+#ifdef USE_TTS
+ Common::U32String convertText(const Common::String &text) const;
+#endif
Common::String _previousSaid;
uint16 _previousVoiceId;
More information about the Scummvm-git-logs
mailing list