[Scummvm-git-logs] scummvm master -> f14a24f07c8ecf6a43f16eeb92f7af5ab54ea322
elasota
noreply at scummvm.org
Sat Jul 16 08:30:00 UTC 2022
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d2cd12a976 MTROPOLIS: Change minimum wipe duration to 500ms
f120ec49f9 MTROPOLIS: Add debug inspectors for movement and rectshift modifiers
f14a24f07c MTROPOLIS: Implement Obsidian rectshift and movement modifiers
Commit: d2cd12a9766c3413091b7ed61382d77701095e37
https://github.com/scummvm/scummvm/commit/d2cd12a9766c3413091b7ed61382d77701095e37
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-16T04:29:01-04:00
Commit Message:
MTROPOLIS: Change minimum wipe duration to 500ms
Changed paths:
engines/mtropolis/plugin/standard.cpp
diff --git a/engines/mtropolis/plugin/standard.cpp b/engines/mtropolis/plugin/standard.cpp
index b8fff035c0d..b279d185ed5 100644
--- a/engines/mtropolis/plugin/standard.cpp
+++ b/engines/mtropolis/plugin/standard.cpp
@@ -1619,8 +1619,10 @@ VThreadState STransCtModifier::consumeMessage(Runtime *runtime, const Common::Sh
// Weird quirk: Duration doesn't seem to affect duration properly for wipe transitions.
// In Obsidian, this mostly effects 180-degree turns.
// Good place to test this is in the corners of the Bureau library.
- if (effect._transitionType == SceneTransitionTypes::kWipe && effect._duration < 1000)
- effect._duration = 1000;
+ const uint32 kMinWipeDuration = 500;
+
+ if (effect._transitionType == SceneTransitionTypes::kWipe && effect._duration < kMinWipeDuration)
+ effect._duration = kMinWipeDuration;
runtime->setSceneTransitionEffect(false, &effect);
} else {
Commit: f120ec49f99268c07755505f9d0a2f307ad86f66
https://github.com/scummvm/scummvm/commit/f120ec49f99268c07755505f9d0a2f307ad86f66
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-16T04:29:01-04:00
Commit Message:
MTROPOLIS: Add debug inspectors for movement and rectshift modifiers
Changed paths:
engines/mtropolis/plugin/obsidian.cpp
engines/mtropolis/plugin/obsidian.h
diff --git a/engines/mtropolis/plugin/obsidian.cpp b/engines/mtropolis/plugin/obsidian.cpp
index 77bdfe60e05..cc301a0db87 100644
--- a/engines/mtropolis/plugin/obsidian.cpp
+++ b/engines/mtropolis/plugin/obsidian.cpp
@@ -59,6 +59,17 @@ MiniscriptInstructionOutcome MovementModifier::writeRefAttribute(MiniscriptThrea
return Modifier::writeRefAttribute(thread, result, attrib);
}
+#ifdef MTROPOLIS_DEBUG_ENABLE
+void MovementModifier::debugInspect(IDebugInspectionReport *report) const {
+ Modifier::debugInspect(report);
+
+ report->declareDynamic("rate", Common::String::format("%i", static_cast<int>(_rate)));
+ report->declareDynamic("frequency", Common::String::format("%i", static_cast<int>(_frequency)));
+ report->declareDynamic("type", Common::String::format(_type ? "true" : "false"));
+ report->declareDynamic("dest", Common::String::format("(%i,%i)", static_cast<int>(_dest.x), static_cast<int>(_dest.y)));
+}
+#endif
+
Common::SharedPtr<Modifier> MovementModifier::shallowClone() const {
return Common::SharedPtr<Modifier>(new MovementModifier(*this));
}
@@ -90,6 +101,15 @@ MiniscriptInstructionOutcome RectShiftModifier::writeRefAttribute(MiniscriptThre
return Modifier::writeRefAttribute(thread, result, attrib);
}
+#ifdef MTROPOLIS_DEBUG_ENABLE
+void RectShiftModifier::debugInspect(IDebugInspectionReport *report) const {
+ Modifier::debugInspect(report);
+
+ report->declareDynamic("direction", Common::String::format("%i", static_cast<int>(_direction)));
+ report->declareDynamic("rate", Common::String::format("%i", static_cast<int>(_rate)));
+}
+#endif
+
Common::SharedPtr<Modifier> RectShiftModifier::shallowClone() const {
return Common::SharedPtr<Modifier>(new RectShiftModifier(*this));
}
diff --git a/engines/mtropolis/plugin/obsidian.h b/engines/mtropolis/plugin/obsidian.h
index 3c539247b08..15c531b1125 100644
--- a/engines/mtropolis/plugin/obsidian.h
+++ b/engines/mtropolis/plugin/obsidian.h
@@ -42,6 +42,7 @@ public:
#ifdef MTROPOLIS_DEBUG_ENABLE
const char *debugGetTypeName() const override { return "Movement Modifier"; }
+ void debugInspect(IDebugInspectionReport *report) const override;
#endif
private:
@@ -62,6 +63,7 @@ public:
#ifdef MTROPOLIS_DEBUG_ENABLE
const char *debugGetTypeName() const override { return "Rect Shift Modifier"; }
+ void debugInspect(IDebugInspectionReport *report) const override;
#endif
private:
Commit: f14a24f07c8ecf6a43f16eeb92f7af5ab54ea322
https://github.com/scummvm/scummvm/commit/f14a24f07c8ecf6a43f16eeb92f7af5ab54ea322
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-16T04:29:01-04:00
Commit Message:
MTROPOLIS: Implement Obsidian rectshift and movement modifiers
Changed paths:
engines/mtropolis/plugin/obsidian.cpp
engines/mtropolis/plugin/obsidian.h
engines/mtropolis/plugin/obsidian_data.cpp
engines/mtropolis/plugin/obsidian_data.h
engines/mtropolis/plugin/standard_data.h
engines/mtropolis/render.cpp
engines/mtropolis/runtime.cpp
engines/mtropolis/runtime.h
diff --git a/engines/mtropolis/plugin/obsidian.cpp b/engines/mtropolis/plugin/obsidian.cpp
index cc301a0db87..a5b4b76f330 100644
--- a/engines/mtropolis/plugin/obsidian.cpp
+++ b/engines/mtropolis/plugin/obsidian.cpp
@@ -19,6 +19,8 @@
*
*/
+#include "graphics/managed_surface.h"
+
#include "mtropolis/plugin/obsidian.h"
#include "mtropolis/plugins.h"
@@ -28,16 +30,78 @@ namespace MTropolis {
namespace Obsidian {
+MovementModifier::MovementModifier() : _runtime(nullptr) {
+}
+
+MovementModifier::~MovementModifier() {
+ if (_moveEvent)
+ _moveEvent->cancel();
+}
+
bool MovementModifier::load(const PlugInModifierLoaderContext &context, const Data::Obsidian::MovementModifier &data) {
- // FIXME: Map these
- _rate = 0;
- _frequency = 0;
- _type = false;
- _dest = Common::Point(0, 0);
+
+ if (data.enableWhen.type != Data::PlugInTypeTaggedValue::kEvent || !_enableWhen.load(data.enableWhen.value.asEvent))
+ return false;
+
+ if (data.disableWhen.type != Data::PlugInTypeTaggedValue::kEvent || !_disableWhen.load(data.disableWhen.value.asEvent))
+ return false;
+
+ if (data.rate.type != Data::PlugInTypeTaggedValue::kFloat)
+ return false;
+
+ _rate = data.rate.value.asFloat.toXPFloat().toDouble();
+
+ if (data.frequency.type != Data::PlugInTypeTaggedValue::kInteger)
+ return false;
+
+ _frequency = data.frequency.value.asInt;
+
+ if (data.type.type != Data::PlugInTypeTaggedValue::kBoolean)
+ return false;
+
+ _type = (data.type.value.asBoolean != 0);
+
+ if (data.dest.type != Data::PlugInTypeTaggedValue::kPoint || !data.dest.value.asPoint.toScummVMPoint(_dest))
+ return false;
+
+ if (data.triggerEvent.type != Data::PlugInTypeTaggedValue::kEvent || !_triggerEvent.load(data.triggerEvent.value.asEvent))
+ return false;
return true;
}
+bool MovementModifier::respondsToEvent(const Event &evt) const {
+ return _enableWhen.respondsTo(evt) || _disableWhen.respondsTo(evt);
+}
+
+VThreadState MovementModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
+ if (_enableWhen.respondsTo(msg->getEvent())) {
+ Structural *structural = findStructuralOwner();
+ if (structural == nullptr || !structural->isElement() || !static_cast<Element *>(structural)->isVisual()) {
+ warning("Movement modifier wasn't attached to a visual element");
+ return kVThreadError;
+ }
+ VisualElement *visual = static_cast<VisualElement *>(structural);
+
+ Common::Rect startRect = visual->getRelativeRect();
+ _moveStartPoint = Common::Point(startRect.left, startRect.top);
+ _moveStartTime = runtime->getPlayTime();
+
+ if (!_moveEvent) {
+ _runtime = runtime;
+ _moveEvent = runtime->getScheduler().scheduleMethod<MovementModifier, &MovementModifier::triggerMove>(runtime->getPlayTime() + 1, this);
+ }
+ }
+ if (_disableWhen.respondsTo(msg->getEvent())) {
+ if (_moveEvent) {
+ _moveEvent->cancel();
+ _moveEvent.reset();
+ }
+ }
+
+ return kVThreadReturn;
+}
+
MiniscriptInstructionOutcome MovementModifier::writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib) {
if (attrib == "type") {
DynamicValueWriteBoolHelper::create(&_type, result);
@@ -48,7 +112,7 @@ MiniscriptInstructionOutcome MovementModifier::writeRefAttribute(MiniscriptThrea
return kMiniscriptInstructionOutcomeContinue;
}
if (attrib == "rate") {
- DynamicValueWriteIntegerHelper<int32>::create(&_rate, result);
+ DynamicValueWriteFloatHelper<double>::create(&_rate, result);
return kMiniscriptInstructionOutcomeContinue;
}
if (attrib == "frequency") {
@@ -63,10 +127,13 @@ MiniscriptInstructionOutcome MovementModifier::writeRefAttribute(MiniscriptThrea
void MovementModifier::debugInspect(IDebugInspectionReport *report) const {
Modifier::debugInspect(report);
- report->declareDynamic("rate", Common::String::format("%i", static_cast<int>(_rate)));
+ report->declareDynamic("enableWhen", Common::String::format("Event(%i,%i)", static_cast<int>(_enableWhen.eventType), static_cast<int>(_enableWhen.eventInfo)));
+ report->declareDynamic("disableWhen", Common::String::format("Event(%i,%i)", static_cast<int>(_disableWhen.eventType), static_cast<int>(_disableWhen.eventInfo)));
+ report->declareDynamic("rate", Common::String::format("%g", _rate));
report->declareDynamic("frequency", Common::String::format("%i", static_cast<int>(_frequency)));
report->declareDynamic("type", Common::String::format(_type ? "true" : "false"));
report->declareDynamic("dest", Common::String::format("(%i,%i)", static_cast<int>(_dest.x), static_cast<int>(_dest.y)));
+ report->declareDynamic("triggerEvent", Common::String::format("Event(%i,%i)", static_cast<int>(_triggerEvent.eventType), static_cast<int>(_triggerEvent.eventInfo)));
}
#endif
@@ -78,21 +145,100 @@ const char *MovementModifier::getDefaultName() const {
return "Movement";
}
+void MovementModifier::triggerMove(Runtime *runtime) {
+ _moveEvent.reset();
+
+ Structural *structural = findStructuralOwner();
+ if (structural == nullptr || !structural->isElement() || !static_cast<Element *>(structural)->isVisual()) {
+ warning("Movement modifier wasn't attached to a visual element");
+ return;
+ }
+ VisualElement *visual = static_cast<VisualElement *>(structural);
+
+
+ Common::Point delta = _dest - _moveStartPoint;
+
+ double deltaLength = sqrt(delta.x * delta.x + delta.y * delta.y);
+
+ double progression = 1.0;
+ if (deltaLength > 0.0 && _rate > 0.0) {
+ double distance = static_cast<double>(runtime->getPlayTime() - _moveStartTime) * _rate / 1000.0;
+ progression = distance / deltaLength;
+ if (progression > 1.0)
+ progression = 1.0;
+ if (progression < 0.0)
+ progression = 0.0;
+ }
+
+ int32 targetX = _moveStartPoint.x + static_cast<int32>(round((_dest.x - _moveStartPoint.x) * progression));
+ int32 targetY = _moveStartPoint.y + static_cast<int32>(round((_dest.y - _moveStartPoint.y) * progression));
+
+ Common::Rect relRect = visual->getRelativeRect();
+ int32 xDelta = targetX - relRect.left;
+ int32 yDelta = targetY - relRect.top;
+
+ relRect.left += xDelta;
+ relRect.right += xDelta;
+ relRect.top += yDelta;
+ relRect.bottom += yDelta;
+
+ visual->setRelativeRect(relRect);
+
+ if (progression == 1.0) {
+ Common::SharedPtr<MessageProperties> props(new MessageProperties(_triggerEvent, DynamicValue(), visual->getSelfReference()));
+ Common::SharedPtr<MessageDispatch> dispatch(new MessageDispatch(props, visual, true, true, false));
+ runtime->sendMessageOnVThread(dispatch);
+ } else {
+ _moveEvent = runtime->getScheduler().scheduleMethod<MovementModifier, &MovementModifier::triggerMove>(runtime->getPlayTime() + 1, this);
+ }
+}
+
+RectShiftModifier::RectShiftModifier() : _enableWhen(Event::create()), _disableWhen(Event::create()), _direction(0), _runtime(nullptr), _isActive(false) {
+}
+
+RectShiftModifier::~RectShiftModifier() {
+ if (_isActive)
+ _runtime->removePostEffect(this);
+}
+
+bool RectShiftModifier::respondsToEvent(const Event &evt) const {
+ return _enableWhen.respondsTo(evt) || _disableWhen.respondsTo(evt);
+}
+
+VThreadState RectShiftModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
+ if (_enableWhen.respondsTo(msg->getEvent()) && !_isActive) {
+ _runtime = runtime;
+ _runtime->addPostEffect(this);
+ _isActive = true;
+ }
+ if (_disableWhen.respondsTo(msg->getEvent()) && _isActive) {
+ _isActive = false;
+ _runtime->removePostEffect(this);
+ _runtime = nullptr;
+ }
+
+ return kVThreadReturn;
+}
+
bool RectShiftModifier::load(const PlugInModifierLoaderContext &context, const Data::Obsidian::RectShiftModifier &data) {
- if (data.rate.type != Data::PlugInTypeTaggedValue::kInteger)
+ if (data.enableWhen.type != Data::PlugInTypeTaggedValue::kEvent || !_enableWhen.load(data.enableWhen.value.asEvent))
+ return false;
+
+ if (data.disableWhen.type != Data::PlugInTypeTaggedValue::kEvent || !_disableWhen.load(data.disableWhen.value.asEvent))
+ return false;
+
+ if (data.direction.type != Data::PlugInTypeTaggedValue::kInteger)
return false;
- _direction = 0;
- _rate = data.rate.value.asInt;
+ _direction = data.direction.value.asInt;
+
+ if (data.enableWhen.type != Data::PlugInTypeTaggedValue::kEvent || !_enableWhen.load(data.enableWhen.value.asEvent))
+ return false;
return true;
}
MiniscriptInstructionOutcome RectShiftModifier::writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib) {
- if (attrib == "rate") {
- DynamicValueWriteIntegerHelper<int32>::create(&_rate, result);
- return kMiniscriptInstructionOutcomeContinue;
- }
if (attrib == "direction") {
DynamicValueWriteIntegerHelper<int32>::create(&_direction, result);
return kMiniscriptInstructionOutcomeContinue;
@@ -101,17 +247,69 @@ MiniscriptInstructionOutcome RectShiftModifier::writeRefAttribute(MiniscriptThre
return Modifier::writeRefAttribute(thread, result, attrib);
}
+void RectShiftModifier::renderPostEffect(Graphics::ManagedSurface &surface) const {
+ Structural *structural = findStructuralOwner();
+ if (!structural)
+ return;
+
+ if (!structural->isElement() || !static_cast<Element *>(structural)->isVisual())
+ return;
+
+ VisualElement *visual = static_cast<VisualElement *>(structural);
+
+ Common::Point absOrigin = visual->getCachedAbsoluteOrigin();
+ Common::Rect relRect = visual->getRelativeRect();
+ Common::Rect absRect(absOrigin.x, absOrigin.y, absOrigin.x + relRect.width(), absOrigin.y + relRect.height());
+
+ if (absRect.left < 0)
+ absRect.left = 0;
+ if (absRect.right >= surface.w)
+ absRect.right = surface.w;
+ if (absRect.top < 0)
+ absRect.top = 0;
+ if (absRect.bottom >= surface.h)
+ absRect.bottom = surface.h;
+
+ if (_direction == 1) {
+ if (absRect.bottom + 1 >= surface.h)
+ absRect.bottom--;
+ } else if (_direction == 4) {
+ if (absRect.right + 1 >= surface.w)
+ absRect.right--;
+ } else
+ return;
+
+ if (!absRect.isValidRect())
+ return;
+
+ uint pitch = (absRect.right - absRect.left) * surface.format.bytesPerPixel;
+
+ for (int32 y = absRect.top; y < absRect.bottom; y++) {
+ void *destPixels = surface.getBasePtr(absRect.left, y);
+ void *srcPixels = destPixels;
+
+ if (_direction == 1)
+ srcPixels = surface.getBasePtr(absRect.left, y + 1);
+ else if (_direction == 4)
+ srcPixels = surface.getBasePtr(absRect.left + 1, y);
+
+ memmove(destPixels, srcPixels, pitch);
+ }
+}
+
#ifdef MTROPOLIS_DEBUG_ENABLE
void RectShiftModifier::debugInspect(IDebugInspectionReport *report) const {
Modifier::debugInspect(report);
report->declareDynamic("direction", Common::String::format("%i", static_cast<int>(_direction)));
- report->declareDynamic("rate", Common::String::format("%i", static_cast<int>(_rate)));
}
#endif
Common::SharedPtr<Modifier> RectShiftModifier::shallowClone() const {
- return Common::SharedPtr<Modifier>(new RectShiftModifier(*this));
+ Common::SharedPtr<RectShiftModifier> clone(new RectShiftModifier(*this));
+ clone->_isActive = false;
+ clone->_runtime = nullptr;
+ return clone;
}
const char *RectShiftModifier::getDefaultName() const {
diff --git a/engines/mtropolis/plugin/obsidian.h b/engines/mtropolis/plugin/obsidian.h
index 15c531b1125..e966fbc9615 100644
--- a/engines/mtropolis/plugin/obsidian.h
+++ b/engines/mtropolis/plugin/obsidian.h
@@ -36,8 +36,14 @@ class WordGameData;
class MovementModifier : public Modifier {
public:
+ MovementModifier();
+ ~MovementModifier();
+
bool load(const PlugInModifierLoaderContext &context, const Data::Obsidian::MovementModifier &data);
+ bool respondsToEvent(const Event &evt) const override;
+ VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
+
MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib) override;
#ifdef MTROPOLIS_DEBUG_ENABLE
@@ -49,18 +55,39 @@ private:
Common::SharedPtr<Modifier> shallowClone() const override;
const char *getDefaultName() const override;
+ void triggerMove(Runtime *runtime);
+
Common::Point _dest;
bool _type;
- int32 _rate;
+ double _rate;
int32 _frequency;
+
+ Event _enableWhen;
+ Event _disableWhen;
+
+ Event _triggerEvent;
+
+ Common::Point _moveStartPoint;
+ uint64 _moveStartTime;
+
+ Common::SharedPtr<ScheduledEvent> _moveEvent;
+ Runtime *_runtime;
};
-class RectShiftModifier : public Modifier {
+class RectShiftModifier : public Modifier, public IPostEffect {
public:
+ RectShiftModifier();
+ ~RectShiftModifier();
+
+ bool respondsToEvent(const Event &evt) const override;
+ VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
+
bool load(const PlugInModifierLoaderContext &context, const Data::Obsidian::RectShiftModifier &data);
MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &result, const Common::String &attrib) override;
+ void renderPostEffect(Graphics::ManagedSurface &surface) const override;
+
#ifdef MTROPOLIS_DEBUG_ENABLE
const char *debugGetTypeName() const override { return "Rect Shift Modifier"; }
void debugInspect(IDebugInspectionReport *report) const override;
@@ -70,8 +97,13 @@ private:
Common::SharedPtr<Modifier> shallowClone() const override;
const char *getDefaultName() const override;
- int32 _rate;
+ Event _enableWhen;
+ Event _disableWhen;
+
int32 _direction;
+
+ Runtime *_runtime;
+ bool _isActive;
};
class TextWorkModifier : public Modifier {
diff --git a/engines/mtropolis/plugin/obsidian_data.cpp b/engines/mtropolis/plugin/obsidian_data.cpp
index 97b4529831a..40591ef91ff 100644
--- a/engines/mtropolis/plugin/obsidian_data.cpp
+++ b/engines/mtropolis/plugin/obsidian_data.cpp
@@ -31,15 +31,15 @@ DataReadErrorCode MovementModifier::load(PlugIn &plugIn, const PlugInModifier &p
if (prefix.plugInRevision != 0)
return kDataReadErrorUnsupportedRevision;
- if (!unknown1Event.load(reader)
- || !unknown2Event.load(reader)
- || !unknown3Point.load(reader)
- || !unknown4Bool.load(reader)
+ if (!enableWhen.load(reader)
+ || !disableWhen.load(reader)
+ || !dest.load(reader)
+ || !type.load(reader)
|| !unknown5Point.load(reader)
|| !unknown6Int.load(reader)
- || !unknown7Float.load(reader)
- || !unknown8Int.load(reader)
- || !unknown9Event.load(reader)
+ || !rate.load(reader)
+ || !frequency.load(reader)
+ || !triggerEvent.load(reader)
|| !unknown10Label.load(reader)
|| !unknown11Null.load(reader)
|| !unknown12Int.load(reader))
@@ -52,7 +52,7 @@ DataReadErrorCode RectShiftModifier::load(PlugIn &plugIn, const PlugInModifier &
if (prefix.plugInRevision != 1)
return kDataReadErrorUnsupportedRevision;
- if (!unknown1Event.load(reader) || !unknown2Event.load(reader) || !rate.load(reader))
+ if (!enableWhen.load(reader) || !disableWhen.load(reader) || !direction.load(reader))
return kDataReadErrorReadFailed;
return kDataReadErrorNone;
diff --git a/engines/mtropolis/plugin/obsidian_data.h b/engines/mtropolis/plugin/obsidian_data.h
index 87f0ef29c9a..e29e2c0d581 100644
--- a/engines/mtropolis/plugin/obsidian_data.h
+++ b/engines/mtropolis/plugin/obsidian_data.h
@@ -40,27 +40,27 @@ namespace Obsidian {
// TextWork - Text manipulation operations
struct MovementModifier : public PlugInModifierData {
- PlugInTypeTaggedValue unknown1Event; // Probably "enable when"
- PlugInTypeTaggedValue unknown2Event; // Probably "disable when"
- PlugInTypeTaggedValue unknown3Point;
- PlugInTypeTaggedValue unknown4Bool;
- PlugInTypeTaggedValue unknown5Point;
- PlugInTypeTaggedValue unknown6Int;
- PlugInTypeTaggedValue unknown7Float;
- PlugInTypeTaggedValue unknown8Int;
- PlugInTypeTaggedValue unknown9Event;
- PlugInTypeTaggedValue unknown10Label;
- PlugInTypeTaggedValue unknown11Null;
- PlugInTypeTaggedValue unknown12Int;
+ PlugInTypeTaggedValue enableWhen; // Event
+ PlugInTypeTaggedValue disableWhen; // Event
+ PlugInTypeTaggedValue dest; // Point
+ PlugInTypeTaggedValue type; // Bool, seems to always be "false"
+ PlugInTypeTaggedValue unknown5Point; // Point, always (0,0)
+ PlugInTypeTaggedValue unknown6Int; // Int, always 5
+ PlugInTypeTaggedValue rate; // Float
+ PlugInTypeTaggedValue frequency; // Int
+ PlugInTypeTaggedValue triggerEvent;
+ PlugInTypeTaggedValue unknown10Label; // Label, always (5,108) which doesn't seem to correspond to anything
+ PlugInTypeTaggedValue unknown11Null; // Null, possibly message payload
+ PlugInTypeTaggedValue unknown12Int; // Int, always 3, possibly message flags
protected:
DataReadErrorCode load(PlugIn &plugIn, const PlugInModifier &prefix, DataReader &reader) override;
};
struct RectShiftModifier : public PlugInModifierData {
- PlugInTypeTaggedValue unknown1Event; // Probably "enable when"
- PlugInTypeTaggedValue unknown2Event; // Probably "disable when"
- PlugInTypeTaggedValue rate;
+ PlugInTypeTaggedValue enableWhen; // Event, enable when
+ PlugInTypeTaggedValue disableWhen; // Event, disable when
+ PlugInTypeTaggedValue direction; // Int, 4 = horizontal, 1 = vertical
protected:
DataReadErrorCode load(PlugIn &plugIn, const PlugInModifier &prefix, DataReader &reader) override;
diff --git a/engines/mtropolis/plugin/standard_data.h b/engines/mtropolis/plugin/standard_data.h
index 00a76be3a2b..259ba5339b6 100644
--- a/engines/mtropolis/plugin/standard_data.h
+++ b/engines/mtropolis/plugin/standard_data.h
@@ -61,7 +61,7 @@ struct MediaCueMessengerModifier : public PlugInModifierData {
enum MessageFlags {
kMessageFlagImmediate = 0x1,
kMessageFlagCascade = 0x2,
- kMessageFlagRelay = 0x3,
+ kMessageFlagRelay = 0x4,
};
enum TriggerTiming {
diff --git a/engines/mtropolis/render.cpp b/engines/mtropolis/render.cpp
index 005185d8be9..40e7caa4fc4 100644
--- a/engines/mtropolis/render.cpp
+++ b/engines/mtropolis/render.cpp
@@ -298,6 +298,9 @@ void renderProject(Runtime *runtime, Window *mainWindow) {
for (Common::Array<RenderItem>::const_iterator it = directBucket.begin(), itEnd = directBucket.end(); it != itEnd; ++it)
renderDirectElement(*it, mainWindow);
+
+ for (const IPostEffect *postEffect : runtime->getPostEffects())
+ postEffect->renderPostEffect(*mainWindow->getSurface());
}
runtime->clearSceneGraphDirty();
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index a4e52895c1f..cb0316cc31e 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -5525,6 +5525,24 @@ void Runtime::removeBoundaryDetector(IBoundaryDetector *boundaryDetector) {
}
}
+void Runtime::addPostEffect(IPostEffect *postEffect) {
+ _postEffects.push_back(postEffect);
+}
+
+void Runtime::removePostEffect(IPostEffect *postEffect) {
+ size_t numPostEffects = _postEffects.size();
+ for (size_t i = 0; i < numPostEffects; i++) {
+ if (_postEffects[i] == postEffect) {
+ _postEffects.remove_at(i);
+ return;
+ }
+ }
+}
+
+const Common::Array<IPostEffect *> &Runtime::getPostEffects() const {
+ return _postEffects;
+}
+
void Runtime::checkBoundaries() {
// Boundary Detection Messenger behavior is very quirky in mTropolis 1.1. Basically, if an object moves in the direction of
// the boundary, then it may trigger collision checks with the boundary. If it moves but does not move in the direction of
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index 84fe30dccea..684fcc599b8 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -98,6 +98,7 @@ struct IMessageConsumer;
struct IModifierContainer;
struct IPlugInModifierFactory;
struct IPlugInModifierFactoryAndDataFactory;
+struct IPostEffect;
struct ISaveUIProvider;
struct IStructuralReferenceVisitor;
struct MessageProperties;
@@ -1588,6 +1589,10 @@ public:
void removeBoundaryDetector(IBoundaryDetector *boundaryDetector);
void checkBoundaries();
+ void addPostEffect(IPostEffect *postEffect);
+ void removePostEffect(IPostEffect *postEffect);
+ const Common::Array<IPostEffect *> &getPostEffects() const;
+
const Common::String *resolveAttributeIDName(uint32 attribID) const;
#ifdef MTROPOLIS_DEBUG_ENABLE
@@ -1804,6 +1809,8 @@ private:
Common::Array<BoundaryCheckState> _boundaryChecks;
uint32 _collisionCheckTime;
+ Common::Array<IPostEffect *> _postEffects;
+
Hacks _hacks;
Common::HashMap<uint32, Common::String> _getSetAttribIDsToAttribName;
@@ -2156,6 +2163,10 @@ struct IBoundaryDetector : public IInterfaceBase {
virtual void triggerCollision(Runtime *runtime) = 0;
};
+struct IPostEffect : public IInterfaceBase {
+ virtual void renderPostEffect(Graphics::ManagedSurface &surface) const = 0;
+};
+
struct MediaCueState {
enum TriggerTiming {
kTriggerTimingStart = 0,
More information about the Scummvm-git-logs
mailing list