[Scummvm-git-logs] scummvm master -> 501e3f219bc2047de63e22fce7809e96f2d5428b

elasota noreply at scummvm.org
Fri Dec 23 15:16:50 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:
501e3f219b MTROPOLIS: Add hack for returning from MTI pause menu.


Commit: 501e3f219bc2047de63e22fce7809e96f2d5428b
    https://github.com/scummvm/scummvm/commit/501e3f219bc2047de63e22fce7809e96f2d5428b
Author: elasota (ejlasota at gmail.com)
Date: 2022-12-23T10:10:42-05:00

Commit Message:
MTROPOLIS: Add hack for returning from MTI pause menu.

Changed paths:
    engines/mtropolis/elements.cpp
    engines/mtropolis/elements.h
    engines/mtropolis/hacks.cpp
    engines/mtropolis/hacks.h
    engines/mtropolis/runtime.cpp
    engines/mtropolis/runtime.h


diff --git a/engines/mtropolis/elements.cpp b/engines/mtropolis/elements.cpp
index ebd7c5fcb08..fda3b109121 100644
--- a/engines/mtropolis/elements.cpp
+++ b/engines/mtropolis/elements.cpp
@@ -426,7 +426,7 @@ MovieElement::MovieElement()
 	: _cacheBitmap(false), _alternate(false), _playEveryFrame(false), _reversed(false), /* _haveFiredAtLastCel(false), */
 	  /* _haveFiredAtFirstCel(false), */_shouldPlayIfNotPaused(true), _needsReset(true), _currentPlayState(kMediaStateStopped),
 	  _assetID(0), _maxTimestamp(0), _timeScale(0), _currentTimestamp(0), _volume(100),
