[Scummvm-git-logs] scummvm master -> b28a106ff59009370735647483bdb5a7f0f9965b
criezy
criezy at scummvm.org
Tue Jun 8 17:23:47 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
b28a106ff5 GRIFFON: Add Text To Speech support
Commit: b28a106ff59009370735647483bdb5a7f0f9965b
https://github.com/scummvm/scummvm/commit/b28a106ff59009370735647483bdb5a7f0f9965b
Author: Twan (77198777+taylorzhancher at users.noreply.github.com)
Date: 2021-06-08T18:23:44+01:00
Commit Message:
GRIFFON: Add Text To Speech support
Changed paths:
engines/griffon/cutscenes.cpp
engines/griffon/detection.cpp
engines/griffon/dialogs.cpp
engines/griffon/griffon.cpp
diff --git a/engines/griffon/cutscenes.cpp b/engines/griffon/cutscenes.cpp
index 9de5f70b04..b43dceb3a4 100644
--- a/engines/griffon/cutscenes.cpp
+++ b/engines/griffon/cutscenes.cpp
@@ -38,6 +38,9 @@
#include "griffon/griffon.h"
+#include "common/config-manager.h"
+#include "common/text-to-speech.h"
+
namespace Griffon {
#define POLL_AND_CHECK_QUIT() if (g_system->getEventManager()->pollEvent(_event)) { \
@@ -133,6 +136,23 @@ const char *story2[27] = {
"and I am free to die as I please."
};
+int textToSpeech(int nextparagraph, const char *storyVariable[], int arraysize) {
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled") && storyVariable[nextparagraph][0] != 0) {
+ Common::String paragraph;
+ while (nextparagraph < arraysize && storyVariable[nextparagraph][0] != ' ') {
+ if (!paragraph.empty())
+ paragraph += " ";
+ paragraph += storyVariable[nextparagraph++];
+ }
+ while (nextparagraph < arraysize && storyVariable[nextparagraph][0] == ' ') {
+ nextparagraph += 1;
+ }
+ ttsMan->say(paragraph, Common::TextToSpeechManager::QUEUE_NO_REPEAT);
+ }
+ return nextparagraph;
+}
+
void GriffonEngine::showLogos() {
_ticks = g_system->getMillis();
int ticks1 = _ticks;
@@ -202,11 +222,15 @@ void GriffonEngine::intro() {
_secsInGame = 0;
_secStart = 0;
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
+
bool ldStop = false;
bool speedUp = false;
int cnt = 0;
float xofs = 0.0;
float ld = 0.0;
+ int nextparagraph = 0;
+
do {
Common::Rect rc;
@@ -234,15 +258,21 @@ void GriffonEngine::intro() {
y--;
}
- for (int i = 0; i <= 37; i++) {
+ for (int i = 0; i < ARRAYSIZE(story); i++) {
int yy = y + i * 10;
+
+ if (i == nextparagraph)
+ nextparagraph = textToSpeech(nextparagraph, story, ARRAYSIZE(story));
+
if (yy > -8 && yy < 240) {
int x = 160 - strlen(story[i]) * 4;
drawString(_videoBuffer, story[i], x, yy, 4);
}
- if (yy < 10 && i == 37)
- return;
+ if (yy < 10 && i == ARRAYSIZE(story) - 1) {
+ if (ttsMan == nullptr || ttsMan->isSpeaking() == false)
+ return;
+ }
}
g_system->copyRectToScreen(_videoBuffer->getPixels(), _videoBuffer->pitch, 0, 0, _videoBuffer->w, _videoBuffer->h);
@@ -274,11 +304,15 @@ void GriffonEngine::intro() {
speedUp = true;
cnt = 6;
}
- else if (_event.customType == kGriffonMenu)
+ else if (_event.customType == kGriffonMenu) {
+ if (ttsMan != nullptr)
+ ttsMan->stop();
return;
+ }
} else if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
- if (_event.customType == kGriffonCutsceneSpeedUp)
+ if (_event.customType == kGriffonCutsceneSpeedUp) {
speedUp = false;
+ }
}
CHECK_QUIT();
@@ -306,6 +340,9 @@ void GriffonEngine::endOfGame() {
float ld = 0;
bool ldstop = false; // CHECKME: Check if actually used
+ int nextparagraph = 0;
+
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
do {
ld += 4 * _fpsr;
@@ -367,15 +404,22 @@ void GriffonEngine::endOfGame() {
_titleImg->blit(*_videoBuffer, rc.left, rc.top);
y = y - spd * _fpsr;
- for (int i = 0; i <= 26; i++) {
+
+ for (int i = 0; i < ARRAYSIZE(story2); i++) {
int yy = y + i * 10;
+
+ if (i == nextparagraph)
+ nextparagraph = textToSpeech(nextparagraph, story2, ARRAYSIZE(story2));
+
if (yy > -8 && yy < 240) {
int x = 160 - strlen(story2[i]) * 4;
drawString(_videoBuffer, story2[i], x, yy, 4);
}
- if (yy < 10 && i == 25)
- break;
+ if (yy < 10 && i == ARRAYSIZE(story2)-1) {
+ if (ttsMan == nullptr || ttsMan->isSpeaking() == false)
+ break;
+ }
}
ya = 255;
@@ -411,8 +455,11 @@ void GriffonEngine::endOfGame() {
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
if (_event.customType == kGriffonCutsceneSpeedUp)
spd = 1.0f;
- else if (_event.customType == kGriffonMenu)
+ else if (_event.customType == kGriffonMenu) {
+ if (ttsMan != nullptr)
+ ttsMan->stop();
break;
+ }
} else if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
if (_event.customType == kGriffonCutsceneSpeedUp)
spd = 0.2f;
diff --git a/engines/griffon/detection.cpp b/engines/griffon/detection.cpp
index 8e326e1e76..87c1650b85 100644
--- a/engines/griffon/detection.cpp
+++ b/engines/griffon/detection.cpp
@@ -23,11 +23,29 @@
#include "base/plugins.h"
#include "engines/advancedDetector.h"
+#include "common/text-to-speech.h"
+#include "common/translation.h"
+
static const PlainGameDescriptor griffonGames[] = {
{"griffon", "The Griffon Legend"},
{NULL, NULL}
};
+#define GAMEOPTION_TTS_NARRATOR GUIO_GAMEOPTIONS1
+
+static const ADExtraGuiOptionsMap optionsList[] = {
+ {
+ GAMEOPTION_TTS_NARRATOR,
+ {
+ _s("Enable Text to Speech"),
+ _s("Use TTS to read the descriptions (if TTS is available)"),
+ "tts_enabled",
+ false
+ }
+ },
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
namespace Griffon {
static const ADGameDescription gameDescriptions[] = {
@@ -38,7 +56,11 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
+#ifdef USE_TTS
+ GUIO2(GUIO_NOMIDI, GAMEOPTION_TTS_NARRATOR)
+#else
GUIO1(GUIO_NOMIDI)
+#endif
},
AD_TABLE_END_MARKER
@@ -48,7 +70,11 @@ static const ADGameDescription gameDescriptions[] = {
class GriffonMetaEngineDetection: public AdvancedMetaEngineDetection {
public:
- GriffonMetaEngineDetection() : AdvancedMetaEngineDetection(Griffon::gameDescriptions, sizeof(ADGameDescription), griffonGames) {
+ GriffonMetaEngineDetection() : AdvancedMetaEngineDetection(Griffon::gameDescriptions, sizeof(ADGameDescription), griffonGames
+#ifdef USE_TTS
+ , optionsList
+#endif
+ ) {
}
const char *getEngineId() const override {
diff --git a/engines/griffon/dialogs.cpp b/engines/griffon/dialogs.cpp
index c76354e5ec..646c9cdc48 100644
--- a/engines/griffon/dialogs.cpp
+++ b/engines/griffon/dialogs.cpp
@@ -39,14 +39,25 @@
#include "griffon/griffon.h"
+#include "common/text-to-speech.h"
+
namespace Griffon {
#define MINCURSEL 7
-#define MAXCURSEL 14
-#define SY 22
+#define MAXCURSEL 16
+#define SY 25
#define PI 3.141593
void GriffonEngine::title(int mode) {
+ const char *optionTitles[4] = {
+ "new game/save/load",
+ "options",
+ "quit game",
+ "return"
+ };
+
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
+
float xofs = 0;
_itemyloc = 0;
bool exitTitle = false;
@@ -109,12 +120,12 @@ void GriffonEngine::title(int mode) {
int y = 172;
int x = 160 - 14 * 4;
- drawString(_videoBuffer, "new game/save/load", x, y, 4);
- drawString(_videoBuffer, "options", x, y + 16, 4);
- drawString(_videoBuffer, "quit game", x, y + 32, 4);
+ drawString(_videoBuffer, optionTitles[0], x, y, 4);
+ drawString(_videoBuffer, optionTitles[1], x, y + 16, 4);
+ drawString(_videoBuffer, optionTitles[2], x, y + 32, 4);
if (mode == 1)
- drawString(_videoBuffer, "return", x, y + 48, 4);
+ drawString(_videoBuffer, optionTitles[3], x, y + 48, 4);
else
drawString(_videoBuffer, "(c) 2005 by Daniel 'Syn9' Kennedy", 28, 224, 4);
@@ -164,6 +175,7 @@ void GriffonEngine::title(int mode) {
_shouldQuit = true;
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
+
switch(_event.customType) {
case kGriffonMenu:
if (mode == 1)
@@ -173,13 +185,19 @@ void GriffonEngine::title(int mode) {
cursel--;
if (cursel < 0)
cursel = (mode == 1 ? 3 : 2);
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan->say(optionTitles[cursel]);
break;
case kGriffonDown:
cursel++;
if (cursel >= (mode == 1 ? 4 : 3))
cursel = 0;
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan->say(optionTitles[cursel]);
break;
case kGriffonConfirm:
+ if (ttsMan != nullptr)
+ ttsMan->stop();
switch(cursel) {
case 0:
_ticks = g_system->getMillis();
@@ -224,27 +242,59 @@ void GriffonEngine::title(int mode) {
}
}
+static Common::String formatPercent(int val) {
+ val = val / 2.55;
+ return Common::String::format("%d percent", val - val % 10);
+}
+
+static void speakMenuItem(int mapTitles, int mapValues, const char *mapTitleText[], const char *mapValueText[]) {
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled")) {
+ Common::TextToSpeechManager::Action valueAction = Common::TextToSpeechManager::INTERRUPT;
+ if (mapTitles != 0) {
+ ttsMan->say(mapTitleText[mapTitles]);
+ valueAction = Common::TextToSpeechManager::QUEUE;
+ }
+ if (mapValues != 0)
+ ttsMan->say(mapValueText[mapValues], valueAction);
+ }
+}
+
void GriffonEngine::configMenu() {
- static const char *optionTitles[22] = {
+ static const char *optionTitles[25] = {
"", "",
"", "", "", "",
"", "", "",
"Music:", "", "",
"Sound Effects:", "", "",
+ "Text to Speech:", "", "",
"Music Volume:", "",
"Effects Volume:", "", "", "", ""
};
- static const char *optionValues[22] = {
+ static const char *optionValues[25] = {
"", "",
"", "", "", "",
"", "", "",
"On", "Off", "",
"On", "Off", "",
+ "On", "Off", "",
"[----------]", "",
"[----------]", "",
"Exit + Save", "",
"Exit"
};
+ static const int curselMapTitles[MAXCURSEL+1] = {
+ 0, 0, 0, 0, 0,
+ 0, 0, 9, 9, 12,
+ 12, 15, 15, 18, 20,
+ 0, 0
+ };
+ static const int curselMapValues[MAXCURSEL+1] = {
+ 0, 0, 0, 0, 0,
+ 0, 0, 9, 10, 12,
+ 13, 15, 16, 0, 0,
+ 22, 24
+ };
int cursel = MINCURSEL;
bool exitMenu = false;
@@ -256,6 +306,7 @@ void GriffonEngine::configMenu() {
int ticks1 = _ticks;
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
do {
_videoBuffer->fillRect(Common::Rect(0, 0, _videoBuffer->w, _videoBuffer->h), 0);
@@ -279,7 +330,7 @@ void GriffonEngine::configMenu() {
int sy = SY;
- for (int i = 0; i <= 21; i++) {
+ for (int i = 0; i <= 24; i++) {
static char line[24];
int destColumn = 3;
@@ -291,14 +342,18 @@ void GriffonEngine::configMenu() {
destColumn = 0;
else if (i == 13 && !config.effects)
destColumn = 0;
- else if (i == 15 || i == 17) {
- int vol = (i == 15 ? config.musicVol : config.effectsVol) * 9 / 255;
+ else if (i == 15 && ConfMan.getBool("tts_enabled"))
+ destColumn = 0;
+ else if (i == 16 && !ConfMan.getBool("tts_enabled"))
+ destColumn = 0;
+ else if (i == 18|| i == 20) {
+ int vol = (i ==18 ? config.musicVol : config.effectsVol) * 9 / 255;
vol = CLIP(vol, 0, 9);
strcpy(line, "[----------]");
line[vol + 1] = 'X';
optionValues[i] = line;
- } else if (i > 18)
+ } else if (i > 21)
destColumn = 0;
drawString(_videoBuffer, optionTitles[i], 156 - 8 * strlen(optionTitles[i]), sy + i * 8, 0);
@@ -310,12 +365,14 @@ void GriffonEngine::configMenu() {
curselt += 1;
if (cursel > 10)
curselt += 1;
- if (cursel > 11)
- curselt += 1;
if (cursel > 12)
curselt += 1;
if (cursel > 13)
curselt += 1;
+ if (cursel > 14)
+ curselt += 1;
+ if (cursel > 15)
+ curselt += 1;
Common::Rect rc;
rc.left = 148 + 3 * cos(2 * PI * _itemyloc / 16.0);
@@ -364,15 +421,20 @@ void GriffonEngine::configMenu() {
break;
case kGriffonLeft:
- if (cursel == 11) {
+ if (cursel == 13) {
config.musicVol = CLIP(config.musicVol - 25, 0, 255);
setChannelVolume(_musicChannel, config.musicVol);
setChannelVolume(_menuChannel, config.musicVol);
- } else if (cursel == 12) {
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan->say(formatPercent(config.musicVol));
+ } else if (cursel == 14) {
config.effectsVol = CLIP(config.effectsVol - 25, 0, 255);
+
setChannelVolume(-1, config.effectsVol);
setChannelVolume(_musicChannel, config.musicVol);
setChannelVolume(_menuChannel, config.musicVol);
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan->say(formatPercent(config.effectsVol));
if (config.effects) {
int snd = playSound(_sfx[kSndDoor]);
@@ -382,16 +444,19 @@ void GriffonEngine::configMenu() {
break;
case kGriffonRight:
- if (cursel == 11) {
+ if (cursel == 13) {
config.musicVol = CLIP(config.musicVol + 25, 0, 255);
setChannelVolume(_musicChannel, config.musicVol);
setChannelVolume(_menuChannel, config.musicVol);
- } else if (cursel == 12) {
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan->say(formatPercent(config.musicVol));
+ } else if (cursel == 14) {
config.effectsVol = CLIP(config.effectsVol + 25, 0, 255);
-
setChannelVolume(-1, config.effectsVol);
setChannelVolume(_musicChannel, config.musicVol);
setChannelVolume(_menuChannel, config.musicVol);
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan->say(formatPercent(config.effectsVol));
if (config.effects) {
int snd = playSound(_sfx[kSndDoor]);
@@ -404,12 +469,14 @@ void GriffonEngine::configMenu() {
cursel--;
if (cursel < MINCURSEL)
cursel = MAXCURSEL;
+ speakMenuItem(curselMapTitles[cursel], curselMapValues[cursel], optionTitles, optionValues);
break;
case kGriffonDown:
++cursel;
if (cursel > MAXCURSEL)
cursel = MINCURSEL;
+ speakMenuItem(curselMapTitles[cursel], curselMapValues[cursel], optionTitles, optionValues);
break;
case kGriffonConfirm:
@@ -439,10 +506,22 @@ void GriffonEngine::configMenu() {
if (config.effects)
config.effects = false;
break;
- case 13:
+ case 11:
+ if (!ConfMan.getBool("tts_enabled")) {
+ ConfMan.setBool("tts_enabled", true);
+ }
+ break;
+ case 12:
+ if (ConfMan.getBool("tts_enabled")) {
+ ConfMan.setBool("tts_enabled", false);
+ }
+ break;
+ case 15:
saveConfig();
// fall through
- case 14:
+ case 16:
+ if (ttsMan != nullptr)
+ ttsMan->stop();
exitMenu = true;
break;
default:
@@ -545,6 +624,10 @@ void GriffonEngine::renderSaveStates() {
}
void GriffonEngine::saveLoadNew() {
+ const char *optionTitles[4] = {
+ "new game", "", "load", "return",
+ };
+
float y = 0.0;
_cloudAngle = 0;
@@ -570,6 +653,8 @@ void GriffonEngine::saveLoadNew() {
}
_saveLoadImg->setAlpha(192, true);
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
+
// Main menu loop
do {
_videoBuffer->fillRect(Common::Rect(0, 0, _videoBuffer->w, _videoBuffer->h), 0);
@@ -605,6 +690,8 @@ void GriffonEngine::saveLoadNew() {
if (curRow == 0) {
if (curCol == 0) {
// NEW GAME
+ if (ttsMan != nullptr)
+ ttsMan->stop();
_gameMode = kGameModeNewGame;
return;
@@ -619,6 +706,8 @@ void GriffonEngine::saveLoadNew() {
curRow = 1;
tickPause = _ticks + 125;
} else if (curCol == 3) {
+ if (ttsMan != nullptr)
+ ttsMan->stop();
// RETURN
return;
} else if (curCol == 4) {
@@ -681,6 +770,8 @@ void GriffonEngine::saveLoadNew() {
tickPause = _ticks + 125;
}
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan -> say(optionTitles[curCol]);
break;
case kGriffonRight:
@@ -694,6 +785,8 @@ void GriffonEngine::saveLoadNew() {
tickPause = _ticks + 125;
}
+ if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
+ ttsMan -> say(optionTitles[curCol]);
break;
default:
;
diff --git a/engines/griffon/griffon.cpp b/engines/griffon/griffon.cpp
index b92c47ff53..a5a5ff197f 100644
--- a/engines/griffon/griffon.cpp
+++ b/engines/griffon/griffon.cpp
@@ -43,6 +43,8 @@
#include "common/translation.h"
#include "graphics/pixelformat.h"
+#include "common/text-to-speech.h"
+
#include "engines/util.h"
#include "griffon/griffon.h"
@@ -129,6 +131,10 @@ void GriffonEngine::saveConfig() {
}
Common::Error GriffonEngine::run() {
+ Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
+ if (ttsMan != nullptr)
+ ttsMan->setLanguage("en");
+
initGraphics(320, 240, new Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
_mixer = g_system->getMixer();
More information about the Scummvm-git-logs
mailing list