From 8461f9c845a4b1588f7af5e4db609dfe7eb86a98 Mon Sep 17 00:00:00 2001 From: elasota Date: Sat, 28 May 2022 01:24:15 -0400 Subject: [PATCH] MTROPOLIS: Fix up auto-play event behavior to hopefully fix Obsidian rebel VO not triggering --- engines/mtropolis/elements.cpp | 26 ++++++++++++++++---------- engines/mtropolis/elements.h | 6 ++++++ engines/mtropolis/runtime.cpp | 33 +++++++++++++++++++++++++++++++++ engines/mtropolis/runtime.h | 8 ++++++++ 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/engines/mtropolis/elements.cpp b/engines/mtropolis/elements.cpp index 45cd9a7f99f..cddb664e462 100644 --- a/engines/mtropolis/elements.cpp +++ b/engines/mtropolis/elements.cpp @@ -635,11 +635,6 @@ void MovieElement::activate() { _playRange = IntRange::create(0, _maxTimestamp); _currentTimestamp = 0; - if (!_paused && _visible) { - StartPlayingTaskData *startPlayingTaskData = _runtime->getVThread().pushTask("MovieElement::startPlayingTask", this, &MovieElement::startPlayingTask); - startPlayingTaskData->runtime = _runtime; - } - if (_name.empty()) _name = project->getAssetNameByID(_assetID); } @@ -657,6 +652,10 @@ void MovieElement::deactivate() { _videoDecoder.reset(); } +bool MovieElement::canAutoPlay() const { + return _visible && !_paused; +} + void MovieElement::render(Window *window) { if (_needsReset) { _videoDecoder->setReverse(_reversed); @@ -1155,6 +1154,10 @@ void MToonElement::deactivate() { _renderSurface.reset(); } +bool MToonElement::canAutoPlay() const { + return _visible && !_paused; +} + void MToonElement::render(Window *window) { if (_cachedMToon) { _cachedMToon->optimize(_runtime); @@ -1762,6 +1765,10 @@ bool SoundElement::load(ElementLoaderContext &context, const Data::SoundElement if (!NonVisualElement::loadCommon(data.name, data.guid, data.elementFlags)) return false; + if (getStaticGUID() == 0x69b65) { + int n = 0; + } + _paused = ((data.soundFlags & Data::SoundElement::kPaused) != 0); _loop = ((data.soundFlags & Data::SoundElement::kLoop) != 0); _leftVolume = data.leftVolume; @@ -1830,11 +1837,6 @@ void SoundElement::activate() { _playMediaSignaller = project->notifyOnPlayMedia(this); - if (!_paused) { - StartPlayingTaskData *startPlayingTaskData = _runtime->getVThread().pushTask("SoundElement::startPlayingTask", this, &SoundElement::startPlayingTask); - startPlayingTaskData->runtime = _runtime; - } - if (_name.empty()) _name = project->getAssetNameByID(_assetID); } @@ -1851,6 +1853,10 @@ void SoundElement::deactivate() { _player.reset(); } +bool SoundElement::canAutoPlay() const { + return !_paused; +} + void SoundElement::playMedia(Runtime *runtime, Project *project) { if (_shouldPlayIfNotPaused) { if (_paused) { diff --git a/engines/mtropolis/elements.h b/engines/mtropolis/elements.h index 9add227f438..1c6e1628594 100644 --- a/engines/mtropolis/elements.h +++ b/engines/mtropolis/elements.h @@ -85,6 +85,8 @@ public: void activate() override; void deactivate() override; + bool canAutoPlay() const override; + void render(Window *window) override; void playMedia(Runtime *runtime, Project *project) override; @@ -189,6 +191,8 @@ public: void activate() override; void deactivate() override; + bool canAutoPlay() const override; + void render(Window *window) override; #ifdef MTROPOLIS_DEBUG_ENABLE @@ -318,6 +322,8 @@ public: void activate() override; void deactivate() override; + bool canAutoPlay() const override; + void playMedia(Runtime *runtime, Project *project) override; #ifdef MTROPOLIS_DEBUG_ENABLE diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp index a65d4da6552..6b9a33a3299 100644 --- a/engines/mtropolis/runtime.cpp +++ b/engines/mtropolis/runtime.cpp @@ -3684,6 +3684,10 @@ bool Runtime::runFrame() { if (_sceneTransitionState == kSceneTransitionStateTransitioning && _playTime >= _sceneTransitionEndTime) { _sceneTransitionState = kSceneTransitionStateNotTransitioning; + + for (const SceneStackEntry &sceneStackEntry : _sceneStack) + recursiveAutoPlayMedia(sceneStackEntry.scene.get()); + queueEventAsLowLevelSceneStateTransitionAction(Event::create(EventIDs::kSceneTransitionEnded, 0), _activeMainScene.get(), true, true); continue; } @@ -4099,6 +4103,15 @@ void Runtime::recursiveDeactivateStructural(Structural *structural) { structural->deactivate(); } +void Runtime::recursiveAutoPlayMedia(Structural *structural) { + if (structural->isElement()) + static_cast(structural)->triggerAutoPlay(this); + + for (const Common::SharedPtr &child : structural->getChildren()) { + recursiveAutoPlayMedia(child.get()); + } +} + void Runtime::recursiveActivateStructural(Structural *structural) { structural->activate(); @@ -6200,6 +6213,13 @@ ObjectLinkingScope *Subsection::getPersistentModifierScope() { return &_modifierScope; } +Element::Element() : _streamLocator(0), _sectionID(0), _haveCheckedAutoPlay(false) { +} + +bool Element::canAutoPlay() const { + return false; +} + bool Element::isElement() const { return true; } @@ -6221,6 +6241,19 @@ void Element::removeMediaCue(const MediaCueState *mediaCue) { } } +void Element::triggerAutoPlay(Runtime *runtime) { + if (_haveCheckedAutoPlay) + return; + + _haveCheckedAutoPlay = true; + + if (canAutoPlay()) { + Common::SharedPtr msgProps(new MessageProperties(Event::create(EventIDs::kPlay, 0), DynamicValue(), getSelfReference())); + Common::SharedPtr dispatch(new MessageDispatch(msgProps, this, false, false, true)); + runtime->queueMessage(dispatch); + } +} + bool Element::resolveMediaMarkerLabel(const Label& label, int32 &outResolution) const { return false; } diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h index 43a6303fa6f..736d5a81b75 100644 --- a/engines/mtropolis/runtime.h +++ b/engines/mtropolis/runtime.h @@ -1670,6 +1670,7 @@ private: void executeCompleteTransitionToScene(const Common::SharedPtr &scene); void executeSharedScenePostSceneChangeActions(); + void recursiveAutoPlayMedia(Structural *structural); void recursiveDeactivateStructural(Structural *structural); void recursiveActivateStructural(Structural *structural); @@ -2301,7 +2302,10 @@ private: class Element : public Structural { public: + Element(); + virtual bool isVisual() const = 0; + virtual bool canAutoPlay() const; bool isElement() const override; uint32 getStreamLocator() const; @@ -2309,6 +2313,8 @@ public: void addMediaCue(MediaCueState *mediaCue); void removeMediaCue(const MediaCueState *mediaCue); + void triggerAutoPlay(Runtime *runtime); + virtual bool resolveMediaMarkerLabel(const Label &label, int32 &outResolution) const; protected: @@ -2316,6 +2322,8 @@ protected: uint16 _sectionID; Common::Array _mediaCues; + + bool _haveCheckedAutoPlay; }; class VisualElementRenderProperties {