[Scummvm-git-logs] scummvm master -> 9f63b7c572e759660d344034976be9ff6267ad48
fracturehill
noreply at scummvm.org
Sun Jan 28 01:11:00 UTC 2024
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:
13dde71233 NANCY: Completely disable nancy7 clock
be67cf827b GRAPHICS: Prevent segfault in ManagedSurface
9f63b7c572 NANCY: Fix Overlay in nancy7 scene 3600
Commit: 13dde712331b58833e7572aab42304d1a1adc28d
https://github.com/scummvm/scummvm/commit/13dde712331b58833e7572aab42304d1a1adc28d
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-27T23:50:10+01:00
Commit Message:
NANCY: Completely disable nancy7 clock
Fixed the CLOK chunk reading, so the parameters that
indicate whether the clock is the day clock (nancy5), or
completely disabled (nancy7) now get read correctly.
Changed paths:
dists/engine-data/nancy.dat
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
engines/nancy/state/scene.cpp
engines/nancy/ui/clock.cpp
diff --git a/dists/engine-data/nancy.dat b/dists/engine-data/nancy.dat
index 796f7597972..2fb1b5ecd0e 100644
Binary files a/dists/engine-data/nancy.dat and b/dists/engine-data/nancy.dat differ
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index ac282738465..f5a6582d981 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -567,11 +567,13 @@ CLOK::CLOK(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
s.syncAsUint32LE(timeToKeepOpen);
s.syncAsUint16LE(frameTime);
+ s.syncAsByte(clockIsDisabled, kGameTypeNancy5);
+ s.syncAsByte(clockIsDay, kGameTypeNancy5);
+ s.syncAsUint32LE(countdownTime, kGameTypeNancy5);
s.skip(2, kGameTypeNancy5);
- s.syncAsUint32LE(nancy5CountdownTime, kGameTypeNancy5);
- s.skip(2, kGameTypeNancy5);
- readRectArray(s, nancy5DaySrcs, 3, 3, kGameTypeNancy5);
- readRectArray(s, nancy5CountdownSrcs, 13, 13, kGameTypeNancy5);
+ readRectArray(s, daySrcs, 3, 3, kGameTypeNancy5);
+ readRectArray(s, countdownSrcs, 13, 13, kGameTypeNancy5);
+ readRect(s, disabledSrc, kGameTypeNancy5);
}
SPEC::SPEC(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index cf053a71bca..099b277bf77 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -357,9 +357,13 @@ struct CLOK : public EngineData {
uint32 timeToKeepOpen = 0;
uint16 frameTime = 0;
- uint32 nancy5CountdownTime = 0;
- Common::Array<Common::Rect> nancy5DaySrcs;
- Common::Array<Common::Rect> nancy5CountdownSrcs;
+ bool clockIsDisabled = false;
+ bool clockIsDay = false; // nancy5 clock
+
+ uint32 countdownTime = 0;
+ Common::Array<Common::Rect> daySrcs;
+ Common::Array<Common::Rect> countdownSrcs;
+ Common::Rect disabledSrc; // possibly useless
};
// Contains data for special effects (fades between scenes/fades to black).
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index d2187e7b353..2eddbe30bf7 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -741,7 +741,12 @@ void Scene::synchronize(Common::Serializer &ser) {
}
UI::Clock *Scene::getClock() {
- return g_nancy->getGameType() != kGameTypeNancy5 ? (UI::Clock *)_clock : nullptr;
+ auto *clok = GetEngineData(CLOK);
+ if (clok->clockIsDisabled || clok->clockIsDay) {
+ return nullptr;
+ } else {
+ return (UI::Clock *)_clock;
+ }
}
void Scene::init() {
@@ -1174,15 +1179,20 @@ void Scene::initStaticData() {
_clock->init();
}
+ // Init just the clock (nancy2 and up; nancy1 has no clock, only a map button)
if (g_nancy->getGameType() >= kGameTypeNancy2) {
- if (g_nancy->getGameType() == kGameTypeNancy5) {
- // Nancy 5 uses a custom "clock" that mostly just indicates the in-game day
+ auto *clok = GetEngineData(CLOK);
+ if (clok->clockIsDay) {
+ // nancy5 uses a different "clock" that mostly just indicates the in-game day
_clock = new UI::Nancy5Clock();
- } else {
+ _clock->init();
+ } else if (!clok->clockIsDisabled) {
_clock = new UI::Clock();
+ _clock->init();
+ } else {
+ // In nancy7 the clock is entirely disabled
+ _clock = nullptr;
}
-
- _clock->init();
}
_state = kLoad;
diff --git a/engines/nancy/ui/clock.cpp b/engines/nancy/ui/clock.cpp
index c7567b6607f..f4c6fc4b72e 100644
--- a/engines/nancy/ui/clock.cpp
+++ b/engines/nancy/ui/clock.cpp
@@ -198,19 +198,19 @@ void Nancy5Clock::updateGraphics() {
if (_currentDay < 3) {
if (NancySceneState.getEventFlag(59, true) && _currentDay == 1) {
_currentDay = 2;
- _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->nancy5DaySrcs[2]);
+ _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->daySrcs[2]);
moveTo(_clockData->staticImageDest);
setVisible(true);
setTransparent(true);
} else if (NancySceneState.getEventFlag(58, true) && _currentDay == 0) {
_currentDay = 1;
- _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->nancy5DaySrcs[1]);
+ _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->daySrcs[1]);
moveTo(_clockData->staticImageDest);
setVisible(true);
setTransparent(true);
} else if (NancySceneState.getEventFlag(57, true) && _currentDay == -1) {
_currentDay = 0;
- _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->nancy5DaySrcs[0]);
+ _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->daySrcs[0]);
moveTo(_clockData->staticImageDest);
setVisible(true);
setTransparent(true);
@@ -221,11 +221,11 @@ void Nancy5Clock::updateGraphics() {
if (NancySceneState.getEventFlag(320, true)) {
_currentDay = 3;
Time timerTime = NancySceneState.getTimerTime();
- int32 countdownFrameID = MIN<int32>((uint32)timerTime / (_clockData->nancy5CountdownTime / 12), 13);
+ int32 countdownFrameID = MIN<int32>((uint32)timerTime / (_clockData->countdownTime / 12), 13);
if (countdownFrameID != _countdownProgress) {
_countdownProgress = countdownFrameID;
- _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->nancy5CountdownSrcs[_countdownProgress]);
+ _drawSurface.create(g_nancy->_graphicsManager->_object0, _clockData->countdownSrcs[_countdownProgress]);
moveTo(_clockData->staticImageDest);
setVisible(true);
}
Commit: be67cf827b125752ba3b7ffcc67c357486c95821
https://github.com/scummvm/scummvm/commit/be67cf827b125752ba3b7ffcc67c357486c95821
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-28T02:06:05+01:00
Commit Message:
GRAPHICS: Prevent segfault in ManagedSurface
The create() overload of ManagedSurface that creates a
new, owned surface, previously assumed that the
_innerSurface was owned before the call was made. Thus,
when switching between sub-surface and owning surface
modes, a segfault would occur when attempting to free
the pixel data of the inner surface, which is not actually
owned by the ManagedSurface. This commit makes sure
that when free() is called, the inner surface no longer
has an active pointer to its old pixel data.
Changed paths:
graphics/managed_surface.cpp
diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index b51dafff0c1..8ad324cfd6c 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -181,8 +181,11 @@ void ManagedSurface::create(ManagedSurface &surf, const Common::Rect &bounds) {
}
void ManagedSurface::free() {
- if (_disposeAfterUse == DisposeAfterUse::YES)
+ if (_disposeAfterUse == DisposeAfterUse::YES) {
_innerSurface.free();
+ } else {
+ _innerSurface.setPixels(nullptr);
+ }
_disposeAfterUse = DisposeAfterUse::NO;
_owner = nullptr;
Commit: 9f63b7c572e759660d344034976be9ff6267ad48
https://github.com/scummvm/scummvm/commit/9f63b7c572e759660d344034976be9ff6267ad48
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-01-28T02:07:46+01:00
Commit Message:
NANCY: Fix Overlay in nancy7 scene 3600
The scene in question is yet another edge case, since it
draws more than one rectangle over a single viewport frame.
Changed paths:
engines/nancy/action/overlay.cpp
engines/nancy/action/overlay.h
diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index 5e01edd9bae..72cba2b52f8 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -44,7 +44,7 @@ void Overlay::init() {
g_nancy->_resource->loadImage(_imageName, _fullSurface);
- setFrame(_firstFrame);
+ _currentFrame = _firstFrame;
RenderObject::init();
}
@@ -221,7 +221,22 @@ void Overlay::execute() {
}
}
- setFrame(nextFrame);
+ // Workaround for:
+ // - the arcade machine in nancy1 scene 833
+ // - the fireplace in nancy2 scene 2491, where one of the rects is invalid.
+ // - the ball thing in nancy2 scene 1562, where one of the rects is twice as tall as it should be
+ // Assumes all rects in a single animation have the same dimensions
+ Common::Rect srcRect = _srcRects[nextFrame];
+ if (!srcRect.isValidRect() || srcRect.width() != _srcRects[0].width() || srcRect.height() != _srcRects[0].height()) {
+ srcRect.setWidth(_srcRects[0].width());
+ srcRect.setHeight(_srcRects[0].height());
+ }
+
+ _drawSurface.create(_fullSurface, srcRect);
+ setTransparent(_transparency == kPlayOverlayTransparent);
+
+ _currentFrame = nextFrame;
+ _needsRedraw = true;
}
} else {
// Check if we've moved the viewport
@@ -233,32 +248,86 @@ void Overlay::execute() {
setVisible(false);
_hasHotspot = false;
+ // First, check if there's more than one blit description for the current viewport frame.
+ // This happens in nancy7 scene 3600
+ Common::Array<uint16> blitsForThisFrame;
+ Common::Rect destRect;
for (uint i = 0; i < _blitDescriptions.size(); ++i) {
if (_currentViewportFrame == _blitDescriptions[i].frameID) {
- moveTo(_blitDescriptions[i].dest);
- setVisible(true);
+ blitsForThisFrame.push_back(i);
+ if (destRect.isEmpty()) {
+ destRect = _blitDescriptions[i].dest;
+ } else {
+ destRect.extend(_blitDescriptions[i].dest);
+ }
+ }
+ }
+
+ if (_overlayType == kPlayOverlayStatic && blitsForThisFrame.size()) {
+ moveTo(destRect);
+ setVisible(true);
+ if (blitsForThisFrame.size() != 1) {
+ _drawSurface.create(destRect.width(), destRect.height(), _fullSurface.format);
+ setTransparent(true); // Force transparency. This shouldn't break anything. Hopefully.
+ _drawSurface.clear(_drawSurface.getTransparentColor());
+ }
+
+ for (uint i = 0; i < blitsForThisFrame.size(); ++i) {
// In static mode every "animation" frame corresponds to a viewport frame
- if (_overlayType == kPlayOverlayStatic) {
- setFrame(i);
-
- if (g_nancy->getGameType() <= kGameTypeNancy2) {
- // In nancy2, the presence of a hotspot relies on whether the Overlay has a scene change
- if (_enableHotspot == kPlayOverlayWithHotspot) {
- _hotspot = _screenPosition;
- _hasHotspot = true;
- }
+ // Static mode overlays use both the general source rects (_srcRects),
+ // and the ones inside the blit description struct corresponding to the current scene background.
+
+ // BlitDescriptions contain the id of the source rect to actually use
+ Common::Rect srcRect = _srcRects[_blitDescriptions[blitsForThisFrame[i]].staticRectID];
+ Common::Rect staticBounds = _blitDescriptions[blitsForThisFrame[i]].src;
+
+ if (_usesAutotext) {
+ // For autotext overlays, the srcRect is junk data
+ srcRect = staticBounds;
+ } else {
+ // Lastly, the general source rect we just got may also be completely empty (nancy5 scenes 2056, 2057),
+ // or have coordinates other than (0, 0) (nancy3 scene 3070, nancy5 scene 2000). Presumably,
+ // the general source rect was used for blitting to an (optional) intermediate surface, while the ones
+ // inside the blit description below were used for blitting from that intermediate surface to the screen.
+ // We can achieve the same results by doung the calculations below
+ srcRect.translate(staticBounds.left, staticBounds.top);
+
+ if (srcRect.isEmpty()) {
+ srcRect.setWidth(staticBounds.width());
+ srcRect.setHeight(staticBounds.height());
} else {
- // nancy3 added a per-frame flag for hotspots. This allows the overlay to be clickable
- // even without a scene change (useful for setting flags).
- if (_blitDescriptions[i].hasHotspot == kPlayOverlayWithHotspot) {
- _hotspot = _screenPosition;
- _hasHotspot = true;
- }
+ // Grab whichever dimensions are smaller. Fixes the book in nancy5 scene 3000
+ srcRect.setWidth(MIN<int>(staticBounds.width(), srcRect.width()));
+ srcRect.setHeight(MIN<int>(staticBounds.height(), srcRect.height()));
}
}
- break;
+ if (blitsForThisFrame.size() == 1) {
+ _drawSurface.create(_fullSurface, srcRect);
+ setTransparent(_transparency == kPlayOverlayTransparent);
+ } else {
+ Common::Rect d = _blitDescriptions[blitsForThisFrame[i]].dest;
+ d.translate(-destRect.left, -destRect.top);
+ _drawSurface.blitFrom(_fullSurface, srcRect, d);
+ }
+
+ _needsRedraw = true;
+
+ if (g_nancy->getGameType() <= kGameTypeNancy2) {
+ // In nancy2, the presence of a hotspot relies on whether the Overlay has a scene change
+ if (_enableHotspot == kPlayOverlayWithHotspot) {
+ _hotspot = _screenPosition;
+ _hasHotspot = true;
+ }
+ } else {
+ // nancy3 added a per-frame flag for hotspots. This allows the overlay to be clickable
+ // even without a scene change (useful for setting flags).
+ if (_blitDescriptions[i].hasHotspot == kPlayOverlayWithHotspot) {
+ _hotspot = _screenPosition;
+ _hasHotspot = true;
+ }
+ }
}
}
}
@@ -293,62 +362,6 @@ Common::String Overlay::getRecordTypeName() const {
}
}
-void Overlay::setFrame(uint frame) {
- _currentFrame = frame;
-
- Common::Rect srcRect;
-
- if (_overlayType == kPlayOverlayAnimated) {
- // Workaround for:
- // - the arcade machine in nancy1 scene 833
- // - the fireplace in nancy2 scene 2491, where one of the rects is invalid.
- // - the ball thing in nancy2 scene 1562, where one of the rects is twice as tall as it should be
- // Assumes all rects in a single animation have the same dimensions
- srcRect = _srcRects[frame];
- if (!srcRect.isValidRect() || srcRect.width() != _srcRects[0].width() || srcRect.height() != _srcRects[0].height()) {
- srcRect.setWidth(_srcRects[0].width());
- srcRect.setHeight(_srcRects[0].height());
- }
- } else {
- if (_currentViewportFrame == -1) {
- return;
- }
-
- // Static mode overlays use both the general source rects (_srcRects),
- // and the ones inside the blit description struct corresponding to the current scene background.
-
- // BlitDescriptions contain the id of the source rect to actually use
- srcRect = _srcRects[_blitDescriptions[frame].staticRectID];
- Common::Rect staticBounds = _blitDescriptions[frame].src;
-
- if (_usesAutotext) {
- // For autotext overlays, the srcRect is junk data
- srcRect = staticBounds;
- } else {
- // Lastly, the general source rect we just got may also be completely empty (nancy5 scenes 2056, 2057),
- // or have coordinates other than (0, 0) (nancy3 scene 3070, nancy5 scene 2000). Presumably,
- // the general source rect was used for blitting to an (optional) intermediate surface, while the ones
- // inside the blit description below were used for blitting from that intermediate surface to the screen.
- // We can achieve the same results by doung the calculations below
- srcRect.translate(staticBounds.left, staticBounds.top);
-
- if (srcRect.isEmpty()) {
- srcRect.setWidth(staticBounds.width());
- srcRect.setHeight(staticBounds.height());
- } else {
- // Grab whichever dimensions are smaller. Fixes the book in nancy5 scene 3000
- srcRect.setWidth(MIN<int>(staticBounds.width(), srcRect.width()));
- srcRect.setHeight(MIN<int>(staticBounds.height(), srcRect.height()));
- }
- }
- }
-
- _drawSurface.create(_fullSurface, srcRect);
- setTransparent(_transparency == kPlayOverlayTransparent);
-
- _needsRedraw = true;
-}
-
void OverlayStaticTerse::readData(Common::SeekableReadStream &stream) {
readFilename(stream, _imageName);
_transparency = stream.readUint16LE();
diff --git a/engines/nancy/action/overlay.h b/engines/nancy/action/overlay.h
index b5c6c090d2f..ccfb27aca3f 100644
--- a/engines/nancy/action/overlay.h
+++ b/engines/nancy/action/overlay.h
@@ -87,8 +87,6 @@ protected:
Common::String getRecordTypeName() const override;
bool isViewportRelative() const override { return true; }
- void setFrame(uint frame);
-
Graphics::ManagedSurface _fullSurface;
};
More information about the Scummvm-git-logs
mailing list