[Scummvm-git-logs] scummvm master -> 9f7970f44548434fb6e93e5559b046ce2cd413cd

bluegr noreply at scummvm.org
Fri Dec 24 00:57:33 UTC 2021


This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
a488bb47e8 SCI: Text to Speech (TTS) functionality for SCI16 (SCI0 - SCI1.1) games
0aaf48f900 SCI: Handle text in TTS where the first character is chopped off
ee2995fe82 SCI: Don't hook up kDisplay to TTS
f335d74e87 SCI: Strip color codes in TTS, and only handle actual texts in TTS
8a748f7e03 SCI: Add TTS support for SCI32 floppy games (QFG4, GK1, PQ4)
763b4cbd84 SCI: Corrections to the initialization/destruction of the SciTTS class
433f11da95 SCI: Only strip color codes in SCI1.1 for TTS
6af691e344 SCI: Skip TTS for QFG4 room 140 (character creation screen)
9f7970f445 NEWS: Mention TTS support in SCI floppy games


Commit: a488bb47e8ff534b5932f7a8e010bb325c69863c
    https://github.com/scummvm/scummvm/commit/a488bb47e8ff534b5932f7a8e010bb325c69863c
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Text to Speech (TTS) functionality for SCI16 (SCI0 - SCI1.1) games

This is based on the work done for GSoC by @taylorzhancher in PR #3256

Highlights:
- TTS has been hooked globally onto places where text is shown
- TTS is currently performed for textboxes and button texts
- TTS stops when text windows are disposed (which enhances the in-game
  experience)
- No game-specific logic has been added
- This hasn't been extensively tested with all SCI16 games yet
- There will be cases that are not handled properly yet
- The TTS functions have been grouped under a SciTTS class

Changed paths:
  A engines/sci/engine/tts.cpp
  A engines/sci/engine/tts.h
    engines/sci/detection.h
    engines/sci/detection_options.h
    engines/sci/detection_tables.h
    engines/sci/engine/kgraphics.cpp
    engines/sci/graphics/controls16.cpp
    engines/sci/graphics/paint16.cpp
    engines/sci/module.mk
    engines/sci/sci.cpp
    engines/sci/sci.h


diff --git a/engines/sci/detection.h b/engines/sci/detection.h
index 118bdd3cee..eed3f48310 100644
--- a/engines/sci/detection.h
+++ b/engines/sci/detection.h
@@ -43,6 +43,7 @@ namespace Sci {
 #define GAMEOPTION_RGB_RENDERING            GUIO_GAMEOPTIONS14
 #define GAMEOPTION_PALETTE_MODS             GUIO_GAMEOPTIONS15
 #define GAMEOPTION_SQ1_BEARDED_MUSICIANS    GUIO_GAMEOPTIONS16
+#define GAMEOPTION_TTS                      GUIO_GAMEOPTIONS17
 
 enum SciGameId {
 	GID_ASTROCHICKEN,
diff --git a/engines/sci/detection_options.h b/engines/sci/detection_options.h
index d8db26ef32..ee13fe429d 100644
--- a/engines/sci/detection_options.h
+++ b/engines/sci/detection_options.h
@@ -185,6 +185,18 @@ const ADExtraGuiOptionsMap optionsList[] = {
 		}
 	},
 
+#ifdef USE_TTS
+ 	{
+ 		GAMEOPTION_TTS,
+ 		{
+ 			_s("Enable Text to Speech"),
+ 			_s("Use TTS to read the descriptions (if TTS is available)"),
+ 			"tts_enabled",
+ 			false
+ 		}
+ 	},
+#endif
+
 	AD_EXTRA_GUI_OPTIONS_TERMINATOR
 };
 
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index cc1bfb127b..4c539272d7 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -22,15 +22,15 @@
 
 namespace Sci {
 
-#define GUIO_STD16 GUIO5(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
-#define GUIO_STD16_HIRES GUIO6(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
-#define GUIO_STD16_UNDITHER GUIO6(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
-#define GUIO_STD16_PALETTEMODS GUIO7(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_PALETTE_MODS)
+#define GUIO_STD16 GUIO6(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_TTS)
+#define GUIO_STD16_HIRES GUIO7(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_TTS)
+#define GUIO_STD16_UNDITHER GUIO7(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_TTS)
+#define GUIO_STD16_PALETTEMODS GUIO8(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_PALETTE_MODS, GAMEOPTION_TTS)
 #define GUIO_STD16_SPEECH GUIO4(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
 #define GUIO_STD16_SPEECH_GM GUIO5(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
-#define GUIO_STD16_MAC GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
-#define GUIO_STD16_MAC_UNDITHER GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
-#define GUIO_STD16_MAC_PALETTEMODS GUIO6(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_PALETTE_MODS)
+#define GUIO_STD16_MAC GUIO5(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_TTS)
+#define GUIO_STD16_MAC_UNDITHER GUIO6(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_TTS)
+#define GUIO_STD16_MAC_PALETTEMODS GUIO7(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING, GAMEOPTION_PALETTE_MODS, GAMEOPTION_TTS)
 #define GUIO_STD16_MAC_SPEECH GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_MIDI_MODE, GAMEOPTION_RGB_RENDERING)
 
 #define FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, resVol, lang) \
@@ -1406,10 +1406,11 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, 0, GUIO_STD16	},
 
