[Scummvm-git-logs] scummvm master -> 74863cb32ffc155ae43cd794c8256b087543fdb2
elasota
noreply at scummvm.org
Sat Jul 2 06:20:41 UTC 2022
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:
74863cb32f MTROPOLIS: Discharge message queue after low-level scene transition actions
Commit: 74863cb32ffc155ae43cd794c8256b087543fdb2
https://github.com/scummvm/scummvm/commit/74863cb32ffc155ae43cd794c8256b087543fdb2
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-02T02:20:26-04:00
Commit Message:
MTROPOLIS: Discharge message queue after low-level scene transition actions
Changed paths:
engines/mtropolis/runtime.cpp
engines/mtropolis/runtime.h
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index 8a9376bcd46..29b0603a3fc 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -3212,18 +3212,20 @@ MessageDispatch::MessageDispatch(const Common::SharedPtr<MessageProperties> &msg
PropagationStack topEntry;
topEntry.index = 0;
- topEntry.propagationStage = PropagationStack::kStageSendCommand;
+ topEntry.propagationStage = PropagationStack::kStageCheckAndSendCommand;
topEntry.ptr.structural = root;
_propagationStack.push_back(topEntry);
} else {
PropagationStack topEntry;
topEntry.index = 0;
- topEntry.propagationStage = PropagationStack::kStageSendToStructuralSelf;
+ topEntry.propagationStage = PropagationStack::kStageCheckAndSendToStructural;
topEntry.ptr.structural = root;
_propagationStack.push_back(topEntry);
}
+
+ _root = root->getSelfReference();
}
MessageDispatch::MessageDispatch(const Common::SharedPtr<MessageProperties> &msgProps, Modifier *root, bool cascade, bool relay, bool couldBeCommand)
@@ -3234,13 +3236,15 @@ MessageDispatch::MessageDispatch(const Common::SharedPtr<MessageProperties> &msg
} else {
PropagationStack topEntry;
topEntry.index = 0;
- topEntry.propagationStage = PropagationStack::kStageSendToModifier;
+ topEntry.propagationStage = PropagationStack::kStageCheckAndSendToModifier;
topEntry.ptr.modifier = root;
_isCommand = (couldBeCommand && EventIDs::isCommand(msgProps->getEvent().eventType));
_propagationStack.push_back(topEntry);
}
+
+ _root = root->getSelfReference();
}
bool MessageDispatch::isTerminated() const {
@@ -3255,6 +3259,21 @@ VThreadState MessageDispatch::continuePropagating(Runtime *runtime) {
PropagationStack &stackTop = _propagationStack.back();
switch (stackTop.propagationStage) {
+ case PropagationStack::kStageCheckAndSendCommand:
+ if (_root.expired())
+ return kVThreadReturn;
+ stackTop.propagationStage = PropagationStack::kStageSendCommand;
+ break;
+ case PropagationStack::kStageCheckAndSendToStructural:
+ if (_root.expired())
+ return kVThreadReturn;
+ stackTop.propagationStage = PropagationStack::kStageSendToStructuralSelf;
+ break;
+ case PropagationStack::kStageCheckAndSendToModifier:
+ if (_root.expired())
+ return kVThreadReturn;
+ stackTop.propagationStage = PropagationStack::kStageSendToModifier;
+ break;
case PropagationStack::kStageSendToModifier: {
Modifier *modifier = stackTop.ptr.modifier;
_propagationStack.pop_back();
@@ -3786,15 +3805,7 @@ bool Runtime::runFrame() {
continue;
}
- if (_messageQueue.size() > 0) {
- Common::SharedPtr<MessageDispatch> msg = _messageQueue[0];
- _messageQueue.remove_at(0);
-
- sendMessageOnVThread(msg);
- continue;
- }
-
- // Teardowns must only occur during idle conditions where there are no queued message and no VThread tasks
+ // Teardowns must only occur during idle conditions where there are no VThread tasks
if (_pendingTeardowns.size() > 0) {
for (Common::Array<Teardown>::const_iterator it = _pendingTeardowns.begin(), itEnd = _pendingTeardowns.end(); it != itEnd; ++it) {
executeTeardown(*it);
@@ -3812,6 +3823,27 @@ bool Runtime::runFrame() {
continue;
}
+ // This has to be in this specific spot: Queued messages that occur from scene transitions are normally discharged
+ // after the "Scene Started" event, but before scene transition.
+ //
+ // Obsidian depends on this behavior in several scripts, most notably setting up conditional ambience correctly.
+ // For example, in Inspiration chapter, on exiting the plane into the statue:
+ // Shared scene fires Parent Enabled which triggers "GEN_SND_Start_Ambience on PE" which sends GEN_SND_Start_Ambience
+ // but not immediately, so it goes into the queue.
+ // After the main scene loads, it fires Scene Started and which in turn triggers "NAV_setup_navigation on SS" which
+ // sends NAV_setup_navigation immediately, which sets the current nav node variable.
+ // Then, the queued GEN_SND_Start_Ambience can read the nav node variable to set up ambience correctly.
+ //
+ // If messages are discharged before low-level scene transitions, then the music plays in the lower level of the
+ // statue on disembarking because the nav node variable is set to the wrong value.
+ if (_messageQueue.size() > 0) {
+ Common::SharedPtr<MessageDispatch> msg = _messageQueue[0];
+ _messageQueue.remove_at(0);
+
+ sendMessageOnVThread(msg);
+ continue;
+ }
+
if (_pendingSceneTransitions.size() > 0) {
HighLevelSceneTransition transition = _pendingSceneTransitions[0];
_pendingSceneTransitions.remove_at(0);
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index 2394f0665cd..e8a1716c0cd 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -1311,6 +1311,10 @@ private:
kStageSendToStructuralModifiers,
kStageSendToStructuralChildren,
+ kStageCheckAndSendToModifier,
+ kStageCheckAndSendToStructural,
+ kStageCheckAndSendCommand,
+
kStageSendCommand,
};
@@ -1321,6 +1325,9 @@ private:
Common::Array<PropagationStack> _propagationStack;
Common::SharedPtr<MessageProperties> _msg;
+
+ Common::WeakPtr<RuntimeObject> _root;
+
bool _cascade; // Traverses structure tree
bool _relay; // Fire on multiple modifiers
bool _terminated;
More information about the Scummvm-git-logs
mailing list