Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DREAMWEB: Text To Speech (TTS) for the game #3048

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

@taylorzhancher
Copy link
Contributor

@taylorzhancher taylorzhancher commented Jun 7, 2021

The TTS feature is implemented to the following:

  • GUI (ScummVM main menu > edit game > "Enable Text To Speech")
  • Opening bible quote ("And I heard...")
  • Opening intro story ("Unseen....")
  • Actions in the game ("Open inventory", "Examine book", "Walk to stone floor", etc.)
  • Everyday objects in the game and actions upon ("Take watch", "Place gum", "Use wallet", etc.)
  • In game options ("Return to map", "Disk options", "Select page", etc.)
Copy link
Member

@sev- sev- left a comment

Added few notes

engines/dreamweb/detection.cpp Outdated Show resolved Hide resolved
engines/dreamweb/stubs.cpp Outdated Show resolved Hide resolved
@@ -963,6 +966,14 @@ void DreamWebEngine::useTimedText() {

const uint8 *string = (const uint8 *)_timedTemp._string;
printDirect(string, _timedTemp._x, _timedTemp._y, 237, true);
const char* theText = (const char*)string;

This comment has been minimized.

@sev-

sev- Jun 7, 2021
Member

The code formatting is incorrect. Please follow our code formatting conventions

engines/dreamweb/stubs.cpp Outdated Show resolved Hide resolved
engines/dreamweb/stubs.cpp Outdated Show resolved Hide resolved

copyName(type, index, commandLine);

uint16 x = _lastXPos;
if (command != 0)
x += 5;
printDirect(commandLine, x, _textAddressY, textLen, (bool)(textLen & 1));
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled")) {
const char *temp = (const char*)commandLine;

This comment has been minimized.

@sev-

sev- Jun 7, 2021
Member

Same question here. The variable looks redundant to me.

engines/dreamweb/titles.cpp Outdated Show resolved Hide resolved
@taylorzhancher taylorzhancher marked this pull request as draft Jun 8, 2021
@taylorzhancher taylorzhancher force-pushed the taylorzhancher:taylorzhancher-dreamweb branch 2 times, most recently from 9af8e82 to 6a47d17 Jun 9, 2021
@criezy
Copy link
Member

@criezy criezy commented Jun 11, 2021

I only had a quick look, but here are some comments:

  • The CD version of the game already has speech for the opening story ("Unseen..."). So you should only use TTS for the floppy version.
    • Alternatively, and it might be better, you could also use TTS for the CD version if speech is disabled (there is an option to select speech, subtitles or both). The advantage of that is that the speech in the CD version is always in English while TTS would be in the language of the game (the subtitles are translated).
  • You are missing some code to set the TextToSpeechManager language to the game language (you can see on https://www.scummvm.org/games/#games-dreamweb that the game is available in French, German, Italian, and Spanish as well, and trying to use TTS with those version currently will not work properly).
    • However the bible quote is always in English I think (it is in English at least in the French version of the game).
    • We could consider asking our community to provide translations for that quote though so that we can speak it in the language of the game.
engines/dreamweb/titles.cpp Outdated Show resolved Hide resolved
@taylorzhancher taylorzhancher force-pushed the taylorzhancher:taylorzhancher-dreamweb branch from 2fc315d to 496a9a2 Jun 15, 2021
break;
}
}

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Does that work when the language is Russian?

Also you can probably use Common::getLanguageCode instead to simplify the code:

ttsMan->setLanguage(Common::getLanguageCode(getLanguage()));
@@ -161,6 +161,7 @@ class DreamWebEngine : public Engine {
Common::RandomSource _rnd;
Common::String _datafilePrefix;
Common::String _speechDirName;
Common::String lastText;

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Formatting.
https://wiki.scummvm.org/index.php?title=Code_Formatting_Conventions#Naming

Class member variables
Prefixed with '_' and in camel case (Yo! no underscore separators), starting with lowercase.
char *_someVariableName;

@@ -963,6 +965,14 @@ void DreamWebEngine::useTimedText() {

const uint8 *string = (const uint8 *)_timedTemp._string;
printDirect(string, _timedTemp._x, _timedTemp._y, 237, true);
const char *theText = (const char*)string;

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Formatting (space between char and *).

const char *theText = (const char *)string;
@@ -963,6 +965,14 @@ void DreamWebEngine::useTimedText() {

const uint8 *string = (const uint8 *)_timedTemp._string;
printDirect(string, _timedTemp._x, _timedTemp._y, 237, true);
const char *theText = (const char*)string;
if (lastText != theText) {

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Is this check needed when using the QUEUE_NO_REPEAT option below? I would expect the NO_REPEAT to skip it if it is the same as the last text.

delTextLine();
const uint8 *string = (const uint8 *)_commandText.getString(command);
printDirect(string, _textAddressX, _textAddressY, _textLen, (bool)(_textLen & 1));
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled")) {
ttsMan->say((const char*)string);

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Formatting (space between char and *).

_talkMode = 0;

const uint8 *str = getPersonText(_character & 0x7F, 0);
uint16 y;

_charShift = 91+91;

if (ttsMan != nullptr && ConfMan.getBool("tts_enabled") && !hasSpeech()) {
ttsMan->say((const char*)str);

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Formatting.

if (ttsMan != nullptr && ConfMan.getBool("tts_enabled") && !hasSpeech()) {
ttsMan->say((const char*)_personText.getString(index*64 + talkPos),
Common::TextToSpeechManager::INTERRUPT);
}

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

The indentation seems off on a couple of lines here. You may be using spaces instead of tabs.

Also maybe it would be worth using a variable for the text.

const uint8 *text = (const uint8 *)_personText.getString(index*64 + talkPos);
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled") && !hasSpeech())
	ttsMan->say((const char*)text),	Common::TextToSpeechManager::INTERRUPT);
return text;	

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Also I am wondering if it might be better to use the TextToSpeechManager in places where this function is called rather than here. And I see you already do that in startTalk(). Doesn't that cause some sentences to be spoken twice?

const char *itStory = "Udii una gran voce dal tempio che diceva ai sette angeli: "
"Andate e versate sulla terra le sette coppe dell’ira di Dio. "
"libro della rivelazione. capitolo 16 versetto 1";

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

For the French text you can drop the guillemets. They should not not difference for the TTS engine.

Also to avoid encoding issues it would be better to encode the non-ASCII characters. By default the TextToSpeechManager expects UTF-8 encoding. And for example the UTF-8 encoding for è is 0xC3 0xA8. So using hex notation you can write "la col\xC3\xA8re de Dieu."

theStory = enStory;
break;
}

This comment has been minimized.

@criezy

criezy Jun 15, 2021
Member

Apparently there are Czech and Russian fan translations as well (we can see those in the detection table).
If we want to default to English for those here, we would need to temporarily change the language of the TextToSpeechManager to English.

@taylorzhancher taylorzhancher force-pushed the taylorzhancher:taylorzhancher-dreamweb branch from 496a9a2 to e9e6ba6 Jun 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants