[Scummvm-git-logs] scummvm master -> 6acba4efc43f062a4b68aff9b90ccd4185ae8e27
elasota
noreply at scummvm.org
Mon Jan 2 23:09:12 UTC 2023
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:
6acba4efc4 MTROPOLIS: Fire "show" commands to unhide elements at scene load instead of them being immediately visible. Fixes MTI B
Commit: 6acba4efc43f062a4b68aff9b90ccd4185ae8e27
https://github.com/scummvm/scummvm/commit/6acba4efc43f062a4b68aff9b90ccd4185ae8e27
Author: elasota (ejlasota at gmail.com)
Date: 2023-01-02T18:08:33-05:00
Commit Message:
MTROPOLIS: Fire "show" commands to unhide elements at scene load instead of them being immediately visible. Fixes MTI Benbow outro.
Changed paths:
engines/mtropolis/runtime.cpp
engines/mtropolis/runtime.h
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index 1db8503e168..7cad07bac2e 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -4138,6 +4138,10 @@ Runtime::ConsumeMessageTaskData::ConsumeMessageTaskData() : consumer(nullptr) {
Runtime::ConsumeCommandTaskData::ConsumeCommandTaskData() : structural(nullptr) {
}
+Runtime::ApplyDefaultVisibilityTaskData::ApplyDefaultVisibilityTaskData() : element(nullptr), targetVisibility(false) {
+}
+
+
Runtime::UpdateMouseStateTaskData::UpdateMouseStateTaskData() : mouseDown(false) {
}
@@ -4444,7 +4448,7 @@ bool Runtime::runFrame() {
}
// 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.
+ // after Scene Started, Scene Changed, and element Show events, 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:
@@ -4780,12 +4784,34 @@ void Runtime::executeLowLevelSceneStateTransition(const LowLevelSceneStateTransi
forceCursorRefreshOnce();
}
break;
+ case LowLevelSceneStateTransitionAction::kShowDefaultVisibleElements:
+ executeSceneChangeRecursiveVisibilityChange(action.getScene().get(), true);
+ break;
+ case LowLevelSceneStateTransitionAction::kHideAllElements:
+ executeSceneChangeRecursiveVisibilityChange(action.getScene().get(), false);
+ break;
default:
assert(false);
break;
}
}
+void Runtime::executeSceneChangeRecursiveVisibilityChange(Structural *structural, bool showing) {
+ const Common::Array<Common::SharedPtr<Structural> > &children = structural->getChildren();
+
+ // Queue in reverse order since VThread sends are LIFO
+ for (size_t i = 0; i < children.size(); i++)
+ executeSceneChangeRecursiveVisibilityChange(children[children.size() - 1 - i].get(), showing);
+
+ if (structural->isElement() && static_cast<Element *>(structural)->isVisual()) {
+ VisualElement *visual = static_cast<VisualElement *>(structural);
+
+ ApplyDefaultVisibilityTaskData *taskData = getVThread().pushTask("Runtime::applyDefaultVisibility", this, &Runtime::applyDefaultVisibility);
+ taskData->element = visual;
+ taskData->targetVisibility = showing;
+ }
+}
+
void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structural> &targetScene) {
// NOTE: Transitioning to the same scene is allowed, Obsidian relies on this to avoid getting stuck
// after going up the wrong side in the Bureau chapter final area (i.e. after reaching the sky face).
@@ -4813,6 +4839,7 @@ void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structura
Common::SharedPtr<Structural> stackedScene = _sceneStack[i].scene;
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneEnded, 0), _activeMainScene.get(), true, true);
+ _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(_activeMainScene, LowLevelSceneStateTransitionAction::kHideAllElements));
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kParentDisabled, 0), _activeMainScene.get(), true, true);
_pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(_activeMainScene, LowLevelSceneStateTransitionAction::kUnload));
@@ -4825,6 +4852,7 @@ void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structura
if (targetSharedScene != _activeSharedScene) {
if (_activeSharedScene) {
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneEnded, 0), _activeSharedScene.get(), true, true);
+ _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(_activeMainScene, LowLevelSceneStateTransitionAction::kHideAllElements));
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kParentDisabled, 0), _activeSharedScene.get(), true, true);
_pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(_activeSharedScene, LowLevelSceneStateTransitionAction::kUnload));
}
@@ -4833,6 +4861,8 @@ void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structura
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kParentEnabled, 0), targetSharedScene.get(), true, true);
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneStarted, 0), targetSharedScene.get(), true, true);
+ _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetSharedScene, LowLevelSceneStateTransitionAction::kShowDefaultVisibleElements));
+
SceneStackEntry sharedSceneEntry;
sharedSceneEntry.scene = targetSharedScene;
@@ -4942,6 +4972,7 @@ void Runtime::executeHighLevelSceneTransition(const HighLevelSceneTransition &tr
_pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetSharedScene, LowLevelSceneStateTransitionAction::kLoad));
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kParentEnabled, 0), targetSharedScene.get(), true, true);
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneStarted, 0), targetSharedScene.get(), true, true);
+ _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetSharedScene, LowLevelSceneStateTransitionAction::kShowDefaultVisibleElements));
SceneStackEntry sharedSceneEntry;
sharedSceneEntry.scene = targetScene;
@@ -4993,6 +5024,7 @@ void Runtime::executeHighLevelSceneTransition(const HighLevelSceneTransition &tr
_pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetSharedScene, LowLevelSceneStateTransitionAction::kLoad));
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kParentEnabled, 0), targetSharedScene.get(), true, true);
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSceneStarted, 0), targetSharedScene.get(), true, true);
+ _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetSharedScene, LowLevelSceneStateTransitionAction::kShowDefaultVisibleElements));
SceneStackEntry sharedSceneEntry;
sharedSceneEntry.scene = targetSharedScene;
@@ -5022,6 +5054,8 @@ void Runtime::executeSharedScenePostSceneChangeActions() {
if (_activeMainScene == subsectionScenes[1])
queueEventAsLowLevelSceneStateTransitionAction(Event(EventIDs::kSharedSceneNoPrevScene, 0), _activeSharedScene.get(), true, true);
}
+
+ _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(_activeMainScene, LowLevelSceneStateTransitionAction::kShowDefaultVisibleElements));
}
void Runtime::recursiveDeactivateStructural(Structural *structural) {
@@ -5725,6 +5759,29 @@ VThreadState Runtime::updateMousePositionTask(const UpdateMousePositionTaskData
return kVThreadReturn;
}
+VThreadState Runtime::applyDefaultVisibility(const ApplyDefaultVisibilityTaskData &data) {
+ Event evt;
+ if (data.targetVisibility) {
+ if (data.element->isVisibleByDefault() == false || data.element->isVisible())
+ return kVThreadReturn;
+
+ evt = Event(EventIDs::kElementShow, 0);
+ } else {
+ if (!data.element->isVisible())
+ return kVThreadReturn;
+
+ evt = Event(EventIDs::kElementHide, 0);
+ }
+
+ // Visibility change events are sourced from the element
+ Common::SharedPtr<MessageProperties> props(new MessageProperties(evt, DynamicValue(), data.element->getSelfReference()));
+ Common::SharedPtr<MessageDispatch> dispatch(new MessageDispatch(props, data.element, false, false, true));
+
+ sendMessageOnVThread(dispatch);
+
+ return kVThreadReturn;
+}
+
void Runtime::updateMainWindowCursor() {
const uint32 kHandPointUpID = 10005;
const uint32 kArrowID = 10011;
@@ -7894,7 +7951,7 @@ VisualElementRenderProperties &VisualElementRenderProperties::operator=(const Vi
*/
VisualElement::VisualElement()
- : _rect(0, 0, 0, 0), _cachedAbsoluteOrigin(Common::Point(0, 0)), _contentsDirty(true), _directToScreen(false), _visible(true), _layer(0) {
+ : _rect(0, 0, 0, 0), _cachedAbsoluteOrigin(Common::Point(0, 0)), _contentsDirty(true), _directToScreen(false), _visible(false), _layer(0) {
}
bool VisualElement::isVisual() const {
@@ -7909,6 +7966,10 @@ bool VisualElement::isVisible() const {
return _visible;
}
+bool VisualElement::isVisibleByDefault() const {
+ return _visibleByDefault;
+}
+
void VisualElement::setVisible(Runtime *runtime, bool visible) {
if (_visible != visible) {
runtime->setSceneGraphDirty();
@@ -8329,7 +8390,7 @@ void VisualElement::debugInspect(IDebugInspectionReport *report) const {
#endif
MiniscriptInstructionOutcome VisualElement::scriptSetVisibility(MiniscriptThread *thread, const DynamicValue &result) {
- // FIXME: Need to make this fire Show/Hide events!
+ // FIXME: Need to make this fire Show/Hide events??
if (result.getType() == DynamicValueTypes::kBoolean) {
const bool targetValue = result.getBool();
if (_visible != targetValue) {
@@ -8348,7 +8409,7 @@ bool VisualElement::loadCommon(const Common::String &name, uint32 guid, const Da
_name = name;
_guid = guid;
- _visible = ((elementFlags & Data::ElementFlags::kHidden) == 0);
+ _visibleByDefault = ((elementFlags & Data::ElementFlags::kHidden) == 0); // Element isn't actually flagged as visible until after Scene Changed, when Show commands are fired
_directToScreen = ((elementFlags & Data::ElementFlags::kNotDirectToScreen) == 0);
_streamLocator = streamLocator;
_sectionID = sectionID;
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index f852fb60367..3977e97ed43 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -1313,6 +1313,8 @@ struct LowLevelSceneStateTransitionAction {
kUnload,
kSendMessage,
kAutoResetCursor,
+ kHideAllElements,
+ kShowDefaultVisibleElements,
};
explicit LowLevelSceneStateTransitionAction(const Common::SharedPtr<MessageDispatch> &msg);
@@ -1573,7 +1575,6 @@ public:
void addVolume(int volumeID, const char *name, bool isMounted);
bool getVolumeState(const Common::String &name, int &outVolumeID, bool &outIsMounted) const;
- void setDefaultVolumeState(bool defaultState);
void addSceneStateTransition(const HighLevelSceneTransition &transition);
@@ -1762,6 +1763,13 @@ private:
Common::SharedPtr<MessageProperties> message;
};
+ struct ApplyDefaultVisibilityTaskData {
+ ApplyDefaultVisibilityTaskData();
+
+ VisualElement *element;
+ bool targetVisibility;
+ };
+
struct UpdateMouseStateTaskData {
UpdateMouseStateTaskData();
@@ -1806,6 +1814,7 @@ private:
void executeHighLevelSceneTransition(const HighLevelSceneTransition &transition);
void executeCompleteTransitionToScene(const Common::SharedPtr<Structural> &scene);
void executeSharedScenePostSceneChangeActions();
+ void executeSceneChangeRecursiveVisibilityChange(Structural *structural, bool showing);
void recursiveAutoPlayMedia(Structural *structural);
void recursiveDeactivateStructural(Structural *structural);
@@ -1831,6 +1840,7 @@ private:
VThreadState consumeCommandTask(const ConsumeCommandTaskData &data);
VThreadState updateMouseStateTask(const UpdateMouseStateTaskData &data);
VThreadState updateMousePositionTask(const UpdateMousePositionTaskData &data);
+ VThreadState applyDefaultVisibility(const ApplyDefaultVisibilityTaskData &data);
void updateMainWindowCursor();
@@ -2692,6 +2702,7 @@ public:
VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
bool isVisible() const;
+ bool isVisibleByDefault() const;
void setVisible(Runtime *runtime, bool visible);
bool isDirectToScreen() const;
@@ -2787,6 +2798,7 @@ protected:
bool _directToScreen;
bool _visible;
+ bool _visibleByDefault;
Common::Rect _rect;
Common::Point _cachedAbsoluteOrigin;
uint16 _layer;
More information about the Scummvm-git-logs
mailing list