[Scummvm-git-logs] scummvm master -> 7abf22dc06b24ae47d82161e096d6a6d674d036c

elasota noreply at scummvm.org
Mon Aug 5 06:44:29 UTC 2024


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

Summary:
993c8ff23c MTROPOLIS: Demote failed number parse to a warning
7abf22dc06 MTROPOLIS: Process returns before scene transitions even if the scene transition was triggered first


Commit: 993c8ff23c396fbb8d48b55d7369bf8f04df3242
    https://github.com/scummvm/scummvm/commit/993c8ff23c396fbb8d48b55d7369bf8f04df3242
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-08-05T02:44:00-04:00

Commit Message:
MTROPOLIS: Demote failed number parse to a warning

Changed paths:
    engines/mtropolis/miniscript.cpp


diff --git a/engines/mtropolis/miniscript.cpp b/engines/mtropolis/miniscript.cpp
index 313a969883f..be101e9a26c 100644
--- a/engines/mtropolis/miniscript.cpp
+++ b/engines/mtropolis/miniscript.cpp
@@ -1259,7 +1259,7 @@ MiniscriptInstructionOutcome BuiltinFunc::executeStr2Num(MiniscriptThread *threa
 
 #ifdef MTROPOLIS_DEBUG_ENABLE
 		if (Debugger *debugger = thread->getRuntime()->debugGetDebugger())
-			debugger->notify(kDebugSeverityError, Common::String::format("Failed to parse '%s' as a number", str.c_str()));
+			debugger->notify(kDebugSeverityWarning, Common::String::format("Failed to parse '%s' as a number", str.c_str()));
 #endif
 
 		result = 0.0;


Commit: 7abf22dc06b24ae47d82161e096d6a6d674d036c
    https://github.com/scummvm/scummvm/commit/7abf22dc06b24ae47d82161e096d6a6d674d036c
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-08-05T02:44:00-04:00

Commit Message:
MTROPOLIS: Process returns before scene transitions even if the scene transition was triggered first

Changed paths:
    engines/mtropolis/modifiers.cpp
    engines/mtropolis/runtime.cpp
    engines/mtropolis/runtime.h


diff --git a/engines/mtropolis/modifiers.cpp b/engines/mtropolis/modifiers.cpp
index be0470eaf79..aecd38a350f 100644
--- a/engines/mtropolis/modifiers.cpp
+++ b/engines/mtropolis/modifiers.cpp
@@ -2735,7 +2735,7 @@ bool ReturnModifier::respondsToEvent(const Event &evt) const {
 }
 
 VThreadState ReturnModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
-	runtime->addSceneStateTransition(HighLevelSceneTransition(nullptr, HighLevelSceneTransition::kTypeReturn, false, false));
+	runtime->addSceneReturn();
 	return kVThreadReturn;
 }
 
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index 93ed0c71988..7e95247aff9 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -4667,8 +4667,8 @@ Runtime::Runtime(OSystem *system, Audio::Mixer *mixer, ISaveUIProvider *saveProv
 	  _cachedMousePosition(Common::Point(0, 0)), _realMousePosition(Common::Point(0, 0)), _trackedMouseOutside(false),
 	  _forceCursorRefreshOnce(true), _autoResetCursor(false), _haveModifierOverrideCursor(false), _haveCursorElement(false), _sceneGraphChanged(false), _isQuitting(false),
 	  _collisionCheckTime(0), /*_elementCursorUpdateTime(0), */_defaultVolumeState(true), _activeSceneTransitionEffect(nullptr), _sceneTransitionStartTime(0), _sceneTransitionEndTime(0),
-	  _sharedSceneWasSetExplicitly(false), _modifierOverrideCursorID(0), _subtitleRenderer(subRenderer), _multiClickStartTime(0), _multiClickInterval(500), _multiClickCount(0), _numMouseBlockers(0)
-{
+	  _sharedSceneWasSetExplicitly(false), _modifierOverrideCursorID(0), _subtitleRenderer(subRenderer), _multiClickStartTime(0), _multiClickInterval(500), _multiClickCount(0), _numMouseBlockers(0),
+	  _pendingSceneReturnCount(0) {
 	_random.reset(new Common::RandomSource("mtropolis"));
 
 	_vthread.reset(new VThread());
@@ -4957,6 +4957,20 @@ bool Runtime::runFrame() {
 			continue;
 		}
 
+		// Scene returns are processed before transitions even if the transition was
+		// executed first.  SPQR requires this behavior to properly return from the
+		// menu, since it sets a scene change via WorldManager to the restored scene
+		// and then triggers a Return modifier which would return to the last scene
+		// that added to the return list, which in this case is the scene that was
+		// active before opening the menu.
+		if (_pendingSceneReturnCount > 0) {
+			_pendingSceneReturnCount--;
+
+			executeHighLevelSceneReturn();
+			_sceneGraphChanged = true;
+			continue;
+		}
+
 		if (_pendingSceneTransitions.size() > 0) {
 			HighLevelSceneTransition transition = _pendingSceneTransitions[0];
 			_pendingSceneTransitions.remove_at(0);
@@ -5584,52 +5598,56 @@ void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structura
 	executeSharedScenePostSceneChangeActions();
 }
 
-void Runtime::executeHighLevelSceneTransition(const HighLevelSceneTransition &transition) {
+void Runtime::executeHighLevelSceneReturn() {
 	if (_sceneStack.size() == 0)
 		_sceneStack.resize(1); // Reserve shared scene slot
 
-	// This replicates a bunch of quirks/bugs of mTropolis's scene transition logic,
-	// see the accompanying notes file.  There are probably some missing cases related to
-	// shared scene, calling return/scene transitions during scene deactivation, or other
-	// edge cases that hopefully no games actually do!
-	switch (transition.type) {
-	case HighLevelSceneTransition::kTypeReturn: {
-			if (_sceneReturnList.size() == 0) {
-				warning("A scene return was requested, but no scenes are in the scene return list");
-				return;
-			}
-
-			const SceneReturnListEntry &sceneReturn = _sceneReturnList.back();
+	if (_sceneReturnList.size() == 0) {
+		warning("A scene return was requested, but no scenes are in the scene return list");
+		return;
+	}
 
-			if (sceneReturn.scene == _activeSharedScene)
-				error("Transitioned into the active shared scene as the main scene, this is not supported");
+	const SceneReturnListEntry &sceneReturn = _sceneReturnList.back();
 
-			if (sceneReturn.scene != _activeMainScene) {
-				assert(_activeMainScene.get() != nullptr); // There should always be an active main scene after the first transition
+	if (sceneReturn.scene == _activeSharedScene)
+		error("Transitioned into the active shared scene as the main scene, this is not supported");
 
-				if (sceneReturn.isAddToDestinationSceneTransition) {
-					// In this case we unload the active main scene and reactivate the old main
-					queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneEnded, 0), _activeMainScene.get(), true, true);
-					queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kParentDisabled, 0), _activeMainScene.get(), true, true);
-					_pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(_activeMainScene, LowLevelSceneStateTransitionAction::kUnload));
+	if (sceneReturn.scene != _activeMainScene) {
+		assert(_activeMainScene.get() != nullptr); // There should always be an active main scene after the first transition
 
-					queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneReactivated, 0), sceneReturn.scene.get(), true, true);
+		if (sceneReturn.isAddToDestinationSceneTransition) {
+			// In this case we unload the active main scene and reactivate the old main
+			queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneEnded, 0), _activeMainScene.get(), true, true);
+			queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kParentDisabled, 0), _activeMainScene.get(), true, true);
+			_pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(_activeMainScene, LowLevelSceneStateTransitionAction::kUnload));
 
