[Scummvm-git-logs] scummvm master -> ce9a9a2c0fc27dbbf4dd9f4399049ac6d6fb3594

fracturehill noreply at scummvm.org
Mon Oct 23 19:33:11 UTC 2023


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
13d95f7bc6 NANCY: Fix SecondaryMovie reading
1da8f422d2 NANCY: Prevent crash when destroying movie
e23b573e7a NANCY: Implement BBallPuzzle
e2bc4a7bcd NANCY: Make sure getCurFrame() is correct for AVF videos
faaba2aae8 NANCY: Forcefully reactivate Autotext records when loading save
ce9a9a2c0f NANCY: Fix rendering of Autotext Overlays


Commit: 13d95f7bc6d2cfe11e7ea55c3f69a26544f3b1ba
    https://github.com/scummvm/scummvm/commit/13d95f7bc6d2cfe11e7ea55c3f69a26544f3b1ba
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-23T22:32:39+03:00

Commit Message:
NANCY: Fix SecondaryMovie reading

A recent addition to the class was missing a game version
check, ensuring nancy6 and earlier movies would always crash

Changed paths:
    engines/nancy/action/secondarymovie.cpp


diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index 22f8ef1115f..a3bbb039b7f 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -52,7 +52,7 @@ void PlaySecondaryMovie::readData(Common::SeekableReadStream &stream) {
 	readFilename(ser, _paletteName, kGameTypeVampire, kGameTypeVampire);
 	readFilename(ser, _bitmapOverlayName);
 
-	ser.syncAsUint16LE(_videoType);
+	ser.syncAsUint16LE(_videoType, kGameTypeNancy7);
 	ser.skip(2); // videoPlaySource
 	ser.syncAsUint16LE(_videoFormat);
 	ser.skip(4, kGameTypeVampire, kGameTypeVampire); // paletteStart, paletteSize


Commit: 1da8f422d2ac485bd9ecbe1851599a4213e72f09
    https://github.com/scummvm/scummvm/commit/1da8f422d2ac485bd9ecbe1851599a4213e72f09
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-23T22:32:39+03:00

Commit Message:
NANCY: Prevent crash when destroying movie

Changed paths:
    engines/nancy/action/secondarymovie.cpp


diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index a3bbb039b7f..67e97344110 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -36,7 +36,6 @@ namespace Nancy {
 namespace Action {
 
 PlaySecondaryMovie::~PlaySecondaryMovie() {
-	_decoder->close();
 	delete _decoder;
 
 	if (_playerCursorAllowed == kNoPlayerCursorAllowed) {


Commit: e23b573e7ad501d82585eee59e55c0a51bf12100
    https://github.com/scummvm/scummvm/commit/e23b573e7ad501d82585eee59e55c0a51bf12100
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-23T22:32:39+03:00

Commit Message:
NANCY: Implement BBallPuzzle

Implemented the action record type responsible for
nancy6's basketball minigame.

Changed paths:
  A engines/nancy/action/puzzle/bballpuzzle.cpp
  A engines/nancy/action/puzzle/bballpuzzle.h
    engines/nancy/action/arfactory.cpp
    engines/nancy/module.mk


diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 6f2bf836768..f6c0eefae8c 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -31,6 +31,7 @@
 #include "engines/nancy/action/secondarymovie.h"
 
 #include "engines/nancy/action/puzzle/assemblypuzzle.h"
+#include "engines/nancy/action/puzzle/bballpuzzle.h"
 #include "engines/nancy/action/puzzle/bombpuzzle.h"
 #include "engines/nancy/action/puzzle/collisionpuzzle.h"
 #include "engines/nancy/action/puzzle/cubepuzzle.h"
@@ -311,6 +312,8 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 		return new PeepholePuzzle();
 	case 217:
 		return new MouseLightPuzzle();
+	case 219:
+		return new BBallPuzzle();
 	case 220:
 		return new TwoDialPuzzle();
 	case 222:
diff --git a/engines/nancy/action/puzzle/bballpuzzle.cpp b/engines/nancy/action/puzzle/bballpuzzle.cpp
new file mode 100644
index 00000000000..8371926d594
--- /dev/null
+++ b/engines/nancy/action/puzzle/bballpuzzle.cpp
@@ -0,0 +1,299 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "engines/nancy/nancy.h"
+#include "engines/nancy/graphics.h"
+#include "engines/nancy/resource.h"
+#include "engines/nancy/sound.h"
+#include "engines/nancy/input.h"
+#include "engines/nancy/util.h"
+
+#include "engines/nancy/state/scene.h"
+
+#include "engines/nancy/action/puzzle/bballpuzzle.h"
+
+namespace Nancy {
+namespace Action {
+
+void BBallPuzzle::init() {
+	Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
+	_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+	_drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+	setTransparent(true);
+	setVisible(true);
+	moveTo(screenBounds);
+
+	g_nancy->_resource->loadImage(_imageName, _image);
+	_image.setTransparentColor(_drawSurface.getTransparentColor());
+
+	// Set up flags
+	if (NancySceneState.getEventFlag(_goodShootFlag, g_nancy->_true)) {
+		// Last shot entered the hoop
+		for (uint i = 0; i < _playerPositionFlags.size(); ++i) {
+			if (NancySceneState.getEventFlag(_playerPositionFlags[i], g_nancy->_true)) {
+				_curPosition = i;
+				break;
+			}
+		}
+
+		// Unset last position flag
+		NancySceneState.setEventFlag(_playerPositionFlags[_curPosition], g_nancy->_false);
+
+		if ((int)_curPosition == _positions - 1) {
+			// Beat the game once, reset to initial
+			_curPosition = 0;
+		} else {
+			// In the middle of the game, move to next position
+			++_curPosition;
+		}
+
+		NancySceneState.setEventFlag(_playerPositionFlags[_curPosition], g_nancy->_true);
+	} else {
+		// Last shot did not enter the hoop, reset to initial position
+		NancySceneState.setEventFlag(_playerPositionFlags[0], g_nancy->_true);
+
+		for (uint i = 1; i < _playerPositionFlags.size(); ++i) {
+			NancySceneState.setEventFlag(_playerPositionFlags[i], g_nancy->_false);
+		}
+	}
+	
+	// Reset shot type flags
+	for (uint i = 0; i < _badShootFlags.size(); ++i) {
+		NancySceneState.setEventFlag(_badShootFlags[i], g_nancy->_false);
+	}
+
+	NancySceneState.setEventFlag(_goodShootFlag, g_nancy->_false);
+
+	// Draw the current player position
+	if (_curPosition > 0) {
+		_drawSurface.blitFrom(_image, _playerSrcs[_curPosition - 1], _playerDest);
+	}
+}
+
+void BBallPuzzle::readData(Common::SeekableReadStream &stream) {
+	readFilename(stream, _imageName);
+
+	_positions = stream.readUint16LE();
+	_powers = stream.readUint16LE();
+	_angles = stream.readUint16LE();
+
+	_correctVals.resize(_positions);
+	for (uint i = 0; i < _positions; ++i) {
+		_correctVals[i].x = stream.readUint16LE();
+		_correctVals[i].y = stream.readUint16LE();
+	}
+
+	readRect(stream, _shootButtonDest);
+	readRect(stream, _minusButtonDest);
+	readRect(stream, _plusButtonDest);
+
+	readRect(stream, _playerDest);
+	readRect(stream, _powerDest);
+	readRect(stream, _angleDest);
+
+	readRectArray(stream, _angleSliderHotspots, 3);
+	
+	readRect(stream, _shootButtonSrc);
+	readRect(stream, _minusButtonSrc);
+	readRect(stream, _plusButtonSrc);
+
+	readRectArray(stream, _playerSrcs, 3);
+	readRectArray(stream, _powerSrcs, 5);
+	readRectArray(stream, _anglesSrcs, 2);
+
+	_shootSound.readNormal(stream);
+	_minusSound.readNormal(stream);
+	_plusSound.readNormal(stream);
+
+	_shootSceneChange.readData(stream);
+	stream.skip(2);
+
+	_badShootFlags.resize(3);
+	for (uint i = 0; i < 3; ++i) {
+		_badShootFlags[i] = stream.readSint16LE();
+	}
+
+	_goodShootFlag = stream.readSint16LE();
+
+	_playerPositionFlags.resize(_positions);
+	for (uint i = 0; i < _positions; ++i) {
+		_playerPositionFlags[i] = stream.readSint16LE();
+	}
+
+	_winFlag = stream.readUint16LE();
+
+	_exitScene.readData(stream);
+	readRect(stream, _exitHotspot);
+}
+
+void BBallPuzzle::execute() {
+	switch (_state) {
+	case kBegin:
+		init();
+		registerGraphics();
+
+		g_nancy->_sound->loadSound(_plusSound);
+		g_nancy->_sound->loadSound(_minusSound);
+		g_nancy->_sound->loadSound(_shootSound);
+
+		_state = kRun;
+		// fall through
+	case kRun:
+		if (_pressedButton) {
+			if (g_nancy->_sound->isSoundPlaying(_plusSound) || g_nancy->_sound->isSoundPlaying(_minusSound)) {
+				return;
+			}
+
+			_pressedButton = false;
+			_drawSurface.fillRect(_powerDest, _drawSurface.getTransparentColor());
+			_drawSurface.fillRect(_plusButtonDest, _drawSurface.getTransparentColor());
+			_drawSurface.fillRect(_minusButtonDest, _drawSurface.getTransparentColor());
+
+			if (_curPower > 0) {
+				_drawSurface.blitFrom(_image, _powerSrcs[_curPower - 1], _powerDest);
+			}
+
+			_needsRedraw = true;
+		}
+
+		break;
+	case kActionTrigger:
+		if (_pressedButton) {
+			// Pressed the shoot button
+			if (g_nancy->_sound->isSoundPlaying(_shootSound)) {
+				return;
+			}
+
+			int16 flagToSet = -1;
+
+			if ((int)_curPower == _correctVals[_curPosition].x && (int)_curAngle == _correctVals[_curPosition].y) {
+				// Selected correct values
+				flagToSet = _goodShootFlag;
+
+				if ((int)_curPosition == _positions - 1) {
+					// Last throw, mark puzzle as solved
+					NancySceneState.setEventFlag(_winFlag, g_nancy->_true);
+				}
+			} else if (_curPower == 0) {
+				// Low throw
+				flagToSet = _badShootFlags[2];
+			} else if ((int)_curPower >= _correctVals[_curPosition].x && (int)_curAngle <= _correctVals[_curPosition].y) {
+				// High throw
+				flagToSet = _badShootFlags[0];
+			} else {
+				// Mid throw
+				flagToSet = _badShootFlags[1];
+			}
+
+			NancySceneState.setEventFlag(flagToSet, g_nancy->_true);
+			NancySceneState.changeScene(_shootSceneChange);
+		} else {
+			// Exited the puzzle
+			_exitScene.execute();
+		}
+
+		g_nancy->_sound->stopSound(_plusSound);
+		g_nancy->_sound->stopSound(_minusSound);
+		g_nancy->_sound->stopSound(_shootSound);
+
+		finishExecution();
+	}
+}
+
+void BBallPuzzle::handleInput(NancyInput &input) {
+	Common::Point localMousePos = input.mousePos;
+	Common::Rect vpPos = NancySceneState.getViewport().getScreenPosition();
+	localMousePos -= { vpPos.left, vpPos.top };
+
+	if (_exitHotspot.contains(localMousePos)) {
+		g_nancy->_cursorManager->setCursorType(g_nancy->_cursorManager->_puzzleExitCursor);
+
+		if (!_pressedButton &&input.input & NancyInput::kLeftMouseButtonUp) {
+			_state = kActionTrigger;
+		}
+
+		return;
+	}
+
+	for (uint i = 0; i < _angleSliderHotspots.size(); ++i) {
+		if (_curAngle != i && _angleSliderHotspots[i].contains(localMousePos)) {
+			g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+			if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
+				_drawSurface.fillRect(_angleDest, _drawSurface.getTransparentColor());
+
+				if (i > 0) {
+					_drawSurface.blitFrom(_image, _anglesSrcs[i - 1], _angleDest);
+				}
+
+				_curAngle = i;
+				_needsRedraw = true;
+			}
+
+			return;
+		}
+	}
+
+	if (_curPower > 0 && _minusButtonDest.contains(localMousePos)) {
+		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+		if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
+			--_curPower;
+			_drawSurface.blitFrom(_image, _minusButtonSrc, _minusButtonDest);
+			g_nancy->_sound->playSound(_minusSound);
+			_pressedButton = true;
+			_needsRedraw = true;
+		}
+
+		return;
+	}
+
+	if ((int)_curPower < _powers - 1 && _plusButtonDest.contains(localMousePos)) {
+		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+		if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
+			++_curPower;
+			_drawSurface.blitFrom(_image, _plusButtonSrc, _plusButtonDest);
+			g_nancy->_sound->playSound(_plusSound);
+			_pressedButton = true;
+			_needsRedraw = true;
+		}
+
+		return;
+	}
+
+	if (_shootButtonDest.contains(localMousePos)) {
+		g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+		if (!_pressedButton && input.input & NancyInput::kLeftMouseButtonUp) {
+			_drawSurface.blitFrom(_image, _shootButtonSrc, _shootButtonDest);
+			g_nancy->_sound->playSound(_shootSound);
+			_pressedButton = true;
+			_needsRedraw = true;
+			_state = kActionTrigger;
+		}
+
+		return;
+	}
+}
+
+} // End of namespace Action
+} // End of namespace Nancy
diff --git a/engines/nancy/action/puzzle/bballpuzzle.h b/engines/nancy/action/puzzle/bballpuzzle.h
new file mode 100644
index 00000000000..fa901a6ff88
--- /dev/null
+++ b/engines/nancy/action/puzzle/bballpuzzle.h
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef NANCY_ACTION_BBALLPUZZLE_H
+#define NANCY_ACTION_BBALLPUZZLE_H
+
+#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/misc/mousefollow.h"
+
+namespace Nancy {
+namespace Action {
+
+class BBallPuzzle : public RenderActionRecord {
+public:
+	BBallPuzzle() : RenderActionRecord(7) {}
+	virtual ~BBallPuzzle() {}
+
+	void init() override;
+
+	void readData(Common::SeekableReadStream &stream) override;
+	void execute() override;
+	void handleInput(NancyInput &input) override;
+
+protected:
+	Common::String getRecordTypeName() const override { return "BBallPuzzle"; };
+	bool isViewportRelative() const override { return true; }
+
+	Common::String _imageName;
+
+	uint16 _positions = 0;
+	uint16 _powers = 0;
+	uint16 _angles = 0;
+
+	Common::Array<Common::Point> _correctVals;
+
+	Common::Rect _shootButtonDest;
+	Common::Rect _minusButtonDest;
+	Common::Rect _plusButtonDest;
+
+	Common::Rect _playerDest;
+	Common::Rect _powerDest;
+	Common::Rect _angleDest;
+	Common::Array<Common::Rect> _angleSliderHotspots;
+
+	Common::Rect _shootButtonSrc;
+	Common::Rect _minusButtonSrc;
+	Common::Rect _plusButtonSrc;
+
+	Common::Array<Common::Rect> _playerSrcs;
+	Common::Array<Common::Rect> _powerSrcs;
+	Common::Array<Common::Rect> _anglesSrcs;
+
+	SoundDescription _shootSound;
+	SoundDescription _minusSound;
+	SoundDescription _plusSound;
+
+	SceneChangeDescription _shootSceneChange;
+
+	Common::Array<int16> _badShootFlags;
+	int16 _goodShootFlag = 0;
+	Common::Array<int16> _playerPositionFlags;
+
+	int16 _winFlag = 0;
+
+	SceneChangeWithFlag _exitScene;
+	Common::Rect _exitHotspot;
+
+	Graphics::ManagedSurface _image;
+
+	uint _curAngle = 0;
+	uint _curPower = 0;
+	uint _curPosition = 0;
+
+	bool _pressedButton = false;
+};
+
+} // End of namespace Action
+} // End of namespace Nancy
+
+#endif // NANCY_ACTION_BBALLPUZZLE_H
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index d305ab4f348..ddf1133048a 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -14,6 +14,7 @@ MODULE_OBJS = \
   action/secondarymovie.o \
   action/secondaryvideo.o \
   action/puzzle/assemblypuzzle.o \
+  action/puzzle/bballpuzzle.o \
   action/puzzle/bombpuzzle.o \
   action/puzzle/collisionpuzzle.o \
   action/puzzle/cubepuzzle.o \


Commit: e2bc4a7bcd89ff290e909df339f7e5a1b0c417e7
    https://github.com/scummvm/scummvm/commit/e2bc4a7bcd89ff290e909df339f7e5a1b0c417e7
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-23T22:32:39+03:00

Commit Message:
NANCY: Make sure getCurFrame() is correct for AVF videos

This fixes an edge case in SecondaryMovie where a frame
flag wouldn't fire when playing in reverse.

Changed paths:
    engines/nancy/video.cpp
    engines/nancy/video.h


diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index e72b74769f7..7f7b77795b8 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -130,7 +130,7 @@ bool AVFDecoder::atEnd() const {
 AVFDecoder::AVFVideoTrack::AVFVideoTrack(Common::SeekableReadStream *stream, uint32 chunkFileFormat, CacheHint cacheHint) {
 	assert(stream);
 	_fileStream = stream;
-	_curFrame = 0;
+	_curFrame = -1;
 	_reversed = false;
 	_dec = new Decompressor;
 
@@ -202,6 +202,14 @@ AVFDecoder::AVFVideoTrack::~AVFVideoTrack() {
 
 bool AVFDecoder::AVFVideoTrack::seek(const Audio::Timestamp &time) {
 	_curFrame = getFrameAtTime(time);
+
+	// Offset by 1 to ensure decodeNextFrame() actually decodes the frame we want
+	if (!_reversed) {
+		--_curFrame;
+	} else {
+		++_curFrame;
+	}
+
 	return true;
 }
 
@@ -360,7 +368,7 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr)  {
 }
 
 const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeNextFrame() {
-	return decodeFrame(_reversed ? --_curFrame : _curFrame++);
+	return decodeFrame(_reversed ? --_curFrame : ++_curFrame);
 }
 
 } // End of namespace Nancy
diff --git a/engines/nancy/video.h b/engines/nancy/video.h
index 0add8f5760d..358706586a7 100644
--- a/engines/nancy/video.h
+++ b/engines/nancy/video.h
@@ -63,7 +63,7 @@ private:
 		uint16 getWidth() const override { return _width; }
 		uint16 getHeight() const override { return _height; }
 		Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
-		int getCurFrame() const override { return _reversed ? _curFrame : _curFrame - 1; }
+		int getCurFrame() const override { return _curFrame; }
 		int getFrameCount() const override { return _frameCount; }
 		bool isSeekable() const override { return true; }
 		bool seek(const Audio::Timestamp &time) override;
@@ -88,6 +88,8 @@ private:
 
 		bool decode(byte *outBuf, uint32 frameSize, Common::ReadStream &inBuf) const;
 
+		const AVFDecoder *_owner;
+
 		Common::SeekableReadStream *_fileStream;
 		Graphics::PixelFormat _pixelFormat;
 		uint _width, _height, _depth, _frameSize;


Commit: faaba2aae8bc2fb474fb48871a1196028cc56a0f
    https://github.com/scummvm/scummvm/commit/faaba2aae8bc2fb474fb48871a1196028cc56a0f
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-23T22:32:39+03:00

Commit Message:
NANCY: Forcefully reactivate Autotext records when loading save

Autotext records generate surfaces that are used by other
action records. When loading from a save, the Autotext
will already be marked as "done", and thus wouldn't generate anything, resulting in a crash. This commit makes
sure this doesn't happen.

Changed paths:
    engines/nancy/action/actionmanager.cpp


diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index a7d762331c0..61d3ed7e054 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -595,6 +595,11 @@ void ActionManager::synchronize(Common::Serializer &ser) {
 	for (auto &rec : _records) {
 		ser.syncAsByte(rec->_isActive);
 		ser.syncAsByte(rec->_isDone);
+
+		// Forcefully re-activate Autotext records, since we need to regenerate the surface
+		if (ser.isLoading() && g_nancy->getGameType() >= kGameTypeNancy6 && rec->_type == 61) {
+			rec->_isDone = false;
+		}
 	}
 }
 


Commit: ce9a9a2c0fc27dbbf4dd9f4399049ac6d6fb3594
    https://github.com/scummvm/scummvm/commit/ce9a9a2c0fc27dbbf4dd9f4399049ac6d6fb3594
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-23T22:32:39+03:00

Commit Message:
NANCY: Fix rendering of Autotext Overlays

It appears that an Overlay's _srcRects are junk data when
the overlay is in Autotext mode. This commit makes sure
they're rendered correctly.

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 27406493ca4..b737cbb55e1 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -42,10 +42,12 @@ void Overlay::init() {
 		uint surfID = _imageName[12] - '1';
 		Graphics::ManagedSurface &surf = g_nancy->_graphicsManager->getAutotextSurface(surfID);
 		_fullSurface.create(surf, surf.getBounds());
+		_usesAutotext = true;
 	} else if (_imageName.hasPrefix("USE_AUTOJOURNAL")) {
 		uint surfID = _imageName.substr(15).asUint64() + 2;
 		Graphics::ManagedSurface &surf = g_nancy->_graphicsManager->getAutotextSurface(surfID);
 		_fullSurface.create(surf, surf.getBounds());
+		_usesAutotext = true;
 	} else {
 		// No autotext, load image source
 		g_nancy->_resource->loadImage(_imageName, _fullSurface);
@@ -342,24 +344,29 @@ void Overlay::setFrame(uint frame) {
 			// for every blit description (nancy4 scene 1300)
 			srcRect = _srcRects[0];
 		}
-
-		// 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
+		
 		Common::Rect staticSrc = _blitDescriptions[frame].src;
-		srcRect.translate(staticSrc.left, staticSrc.top);
 
-		if (srcRect.isEmpty()) {
-			srcRect.setWidth(staticSrc.width());
-			srcRect.setHeight(staticSrc.height());
+		if (_usesAutotext) {
+			// For autotext overlays, the srcRect is junk data
+			srcRect = staticSrc;
 		} else {
-			// Grab whichever dimensions are smaller. Fixes the book in nancy5 scene 3000
-			srcRect.setWidth(MIN<int>(staticSrc.width(), srcRect.width()));
-			srcRect.setHeight(MIN<int>(staticSrc.height(), srcRect.height()));
-		}
-		
+			// 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(staticSrc.left, staticSrc.top);
+
+			if (srcRect.isEmpty()) {
+				srcRect.setWidth(staticSrc.width());
+				srcRect.setHeight(staticSrc.height());
+			} else {
+				// Grab whichever dimensions are smaller. Fixes the book in nancy5 scene 3000
+				srcRect.setWidth(MIN<int>(staticSrc.width(), srcRect.width()));
+				srcRect.setHeight(MIN<int>(staticSrc.height(), srcRect.height()));
+			}
+		}	
 	}
 
 	_drawSurface.create(_fullSurface, srcRect);
diff --git a/engines/nancy/action/overlay.h b/engines/nancy/action/overlay.h
index c7ade17c38c..3c228e54dc1 100644
--- a/engines/nancy/action/overlay.h
+++ b/engines/nancy/action/overlay.h
@@ -43,7 +43,7 @@ namespace Action {
 // that was also when static mode got introduced.
 class Overlay : public RenderActionRecord {
 public:
-	Overlay(bool interruptible) : RenderActionRecord(7), _isInterruptible(interruptible) {}
+	Overlay(bool interruptible) : RenderActionRecord(7), _isInterruptible(interruptible), _usesAutotext(false) {}
 	virtual ~Overlay() { _fullSurface.free(); }
 
 	void init() override;
@@ -80,6 +80,7 @@ public:
 	int16 _currentViewportFrame = -1;
 	uint32 _nextFrameTime = 0;
 	bool _isInterruptible;
+	bool _usesAutotext;
 
 protected:
 	bool canHaveHotspot() const override { return true; }




More information about the Scummvm-git-logs mailing list