[Scummvm-git-logs] scummvm master -> 39cfcab074a338555a380ca5286902c355dc90c0

elasota noreply at scummvm.org
Fri May 26 05:47:19 UTC 2023


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

Summary:
e86a033c2d VCRUISE: Better fix for exitToMenu state leak
6744da56cd VCRUISE: Release menu page when leaving the menu
40b4c54788 VCRUISE: Fix more UI labels.  Fix labels not using the correct code page.
529063ef44 VCRUISE: Adjust quit behavior in Schizm
f97c1d1687 VCRUISE: Fix missing menu music
8bb78cb2cd VCRUISE: Only stop subtitles on animation change if the subtitles are from an animation, rather than VO
a64279fe6f VCRUISE: Add detection for Reah English CD-ROM Project Two Interactive variation
39cfcab074 VCRUISE: Rework music mute behavior to make ScoreAlways op work


Commit: e86a033c2def16c5968a2c1c931b1b615e8c458c
    https://github.com/scummvm/scummvm/commit/e86a033c2def16c5968a2c1c931b1b615e8c458c
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:53-04:00

Commit Message:
VCRUISE: Better fix for exitToMenu state leak

Changed paths:
    engines/vcruise/runtime.cpp


diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index 566b55b9bc5..4ebbba22b14 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -2274,6 +2274,13 @@ bool Runtime::requireAvailableStack(uint n) {
 void Runtime::terminateScript() {
 	_scriptCallStack.clear();
 
+	// Collect any script env vars that affect script termination, then clear so this doesn't leak into
+	// future executions.
+	bool puzzleWasSet = _scriptEnv.puzzleWasSet;
+	bool exitToMenu = _scriptEnv.exitToMenu;
+
+	_scriptEnv = ScriptEnvironmentVars();
+
 	if (_gameState == kGameStateScript)
 		_gameState = kGameStateIdle;
 
@@ -2296,14 +2303,14 @@ void Runtime::terminateScript() {
 
 			// The circuit puzzle doesn't call puzzleDone unless you zoom back into the puzzle,
 			// which can cause the puzzle to leak.  Clean it up here instead.
-			if (!_scriptEnv.puzzleWasSet)
+			if (!puzzleWasSet)
 				_circuitPuzzle.reset();
 		}
 
 		changeToScreen(_roomNumber, _screenNumber);
 	}
 
-	if (_scriptEnv.exitToMenu && _gameState == kGameStateIdle) {
+	if (exitToMenu && _gameState == kGameStateIdle) {
 		changeToCursor(_cursors[kCursorArrow]);
 		if (_gameID == GID_REAH || _gameID == GID_SCHIZM)
 			changeToMenuPage(createMenuMain(_gameID == GID_SCHIZM));
@@ -5392,9 +5399,6 @@ void Runtime::restoreSaveGameSnapshot() {
 	_gameState = kGameStateWaitingForAnimation;
 	_isInGame = true;
 
-	// Clear script env vars so nothing triggers from terminateScript
-	_scriptEnv = ScriptEnvironmentVars();
-
 	_havePendingScreenChange = true;
 	_forceScreenChange = true;
 


Commit: 6744da56cd920f32693af3dc1077b22a5106c1ab
    https://github.com/scummvm/scummvm/commit/6744da56cd920f32693af3dc1077b22a5106c1ab
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:53-04:00

Commit Message:
VCRUISE: Release menu page when leaving the menu

Changed paths:
    engines/vcruise/runtime.cpp


diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index 4ebbba22b14..b6c9a892890 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -1192,6 +1192,10 @@ bool Runtime::runFrame() {
 			break;
 		case kGameStateMenu:
 			moreActions = _menuPage->run();
+
+			if (_gameState != kGameStateMenu)
+				_menuPage.reset();
+
 			break;
 		default:
 			error("Unknown game state");


Commit: 40b4c54788f739058c588947006e9e27973333c9
    https://github.com/scummvm/scummvm/commit/40b4c54788f739058c588947006e9e27973333c9
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:54-04:00

Commit Message:
VCRUISE: Fix more UI labels.  Fix labels not using the correct code page.

Changed paths:
    engines/vcruise/menu.cpp
    engines/vcruise/runtime.cpp
    engines/vcruise/runtime.h


diff --git a/engines/vcruise/menu.cpp b/engines/vcruise/menu.cpp
index 9c3e4b20610..2c628c222c1 100644
--- a/engines/vcruise/menu.cpp
+++ b/engines/vcruise/menu.cpp
@@ -666,11 +666,35 @@ ReahHelpMenuPage::ReahHelpMenuPage(bool isSchizm) : ReahMenuBarPage(kMenuBarButt
 }
 
 void ReahHelpMenuPage::addPageContents() {
+	Graphics::ManagedSurface *menuSurf = _menuInterface->getMenuSurface();
+
 	Graphics::Surface *helpBG = _menuInterface->getUIGraphic(12);
+
 	if (helpBG) {
-		_menuInterface->getMenuSurface()->blitFrom(*helpBG, Common::Point(0, 44));
+		menuSurf->blitFrom(*helpBG, Common::Point(0, 44));
 		_menuInterface->commitRect(Common::Rect(0, 44, helpBG->w, 44 + helpBG->h));
 	}
+
+	if (_isSchizm) {
+		for (int htX = 0; htX < 2; htX++) {
+			for (int htY = 0; htY < 6; htY++) {
+				Common::String labelID = Common::String::format("szData012_%02i", htX * 6 + htY + 2);
+
+				Common::Point topLeft = Common::Point(htX * 280 + 60, htY * 25 + 140);
+				Common::Rect rect(topLeft.x, topLeft.y, topLeft.x + 280, topLeft.y + 25);
+
+				_menuInterface->drawLabel(menuSurf, labelID, rect);
+
+				_menuInterface->commitRect(rect);
+			}
+		}
+
+		Common::Rect titleRect(240, 80, 400, 124);
+
+		_menuInterface->drawLabel(menuSurf, "szData012_01", titleRect);
+
+		_menuInterface->commitRect(titleRect);
+	}
 }
 
 ReahSoundMenuPage::ReahSoundMenuPage(bool isSchizm) : ReahMenuBarPage(kMenuBarButtonSound, isSchizm), _soundChecked(false), _musicChecked(false), _subtitleChecked(false) {
@@ -1058,6 +1082,13 @@ void ReahSchizmMainMenuPage::start() {
 		_buttons.push_back(Button(buttonGraphic, graphicRect, screenRect, interactiveRect, Common::Point(buttonSize.x, 0), isEnabled, buttonStates[i]));
 	}
 
+	if (_isSchizm) {
+		Common::Rect copyrightRect = Common::Rect(6, 456, 308, 480);
+
+		_menuInterface->drawLabel(menuSurf, "szData000_01", copyrightRect);
+		_menuInterface->commitRect(copyrightRect);
+	}
+
 	ReahSchizmMenuPage::start();
 }
 
diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index b6c9a892890..745bec68f47 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -1388,7 +1388,21 @@ void Runtime::drawLabel(Graphics::ManagedSurface *surface, const Common::String
 	int strWidth = font->getStringWidth(text);
 	int strHeight = font->getFontHeight();
 
-	Common::Point textPos(contentRect.left + (contentRect.width() - strWidth) / 2, contentRect.top + (static_cast<int>(labelDef.graphicHeight) - strHeight) / 2);
+	Common::Point textPos;
+
+	switch (styleIt->_value.alignment % 10u) {
+	case 1:
+		textPos.x = contentRect.left + (contentRect.width() - strWidth) / 2;
+		break;
+	case 2:
+		textPos.x = contentRect.left - strWidth;
+		break;
+	default:
+		textPos.x = contentRect.left;
+		break;
+	}
+
+	textPos.y = contentRect.top + (static_cast<int>(labelDef.graphicHeight) - strHeight) / 2;
 
 	if (shadowColorRGB != 0) {
 		Common::Point shadowPos = textPos + Common::Point(shadowOffset, shadowOffset);
@@ -4830,7 +4844,7 @@ bool Runtime::loadSubtitles(Common::CodePage codePage) {
 				if (textToken[0] != '\"' || textToken[textToken.size() - 1] != '\"')
 					continue;
 
-				_locStrings[kv.key] = textToken.substr(1, textToken.size() - 2);
+				_locStrings[kv.key] = textToken.substr(1, textToken.size() - 2).decode(codePage).encode(Common::kUtf8);
 			} else if (isFontData) {
 				if (tokens.size() != 9)
 					continue;
@@ -4849,7 +4863,7 @@ bool Runtime::loadSubtitles(Common::CodePage codePage) {
 					sscanf(tokens[4].c_str(), "%u", &tsDef.unknown3) &&
 					sscanf(tokens[5].c_str(), "0x%x", &tsDef.colorRGB) &&
 					sscanf(tokens[6].c_str(), "0x%x", &tsDef.shadowColorRGB) &&
-					sscanf(tokens[7].c_str(), "%u", &tsDef.unknown4) &&
+					sscanf(tokens[7].c_str(), "%u", &tsDef.alignment) &&
 					sscanf(tokens[8].c_str(), "%u", &tsDef.unknown5)) {
 					_locTextStyles[kv.key] = tsDef;
 				}
diff --git a/engines/vcruise/runtime.h b/engines/vcruise/runtime.h
index b2d0a138bee..85cccd2d06f 100644
--- a/engines/vcruise/runtime.h
+++ b/engines/vcruise/runtime.h
@@ -533,7 +533,7 @@ struct TextStyleDef {
 	uint unknown3;	// Seems to always be 0 for English, other values for other languages
 	uint colorRGB;
 	uint shadowColorRGB;
-	uint unknown4;
+	uint alignment;	// Modulo 10 seems to be alignment: 0 = left, 1 = center, 2 = right
 	uint unknown5;	// Possibly drop shadow offset
 };
 


Commit: 529063ef4405f27dde718f065db275ae870519da
    https://github.com/scummvm/scummvm/commit/529063ef4405f27dde718f065db275ae870519da
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:54-04:00

Commit Message:
VCRUISE: Adjust quit behavior in Schizm

Changed paths:
    engines/vcruise/menu.cpp
    engines/vcruise/menu.h
    engines/vcruise/runtime.cpp


diff --git a/engines/vcruise/menu.cpp b/engines/vcruise/menu.cpp
index 2c628c222c1..38f8a0c9344 100644
--- a/engines/vcruise/menu.cpp
+++ b/engines/vcruise/menu.cpp
@@ -582,7 +582,10 @@ void ReahMenuBarPage::onButtonClicked(uint button, bool &outChangedState) {
 		outChangedState = true;
 		break;
 	case kMenuBarButtonQuit:
-		_menuInterface->changeMenu(new ReahQuitMenuPage(_isSchizm));
+		if (_isSchizm && !_menuInterface->isInGame())
+			_menuInterface->changeMenu(new ReahSchizmMainMenuPage(_isSchizm));
+		else
+			_menuInterface->changeMenu(new ReahQuitMenuPage(_isSchizm));
 		outChangedState = true;
 		break;
 
@@ -980,9 +983,12 @@ void ReahQuitMenuPage::addPageContents() {
 void ReahQuitMenuPage::onButtonClicked(uint button, bool &outChangedState) {
 	ReahMenuBarPage::onButtonClicked(button, outChangedState);
 
-	if (button == kButtonYes)
-		_menuInterface->quitGame();
-	else if (button == kButtonNo)
+	if (button == kButtonYes) {
+		if (_isSchizm && _menuInterface->isInGame())
+			_menuInterface->changeMenu(new ReahSchizmMainMenuPage(_isSchizm));
+		else
+			_menuInterface->quitGame();
+	} else if (button == kButtonNo)
 		onButtonClicked(kMenuBarButtonReturn, outChangedState);
 }
 
@@ -1119,7 +1125,6 @@ void ReahSchizmMainMenuPage::onButtonClicked(uint button, bool &outChangedState)
 		break;
 
 	case kButtonQuit:
-		// In Schizm, quitting from the main menu doesn't prompt
 		if (_isSchizm)
 			_menuInterface->quitGame();
 		else
diff --git a/engines/vcruise/menu.h b/engines/vcruise/menu.h
index c4d238005c9..9d7169b0ec0 100644
--- a/engines/vcruise/menu.h
+++ b/engines/vcruise/menu.h
@@ -55,6 +55,7 @@ public:
 	virtual Graphics::ManagedSurface *getMenuSurface() const = 0;
 	virtual bool hasDefaultSave() const = 0;
 	virtual bool hasAnySave() const = 0;
+	virtual bool isInGame() const = 0;
 	virtual Common::Point getMouseCoordinate() const = 0;
 	virtual void restartGame() const = 0;
 	virtual void goToCredits() const = 0;
diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index 745bec68f47..f8f2fc2dd53 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -71,6 +71,7 @@ public:
 	Graphics::ManagedSurface *getMenuSurface() const override;
 	bool hasDefaultSave() const override;
 	bool hasAnySave() const override;
+	bool isInGame() const override;
 	Common::Point getMouseCoordinate() const override;
 	void restartGame() const override;
 	void goToCredits() const override;
@@ -115,6 +116,10 @@ bool RuntimeMenuInterface::hasAnySave() const {
 	return static_cast<VCruiseEngine *>(g_engine)->hasAnySave();
 }
 
+bool RuntimeMenuInterface::isInGame() const {
+	return _runtime->_isInGame;
+}
+
 Common::Point RuntimeMenuInterface::getMouseCoordinate() const {
 	return _runtime->_mousePos;
 }


Commit: f97c1d1687f47a1b083f3490e7ce0ff62974379d
    https://github.com/scummvm/scummvm/commit/f97c1d1687f47a1b083f3490e7ce0ff62974379d
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:54-04:00

Commit Message:
VCRUISE: Fix missing menu music

Changed paths:
    engines/vcruise/runtime.cpp


diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index f8f2fc2dd53..1b1edfb304e 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -2335,6 +2335,13 @@ void Runtime::terminateScript() {
 
 	if (exitToMenu && _gameState == kGameStateIdle) {
 		changeToCursor(_cursors[kCursorArrow]);
+
+		if (_gameID == GID_SCHIZM && _musicActive) {
+			_scoreTrack = "music99";
+			_scoreSection = "start";
+			startScoreSection();
+		}
+
 		if (_gameID == GID_REAH || _gameID == GID_SCHIZM)
 			changeToMenuPage(createMenuMain(_gameID == GID_SCHIZM));
 		else


Commit: 8bb78cb2cd8d60237a38be3197af0affa428cfa6
    https://github.com/scummvm/scummvm/commit/8bb78cb2cd8d60237a38be3197af0affa428cfa6
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:54-04:00

Commit Message:
VCRUISE: Only stop subtitles on animation change if the subtitles are from an animation, rather than VO

Changed paths:
    engines/vcruise/runtime.cpp
    engines/vcruise/runtime.h


diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index 1b1edfb304e..598299f3350 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -1016,7 +1016,8 @@ Runtime::Runtime(OSystem *system, Audio::Mixer *mixer, const Common::FSNode &roo
 	  _havePendingCompletionCheck(false), _havePendingPlayAmbientSounds(false), _ambientSoundFinishTime(0), _escOn(false), _debugMode(false), _fastAnimationMode(false),
 	  _musicTrack(0), _musicActive(true), _scoreSectionEndTime(0), _musicVolume(getDefaultSoundVolume()), _musicVolumeRampStartTime(0), _musicVolumeRampStartVolume(0), _musicVolumeRampRatePerMSec(0), _musicVolumeRampEnd(0),
 	  _panoramaDirectionFlags(0),
-	  _loadedAnimation(0), _loadedAnimationHasSound(false), _animTerminateAtStartOfFrame(true), _animPendingDecodeFrame(0), _animDisplayingFrame(0), _animFirstFrame(0), _animLastFrame(0), _animStopFrame(0), _animVolume(getDefaultSoundVolume()),
+	  _loadedAnimation(0), _loadedAnimationHasSound(false),
+	  _animTerminateAtStartOfFrame(true), _animPendingDecodeFrame(0), _animDisplayingFrame(0), _animFirstFrame(0), _animLastFrame(0), _animStopFrame(0), _animVolume(getDefaultSoundVolume()),
 	  _animStartTime(0), _animFramesDecoded(0), _animDecoderState(kAnimDecoderStateStopped),
 	  _animPlayWhileIdle(false), _idleLockInteractions(false), _idleIsOnInteraction(false), _idleIsOnOpenCircuitPuzzleLink(false), _idleIsCircuitPuzzleLinkDown(false),
 	  _idleHaveClickInteraction(false), _idleHaveDragInteraction(false), _idleInteractionID(0), _haveIdleStaticAnimation(false),
@@ -1026,7 +1027,7 @@ Runtime::Runtime(OSystem *system, Audio::Mixer *mixer, const Common::FSNode &roo
 	  _panoramaState(kPanoramaStateInactive),
 	  _listenerX(0), _listenerY(0), _listenerAngle(0), _soundCacheIndex(0),
 	  _isInGame(false),
-	  _subtitleFont(nullptr), _isDisplayingSubtitles(false), _languageIndex(0), _defaultLanguage(defaultLanguage),
+	  _subtitleFont(nullptr), _isDisplayingSubtitles(false), _isSubtitleSourceAnimation(false), _languageIndex(0), _defaultLanguage(defaultLanguage),
 	  _isCDVariant(false) {
 
 	for (uint i = 0; i < kNumDirections; i++) {
@@ -1989,6 +1990,7 @@ void Runtime::continuePlayingAnimation(bool loop, bool useStopFrame, bool &outAn
 
 				_subtitleQueue.clear();
 				_isDisplayingSubtitles = false;
+				_isSubtitleSourceAnimation = true;
 
 				SubtitleQueueItem queueItem;
 				queueItem.startTime = millis;
@@ -3561,7 +3563,8 @@ void Runtime::changeAnimation(const AnimationDef &animDef, uint initialFrame, bo
 
 		_loadedAnimationHasSound = (_animDecoder->getAudioTrackCount() > 0);
 
-		stopSubtitles();
+		if (_isSubtitleSourceAnimation)
+			stopSubtitles();
 	}
 
 	if (_animDecoderState == kAnimDecoderStatePlaying) {
@@ -3771,6 +3774,7 @@ void Runtime::triggerWaveSubtitles(const SoundInstance &snd, const Common::Strin
 void Runtime::stopSubtitles() {
 	_subtitleQueue.clear();
 	_isDisplayingSubtitles = false;
+	_isSubtitleSourceAnimation = false;
 	redrawTray();
 }
 
diff --git a/engines/vcruise/runtime.h b/engines/vcruise/runtime.h
index 85cccd2d06f..d6d1a8c365a 100644
--- a/engines/vcruise/runtime.h
+++ b/engines/vcruise/runtime.h
@@ -1323,6 +1323,7 @@ private:
 	Common::HashMap<Common::String, SubtitleDef> _waveSubtitles;
 	Common::Array<SubtitleQueueItem> _subtitleQueue;
 	bool _isDisplayingSubtitles;
+	bool _isSubtitleSourceAnimation;
 
 	Common::HashMap<Common::String, Common::String> _locStrings;
 	Common::HashMap<Common::String, TextStyleDef> _locTextStyles;


Commit: a64279fe6ff32248bcbf5923da4e1e00412e5983
    https://github.com/scummvm/scummvm/commit/a64279fe6ff32248bcbf5923da4e1e00412e5983
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:54-04:00

Commit Message:
VCRUISE: Add detection for Reah English CD-ROM Project Two Interactive variation

Changed paths:
    engines/vcruise/detection_tables.h


diff --git a/engines/vcruise/detection_tables.h b/engines/vcruise/detection_tables.h
index dd59b31aa8c..01169d22077 100644
--- a/engines/vcruise/detection_tables.h
+++ b/engines/vcruise/detection_tables.h
@@ -71,6 +71,20 @@ static const VCruiseGameDescription gameDescriptions[] = {
 		GID_REAH,
 		Common::EN_ANY,
 	},
+	{ // Reah: Face the Unknown, English 6 CD Version (Project Two Interactive variation)
+		{
+			"reah",
+			"English CD",
+			AD_ENTRY2s("Reah.exe", "77bc7f7819cdd443f52b193529138c87", 305664,
+					   "0170_b.wav", "36c0bf57ab5a748ef6699a159195b3ae", 124356),
+			Common::UNK_LANG,
+			Common::kPlatformWindows,
+			ADGF_TESTING,
+			GUIO0()
+		},
+		GID_REAH,
+		Common::EN_ANY,
+	},
 	{ // Reah: Face the Unknown, German 6 CD Version
 		{
 			"reah",


Commit: 39cfcab074a338555a380ca5286902c355dc90c0
    https://github.com/scummvm/scummvm/commit/39cfcab074a338555a380ca5286902c355dc90c0
Author: elasota (ejlasota at gmail.com)
Date: 2023-05-26T01:46:54-04:00

Commit Message:
VCRUISE: Rework music mute behavior to make ScoreAlways op work

Changed paths:
    engines/vcruise/menu.cpp
    engines/vcruise/menu.h
    engines/vcruise/runtime.cpp
    engines/vcruise/runtime.h
    engines/vcruise/vcruise.cpp


diff --git a/engines/vcruise/menu.cpp b/engines/vcruise/menu.cpp
index 38f8a0c9344..5beb5a7e637 100644
--- a/engines/vcruise/menu.cpp
+++ b/engines/vcruise/menu.cpp
@@ -901,7 +901,14 @@ void ReahSoundMenuPage::applyMusicVolume() const {
 	ConfMan.setInt("music_volume", vol, ConfMan.getActiveDomainName());
 	ConfMan.setBool("vcruise_mute_music", !_musicChecked, ConfMan.getActiveDomainName());
 
+	// Try to avoid changing music volume right before stopping music to avoid an audio pop
+	if (!_musicChecked)
+		_menuInterface->setMusicMute(true);
+
 	g_engine->syncSoundSettings();
+
+	if (_musicChecked)
+		_menuInterface->setMusicMute(false);
 }
 
 ReahQuitMenuPage::ReahQuitMenuPage(bool isSchizm) : ReahMenuBarPage(kMenuBarButtonQuit, isSchizm) {
diff --git a/engines/vcruise/menu.h b/engines/vcruise/menu.h
index 9d7169b0ec0..df5b7d73e13 100644
--- a/engines/vcruise/menu.h
+++ b/engines/vcruise/menu.h
@@ -63,6 +63,7 @@ public:
 	virtual void quitGame() const = 0;
 	virtual bool canSave() const = 0;
 	virtual bool reloadFromCheckpoint() const = 0;
+	virtual void setMusicMute(bool muted) const = 0;
 
 	virtual void drawLabel(Graphics::ManagedSurface *surface, const Common::String &labelID, const Common::Rect &contentRect) const = 0;
 };
diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index 598299f3350..de75670eb0e 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -79,6 +79,7 @@ public:
 	void quitGame() const override;
 	bool canSave() const override;
 	bool reloadFromCheckpoint() const override;
+	void setMusicMute(bool muted) const override;
 
 	void drawLabel(Graphics::ManagedSurface *surface, const Common::String &labelID, const Common::Rect &contentRect) const override;
 
@@ -165,6 +166,10 @@ bool RuntimeMenuInterface::reloadFromCheckpoint() const {
 	return true;
 }
 
+void RuntimeMenuInterface::setMusicMute(bool muted) const {
+	_runtime->setMusicMute(muted);
+}
+
 void RuntimeMenuInterface::drawLabel(Graphics::ManagedSurface *surface, const Common::String &labelID, const Common::Rect &contentRect) const {
 	_runtime->drawLabel(surface, labelID, contentRect);
 }
@@ -739,7 +744,7 @@ void SaveGameSwappableState::Sound::read(Common::ReadStream *stream, uint saveGa
 }
 
 SaveGameSwappableState::SaveGameSwappableState() : roomNumber(0), screenNumber(0), direction(0), havePendingPostSwapScreenReset(false),
-												   musicTrack(0), musicVolume(100), musicActive(true), animVolume(100),
+												   musicTrack(0), musicVolume(100), musicActive(true), musicMuteDisabled(false), animVolume(100),
 												   loadedAnimation(0), animDisplayingFrame(0) {
 }
 
@@ -774,6 +779,7 @@ void SaveGameSnapshot::write(Common::WriteStream *stream) const {
 		writeString(stream, states[sti]->scoreTrack);
 		writeString(stream, states[sti]->scoreSection);
 		stream->writeByte(states[sti]->musicActive ? 1 : 0);
+		stream->writeByte(states[sti]->musicMuteDisabled ? 1 : 0);
 
 		stream->writeUint32BE(states[sti]->loadedAnimation);
 		stream->writeUint32BE(states[sti]->animDisplayingFrame);
@@ -898,6 +904,11 @@ LoadGameOutcome SaveGameSnapshot::read(Common::ReadStream *stream) {
 			states[sti]->musicActive = true;
 		}
 
+		if (saveVersion >= 9)
+			states[sti]->musicMuteDisabled = (stream->readByte() != 0);
+		else
+			states[sti]->musicMuteDisabled = false;
+
 		states[sti]->loadedAnimation = stream->readUint32BE();
 		states[sti]->animDisplayingFrame = stream->readUint32BE();
 
@@ -1014,7 +1025,8 @@ Runtime::Runtime(OSystem *system, Audio::Mixer *mixer, const Common::FSNode &roo
 	  _haveHorizPanAnimations(false), _loadedRoomNumber(0), _activeScreenNumber(0),
 	  _gameState(kGameStateBoot), _gameID(gameID), _havePendingScreenChange(false), _forceScreenChange(false), _havePendingPreIdleActions(false), _havePendingReturnToIdleState(false), _havePendingPostSwapScreenReset(false),
 	  _havePendingCompletionCheck(false), _havePendingPlayAmbientSounds(false), _ambientSoundFinishTime(0), _escOn(false), _debugMode(false), _fastAnimationMode(false),
-	  _musicTrack(0), _musicActive(true), _scoreSectionEndTime(0), _musicVolume(getDefaultSoundVolume()), _musicVolumeRampStartTime(0), _musicVolumeRampStartVolume(0), _musicVolumeRampRatePerMSec(0), _musicVolumeRampEnd(0),
+	  _musicTrack(0), _musicActive(true), _musicMute(false), _musicMuteDisabled(false),
+	  _scoreSectionEndTime(0), _musicVolume(getDefaultSoundVolume()), _musicVolumeRampStartTime(0), _musicVolumeRampStartVolume(0), _musicVolumeRampRatePerMSec(0), _musicVolumeRampEnd(0),
 	  _panoramaDirectionFlags(0),
 	  _loadedAnimation(0), _loadedAnimationHasSound(false),
 	  _animTerminateAtStartOfFrame(true), _animPendingDecodeFrame(0), _animDisplayingFrame(0), _animFirstFrame(0), _animLastFrame(0), _animStopFrame(0), _animVolume(getDefaultSoundVolume()),
@@ -1229,6 +1241,11 @@ bool Runtime::bootGame(bool newGame) {
 	if (!ConfMan.hasKey("vcruise_increase_drag_distance") || ConfMan.hasKey("vcruise_increase_drag_distance"))
 		_lmbDragTolerance = 3;
 
+	if (ConfMan.hasKey("vcruise_mute_music") && !ConfMan.getBool("vcruise_mute_music"))
+		_musicMute = true;
+	else
+		_musicMute = false;
+
 	debug(1, "Booting V-Cruise game...");
 	loadIndex();
 	debug(1, "Index loaded OK");
@@ -2502,12 +2519,17 @@ void Runtime::processUniversalKeymappedEvents(KeymappedEvent evt) {
 	const int soundSettingGranularity = 25;
 
 	switch (evt) {
-	case kKeymappedEventMusicToggle:
-		ConfMan.setBool("vcruise_mute_music", !(ConfMan.hasKey("vcruise_mute_music")) || !(ConfMan.getBool("vcruise_mute_music")), ConfMan.getActiveDomainName());
-		g_engine->syncSoundSettings();
-		if (_menuPage)
-			_menuPage->onSettingsChanged();
-		break;
+	case kKeymappedEventMusicToggle: {
+			if (ConfMan.hasKey("vcruise_mute_music") && !ConfMan.getBool("vcruise_mute_music"))
+				setMusicMute(false);
+			else
+				setMusicMute(true);
+
+			ConfMan.setBool("vcruise_mute_music", _musicMute, ConfMan.getActiveDomainName());
+
+			if (_menuPage)
+				_menuPage->onSettingsChanged();
+		} break;
 	case kKeymappedEventMusicVolumeUp: {
 			int newVol = ConfMan.getInt("music_volume") + soundSettingGranularity;
 			if (newVol > Audio::Mixer::kMaxMixerVolume)
@@ -3443,6 +3465,9 @@ void Runtime::changeMusicTrack(int track) {
 	if (!_musicActive)
 		return;
 
+	if (_musicMute && !_musicMuteDisabled)
+		return;
+
 	Common::String wavFileName = Common::String::format("Sfx/Music-%02i.wav", static_cast<int>(track));
 	Common::File *wavFile = new Common::File();
 	if (wavFile->open(wavFileName)) {
@@ -3460,10 +3485,14 @@ void Runtime::changeMusicTrack(int track) {
 
 void Runtime::startScoreSection() {
 	_musicPlayer.reset();
+	_scoreSectionEndTime = 0;
 
 	if (!_musicActive)
 		return;
 
+	if (_musicMute && !_musicMuteDisabled)
+		return;
+
 #ifdef USE_VORBIS
 	Common::HashMap<Common::String, ScoreTrackDef>::const_iterator trackIt = _scoreDefs.find(_scoreTrack);
 	if (trackIt != _scoreDefs.end()) {
@@ -3498,6 +3527,31 @@ void Runtime::startScoreSection() {
 #endif
 }
 
+void Runtime::setMusicMute(bool muted) {
+	if (muted == _musicMute)
+		return;
+
+	bool prevIsActuallyMuted = (_musicMute && !_musicMuteDisabled);
+
+	_musicMute = muted;
+
+	bool isActuallyMuted = (_musicMute && !_musicMuteDisabled);
+
+	if (prevIsActuallyMuted != isActuallyMuted) {
+		if (isActuallyMuted) {
+			// Became muted
+			_musicPlayer.reset();
+			_scoreSectionEndTime = 0;
+		} else {
+			// Became unmuted
+			if (_gameID == GID_REAH)
+				changeMusicTrack(_musicTrack);
+			else if (_gameID == GID_SCHIZM)
+				startScoreSection();
+		}
+	}
+}
+
 void Runtime::changeAnimation(const AnimationDef &animDef, bool consumeFPSOverride) {
 	changeAnimation(animDef, animDef.firstFrame, consumeFPSOverride);
 }
@@ -3905,6 +3959,22 @@ void Runtime::updateSounds(uint32 timestamp) {
 		if (newVolume == _musicVolumeRampEnd)
 			_musicVolumeRampRatePerMSec = 0;
 	}
+
+	if (_scoreSectionEndTime != 0 && _scoreSectionEndTime < timestamp) {
+
+#ifdef USE_VORBIS
+		Common::HashMap<Common::String, ScoreTrackDef>::const_iterator trackIt = _scoreDefs.find(_scoreTrack);
+		if (trackIt != _scoreDefs.end()) {
+			const ScoreTrackDef::ScoreSectionMap_t &sectionMap = trackIt->_value.sections;
+
+			ScoreTrackDef::ScoreSectionMap_t::const_iterator sectionIt = sectionMap.find(_scoreSection);
+			if (sectionIt != sectionMap.end())
+				_scoreSection = sectionIt->_value.nextSection;
+
+			startScoreSection();
+		}
+#endif
+	}
 }
 
 void Runtime::updateSubtitles() {
@@ -5258,6 +5328,7 @@ void Runtime::recordSaveGameSnapshot() {
 
 	mainState->musicTrack = _musicTrack;
 	mainState->musicActive = _musicActive;
+	mainState->musicMuteDisabled = _musicMuteDisabled;
 
 	mainState->musicVolume = _musicVolume;
 
@@ -5369,6 +5440,7 @@ void Runtime::restoreSaveGameSnapshot() {
 	_musicVolumeRampEnd = _musicVolume;
 
 	_musicActive = mainState->musicActive;
+	_musicMuteDisabled = mainState->musicMuteDisabled;
 
 	if (_gameID == GID_REAH)
 		changeMusicTrack(mainState->musicTrack);
@@ -6957,13 +7029,22 @@ void Runtime::scriptOpMusicPlayScore(ScriptArg_t arg) {
 }
 
 void Runtime::scriptOpScoreAlways(ScriptArg_t arg) {
-	// This op should temporarily disable music mute
-	warning("ScoreAlways opcode isn't implemented yet");
+	assert(_gameID == GID_SCHIZM);
+
+	_musicMuteDisabled = true;
+
+	// We don't call startScoreSection here because ScoreAlways is always followed by a PlayScore
+	// that triggers the actual music, and we don't want to play any amount of the score that's about
+	// to be disabled.  PlayScore will call startScoreSection after changing to the correct section.
 }
 
 void Runtime::scriptOpScoreNormal(ScriptArg_t arg) {
-	// This op should re-enable music mute
-	warning("ScoreNormal opcode isn't implemented yet");
+	_musicMuteDisabled = false;
+
+	if (_musicMute) {
+		_musicPlayer.reset();
+		_scoreSectionEndTime = 0;
+	}
 }
 
 void Runtime::scriptOpSndPlay(ScriptArg_t arg) {
diff --git a/engines/vcruise/runtime.h b/engines/vcruise/runtime.h
index d6d1a8c365a..585571f848e 100644
--- a/engines/vcruise/runtime.h
+++ b/engines/vcruise/runtime.h
@@ -437,6 +437,7 @@ struct SaveGameSwappableState {
 	Common::String scoreTrack;
 	Common::String scoreSection;
 	bool musicActive;
+	bool musicMuteDisabled;
 
 	int32 musicVolume;
 	int32 animVolume;
@@ -453,7 +454,7 @@ struct SaveGameSnapshot {
 	LoadGameOutcome read(Common::ReadStream *stream);
 
 	static const uint kSaveGameIdentifier = 0x53566372;
-	static const uint kSaveGameCurrentVersion = 8;
+	static const uint kSaveGameCurrentVersion = 9;
 	static const uint kSaveGameEarliestSupportedVersion = 2;
 	static const uint kMaxStates = 2;
 
@@ -837,6 +838,7 @@ private:
 
 	void changeMusicTrack(int musicID);
 	void startScoreSection();
+	void setMusicMute(bool muted);
 
 	void changeAnimation(const AnimationDef &animDef, bool consumeFPSOverride);
 	void changeAnimation(const AnimationDef &animDef, uint initialFrame, bool consumeFPSOverride);
@@ -1194,6 +1196,8 @@ private:
 	int _musicTrack;
 	int32 _musicVolume;
 	bool _musicActive;
+	bool _musicMute;
+	bool _musicMuteDisabled;
 
 	Common::String _scoreTrack;
 	Common::String _scoreSection;
diff --git a/engines/vcruise/vcruise.cpp b/engines/vcruise/vcruise.cpp
index 2ca0dd5f5f7..d80e1e0fe67 100644
--- a/engines/vcruise/vcruise.cpp
+++ b/engines/vcruise/vcruise.cpp
@@ -240,16 +240,14 @@ void VCruiseEngine::syncSoundSettings() {
 	if (!speechMute)
 		speechMute = ConfMan.getBool("speech_mute");
 
-	bool muteMusic = false;
-	if (ConfMan.hasKey("vcruise_mute_music"))
-		muteMusic = ConfMan.getBool("vcruise_mute_music");
-
 	bool muteSound = ConfMan.getBool("vcruise_mute_sound");
 	if (ConfMan.hasKey("vcruise_mute_sound"))
 		muteSound = ConfMan.getBool("vcruise_mute_sound");
 
+	// We don't mute music here because Schizm has a special behavior that bypasses music mute when using one
+	// of the ships to transition zones.
 	_mixer->muteSoundType(Audio::Mixer::kPlainSoundType, mute || muteSound);
-	_mixer->muteSoundType(Audio::Mixer::kMusicSoundType, mute || muteMusic);
+	_mixer->muteSoundType(Audio::Mixer::kMusicSoundType, mute);
 	_mixer->muteSoundType(Audio::Mixer::kSFXSoundType, mute || muteSound);
 	_mixer->muteSoundType(Audio::Mixer::kSpeechSoundType, speechMute || muteSound);
 




More information about the Scummvm-git-logs mailing list