-#define GUIO_JONES_FLOPPY GUIO4(GUIO_NOSPEECH,             \
+#define GUIO_JONES_FLOPPY GUIO5(GUIO_NOSPEECH,             \
 							GAMEOPTION_PREFER_DIGITAL_SFX, \
 		                    GAMEOPTION_MIDI_MODE,          \
-	                        GAMEOPTION_RGB_RENDERING)
+	                        GAMEOPTION_RGB_RENDERING,      \
+	                        GAMEOPTION_TTS)
 
 #define GUIO_JONES_CD GUIO4(GAMEOPTION_JONES_CDAUDIO,      \
 							GAMEOPTION_PREFER_DIGITAL_SFX, \
@@ -5027,12 +5028,13 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE)	},
 
-#define GUIO_SQ1_ENGLISH_PC GUIO6(GUIO_NOSPEECH,                 \
+#define GUIO_SQ1_ENGLISH_PC GUIO7(GUIO_NOSPEECH,                 \
                                   GAMEOPTION_PREFER_DIGITAL_SFX, \
                                   GAMEOPTION_ORIGINAL_SAVELOAD,  \
                                   GAMEOPTION_MIDI_MODE,          \
                                   GAMEOPTION_RGB_RENDERING,      \
-                                  GAMEOPTION_SQ1_BEARDED_MUSICIANS)
+                                  GAMEOPTION_SQ1_BEARDED_MUSICIANS, \
+                                  GAMEOPTION_TTS)
 
 	// Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org)
 	// SCI interpreter version 1.000.510 (just a guess)
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index de435e9c3b..4a1b600a48 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -37,6 +37,7 @@
 #include "sci/engine/savegame.h"
 #include "sci/engine/state.h"
 #include "sci/engine/selector.h"
+#include "sci/engine/tts.h"
 #include "sci/engine/kernel.h"
 #include "sci/graphics/animate.h"
 #include "sci/graphics/cache.h"
@@ -1178,6 +1179,8 @@ reg_t kDisposeWindow(EngineState *s, int argc, reg_t *argv) {
 		reanimate = true;
 
 	g_sci->_gfxPorts->kernelDisposeWindow(windowId, reanimate);
+	g_sci->_tts->stop();
+
 	return s->r_acc;
 }
 
