[Scummvm-git-logs] scummvm master -> d9642925ebe84a33ad31e8cb1186850576902f99
elasota
noreply at scummvm.org
Tue Jul 19 21:39:41 UTC 2022
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d285f0e96b MTROPOLIS: Clean up unused namespace def
56161d17f0 MTROPOLIS: Improve anamorphic filter
e43a2fcb89 MTROPOLIS: Fix STransCt wipe duration at 500ms since that seems to be the accurate behavior
0d8ba6982a MTROPOLIS: Make autorefreshcursor trigger later to fix Obsidian wave puzzle completing instantly in the Mac version
d9642925eb MTROPOLIS: Implement mToon stop command
Commit: d285f0e96b7bca8a7e1214b04574f1830fb024a3
https://github.com/scummvm/scummvm/commit/d285f0e96b7bca8a7e1214b04574f1830fb024a3
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-19T17:38:09-04:00
Commit Message:
MTROPOLIS: Clean up unused namespace def
Changed paths:
engines/mtropolis/assets.h
diff --git a/engines/mtropolis/assets.h b/engines/mtropolis/assets.h
index 6148ca38b9a..c1824a19243 100644
--- a/engines/mtropolis/assets.h
+++ b/engines/mtropolis/assets.h
@@ -26,9 +26,6 @@
#include "mtropolis/runtime.h"
#include "mtropolis/render.h"
-namespace Audio {
-} // End of namespace Audio
-
namespace MTropolis {
struct AssetLoaderContext;
Commit: 56161d17f085e6d598810a9a9efd264c77ee0bf4
https://github.com/scummvm/scummvm/commit/56161d17f085e6d598810a9a9efd264c77ee0bf4
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-19T17:38:09-04:00
Commit Message:
MTROPOLIS: Improve anamorphic filter
Changed paths:
engines/mtropolis/hacks.cpp
diff --git a/engines/mtropolis/hacks.cpp b/engines/mtropolis/hacks.cpp
index 5a2b9cf85d9..d263bac2b61 100644
--- a/engines/mtropolis/hacks.cpp
+++ b/engines/mtropolis/hacks.cpp
@@ -156,6 +156,9 @@ private:
template<class TPixel>
void anamorphicScaleFrameTyped(const Graphics::Surface &src, Graphics::Surface &dest) const;
+ static double anamorphicCurve(double d);
+ static double inverseAnamorphicCurve(double d);
+
template<class TPixel>
void halveWidthTyped(const Graphics::Surface &src, Graphics::Surface &dest) const;
@@ -168,6 +171,8 @@ private:
ObsidianRSGLogoAnamorphicFilter::ObsidianRSGLogoAnamorphicFilter() {
// Anamorphic rescale, keeps the RSG logo proportional but preserves the vertical spacing!
+ // We use an anamorphic curve of y=x+x^2 which ensures the derivative at 0 is 1, meaning
+ // the rate of change stays constant at with the unfiltered pixels at the edge of the filter.
const uint unscaledWidth = 640;
const uint unscaledHeight = 480;
@@ -184,17 +189,35 @@ ObsidianRSGLogoAnamorphicFilter::ObsidianRSGLogoAnamorphicFilter() {
const double sideMarginInScaledImage = (static_cast<double>(scaledWidth) - ((static_cast<double>(unscaledWidth) - sideMarginInOriginalImage * 2.0) * scalingFactor)) * 0.5;
+ const double originalMarginHeightFraction = sideMarginInOriginalImage / static_cast<double>(unscaledHeight);
+ const double scaledMarginHeightFraction = sideMarginInScaledImage / static_cast<double>(scaledHeight);
+
+ const double targetCurveRatio = scaledMarginHeightFraction / originalMarginHeightFraction;
+
+ // (x + x^2) / x = targetCurveRatio
+ // (x + x^2) = targetCurveRatio * x
+ // 1 + x = targetCurveRatio
+
+ const double xCurveRatio = targetCurveRatio - 1.0;
+ const double yCurveRatio = anamorphicCurve(xCurveRatio);
+
const double rightMarginStart = static_cast<double>(scaledWidth) - sideMarginInScaledImage;
for (uint i = 0; i < scaledWidth; i++) {
double pixelCenterX = static_cast<double>(i) + 0.5;
double originalImagePixelCenter = 0.0;
if (pixelCenterX < sideMarginInScaledImage) {
- double marginFraction = pixelCenterX / sideMarginInScaledImage;
- originalImagePixelCenter = sqrt(marginFraction) * sideMarginInOriginalImage;
+ double marginFraction = 1.0 - pixelCenterX / sideMarginInScaledImage;
+ double marginCurveY = marginFraction * yCurveRatio;
+ double marginCurveX = inverseAnamorphicCurve(marginCurveY);
+ double multiplier = 1.0 - marginCurveX / xCurveRatio;
+ originalImagePixelCenter = multiplier * sideMarginInOriginalImage;
} else if (pixelCenterX > rightMarginStart) {
- double marginFraction = (static_cast<double>(scaledWidth) - pixelCenterX) / sideMarginInScaledImage;
- originalImagePixelCenter = static_cast<double>(unscaledWidth) - sqrt(marginFraction) * sideMarginInOriginalImage;
+ double marginFraction = 1.0 - (static_cast<double>(scaledWidth) - pixelCenterX) / sideMarginInScaledImage;
+ double marginCurveY = marginFraction * yCurveRatio;
+ double marginCurveX = inverseAnamorphicCurve(marginCurveY);
+ double multiplier = 1.0 - marginCurveX / xCurveRatio;
+ originalImagePixelCenter = static_cast<double>(unscaledWidth) - multiplier * sideMarginInOriginalImage;
} else {
double offsetFromCenter = pixelCenterX - (static_cast<double>(scaledWidth) * 0.5);
double offsetFromCenterInOriginalImage = offsetFromCenter * invScalingFactor;
@@ -234,6 +257,14 @@ void ObsidianRSGLogoAnamorphicFilter::anamorphicScaleFrameTyped(const Graphics::
}
}
+double ObsidianRSGLogoAnamorphicFilter::anamorphicCurve(double d) {
+ return d + d * d;
+}
+
+double ObsidianRSGLogoAnamorphicFilter::inverseAnamorphicCurve(double d) {
+ return -0.5 + sqrt(0.25 + d);
+}
+
template<class TPixel>
void ObsidianRSGLogoAnamorphicFilter::halveWidthTyped(const Graphics::Surface &src, Graphics::Surface &dest) const {
const uint widthHigh = src.w;
Commit: e43a2fcb89442f4805ef94c8e21c3c2cfe0acf52
https://github.com/scummvm/scummvm/commit/e43a2fcb89442f4805ef94c8e21c3c2cfe0acf52
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-19T17:38:09-04:00
Commit Message:
MTROPOLIS: Fix STransCt wipe duration at 500ms since that seems to be the accurate behavior
Changed paths:
engines/mtropolis/plugin/standard.cpp
diff --git a/engines/mtropolis/plugin/standard.cpp b/engines/mtropolis/plugin/standard.cpp
index b279d185ed5..ab4a147def3 100644
--- a/engines/mtropolis/plugin/standard.cpp
+++ b/engines/mtropolis/plugin/standard.cpp
@@ -1616,13 +1616,12 @@ VThreadState STransCtModifier::consumeMessage(Runtime *runtime, const Common::Sh
effect._steps = _steps;
if (SceneTransitionTypes::loadFromData(effect._transitionType, _transitionType) && SceneTransitionDirections::loadFromData(effect._transitionDirection, _transitionDirection)) {
- // Weird quirk: Duration doesn't seem to affect duration properly for wipe transitions.
+ // Duration doesn't seem to affect wipe transitions for some reason.
// In Obsidian, this mostly effects 180-degree turns.
- // Good place to test this is in the corners of the Bureau library.
- const uint32 kMinWipeDuration = 500;
-
- if (effect._transitionType == SceneTransitionTypes::kWipe && effect._duration < kMinWipeDuration)
- effect._duration = kMinWipeDuration;
+ // Good place to test this is in the corners of the Bureau library, where it's 0,
+ // but some cases where it is set (e.g. the Spider control room) have the same duration anyway.
+ if (effect._transitionType == SceneTransitionTypes::kWipe)
+ effect._duration = 500;
runtime->setSceneTransitionEffect(false, &effect);
} else {
Commit: 0d8ba6982a11ed36925cf381cdd33dfedf1f53f1
https://github.com/scummvm/scummvm/commit/0d8ba6982a11ed36925cf381cdd33dfedf1f53f1
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-19T17:38:09-04:00
Commit Message:
MTROPOLIS: Make autorefreshcursor trigger later to fix Obsidian wave puzzle completing instantly in the Mac version
Changed paths:
engines/mtropolis/runtime.cpp
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index cb0316cc31e..d994cba6973 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -3507,6 +3507,10 @@ RuntimeObject *MessageDispatch::getRootPropagator() const {
case PropagationStack::kStageSendToStructuralModifiers:
case PropagationStack::kStageSendToStructuralSelf:
return lowest.ptr.structural;
+ case PropagationStack::kStageCheckAndSendToModifier:
+ case PropagationStack::kStageCheckAndSendToStructural:
+ case PropagationStack::kStageCheckAndSendCommand:
+ return _root.lock().get();
default:
break;
}
@@ -4291,7 +4295,6 @@ void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structura
}
{
- _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetSharedScene, LowLevelSceneStateTransitionAction::kAutoResetCursor));
_pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetScene, LowLevelSceneStateTransitionAction::kLoad));
queueEventAsLowLevelSceneStateTransitionAction(Event::create(EventIDs::kParentEnabled, 0), targetScene.get(), true, true);
queueEventAsLowLevelSceneStateTransitionAction(Event::create(EventIDs::kSceneStarted, 0), targetScene.get(), true, true);
@@ -4302,6 +4305,12 @@ void Runtime::executeCompleteTransitionToScene(const Common::SharedPtr<Structura
_sceneStack.push_back(sceneEntry);
}
+ // This might not be exactly where this belongs but it must go after Parent Enabled for sure, otherwise
+ // the wave puzzle in the Mac version of Obsidian completes instantly because Parent Enabled hasn't had
+ // a chance to clear the flags. It looks like what's supposed to happen is the cursor override gets
+ // cleared by the scene transition starting and the cursor reset happens after. Fix this later...
+ _pendingLowLevelTransitions.push_back(LowLevelSceneStateTransitionAction(targetScene, LowLevelSceneStateTransitionAction::kAutoResetCursor));
+
_activeMainScene = targetScene;
_activeSharedScene = targetSharedScene;
Commit: d9642925ebe84a33ad31e8cb1186850576902f99
https://github.com/scummvm/scummvm/commit/d9642925ebe84a33ad31e8cb1186850576902f99
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-19T17:38:09-04:00
Commit Message:
MTROPOLIS: Implement mToon stop command
Changed paths:
engines/mtropolis/elements.cpp
engines/mtropolis/elements.h
diff --git a/engines/mtropolis/elements.cpp b/engines/mtropolis/elements.cpp
index eeec9bb08a0..e818c039f91 100644
--- a/engines/mtropolis/elements.cpp
+++ b/engines/mtropolis/elements.cpp
@@ -1125,7 +1125,7 @@ MiniscriptInstructionOutcome MToonElement::writeRefAttribute(MiniscriptThread *t
return VisualElement::writeRefAttribute(thread, result, attrib);
}
-VThreadState MToonElement::consumeCommand(Runtime *runtime, const Common::SharedPtr<MessageProperties>& msg) {
+VThreadState MToonElement::consumeCommand(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
if (Event::create(EventIDs::kPlay, 0).respondsTo(msg->getEvent())) {
StartPlayingTaskData *startPlayingTaskData = runtime->getVThread().pushTask("MToonElement::startPlayingTask", this, &MToonElement::startPlayingTask);
startPlayingTaskData->runtime = runtime;
@@ -1137,12 +1137,12 @@ VThreadState MToonElement::consumeCommand(Runtime *runtime, const Common::Shared
return kVThreadReturn;
}
if (Event::create(EventIDs::kStop, 0).respondsTo(msg->getEvent())) {
- // Works differently from movies: Needs to hide the element and pause
-#ifdef MTROPOLIS_DEBUG_ENABLE
- if (Debugger *debugger = runtime->debugGetDebugger())
- debugger->notify(kDebugSeverityError, "mToon element was commanded to stop, but that's not implemented yet");
-#endif
- warning("mToon element stops are not implemented");
+ ChangeFlagTaskData *becomeVisibleTaskData = runtime->getVThread().pushTask("MToonElement::changeVisibilityTask", static_cast<VisualElement *>(this), &MToonElement::changeVisibilityTask);
+ becomeVisibleTaskData->desiredFlag = false;
+ becomeVisibleTaskData->runtime = runtime;
+
+ StopPlayingTaskData *stopPlayingTaskData = runtime->getVThread().pushTask("MToonElement::startPlayingTask", this, &MToonElement::stopPlayingTask);
+ stopPlayingTaskData->runtime = runtime;
return kVThreadReturn;
}
@@ -1299,6 +1299,17 @@ VThreadState MToonElement::startPlayingTask(const StartPlayingTaskData &taskData
return kVThreadReturn;
}
+VThreadState MToonElement::stopPlayingTask(const StopPlayingTaskData &taskData) {
+ _contentsDirty = true;
+ _isPlaying = false;
+
+ Common::SharedPtr<MessageProperties> msgProps(new MessageProperties(Event::create(EventIDs::kStop, 0), DynamicValue(), getSelfReference()));
+ Common::SharedPtr<MessageDispatch> dispatch(new MessageDispatch(msgProps, this, false, true, false));
+ taskData.runtime->sendMessageOnVThread(dispatch);
+
+ return kVThreadReturn;
+}
+
void MToonElement::playMedia(Runtime *runtime, Project *project) {
if (_paused)
return;
diff --git a/engines/mtropolis/elements.h b/engines/mtropolis/elements.h
index 71732a18248..60609b32995 100644
--- a/engines/mtropolis/elements.h
+++ b/engines/mtropolis/elements.h
@@ -229,12 +229,17 @@ private:
Runtime *runtime;
};
+ struct StopPlayingTaskData {
+ Runtime *runtime;
+ };
+
struct ChangeFrameTaskData {
Runtime *runtime;
uint32 frame;
};
VThreadState startPlayingTask(const StartPlayingTaskData &taskData);
+ VThreadState stopPlayingTask(const StopPlayingTaskData &taskData);
void playMedia(Runtime *runtime, Project *project) override;
MiniscriptInstructionOutcome scriptSetRate(MiniscriptThread *thread, const DynamicValue &value);
More information about the Scummvm-git-logs
mailing list