-					for (uint i = 1; i < _sceneStack.size(); i++) {
-						if (_sceneStack[i].scene == _activeMainScene) {
-							_sceneStack.remove_at(i);
-							break;
-						}
-					}
-
-					_activeMainScene = sceneReturn.scene;
+			queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneReactivated, 0), sceneReturn.scene.get(), true, true);
 
-					executeSharedScenePostSceneChangeActions();
-				} else {
-					executeCompleteTransitionToScene(sceneReturn.scene);
+			for (uint i = 1; i < _sceneStack.size(); i++) {
+				if (_sceneStack[i].scene == _activeMainScene) {
+					_sceneStack.remove_at(i);
+					break;
 				}
 			}
-		} break;
+
+			_activeMainScene = sceneReturn.scene;
+
+			executeSharedScenePostSceneChangeActions();
+		} else {
+			executeCompleteTransitionToScene(sceneReturn.scene);
+		}
+	}
+}
+
+void Runtime::executeHighLevelSceneTransition(const HighLevelSceneTransition &transition) {
+	if (_sceneStack.size() == 0)
+		_sceneStack.resize(1); // Reserve shared scene slot
+
+	// This replicates a bunch of quirks/bugs of mTropolis's scene transition logic,
+	// see the accompanying notes file.  There are probably some missing cases related to
+	// shared scene, calling return/scene transitions during scene deactivation, or other
+	// edge cases that hopefully no games actually do!
+	switch (transition.type) {
 	case HighLevelSceneTransition::kTypeChangeToScene: {
 			const Common::SharedPtr<Structural> targetScene = transition.scene;
 
@@ -7166,6 +7184,9 @@ bool Runtime::isIdle() const {
 	if (_messageQueue.size() > 0)
 		return false;
 
+	if (_pendingSceneReturnCount > 0)
+		return false;
+
 	if (_pendingSceneTransitions.size() > 0)
 		return false;
 
@@ -7293,6 +7314,10 @@ void Runtime::addSceneStateTransition(const HighLevelSceneTransition &transition
 	_pendingSceneTransitions.push_back(transition);
 }
 
+void Runtime::addSceneReturn() {
+	_pendingSceneReturnCount++;
+}
+
 void Runtime::setSceneTransitionEffect(bool isInDestinationScene, SceneTransitionEffect *effect) {
 	SceneTransitionEffect *target = isInDestinationScene ? &_destinationSceneTransitionEffect : &_sourceSceneTransitionEffect;
 	if (!effect)
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index 9094c4e8be9..ce38e7b73bd 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -1363,7 +1363,6 @@ struct ObjectParentChange {
 
 struct HighLevelSceneTransition {
 	enum Type {
-		kTypeReturn,
 		kTypeChangeToScene,
 		kTypeChangeSharedScene,
 		kTypeForceLoadScene,
@@ -1609,6 +1608,7 @@ public:
 	void addVolume(int volumeID, const char *name, bool isMounted);
 	bool getVolumeState(const Common::String &name, int &outVolumeID, bool &outIsMounted) const;
 
+	void addSceneReturn();
 	void addSceneStateTransition(const HighLevelSceneTransition &transition);
 
 	void setSceneTransitionEffect(bool isInDestinationScene, SceneTransitionEffect *effect);
@@ -1850,6 +1850,7 @@ private:
 	static Common::SharedPtr<Structural> findDefaultSharedSceneForScene(Structural *scene);
 	void executeTeardown(const Teardown &teardown);
 	void executeLowLevelSceneStateTransition(const LowLevelSceneStateTransitionAction &transitionAction);
+	void executeHighLevelSceneReturn();
 	void executeHighLevelSceneTransition(const HighLevelSceneTransition &transition);
 	void executeCompleteTransitionToScene(const Common::SharedPtr<Structural> &scene);
 	void executeSharedScenePostSceneChangeActions();
@@ -1904,6 +1905,7 @@ private:
 	Common::Array<Common::WeakPtr<Structural> > _pendingPostCloneShowChecks;
 	Common::Array<Common::WeakPtr<Structural> > _pendingShowClonedObject;
 	Common::Array<ObjectParentChange> _pendingParentChanges;
+	uint _pendingSceneReturnCount;
 	Common::Array<HighLevelSceneTransition> _pendingSceneTransitions;
 	Common::Array<SceneStackEntry> _sceneStack;
 	Common::SharedPtr<Structural> _activeMainScene;




More information about the Scummvm-git-logs mailing list