diff --git a/engines/sci/engine/tts.cpp b/engines/sci/engine/tts.cpp
new file mode 100644
index 0000000000..da2256f4ff
--- /dev/null
+++ b/engines/sci/engine/tts.cpp
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sci/sci.h"
+#include "sci/engine/tts.h"
+#include "common/system.h"
+#include "common/text-to-speech.h"
+#include "common/config-manager.h"
+
+namespace Sci {
+
+SciTTS::SciTTS() : _lastText("") {
+	_ttsMan = ConfMan.getBool("tts_enabled") ? g_system->getTextToSpeechManager() : nullptr;
+	if (_ttsMan != nullptr)
+		_ttsMan->setLanguage(ConfMan.get("language"));
+}
+
+void SciTTS::button(const Common::String &text) {
+	if (_ttsMan != nullptr)
+		_ttsMan->say(text, Common::TextToSpeechManager::QUEUE_NO_REPEAT);
+}
+
+void SciTTS::text(const Common::String &text) {
+	if (_ttsMan != nullptr)
+		_ttsMan->say(text, Common::TextToSpeechManager::INTERRUPT);
+}
+
+void SciTTS::display(const Common::String &text) {
+	if (_ttsMan != nullptr && text != _lastText) {
+		_ttsMan->say(text, Common::TextToSpeechManager::QUEUE_NO_REPEAT);
+		_lastText = text;
+	}
+}
+
+void SciTTS::stop() {
+	if (_ttsMan != nullptr)
+		_ttsMan->stop();
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/engine/tts.h b/engines/sci/engine/tts.h
new file mode 100644
index 0000000000..1af0c854cc
--- /dev/null
+++ b/engines/sci/engine/tts.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/text-to-speech.h"
+#include "sci/sci.h"
+
+namespace Sci {
+
+class SciTTS {
+public:
+	SciTTS();
+
+	void button(const Common::String &text);
+	void text(const Common::String &text);
+	void display(const Common::String &text);
+	void stop();
+
+private:
+	Common::TextToSpeechManager *_ttsMan;
+	Common::String _lastText;
+};
+
+} // End of namespace Sci
diff --git a/engines/sci/graphics/controls16.cpp b/engines/sci/graphics/controls16.cpp
index a78f95f623..811b79e6cd 100644
--- a/engines/sci/graphics/controls16.cpp
+++ b/engines/sci/graphics/controls16.cpp
@@ -31,6 +31,7 @@
 #include "sci/engine/kernel.h"
 #include "sci/engine/state.h"
 #include "sci/engine/selector.h"
+#include "sci/engine/tts.h"
 #include "sci/graphics/compare.h"
 #include "sci/graphics/ports.h"
 #include "sci/graphics/paint16.h"
@@ -312,6 +313,8 @@ int GfxControls16::getPicNotValid() {
 }
 
 void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, int16 style, bool hilite) {
+	g_sci->_tts->button(text);
+
 	int16 sci0EarlyPen = 0, sci0EarlyBack = 0;
 	if (!hilite) {
 		if (getSciVersion() == SCI_VERSION_0_EARLY) {
@@ -350,6 +353,8 @@ void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *t
 }
 
 void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, uint16 languageSplitter, int16 fontId, TextAlignment alignment, int16 style, bool hilite) {
+	g_sci->_tts->text(text);
+
 	if (!hilite) {
 		rect.grow(1);
 		_paint16->eraseRect(rect);
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index 29688e9952..21d5c3415f 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -24,6 +24,7 @@
 #include "sci/engine/features.h"
 #include "sci/engine/state.h"
 #include "sci/engine/selector.h"
+#include "sci/engine/tts.h"
 #include "sci/engine/workarounds.h"
 #include "sci/graphics/cache.h"
 #include "sci/graphics/coordadjuster.h"
@@ -495,6 +496,8 @@ reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int a
 	// SCI01+ only)
 	Port oldPort = *_ports->getPort();
 
+	g_sci->_tts->display(text);
+
 	// setting defaults
 	_ports->penMode(0);
 	_ports->penColor(0);
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index a9129b4804..fb4febe68f 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -37,6 +37,7 @@ MODULE_OBJS := \
 	engine/segment.o \
 	engine/state.o \
 	engine/static_selectors.o \
+	engine/tts.o \
 	engine/vm.o \
 	engine/vm_types.o \
 	engine/workarounds.o \
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 477bb34f8d..174883ca69 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -43,6 +43,7 @@
 #include "sci/engine/script_patches.h"
 #include "sci/engine/selector.h"	// for SELECTOR
 #include "sci/engine/scriptdebug.h"
+#include "sci/engine/tts.h"
 
 #include "sci/sound/audio.h"
 #include "sci/sound/music.h"
@@ -254,12 +255,15 @@ SciEngine::~SciEngine() {
 
 	delete _scriptPatcher;
 	delete _resMan;	// should be deleted last
+	delete _tts;
 	g_sci = nullptr;
 }
 
 extern int showScummVMDialog(const Common::U32String &message, const Common::U32String &altButton = Common::U32String(), bool alignCenter = true);
 
 Common::Error SciEngine::run() {
+	_tts = new SciTTS();
+
 	_resMan = new ResourceManager();
 	_resMan->addAppropriateSources();
 	_resMan->init();
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 85491bb5b8..9096174bf0 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -80,6 +80,7 @@ class GfxScreen;
 class GfxText16;
 class GfxText32;
 class GfxTransitions;
+class SciTTS;
 
 #ifdef ENABLE_SCI32
 class GfxFrameout;
@@ -256,6 +257,7 @@ public:
 	GfxText16 *_gfxText16;
 	GfxTransitions *_gfxTransitions; // transitions between screens for 16-bit gfx
 	GfxMacIconBar *_gfxMacIconBar; // Mac Icon Bar manager
+	SciTTS *_tts;
 
 #ifdef ENABLE_SCI32
 	GfxControls32 *_gfxControls32; // Controls for 32-bit gfx


Commit: 0aaf48f900ceb2b22a960d72353ed86ceb468399
    https://github.com/scummvm/scummvm/commit/0aaf48f900ceb2b22a960d72353ed86ceb468399
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Handle text in TTS where the first character is chopped off

This occurs in games such as KQ5 and KQ6

Changed paths:
    engines/sci/engine/kstring.cpp
    engines/sci/engine/message.cpp
    engines/sci/engine/tts.cpp
    engines/sci/engine/tts.h


diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 900c640ceb..03f897b2ce 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -24,10 +24,11 @@
 
 #include "sci/resource/resource.h"
 #include "sci/engine/features.h"
-#include "sci/engine/state.h"
+#include "sci/engine/kernel.h"
 #include "sci/engine/message.h"
+#include "sci/engine/state.h"
 #include "sci/engine/selector.h"
-#include "sci/engine/kernel.h"
+#include "sci/engine/tts.h"
 
 namespace Sci {
 
@@ -102,6 +103,8 @@ reg_t kStrAt(EngineState *s, int argc, reg_t *argv) {
 	if (argc > 2)
 		newvalue = argv[2].toSint16();
 
+	g_sci->_tts->setMessage(s->_segMan->getString(argv[0]));
+
 	// in kq5 this here gets called with offset 0xFFFF
 	//  (in the desert wheng getting the staff)
 	if ((int)offset >= dest_r.maxSize) {
@@ -441,6 +444,8 @@ reg_t kStrLen(EngineState *s, int argc, reg_t *argv) {
 reg_t kGetFarText(EngineState *s, int argc, reg_t *argv) {
 	const Common::String text = g_sci->getKernel()->lookupText(make_reg(0, argv[0].toUint16()), argv[1].toUint16());
 
+	g_sci->_tts->setMessage(text);
+
 	// If the third argument is NULL, allocate memory for the destination. This
 	// occurs in SCI1 Mac games. The memory will later be freed by the game's
 	// scripts.
diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp
index d07f20aebf..132b5c8f83 100644
--- a/engines/sci/engine/message.cpp
+++ b/engines/sci/engine/message.cpp
@@ -25,6 +25,7 @@
 #include "sci/engine/kernel.h"
 #include "sci/engine/seg_manager.h"
 #include "sci/engine/state.h"
+#include "sci/engine/tts.h"
 #include "sci/engine/workarounds.h"
 #include "sci/util.h"
 
@@ -314,6 +315,7 @@ int MessageState::nextMessage(reg_t buf) {
 			_lastReturned = record.tuple;
 			_lastReturnedModule = _cursorStack.getModule();
 			_cursorStack.top().seq++;
+			g_sci->_tts->setMessage(record.string);
 			return record.talker;
 		} else {
 			MessageTuple &t = _cursorStack.top();
@@ -323,9 +325,10 @@ int MessageState::nextMessage(reg_t buf) {
 	} else {
 		CursorStack stack = _cursorStack;
 
-		if (getRecord(stack, true, record))
+		if (getRecord(stack, true, record)) {
+			g_sci->_tts->setMessage(record.string);
 			return record.talker;
-		else
+		} else
 			return 0;
 	}
 }
@@ -348,6 +351,7 @@ bool MessageState::messageRef(int module, const MessageTuple &t, MessageTuple &r
 	stack.init(module, t);
 	if (getRecord(stack, false, record)) {
 		ref = record.refTuple;
+		g_sci->_tts->setMessage(record.string);
 		return true;
 	}
 
diff --git a/engines/sci/engine/tts.cpp b/engines/sci/engine/tts.cpp
index da2256f4ff..ec4eb3271b 100644
--- a/engines/sci/engine/tts.cpp
+++ b/engines/sci/engine/tts.cpp
@@ -28,7 +28,7 @@
 
 namespace Sci {
 
-SciTTS::SciTTS() : _lastText("") {
+SciTTS::SciTTS() : _lastText(""), _message("") {
 	_ttsMan = ConfMan.getBool("tts_enabled") ? g_system->getTextToSpeechManager() : nullptr;
 	if (_ttsMan != nullptr)
 		_ttsMan->setLanguage(ConfMan.get("language"));
@@ -36,17 +36,17 @@ SciTTS::SciTTS() : _lastText("") {
 
 void SciTTS::button(const Common::String &text) {
 	if (_ttsMan != nullptr)
-		_ttsMan->say(text, Common::TextToSpeechManager::QUEUE_NO_REPEAT);
+		_ttsMan->say(getMessage(text), Common::TextToSpeechManager::QUEUE_NO_REPEAT);
 }
 
 void SciTTS::text(const Common::String &text) {
 	if (_ttsMan != nullptr)
-		_ttsMan->say(text, Common::TextToSpeechManager::INTERRUPT);
+		_ttsMan->say(getMessage(text), Common::TextToSpeechManager::INTERRUPT);
 }
 
 void SciTTS::display(const Common::String &text) {
 	if (_ttsMan != nullptr && text != _lastText) {
-		_ttsMan->say(text, Common::TextToSpeechManager::QUEUE_NO_REPEAT);
+		_ttsMan->say(getMessage(text), Common::TextToSpeechManager::QUEUE_NO_REPEAT);
 		_lastText = text;
 	}
 }
@@ -56,4 +56,20 @@ void SciTTS::stop() {
 		_ttsMan->stop();
 }
 
+void SciTTS::setMessage(const Common::String &text) {
+	if (text.size() > 0)
+		_message = text;
+}
+
+Common::String SciTTS::getMessage(const Common::String &text) {
+	// If the current message contains a substring of the text to be displayed,
+	// minus the first letter, prefer the message instead. The first letter is
+	// chopped off in messages in games such as KQ6 and is replaced with tabs in
+	// KQ6 or spaces in KQ5, so that a calligraphic first letter is drawn instead.
+	if (_message.size() > 0 && text.size() > 0 && text.hasSuffix(_message.substr(1)))
+		return _message;
+	else
+		return text;
+}
+
 } // End of namespace Sci
diff --git a/engines/sci/engine/tts.h b/engines/sci/engine/tts.h
index 1af0c854cc..cb36b16a26 100644
--- a/engines/sci/engine/tts.h
+++ b/engines/sci/engine/tts.h
@@ -33,10 +33,14 @@ public:
 	void text(const Common::String &text);
 	void display(const Common::String &text);
 	void stop();
+	void setMessage(const Common::String &text);
 
 private:
 	Common::TextToSpeechManager *_ttsMan;
 	Common::String _lastText;
+	Common::String _message;
+
+	Common::String getMessage(const Common::String &text);
 };
 
 } // End of namespace Sci


Commit: ee2995fe82937e053ff9573d36b05cde5f736b0f
    https://github.com/scummvm/scummvm/commit/ee2995fe82937e053ff9573d36b05cde5f736b0f
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Don't hook up kDisplay to TTS

kDisplay is used to redraw parts of the UI, so it's not ideal to hook
TTS there, as it keeps spamming sentences that get redrawn in the UI
frequently, such as the intro text and the points in SQ5

Changed paths:
    engines/sci/engine/tts.cpp
    engines/sci/engine/tts.h
    engines/sci/graphics/paint16.cpp


diff --git a/engines/sci/engine/tts.cpp b/engines/sci/engine/tts.cpp
index ec4eb3271b..898968fdf3 100644
--- a/engines/sci/engine/tts.cpp
+++ b/engines/sci/engine/tts.cpp
@@ -28,7 +28,7 @@
 
 namespace Sci {
 
-SciTTS::SciTTS() : _lastText(""), _message("") {
+SciTTS::SciTTS() : _message("") {
 	_ttsMan = ConfMan.getBool("tts_enabled") ? g_system->getTextToSpeechManager() : nullptr;
 	if (_ttsMan != nullptr)
 		_ttsMan->setLanguage(ConfMan.get("language"));
@@ -44,13 +44,6 @@ void SciTTS::text(const Common::String &text) {
 		_ttsMan->say(getMessage(text), Common::TextToSpeechManager::INTERRUPT);
 }
 
-void SciTTS::display(const Common::String &text) {
-	if (_ttsMan != nullptr && text != _lastText) {
-		_ttsMan->say(getMessage(text), Common::TextToSpeechManager::QUEUE_NO_REPEAT);
-		_lastText = text;
-	}
-}
-
 void SciTTS::stop() {
 	if (_ttsMan != nullptr)
 		_ttsMan->stop();
diff --git a/engines/sci/engine/tts.h b/engines/sci/engine/tts.h
index cb36b16a26..b1921da4f9 100644
--- a/engines/sci/engine/tts.h
+++ b/engines/sci/engine/tts.h
@@ -31,13 +31,11 @@ public:
 
 	void button(const Common::String &text);
 	void text(const Common::String &text);
-	void display(const Common::String &text);
 	void stop();
 	void setMessage(const Common::String &text);
 
 private:
 	Common::TextToSpeechManager *_ttsMan;
-	Common::String _lastText;
 	Common::String _message;
 
 	Common::String getMessage(const Common::String &text);
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index 21d5c3415f..29688e9952 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -24,7 +24,6 @@
 #include "sci/engine/features.h"
 #include "sci/engine/state.h"
 #include "sci/engine/selector.h"
-#include "sci/engine/tts.h"
 #include "sci/engine/workarounds.h"
 #include "sci/graphics/cache.h"
 #include "sci/graphics/coordadjuster.h"
@@ -496,8 +495,6 @@ reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int a
 	// SCI01+ only)
 	Port oldPort = *_ports->getPort();
 
-	g_sci->_tts->display(text);
-
 	// setting defaults
 	_ports->penMode(0);
 	_ports->penColor(0);


Commit: f335d74e8776f663ae7417629e591d6f3c9b400e
    https://github.com/scummvm/scummvm/commit/f335d74e8776f663ae7417629e591d6f3c9b400e
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Strip color codes in TTS, and only handle actual texts in TTS

We now remove all color codes from strings, and only handle texts in
TTS if they contain at least one vowel. This allows us to skip texts
such as the one shown when talking to the alien in SQ5 room 500, where
a series of symbols is shown, as part of a joke

Changed paths:
    engines/sci/engine/tts.cpp
    engines/sci/engine/tts.h


diff --git a/engines/sci/engine/tts.cpp b/engines/sci/engine/tts.cpp
index 898968fdf3..2f5362beaf 100644
--- a/engines/sci/engine/tts.cpp
+++ b/engines/sci/engine/tts.cpp
@@ -28,7 +28,7 @@
 
 namespace Sci {
 
-SciTTS::SciTTS() : _message("") {
+SciTTS::SciTTS() : _curMessage("") {
 	_ttsMan = ConfMan.getBool("tts_enabled") ? g_system->getTextToSpeechManager() : nullptr;
 	if (_ttsMan != nullptr)
 		_ttsMan->setLanguage(ConfMan.get("language"));
@@ -51,18 +51,49 @@ void SciTTS::stop() {
 
 void SciTTS::setMessage(const Common::String &text) {
 	if (text.size() > 0)
-		_message = text;
+		_curMessage = text;
 }
 
 Common::String SciTTS::getMessage(const Common::String &text) {
+	Common::String message = text;
+
 	// If the current message contains a substring of the text to be displayed,
 	// minus the first letter, prefer the message instead. The first letter is
 	// chopped off in messages in games such as KQ6 and is replaced with tabs in
 	// KQ6 or spaces in KQ5, so that a calligraphic first letter is drawn instead.
-	if (_message.size() > 0 && text.size() > 0 && text.hasSuffix(_message.substr(1)))
-		return _message;
+	if (_curMessage.size() > 0 && text.size() > 0 && text.hasSuffix(_curMessage.substr(1)))
+		message = _curMessage;
+	else
+		message = text;
+
+	// Strip color code characters in SCI1.1 or newer
+	if (getSciVersion() >= SCI_VERSION_1_1) {
+		int32 index = message.find('|');
+
+		while (index >= 0) {
+			do {
+				message.deleteChar(index);
+			} while (message.size() > 0 && message[index] != '|');
+
+			if (message.size() > 0)
+				message.deleteChar(index);
+
+			index = message.find('|');
+		}
+	}
+
+	// Check if it's an actual message, by checking for the
+	// existence of any vowel.
+	// For example, when talking to the alien in SQ5 room 500, a
+	// series of symbols is shown, as part of a joke.
+	if (message.contains('a') ||
+		message.contains('e') ||
+		message.contains('i') ||
+		message.contains('o') ||
+		message.contains('u'))
+		return message;
 	else
-		return text;
+		return "";
 }
 
 } // End of namespace Sci
diff --git a/engines/sci/engine/tts.h b/engines/sci/engine/tts.h
index b1921da4f9..61bece74af 100644
--- a/engines/sci/engine/tts.h
+++ b/engines/sci/engine/tts.h
@@ -36,7 +36,7 @@ public:
 
 private:
 	Common::TextToSpeechManager *_ttsMan;
-	Common::String _message;
+	Common::String _curMessage;
 
 	Common::String getMessage(const Common::String &text);
 };


Commit: 8a748f7e03342b24c770734a605fc9c8229a2aaa
    https://github.com/scummvm/scummvm/commit/8a748f7e03342b24c770734a605fc9c8229a2aaa
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Add TTS support for SCI32 floppy games (QFG4, GK1, PQ4)

Changed paths:
    engines/sci/detection_tables.h
    engines/sci/engine/kgraphics32.cpp
    engines/sci/graphics/text32.cpp


diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 4c539272d7..f5a811b6eb 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -809,8 +809,9 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, 0, GUIO_STD16_SPEECH	},
 
-#define GUIO_GK1_FLOPPY GUIO2(GUIO_NOSPEECH, \
-							  GAMEOPTION_ORIGINAL_SAVELOAD)
+#define GUIO_GK1_FLOPPY GUIO3(GUIO_NOSPEECH, \
+							  GAMEOPTION_ORIGINAL_SAVELOAD, \
+							  GAMEOPTION_TTS)
 #define GUIO_GK1_CD_DOS GUIO4(GUIO_LINKSPEECHTOSFX, \
 							  GAMEOPTION_ORIGINAL_SAVELOAD, \
 							  GAMEOPTION_HIGH_RESOLUTION_GRAPHICS, \
@@ -818,7 +819,8 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 #define GUIO_GK1_CD_WIN GUIO3(GUIO_LINKSPEECHTOSFX, \
 							  GAMEOPTION_ORIGINAL_SAVELOAD, \
 							  GAMEOPTION_HQ_VIDEO)
-#define GUIO_GK1_MAC    GUIO1(GUIO_NOSPEECH)
+#define GUIO_GK1_MAC    GUIO2(GUIO_NOSPEECH, \
+							  GAMEOPTION_TTS)
 
 	// Gabriel Knight - English DOS Floppy
 	// SCI interpreter version 2.000.000
@@ -4199,8 +4201,9 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, 0, GUIO_STD16	},
 
-#define GUIO_PQ4_FLOPPY GUIO2(GUIO_NOSPEECH, \
-							  GAMEOPTION_ORIGINAL_SAVELOAD)
+#define GUIO_PQ4_FLOPPY GUIO3(GUIO_NOSPEECH, \
+							  GAMEOPTION_ORIGINAL_SAVELOAD, \
+							  GAMEOPTION_TTS)
 #define GUIO_PQ4_CD     GUIO3(GUIO_LINKSPEECHTOSFX, \
 							  GAMEOPTION_HIGH_RESOLUTION_GRAPHICS, \
 							  GAMEOPTION_ORIGINAL_SAVELOAD)
@@ -4744,8 +4747,9 @@ static const struct ADGameDescription SciGameDescriptions[] = {
 		AD_LISTEND},
 		Common::EN_ANY, Common::kPlatformDOS, 0, GUIO_STD16 },
 
-#define GUIO_QFG4_FLOPPY GUIO2(GUIO_NOSPEECH, \
-							   GAMEOPTION_ORIGINAL_SAVELOAD)
+#define GUIO_QFG4_FLOPPY GUIO3(GUIO_NOSPEECH, \
+							   GAMEOPTION_ORIGINAL_SAVELOAD, \
+							   GAMEOPTION_TTS)
 #define GUIO_QFG4_CD     GUIO3(GUIO_LINKSPEECHTOSFX, \
 							   GAMEOPTION_ORIGINAL_SAVELOAD, \
 							   GAMEOPTION_HQ_VIDEO)
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 64ed1b6789..9c18500a0d 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -33,6 +33,7 @@
 #include "sci/engine/features.h"
 #include "sci/engine/state.h"
 #include "sci/engine/selector.h"
+#include "sci/engine/tts.h"
 #include "sci/engine/kernel.h"
 #include "sci/graphics/animate.h"
 #include "sci/graphics/cache.h"
@@ -191,7 +192,10 @@ reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) {
 }
 
 reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) {
-	debugC(6, kDebugLevelGraphics, "kDeleteScreenItem %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0]));
+	Common::String objectName = s->_segMan->getObjectName(argv[0]);
+	debugC(6, kDebugLevelGraphics, "kDeleteScreenItem %x:%x (%s)", PRINT_REG(argv[0]), objectName.c_str());
+	if (objectName == "DText")
+		g_sci->_tts->stop();
 	g_sci->_gfxFrameout->kernelDeleteScreenItem(argv[0]);
 	return s->r_acc;
 }
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index 3d20fd45aa..0be372924e 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -29,6 +29,7 @@
 #include "sci/engine/kernel.h"
 #include "sci/engine/selector.h"
 #include "sci/engine/state.h"
+#include "sci/engine/tts.h"
 #include "sci/graphics/cache.h"
 #include "sci/graphics/celobj32.h"
 #include "sci/graphics/compare.h"
@@ -326,6 +327,8 @@ void GfxText32::drawTextBox() {
 		return;
 	}
 
+	g_sci->_tts->text(_text);
+
 	const char *text = _text.c_str();
 	const char *sourceText = text;
 	int16 textRectWidth = _textRect.width();


Commit: 763b4cbd8497ddaf2b82fc17951efc636b0319da
    https://github.com/scummvm/scummvm/commit/763b4cbd8497ddaf2b82fc17951efc636b0319da
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Corrections to the initialization/destruction of the SciTTS class

Changed paths:
    engines/sci/sci.cpp


diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 174883ca69..403ee80982 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -131,6 +131,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
 	_eventMan(nullptr),
 	_gameObjectAddress(),
 	_console(nullptr),
+	_tts(nullptr),
 	_rng("sci"),
 	_forceHiresGraphics(false) {
 
@@ -254,8 +255,8 @@ SciEngine::~SciEngine() {
 	delete[] _opcode_formats;
 
 	delete _scriptPatcher;
-	delete _resMan;	// should be deleted last
 	delete _tts;
+	delete _resMan;	// should be deleted last
 	g_sci = nullptr;
 }
 


Commit: 433f11da95b033d2d450bf6f91706efec956f242
    https://github.com/scummvm/scummvm/commit/433f11da95b033d2d450bf6f91706efec956f242
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Only strip color codes in SCI1.1 for TTS

Color code processing has been removed in newer SCI versions

Changed paths:
    engines/sci/engine/tts.cpp


diff --git a/engines/sci/engine/tts.cpp b/engines/sci/engine/tts.cpp
index 2f5362beaf..d765f93879 100644
--- a/engines/sci/engine/tts.cpp
+++ b/engines/sci/engine/tts.cpp
@@ -66,8 +66,8 @@ Common::String SciTTS::getMessage(const Common::String &text) {
 	else
 		message = text;
 
-	// Strip color code characters in SCI1.1 or newer
-	if (getSciVersion() >= SCI_VERSION_1_1) {
+	// Strip color code characters in SCI1.1
+	if (getSciVersion() == SCI_VERSION_1_1) {
 		int32 index = message.find('|');
 
 		while (index >= 0) {


Commit: 6af691e3449c1b9f16f3a04ea4122bc24800a5da
    https://github.com/scummvm/scummvm/commit/6af691e3449c1b9f16f3a04ea4122bc24800a5da
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
SCI: Skip TTS for QFG4 room 140 (character creation screen)

In this screen, the UI is refreshed with many short sentences (e.g.
"Strength"), which are drawn very quickly. Since this causes TTS to
constantly start and stop, it introduces an unwanted lag, thus we
skip TTS in that screen

Changed paths:
    engines/sci/engine/tts.cpp
    engines/sci/engine/tts.h


diff --git a/engines/sci/engine/tts.cpp b/engines/sci/engine/tts.cpp
index d765f93879..af80633666 100644
--- a/engines/sci/engine/tts.cpp
+++ b/engines/sci/engine/tts.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "sci/sci.h"
+#include "sci/engine/state.h"
 #include "sci/engine/tts.h"
 #include "common/system.h"
 #include "common/text-to-speech.h"
@@ -35,12 +36,12 @@ SciTTS::SciTTS() : _curMessage("") {
 }
 
 void SciTTS::button(const Common::String &text) {
-	if (_ttsMan != nullptr)
+	if (_ttsMan != nullptr && shouldPerformTTS(text))
 		_ttsMan->say(getMessage(text), Common::TextToSpeechManager::QUEUE_NO_REPEAT);
 }
 
 void SciTTS::text(const Common::String &text) {
-	if (_ttsMan != nullptr)
+	if (_ttsMan != nullptr && shouldPerformTTS(text))
 		_ttsMan->say(getMessage(text), Common::TextToSpeechManager::INTERRUPT);
 }
 
@@ -82,18 +83,29 @@ Common::String SciTTS::getMessage(const Common::String &text) {
 		}
 	}
 
+	return message;
+}
+
+bool SciTTS::shouldPerformTTS(const Common::String &message) const {
+	SciGameId gameId = g_sci->getGameId();
+	uint16 roomNumber = g_sci->getEngineState()->currentRoomNumber();
+
 	// Check if it's an actual message, by checking for the
 	// existence of any vowel.
 	// For example, when talking to the alien in SQ5 room 500, a
 	// series of symbols is shown, as part of a joke.
-	if (message.contains('a') ||
-		message.contains('e') ||
-		message.contains('i') ||
-		message.contains('o') ||
-		message.contains('u'))
-		return message;
-	else
-		return "";
+	if (!message.contains('a') &&
+		!message.contains('e') &&
+		!message.contains('i') &&
+		!message.contains('o') &&
+		!message.contains('u'))
+		return false;
+
+	// Skip TTS for QFG4 room 140 (character creation screen).
+	if (gameId == GID_QFG4 && roomNumber == 140)
+		return false;
+
+	return true;
 }
 
 } // End of namespace Sci
diff --git a/engines/sci/engine/tts.h b/engines/sci/engine/tts.h
index 61bece74af..172e174f62 100644
--- a/engines/sci/engine/tts.h
+++ b/engines/sci/engine/tts.h
@@ -39,6 +39,7 @@ private:
 	Common::String _curMessage;
 
 	Common::String getMessage(const Common::String &text);
+	bool shouldPerformTTS(const Common::String &message) const;
 };
 
 } // End of namespace Sci


Commit: 9f7970f44548434fb6e93e5559b046ce2cd413cd
    https://github.com/scummvm/scummvm/commit/9f7970f44548434fb6e93e5559b046ce2cd413cd
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-12-24T02:57:27+02:00

Commit Message:
NEWS: Mention TTS support in SCI floppy games

Changed paths:
    NEWS.md


diff --git a/NEWS.md b/NEWS.md
index de4bea0799..9387637f40 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -33,6 +33,9 @@ For a more comprehensive changelog of the latest experimental code, see:
  Supernova:
    - Added text to speech for dialogs and object descriptions.
 
+ SCI:
+   - Added support for Text To Speech in SCI floppy games.
+
  SCUMM:
    - New Digital iMUSE engine.
    - Improved support for the high-resolution text in the 16-color Macintosh




More information about the Scummvm-git-logs mailing list