-	  _displayFrame(nullptr), _runtime(nullptr) {
+	  _displayFrame(nullptr) {
 }
 
 MovieElement::~MovieElement() {
@@ -450,8 +450,6 @@ bool MovieElement::load(ElementLoaderContext &context, const Data::MovieElement
 	_assetID = data.assetID;
 	_volume = data.volume;
 
-	_runtime = context.runtime;
-
 	return true;
 }
 
@@ -540,7 +538,7 @@ VThreadState MovieElement::consumeCommand(Runtime *runtime, const Common::Shared
 }
 
 void MovieElement::activate() {
-	Project *project = _runtime->getProject();
+	Project *project = getRuntime()->getProject();
 	Common::SharedPtr<Asset> asset = project->getAssetByID(_assetID).lock();
 
 	if (!asset) {
@@ -576,7 +574,7 @@ void MovieElement::activate() {
 	if (!_videoDecoder->loadStream(movieDataStream))
 		_videoDecoder.reset();
 
-	if (_runtime->getHacks().removeQuickTimeEdits)
+	if (getRuntime()->getHacks().removeQuickTimeEdits)
 		qtDecoder->flattenEditLists();
 	_timeScale = qtDecoder->getTimeScale();
 
@@ -599,7 +597,7 @@ void MovieElement::activate() {
 		}
 
 		if (subSetIDPtr)
-			_subtitles.reset(new SubtitlePlayer(_runtime, *subSetIDPtr, subtitleTables));
+			_subtitles.reset(new SubtitlePlayer(getRuntime(), *subSetIDPtr, subtitleTables));
 	}
 }
 
@@ -889,7 +887,7 @@ MiniscriptInstructionOutcome MovieElement::scriptSetTimestamp(MiniscriptThread *
 
 	if (asInteger != (int32)_currentTimestamp) {
 		SeekToTimeTaskData *taskData = thread->getRuntime()->getVThread().pushTask("MovieElement::seekToTimeTask", this, &MovieElement::seekToTimeTask);
-		taskData->runtime = _runtime;
+		taskData->runtime = getRuntime();
 		taskData->timestamp = asInteger;
 
 		return kMiniscriptInstructionOutcomeYieldToVThreadNoRetry;
@@ -963,7 +961,7 @@ MiniscriptInstructionOutcome MovieElement::scriptSetRangeTyped(MiniscriptThread
 
 	if (targetTS != _currentTimestamp) {
 		SeekToTimeTaskData *taskData = thread->getRuntime()->getVThread().pushTask("MovieElement::seekToTimeTask", this, &MovieElement::seekToTimeTask);
-		taskData->runtime = _runtime;
+		taskData->runtime = getRuntime();
 		taskData->timestamp = targetTS;
 
 		return kMiniscriptInstructionOutcomeYieldToVThreadNoRetry;
@@ -1016,7 +1014,7 @@ VThreadState MovieElement::seekToTimeTask(const SeekToTimeTaskData &taskData) {
 	return kVThreadReturn;
 }
 
-ImageElement::ImageElement() : _cacheBitmap(false), _assetID(0), _runtime(nullptr) {
+ImageElement::ImageElement() : _cacheBitmap(false), _assetID(0) {
 }
 
 ImageElement::~ImageElement() {
@@ -1027,7 +1025,6 @@ bool ImageElement::load(ElementLoaderContext &context, const Data::ImageElement
 		return false;
 
 	_cacheBitmap = ((data.elementFlags & Data::ElementFlags::kCacheBitmap) != 0);
-	_runtime = context.runtime;
 	_assetID = data.imageAssetID;
 
 	return true;
@@ -1057,7 +1054,7 @@ MiniscriptInstructionOutcome ImageElement::writeRefAttribute(MiniscriptThread *t
 }
 
 void ImageElement::activate() {
-	Project *project = _runtime->getProject();
+	Project *project = getRuntime()->getProject();
 	Common::SharedPtr<Asset> asset = project->getAssetByID(_assetID).lock();
 
 	if (!asset) {
@@ -1070,7 +1067,7 @@ void ImageElement::activate() {
 		return;
 	}
 
-	_cachedImage = static_cast<ImageAsset *>(asset.get())->loadAndCacheImage(_runtime);
+	_cachedImage = static_cast<ImageAsset *>(asset.get())->loadAndCacheImage(getRuntime());
 
 	if (_name.empty())
 		_name = project->getAssetNameByID(_assetID);
@@ -1087,7 +1084,7 @@ void ImageElement::render(Window *window) {
 		if (inkMode == VisualElementRenderProperties::kInkModeInvisible)
 			return;
 
-		Common::SharedPtr<Graphics::ManagedSurface> optimized = _cachedImage->optimize(_runtime);
+		Common::SharedPtr<Graphics::ManagedSurface> optimized = _cachedImage->optimize(getRuntime());
 		Common::Rect srcRect(optimized->w, optimized->h);
 		Common::Rect destRect(_cachedAbsoluteOrigin.x, _cachedAbsoluteOrigin.y, _cachedAbsoluteOrigin.x + _rect.width(), _cachedAbsoluteOrigin.y + _rect.height());
 
@@ -1103,7 +1100,7 @@ void ImageElement::render(Window *window) {
 			} else {
 				const Palette *palette = getPalette().get();
 				if (!palette)
-					palette = &_runtime->getGlobalPalette();
+					palette = &getRuntime()->getGlobalPalette();
 
 				optimized->setPalette(palette->getPalette(), 0, 256);
 			}
@@ -1144,7 +1141,7 @@ MiniscriptInstructionOutcome ImageElement::scriptSetFlushPriority(MiniscriptThre
 
 MToonElement::MToonElement()
 	: _cacheBitmap(false), _maintainRate(false), _assetID(0), _rateTimes100000(0), _flushPriority(0), _celStartTimeMSec(0),
-	  _isPlaying(false), _runtime(nullptr), _renderedFrame(0), _playRange(IntRange(1, 1)), _cel(1) {
+	  _isPlaying(false), _renderedFrame(0), _playRange(IntRange(1, 1)), _cel(1) {
 }
 
 MToonElement::~MToonElement() {
@@ -1161,7 +1158,6 @@ bool MToonElement::load(ElementLoaderContext &context, const Data::MToonElement
 	_loop = ((data.animationFlags & Data::AnimationFlags::kLoop) != 0);
 	_maintainRate = ((data.elementFlags & Data::AnimationFlags::kPlayEveryFrame) == 0);	// NOTE: Inverted intentionally
 	_assetID = data.assetID;
-	_runtime = context.runtime;
 	_rateTimes100000 = data.rateTimes100000;
 
 	return true;
@@ -1240,7 +1236,7 @@ VThreadState MToonElement::consumeCommand(Runtime *runtime, const Common::Shared
 }
 
 void MToonElement::activate() {
-	Project *project = _runtime->getProject();
+	Project *project = getRuntime()->getProject();
 	Common::SharedPtr<Asset> asset = project->getAssetByID(_assetID).lock();
 
 	if (!asset) {
@@ -1253,7 +1249,7 @@ void MToonElement::activate() {
 		return;
 	}
 
-	_cachedMToon = static_cast<MToonAsset *>(asset.get())->loadAndCacheMToon(_runtime);
+	_cachedMToon = static_cast<MToonAsset *>(asset.get())->loadAndCacheMToon(getRuntime());
 	_metadata = _cachedMToon->getMetadata();
 
 	_playMediaSignaller = project->notifyOnPlayMedia(this);
@@ -1278,7 +1274,7 @@ bool MToonElement::canAutoPlay() const {
 
 void MToonElement::render(Window *window) {
 	if (_cachedMToon) {
-		_cachedMToon->optimize(_runtime);
+		_cachedMToon->optimize(getRuntime());
 
 		uint32 frame = _cel - 1;
 		assert(frame < _metadata->frames.size());
@@ -1288,7 +1284,7 @@ void MToonElement::render(Window *window) {
 		if (_renderSurface->format.bytesPerPixel == 1) {
 			const Palette *palette = getPalette().get();
 			if (!palette)
-				palette = &_runtime->getGlobalPalette();
+				palette = &getRuntime()->getGlobalPalette();
 
 			// FIXME: Should support passing the palette to the blit function instead
 			_renderSurface->setPalette(palette->getPalette(), 0, 256);
@@ -1643,7 +1639,7 @@ MiniscriptInstructionOutcome MToonElement::scriptSetRangeTyped(MiniscriptThread
 }
 
 void MToonElement::onPauseStateChanged() {
-	_celStartTimeMSec = _runtime->getPlayTime();
+	_celStartTimeMSec = getRuntime()->getPlayTime();
 }
 
 MiniscriptInstructionOutcome MToonElement::scriptSetRate(MiniscriptThread *thread, const DynamicValue &value) {
@@ -1666,7 +1662,7 @@ MiniscriptInstructionOutcome MToonElement::scriptSetRate(MiniscriptThread *threa
 
 TextLabelElement::TextLabelElement()
 	: _cacheBitmap(false), _needsRender(false), /*_isBitmap(false), */_assetID(0),
-	  _macFontID(0), _size(12), _alignment(kTextAlignmentLeft), _runtime(nullptr) {
+	  _macFontID(0), _size(12), _alignment(kTextAlignmentLeft) {
 }
 
 TextLabelElement::~TextLabelElement() {
@@ -1682,7 +1678,6 @@ bool TextLabelElement::load(ElementLoaderContext &context, const Data::TextLabel
 
 	_cacheBitmap = ((data.elementFlags & Data::ElementFlags::kCacheBitmap) != 0);
 	_assetID = data.assetID;
-	_runtime = context.runtime;
 
 	return true;
 }
@@ -1745,7 +1740,7 @@ MiniscriptInstructionOutcome TextLabelElement::writeRefAttributeIndexed(Miniscri
 }
 
 void TextLabelElement::activate() {
-	Project *project = _runtime->getProject();
+	Project *project = getRuntime()->getProject();
 	Common::SharedPtr<Asset> asset = project->getAssetByID(_assetID).lock();
 
 	if (!asset) {
@@ -1823,7 +1818,7 @@ void TextLabelElement::render(Window *window) {
 			Graphics::MacFont macFont(_macFontID, _size, slant);
 			macFont.setFallback(fallback);
 
-			font = _runtime->getMacFontManager()->getFont(macFont);
+			font = getRuntime()->getMacFontManager()->getFont(macFont);
 		}
 
 		// Some weird cases (like the Immediate Action entryway in Obsidian) have no font info at all
@@ -2060,7 +2055,7 @@ MiniscriptInstructionOutcome TextLabelElement::TextLabelLineWriteInterface::refA
 
 SoundElement::SoundElement()
 	: _leftVolume(0), _rightVolume(0), _balance(0), _assetID(0), _startTime(0), _finishTime(0), _cueCheckTime(0),
-	  _startTimestamp(0), _shouldPlayIfNotPaused(true), _needsReset(true), _runtime(nullptr) {
+	  _startTimestamp(0), _shouldPlayIfNotPaused(true), _needsReset(true) {
 }
 
 SoundElement::~SoundElement() {
@@ -2078,7 +2073,6 @@ bool SoundElement::load(ElementLoaderContext &context, const Data::SoundElement
 	_rightVolume = data.rightVolume;
 	_balance = data.balance;
 	_assetID = data.assetID;
-	_runtime = context.runtime;
 
 	return true;
 }
@@ -2128,7 +2122,7 @@ VThreadState SoundElement::consumeCommand(Runtime *runtime, const Common::Shared
 }
 
 void SoundElement::activate() {
-	Project *project = _runtime->getProject();
+	Project *project = getRuntime()->getProject();
 	Common::SharedPtr<Asset> asset = project->getAssetByID(_assetID).lock();
 
 	if (!asset) {
@@ -2141,7 +2135,7 @@ void SoundElement::activate() {
 		return;
 	}
 
-	_cachedAudio = static_cast<AudioAsset *>(asset.get())->loadAndCacheAudio(_runtime);
+	_cachedAudio = static_cast<AudioAsset *>(asset.get())->loadAndCacheAudio(getRuntime());
 	_metadata = static_cast<AudioAsset *>(asset.get())->getMetadata();
 
 	_playMediaSignaller = project->notifyOnPlayMedia(this);
@@ -2159,7 +2153,7 @@ void SoundElement::activate() {
 		}
 
 		if (subtitleSetIDPtr)
-			_subtitlePlayer.reset(new SubtitlePlayer(_runtime, *subtitleSetIDPtr, subTables));
+			_subtitlePlayer.reset(new SubtitlePlayer(getRuntime(), *subtitleSetIDPtr, subTables));
 	}
 }
 
@@ -2194,21 +2188,21 @@ void SoundElement::playMedia(Runtime *runtime, Project *project) {
 			}
 
 			if (!_player) {
-				_finishTime = _runtime->getPlayTime() + _metadata->durationMSec;
+				_finishTime = getRuntime()->getPlayTime() + _metadata->durationMSec;
 
 				int normalizedVolume = (_leftVolume + _rightVolume) * 255 / 200;
 				int normalizedBalance = _balance * 127 / 100;
 
 				// TODO: Support ranges
 				size_t numSamples = _cachedAudio->getNumSamples(*_metadata);
-				_player.reset(new AudioPlayer(_runtime->getAudioMixer(), normalizedVolume, normalizedBalance, _metadata, _cachedAudio, _loop, 0, 0, numSamples));
+				_player.reset(new AudioPlayer(getRuntime()->getAudioMixer(), normalizedVolume, normalizedBalance, _metadata, _cachedAudio, _loop, 0, 0, numSamples));
 
 				_startTime = runtime->getPlayTime();
 				_cueCheckTime = _startTime;
 				_startTimestamp = 0;
 			}
 
-			uint64 newTime = _runtime->getPlayTime();
+			uint64 newTime = getRuntime()->getPlayTime();
 			if (newTime > _cueCheckTime) {
 				uint64 oldTimeRelative = _cueCheckTime - _startTime + _startTimestamp;
 				uint64 newTimeRelative = newTime - _startTime + _startTimestamp;
diff --git a/engines/mtropolis/elements.h b/engines/mtropolis/elements.h
index 8b773c5960d..e07dee2a7a4 100644
--- a/engines/mtropolis/elements.h
+++ b/engines/mtropolis/elements.h
@@ -173,8 +173,6 @@ private:
 	Common::SharedPtr<SubtitlePlayer> _subtitles;
 
 	Common::Array<int> _damagedFrames;
-
-	Runtime *_runtime;
 };
 
 class ImageElement : public VisualElement {
@@ -207,8 +205,6 @@ private:
 	Common::SharedPtr<CachedImage> _cachedImage;
 
 	Common::String _text;	// ...???
-
-	Runtime *_runtime;
 };
 
 class MToonElement : public VisualElement, public IPlayMediaSignalReceiver {
@@ -287,7 +283,6 @@ private:
 	uint32 _celStartTimeMSec;
 	bool _isPlaying;	// Is actually rolling media, this is only set by playMedia because it needs to start after scene transition
 
-	Runtime *_runtime;
 	Common::SharedPtr<Graphics::ManagedSurface> _renderSurface;
 	uint32 _renderedFrame;
 
@@ -361,8 +356,6 @@ private:
 	// If you need to render again, recreate the surface.  If you want to change
 	// this behavior, please add a flag indicating that it is from the asset.
 	Common::SharedPtr<Graphics::ManagedSurface> _renderedText;
-
-	Runtime *_runtime;
 };
 
 class SoundElement : public NonVisualElement, public IPlayMediaSignalReceiver {
@@ -430,8 +423,6 @@ private:
 	Common::SharedPtr<PlayMediaSignaller> _playMediaSignaller;
 
 	Common::SharedPtr<SubtitlePlayer> _subtitlePlayer;
-
-	Runtime *_runtime;
 };
 
 } // End of namespace MTropolis
diff --git a/engines/mtropolis/hacks.cpp b/engines/mtropolis/hacks.cpp
index 5ee54392aac..9e3c2ad353a 100644
--- a/engines/mtropolis/hacks.cpp
+++ b/engines/mtropolis/hacks.cpp
@@ -42,6 +42,7 @@ Hacks::Hacks() {
 	minTransitionDuration = 0;
 	ignoreMToonMaintainRateFlag = false;
 	mtiVariableReferencesHack = false;
+	mtiSceneReturnHack = false;
 }
 
 Hacks::~Hacks() {
@@ -1044,6 +1045,11 @@ void addMTIQuirks(const MTropolisGameDescription &desc, Hacks &hacks) {
 	// Haven't figured out anything that would explain why it would reference the variables in the compound
 	// modifier.  Probably some quirk of early-version mTropolis.
 	hacks.mtiVariableReferencesHack = true;
+
+	// MTI returns from the menu by transitioning to a "return" scene that sends a return message to the target
+	// scene, which is supposed to activate a scene transtion modifier in the scene that transitions to itself.
+	// This doesn't work because the modifier is gone when the scene is unloaded.
+	hacks.mtiSceneReturnHack = true;
 }
 
 } // End of namespace HackSuites
diff --git a/engines/mtropolis/hacks.h b/engines/mtropolis/hacks.h
index cf8a77bd125..57ce41b65b4 100644
--- a/engines/mtropolis/hacks.h
+++ b/engines/mtropolis/hacks.h
@@ -52,6 +52,7 @@ struct Hacks {
 	bool removeQuickTimeEdits;
 	bool ignoreMToonMaintainRateFlag;
 	bool mtiVariableReferencesHack;
+	bool mtiSceneReturnHack;
 
 	uint midiVolumeScale;	// 256 = 1.0
 
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index fdeba34d32a..5630ee7706c 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -2935,7 +2935,10 @@ void StructuralHooks::onSetPosition(Runtime *runtime, Structural *structural, Co
 ProjectPresentationSettings::ProjectPresentationSettings() : width(640), height(480), bitsPerPixel(8) {
 }
 
-Structural::Structural() : _parent(nullptr), _paused(false), _loop(false), _flushPriority(0) {
+Structural::Structural() : Structural(nullptr) {
+}
+
+Structural::Structural(Runtime *runtime) : _parent(nullptr), _paused(false), _loop(false), _flushPriority(0), _runtime(runtime) {
 }
 
 Structural::~Structural() {
@@ -3239,6 +3242,10 @@ Structural *Structural::findPrevSibling() const {
 	return nullptr;
 }
 
+Runtime *Structural::getRuntime() const {
+	return _runtime;
+}
+
 void Structural::setParent(Structural *parent) {
 	_parent = parent;
 }
@@ -3281,6 +3288,8 @@ void Structural::materializeSelfAndDescendents(Runtime *runtime, ObjectLinkingSc
 	setRuntimeGUID(runtime->allocateRuntimeGUID());
 
 	materializeDescendents(runtime, outerScope);
+
+	_runtime = runtime;
 }
 
 void Structural::materializeDescendents(Runtime *runtime, ObjectLinkingScope *outerScope) {
@@ -6703,7 +6712,7 @@ Project::AssetDesc::AssetDesc() : typeCode(0), id(0) {
 }
 
 Project::Project(Runtime *runtime)
-	: _runtime(runtime), _projectFormat(Data::kProjectFormatUnknown), _isBigEndian(false),
+	: Structural(runtime), _projectFormat(Data::kProjectFormatUnknown), _isBigEndian(false),
 	  _haveGlobalObjectInfo(false), _haveProjectStructuralDef(false), _playMediaSignaller(new PlayMediaSignaller()),
 	  _keyboardEventSignaller(new KeyboardEventSignaller()) {
 }
@@ -7022,7 +7031,7 @@ Common::SharedPtr<SegmentUnloadSignaller> Project::notifyOnSegmentUnload(int seg
 }
 
 void Project::onPostRender() {
-	_playMediaSignaller->playMedia(_runtime, this);
+	_playMediaSignaller->playMedia(getRuntime(), this);
 }
 
 Common::SharedPtr<PlayMediaSignaller> Project::notifyOnPlayMedia(IPlayMediaSignalReceiver *receiver) {
@@ -7245,7 +7254,7 @@ Common::SharedPtr<Modifier> Project::loadModifierObject(ModifierLoaderContext &l
 		error("Modifier object failed to load");
 
 	uint32 guid = modifier->getStaticGUID();
-	const Common::HashMap<uint32, Common::SharedPtr<ModifierHooks> > &hooksMap = _runtime->getHacks().modifierHooks;
+	const Common::HashMap<uint32, Common::SharedPtr<ModifierHooks> > &hooksMap = getRuntime()->getHacks().modifierHooks;
 	Common::HashMap<uint32, Common::SharedPtr<ModifierHooks> >::const_iterator hooksIt = hooksMap.find(guid);
 	if (hooksIt != hooksMap.end()) {
 		modifier->setHooks(hooksIt->_value);
@@ -7474,11 +7483,11 @@ void Project::loadContextualObject(size_t streamIndex, ChildLoaderStack &stack,
 					error("No element factory defined for structural object");
 				}
 
-				ElementLoaderContext elementLoaderContext(_runtime, streamIndex);
+				ElementLoaderContext elementLoaderContext(getRuntime(), streamIndex);
 				Common::SharedPtr<Element> element = elementFactory->createElement(elementLoaderContext, dataObject);
 
 				uint32 guid = element->getStaticGUID();
-				const Common::HashMap<uint32, Common::SharedPtr<StructuralHooks> > &hooksMap = _runtime->getHacks().structuralHooks;
+				const Common::HashMap<uint32, Common::SharedPtr<StructuralHooks> > &hooksMap = getRuntime()->getHacks().structuralHooks;
 				Common::HashMap<uint32, Common::SharedPtr<StructuralHooks> >::const_iterator hooksIt = hooksMap.find(guid);
 				if (hooksIt != hooksMap.end()) {
 					element->setHooks(hooksIt->_value);
@@ -7843,6 +7852,29 @@ VThreadState VisualElement::consumeCommand(Runtime *runtime, const Common::Share
 	return Element::consumeCommand(runtime, msg);
 }
 
+bool VisualElement::respondsToEvent(const Event &evt) const {
+	if (Event(EventIDs::kAuthorMessage, 13).respondsTo(evt)) {
+		if (getRuntime()->getHacks().mtiSceneReturnHack)
+			return true;
+	}
+
+	return Element::respondsToEvent(evt);
+}
+
+VThreadState VisualElement::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
+	if (Event(EventIDs::kAuthorMessage, 13).respondsTo(msg->getEvent())) {
+		if (getRuntime()->getHacks().mtiSceneReturnHack) {
+			assert(this->getParent());
+			assert(this->getParent()->isSubsection());
+			runtime->addSceneStateTransition(HighLevelSceneTransition(this->getSelfReference().lock().staticCast<Structural>(), HighLevelSceneTransition::kTypeChangeToScene, false, false));
+
+			return kVThreadReturn;
+		}
+	}
+
+	return Element::consumeMessage(runtime, msg);
+}
+
 bool VisualElement::isMouseInsideDrawableArea(int32 relativeX, int32 relativeY) const {
 	if (relativeX < _rect.left || relativeX >= _rect.right || relativeY < _rect.top || relativeY >= _rect.bottom)
 		return false;
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index c657bbf59e1..1e35aecbfa6 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -2099,6 +2099,7 @@ public:
 class Structural : public RuntimeObject, public IModifierContainer, public IMessageConsumer, public Debuggable {
 public:
 	Structural();
+	explicit Structural(Runtime *runtime);
 	virtual ~Structural();
 
 	bool isStructural() const override;
@@ -2165,6 +2166,8 @@ protected:
 
 	virtual void onPauseStateChanged();
 
+	Runtime *getRuntime() const;
+
 	Structural *_parent;
 	Common::Array<Common::SharedPtr<Structural> > _children;
 	Common::Array<Common::SharedPtr<Modifier> > _modifiers;
@@ -2184,6 +2187,9 @@ protected:
 	int32 _flushPriority;
 
 	Common::SharedPtr<StructuralHooks> _hooks;
+
+private:
+	Runtime *_runtime;
 };
 
 struct ProjectPresentationSettings {
@@ -2493,8 +2499,6 @@ private:
 	Common::SharedPtr<KeyboardEventSignaller> _keyboardEventSignaller;
 
 	SubtitleTables _subtitles;
-
-	Runtime *_runtime;
 };
 
 class Section : public Structural {
@@ -2672,6 +2676,9 @@ public:
 
 	VThreadState consumeCommand(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
 
+	bool respondsToEvent(const Event &evt) const override;
+	VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
+
 	bool isVisible() const;
 	void setVisible(Runtime *runtime, bool visible);
 




More information about the Scummvm-git-logs mailing list