[Scummvm-git-logs] scummvm master -> 41d443452944aaff51ae93d4f0fb44452b2832cc

criezy criezy at scummvm.org
Wed Sep 8 19:04:04 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:
41d4434529 SUPERNOVA: Improve synchronization of TTS with text displayed on screen


Commit: 41d443452944aaff51ae93d4f0fb44452b2832cc
    https://github.com/scummvm/scummvm/commit/41d443452944aaff51ae93d4f0fb44452b2832cc
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2021-09-08T20:03:24+01:00

Commit Message:
SUPERNOVA: Improve synchronization of TTS with text displayed on screen

Changed paths:
    engines/supernova/game-manager.cpp
    engines/supernova/game-manager.h
    engines/supernova/supernova1/rooms.cpp
    engines/supernova/supernova2/rooms.cpp
    engines/supernova/supernova2/state.cpp


diff --git a/engines/supernova/game-manager.cpp b/engines/supernova/game-manager.cpp
index 02f231bc8b..a620c67b9e 100644
--- a/engines/supernova/game-manager.cpp
+++ b/engines/supernova/game-manager.cpp
@@ -607,7 +607,11 @@ void GameManager::say(const char *text) {
 	}
 
 	Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
-	if (ttsMan != nullptr && ConfMan.getBool("tts_enabled")) {
+	if (ttsMan && ConfMan.getBool("tts_enabled")) {
+		// Wait for the end of the current speech
+		if (ttsMan->isSpeaking())
+			wait(0, true, true);
+		// New sentence
 		Common::String ttsText;
 		for (uint i = 0; i < numRows; ++i) {
 			if (!ttsText.empty())
@@ -621,7 +625,7 @@ void GameManager::say(const char *text) {
 	_vm->renderBox(0, 141, 320, numRows * 10 - 1, kColorWhite25);
 	for (uint r = 0; r < numRows; ++r)
 		_vm->renderText(row[r], 1, 142 + r * 10, kColorDarkGreen);
-	wait((t.size() + 20) * _vm->_textSpeed / 10, true);
+	wait((t.size() + 20) * _vm->_textSpeed / 10, true, true);
 	_vm->renderBox(0, 138, 320, 62, kColorBlack);
 }
 
@@ -632,21 +636,36 @@ void GameManager::reply(int textId, int aus1, int aus2) {
 }
 
 void GameManager::reply(const char *text, int aus1, int aus2) {
-	if (*text != '|')
+	Common::TextToSpeechManager *ttsMan = nullptr;
+	if (*text != '|') {
+		if (ConfMan.getBool("tts_enabled"))
+			ttsMan = g_system->getTextToSpeechManager();
+		// Wait for the end of the current speech
+		if (ttsMan && ttsMan->isSpeaking())
+			wait(0, true, ttsMan);
 		_vm->renderMessage(text, kMessageTop);
+	}
 
-	for (int z = (strlen(text) + 20) * _vm->_textSpeed / 40; z > 0; --z) {
+	int z = (strlen(text) + 20) * _vm->_textSpeed / 40;
+	bool inputEvent = false;
+	while ((z > 0 || (ttsMan != nullptr && ttsMan->isSpeaking())) && !_vm->shouldQuit() && !inputEvent) {
 		if (aus1)
 			_vm->renderImage(aus1);
 		wait(2, true);
 		if (_keyPressed || _mouseClicked)
-			z = 1;
+			inputEvent = true;
 		if (aus2)
 			_vm->renderImage(aus2);
 		wait(2, true);
 		if (_keyPressed || _mouseClicked)
-			z = 1;
+			inputEvent = true;
+		--z;
 	}
+
+	// If we had an input event, interrupt the speech
+	if (inputEvent && ttsMan)
+			ttsMan->stop();
+
 	if (*text != '|')
 		_vm->removeMessage();
 }
@@ -775,7 +794,11 @@ void GameManager::changeRoom(RoomId id) {
 	}
 }
 
-void GameManager::wait(int ticks, bool checkInput) {
+void GameManager::wait(int ticks, bool checkInput, bool waitForSpeech) {
+	Common::TextToSpeechManager *ttsMan = nullptr;
+	if (waitForSpeech && ConfMan.getBool("tts_enabled"))
+		ttsMan = g_system->getTextToSpeechManager();
+
 	int32 end = _time + ticksToMsec(ticks);
 	bool inputEvent = false;
 	do {
@@ -784,10 +807,17 @@ void GameManager::wait(int ticks, bool checkInput) {
 		g_system->updateScreen();
 		if (checkInput)
 			inputEvent = _keyPressed || _mouseClicked;
-	} while (_time < end && !_vm->shouldQuit() && !inputEvent);
+	} while ((_time < end || (ttsMan && ttsMan->isSpeaking())) && !_vm->shouldQuit() && !inputEvent);
+	// If we had an input event, interrupt the speech
+	if (inputEvent && ttsMan)
+			ttsMan->stop();
 }
 
-bool GameManager::waitOnInput(int ticks, Common::KeyCode &keycode) {
+bool GameManager::waitOnInput(int ticks, Common::KeyCode &keycode, bool waitForSpeech) {
+	Common::TextToSpeechManager *ttsMan = nullptr;
+	if (waitForSpeech && ConfMan.getBool("tts_enabled"))
+		ttsMan = g_system->getTextToSpeechManager();
+
 	keycode = Common::KEYCODE_INVALID;
 	int32 end = _time + ticksToMsec(ticks);
 	do {
@@ -797,10 +827,15 @@ bool GameManager::waitOnInput(int ticks, Common::KeyCode &keycode) {
 		if (_keyPressed) {
 			keycode = _key.keycode;
 			_key.reset();
+			if (ttsMan)
+				ttsMan->stop();
 			return true;
-		} else if (_mouseClicked)
+		} else if (_mouseClicked) {
+			if (ttsMan)
+				ttsMan->stop();
 			return true;
-	} while (_time < end  && !_vm->shouldQuit());
+		}
+	} while ((_time < end || (ttsMan && ttsMan->isSpeaking()))  && !_vm->shouldQuit());
 	return false;
 }
 
diff --git a/engines/supernova/game-manager.h b/engines/supernova/game-manager.h
index 39f697a57d..771d43f69a 100644
--- a/engines/supernova/game-manager.h
+++ b/engines/supernova/game-manager.h
@@ -166,8 +166,8 @@ public:
 	virtual bool canSaveGameStateCurrently();
 	virtual bool genericInteract(Action verb, Object &obj1, Object &obj2);
 	void getInput(bool onlyKeys = false);
-	void wait(int ticks, bool checkInput = false);
-	bool waitOnInput(int ticks, Common::KeyCode &keycode);
+	void wait(int ticks, bool checkInput = false, bool waitForSpeech = false);
+	bool waitOnInput(int ticks, Common::KeyCode &keycode, bool waitForSpeech = false);
 	void screenShake();
 	virtual void roomBrightness();
 	void showMenu();
diff --git a/engines/supernova/supernova1/rooms.cpp b/engines/supernova/supernova1/rooms.cpp
index 2ea13b6914..c8565113fa 100644
--- a/engines/supernova/supernova1/rooms.cpp
+++ b/engines/supernova/supernova1/rooms.cpp
@@ -762,10 +762,10 @@ void ShipSleepCabin::animation() {
 void ShipSleepCabin::onEntrance() {
 	if (_gm->_state._dream && (_gm->_rooms[CAVE]->getObject(1)->_exitRoom == MEETUP3)) {
 		_vm->renderMessage(kStringShipSleepCabin14);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_vm->renderMessage(kStringShipSleepCabin15);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_vm->renderMessage(kStringShipSleepCabin16);
 		_gm->_state._dream = false;
@@ -2089,7 +2089,7 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
 				_vm->renderMessage(kStringArsanoEntrance20);
 			else {
 				_vm->renderMessage(kStringArsanoEntrance21);
-				_gm->wait(_gm->_messageDuration, true);
+				_gm->wait(_gm->_messageDuration, true, true);
 				_vm->removeMessage();
 				_vm->renderMessage(kStringArsanoEntrance22);
 				_gm->takeObject(*getObject(16));
@@ -2136,7 +2136,7 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
 			_gm->_rooms[AIRLOCK]->getObject(4)->setProperty(WORN);
 			_gm->_rooms[AIRLOCK]->getObject(5)->setProperty(WORN);
 			_gm->_rooms[AIRLOCK]->getObject(6)->setProperty(WORN);
-			_gm->wait(_gm->_messageDuration, true);
+			_gm->wait(_gm->_messageDuration, true, true);
 			_vm->removeMessage();
 		}
 		return false;
@@ -2456,7 +2456,7 @@ bool ArsanoRoger::interact(Action verb, Object &obj1, Object &obj2) {
 		_vm->_screen->setGuiBrightness(255);
 		_vm->paletteBrightness();
 		_vm->renderMessage(kStringArsanoRoger39);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_vm->_screen->setGuiBrightness(0);
 		_vm->paletteBrightness();
@@ -2473,7 +2473,7 @@ bool ArsanoRoger::interact(Action verb, Object &obj1, Object &obj2) {
 		getObject(6)->_click = 7;
 		_vm->paletteFadeIn();
 		_vm->renderMessage(kStringArsanoRoger40);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 	} else
 		return false;
@@ -2703,7 +2703,7 @@ bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) {
 				_gm->wait(18);
 				_vm->renderMessage(kStringArsanoMeetup2_12);
 				_gm->great(0);
-				_gm->wait(_gm->_messageDuration, true);
+				_gm->wait(_gm->_messageDuration, true, true);
 				_vm->removeMessage();
 				_vm->paletteFadeOut();
 				g_system->fillScreen(kColorBlack);
@@ -4017,7 +4017,7 @@ bool AxacussElevator::interact(Action verb, Object &obj1, Object &obj2) {
 		_vm->_screen->setGuiBrightness(255);
 		_vm->paletteBrightness();
 		_vm->renderMessage(kStringAxacussElevator_3);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_vm->_screen->setGuiBrightness(0);
 		_vm->paletteBrightness();
diff --git a/engines/supernova/supernova2/rooms.cpp b/engines/supernova/supernova2/rooms.cpp
index e5890801d8..49627ba377 100644
--- a/engines/supernova/supernova2/rooms.cpp
+++ b/engines/supernova/supernova2/rooms.cpp
@@ -121,7 +121,7 @@ bool Intro2::displayThoughtMessage(int id) {
 	Common::KeyCode key = Common::KEYCODE_INVALID;
 	const Common::String& text = _vm->getGameString(id);
 	_vm->renderMessage(text, kMessageNormal);
-	if (_gm->waitOnInput((text.size() + 20) * _vm->_textSpeed / 10, key)) {
+	if (_gm->waitOnInput((text.size() + 20) * _vm->_textSpeed / 10, key, true)) {
 		_vm->removeMessage();
 		return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit();
 	}
@@ -1027,19 +1027,19 @@ bool Checkout::interact(Action verb, Object &obj1, Object &obj2) {
 					_gm->dialog(3, _gm->_dials, dialStage1, 0);
 					_gm->dialog(2, _gm->_dials, dialStage2, 0);
 					_vm->renderMessage(kStringCheckout20, 100, 70);
-					_gm->wait(_gm->_messageDuration, true);
+					_gm->wait(_gm->_messageDuration, true, true);
 					_vm->removeMessage();
 					_vm->renderMessage(kStringCheckout21, 200, 40);
-					_gm->wait(_gm->_messageDuration, true);
+					_gm->wait(_gm->_messageDuration, true, true);
 					_vm->removeMessage();
 					_gm->say(kStringCheckout22);
 					_gm->dialog(3, _gm->_dials, dialStage3, 0);
 					_vm->renderMessage(kStringCheckout23, 120, 70);
-					_gm->wait(_gm->_messageDuration, true);
+					_gm->wait(_gm->_messageDuration, true, true);
 					_vm->removeMessage();
 					_gm->say(kStringCheckout24);
 					_vm->renderMessage(kStringCheckout25, 40, 100);
-					_gm->wait(_gm->_messageDuration, true);
+					_gm->wait(_gm->_messageDuration, true, true);
 					_vm->removeMessage();
 					_gm->dialog(2, _gm->_dials, dialStage4, 0);
 					_vm->playSound(kAudioStage1);
@@ -1070,10 +1070,10 @@ bool Checkout::interact(Action verb, Object &obj1, Object &obj2) {
 					_vm->removeMessage();
 					_vm->playSound(kAudioStage2);
 					_vm->renderMessage(kStringCheckout26, 180, 50);
-					_gm->wait(_gm->_messageDuration, true);
+					_gm->wait(_gm->_messageDuration, true, true);
 					_vm->removeMessage();
 					_vm->renderMessage(kStringCheckout28, 50, 110);
-					_gm->wait(_gm->_messageDuration, true);
+					_gm->wait(_gm->_messageDuration, true, true);
 					_vm->removeMessage();
 					_gm->say(kStringCheckout29);
 					_vm->renderRoom(*this);
@@ -1086,7 +1086,7 @@ bool Checkout::interact(Action verb, Object &obj1, Object &obj2) {
 				}
 			} else {
 				_vm->renderMessage(kStringCheckout32);
-				_gm->wait(_gm->_messageDuration, true);
+				_gm->wait(_gm->_messageDuration, true, true);
 				_vm->removeMessage();
 				_vm->renderMessage(kStringCheckout33);
 			}
@@ -1392,22 +1392,22 @@ void Checkout::appearance() {
 	_vm->_screen->setGuiBrightness(255);
 	_vm->paletteBrightness();
 	_vm->renderMessage(kStringAppearance22);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance23);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance24);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance25);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance26);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance27);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->_screen->setViewportBrightness(0);
 	_vm->_screen->setGuiBrightness(0);
@@ -1439,16 +1439,16 @@ void Checkout::appearance() {
 	_vm->_screen->setGuiBrightness(255);
 	_vm->paletteBrightness();
 	_vm->renderMessage(kStringAppearance28);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance29);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance30);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringAppearance31);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_gm->changeRoom(SHIP);
 	_gm->_state._dark = true;
@@ -1611,7 +1611,7 @@ bool Elevator2::interact(Action verb, Object &obj1, Object &obj2) {
 				_gm->wait(3);
 				_vm->renderImage(1 + kSectionInvert);
 				_vm->renderMessage(kStringElevator12);
-				_gm->wait(_gm->_messageDuration, true);
+				_gm->wait(_gm->_messageDuration, true, true);
 				_vm->removeMessage();
 				_vm->renderImage(1);
 				_gm->wait(3);
@@ -1627,7 +1627,7 @@ bool Elevator2::interact(Action verb, Object &obj1, Object &obj2) {
 				_vm->_system->fillScreen(kColorBlack);
 				_vm->_screen->setViewportBrightness(255);
 				_vm->renderMessage(kStringElevator14);
-				_gm->wait(_gm->_messageDuration, true);
+				_gm->wait(_gm->_messageDuration, true, true);
 				_vm->removeMessage();
 				_vm->_screen->setViewportBrightness(0);
 				_vm->setCurrentImage(26);
@@ -1783,7 +1783,7 @@ void Elevator2::jobDescription() {
 	_vm->_system->fillScreen(kColorBlack);
 	_vm->_screen->setViewportBrightness(255);
 	_vm->renderMessage(kStringElevator55);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->_screen->setViewportBrightness(0);
 	_gm->_state._tipsy = false;
@@ -1799,10 +1799,10 @@ void Elevator2::jobDescription() {
 	_vm->renderImage(0);
 	_vm->paletteFadeIn();
 	_vm->renderMessage(kStringElevator56);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringElevator57);
-	_gm->wait(_gm->_messageDuration, true);
+	_gm->wait(_gm->_messageDuration, true, true);
 	_vm->removeMessage();
 	_vm->renderMessage(kStringElevator58);
 	_gm->drawGUI();
@@ -1852,7 +1852,7 @@ bool Apartment::interact(Action verb, Object &obj1, Object &obj2) {
 			_vm->playSound(kAudioSuccess2);
 		} else {
 			_vm->renderMessage(kStringApartment3);
-			_gm->wait(_gm->_messageDuration, true);
+			_gm->wait(_gm->_messageDuration, true, true);
 			_vm->removeMessage();
 			_vm->renderMessage(kStringApartment4);
 		}
@@ -2051,27 +2051,27 @@ bool Ship::interact(Action verb, Object &obj1, Object &obj2) {
 		_vm->renderImage(0);
 		_gm->wait(16);
 		_vm->renderMessage(kStringShip7, kMessageRight);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_gm->reply(kStringShip8, 1, 1 + kSectionInvert);
 		_vm->renderMessage(kStringShip9, kMessageRight);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_gm->reply(kStringShip10, 1, 1 + kSectionInvert);
 		_gm->reply(kStringShip11, 1, 1 + kSectionInvert);
 		_gm->reply(kStringShip12, 1, 1 + kSectionInvert);
 		_gm->reply(kStringShip13, 1, 1 + kSectionInvert);
 		_vm->renderMessage(kStringShip14, kMessageRight);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_gm->reply(kStringShip15, 1, 1 + kSectionInvert);
 		_vm->renderMessage(kStringShip16, kMessageRight);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_gm->reply(kStringAha, 1, 1 + kSectionInvert);
 		_gm->reply(kStringShip17, 1, 1 + kSectionInvert);
 		_vm->renderMessage(kStringShip18, kMessageRight);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_gm->reply(kStringShip19, 1, 1 + kSectionInvert);
 		_gm->wait(16);
@@ -2296,7 +2296,7 @@ void PyrEntrance::animation() {
 	if (_gm->_state._pyraS == 8 && _gm->_state._pyraZ == 5) {
 		if (g_system->getMillis() >= _waitTime) { // around 1 minute
 			_vm->renderMessage(kStringPyramid4);
-			_gm->wait(_gm->_messageDuration, true);
+			_gm->wait(_gm->_messageDuration, true, true);
 			_vm->removeMessage();
 			_gm->_state._pyraZ++;
 			_gm->_state._pyraDirection = 0;
@@ -3789,14 +3789,14 @@ void Museum::onEntrance() {
 		_gm->_state._alarmOn = false;
 		_gm->_state._haste = false;
 		_vm->renderMessage(kStringMuseum1);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_gm->_state._sirenOn = false;
 		_vm->stopSound();
 		_vm->paletteFadeOut();
 		_vm->_system->fillScreen(kColorBlack);
 		_vm->_screen->setViewportBrightness(255);
 		_vm->renderMessage(kStringMuseum2);
-		_gm->wait(_gm->_messageDuration, true);
+		_gm->wait(_gm->_messageDuration, true, true);
 		_vm->removeMessage();
 		_vm->_screen->setViewportBrightness(0);
 		_vm->setCurrentImage(26);
@@ -3841,7 +3841,7 @@ bool Museum::interact(Action verb, Object &obj1, Object &obj2) {
 				}
 			} else
 				_vm->renderMessage(kStringMuseum12);
-			_gm->wait(_gm->_messageDuration, true);
+			_gm->wait(_gm->_messageDuration, true, true);
 			_vm->removeMessage();
 			_vm->paletteFadeOut();
 			_vm->_system->fillScreen(kColorBlack);
@@ -3849,7 +3849,7 @@ bool Museum::interact(Action verb, Object &obj1, Object &obj2) {
 			_vm->_screen->setGuiBrightness(255);
 			_vm->_screen->paletteBrightness();
 			_vm->renderMessage(kStringMuseum13);
-			_gm->wait(_gm->_messageDuration, true);
+			_gm->wait(_gm->_messageDuration, true, true);
 			_vm->removeMessage();
 			_vm->_screen->setViewportBrightness(0);
 			_vm->_screen->setGuiBrightness(0);
diff --git a/engines/supernova/supernova2/state.cpp b/engines/supernova/supernova2/state.cpp
index a364829335..472ede386f 100644
--- a/engines/supernova/supernova2/state.cpp
+++ b/engines/supernova/supernova2/state.cpp
@@ -21,6 +21,8 @@
  */
 
 #include "common/system.h"
+#include "common/config-manager.h"
+#include "common/text-to-speech.h"
 #include "graphics/cursorman.h"
 #include "graphics/palette.h"
 #include "gui/message.h"
@@ -933,16 +935,30 @@ bool GameManager2::talk(int mod1, int mod2, int rest, MessagePosition pos, int i
 	Common::KeyCode key = Common::KEYCODE_INVALID;
 	const Common::String& text = _vm->getGameString(id);
 
+	Common::TextToSpeechManager *ttsMan = nullptr;
+	if (ConfMan.getBool("tts_enabled"))
+		ttsMan = g_system->getTextToSpeechManager();
+
+	// Wait for the end of the current speech
+	if (ttsMan && ttsMan->isSpeaking())
+		wait(0, true, ttsMan);
+
 	_vm->renderMessage(text, pos);
 	int animation_count = (text.size() + 20) * (10 - rest) * _vm->_textSpeed / 400;
 	_restTime =  (text.size() + 20) * rest * _vm->_textSpeed / 400;
 
-	while (animation_count) {
+	// We only wait for TTS below if there is no rest time
+	if (_restTime)
+		ttsMan = nullptr;
+
+	while (animation_count || (ttsMan && ttsMan->isSpeaking())) {
 		if (mod1)
 			_vm->renderImage(mod1);
 
 		if (waitOnInput(2, key)) {
 			_vm->removeMessage();
+			if (ttsMan)
+				ttsMan->stop();
 			return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit();
 		}
 		if (mod2)
@@ -950,9 +966,12 @@ bool GameManager2::talk(int mod1, int mod2, int rest, MessagePosition pos, int i
 
 		if (waitOnInput(2, key)) {
 			_vm->removeMessage();
+			if (ttsMan)
+				ttsMan->stop();
 			return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit();
 		}
-		animation_count--;
+		if (animation_count)
+			animation_count--;
 	}
 	if (_restTime == 0)
 		_vm->removeMessage();
@@ -961,19 +980,28 @@ bool GameManager2::talk(int mod1, int mod2, int rest, MessagePosition pos, int i
 }
 
 bool GameManager2::talkRest(int mod1, int mod2, int rest) {
+	Common::TextToSpeechManager *ttsMan = nullptr;
+	if (ConfMan.getBool("tts_enabled"))
+		ttsMan = g_system->getTextToSpeechManager();
+
 	Common::KeyCode key = Common::KEYCODE_INVALID;
-	while (rest) {
+	while (rest || (ttsMan && ttsMan->isSpeaking())) {
 		_vm->renderImage(mod1);
 		if (waitOnInput(2, key)) {
 			_vm->removeMessage();
+			if (ttsMan)
+				ttsMan->stop();
 			return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit();
 		}
 		_vm->renderImage(mod2);
 		if (waitOnInput(2, key)) {
 			_vm->removeMessage();
+			if (ttsMan)
+				ttsMan->stop();
 			return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit();
 		}
-		rest--;
+		if (rest)
+			rest--;
 	}
 	return true;
 }




More information about the Scummvm-git-logs mailing list