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

fracturehill noreply at scummvm.org
Wed Sep 20 13:16:50 UTC 2023


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

Summary:
9b07e45dc1 DEVTOOLS: Fix incorrect nancy3 data in nancy.dat
6b75ce4453 NANCY: Fix HotMultiframeMultisceneChange in nancy3
2e64313d91 NANCY: Add minimum allowed sound volume
1d07ef258b NANCY: Remove items from inventory when held
cffac1e6ae NANCY: Improve Overlay drawing accuracy
6cfc805477 NANCY: Rename data struct
29b8052958 NANCY: Correctly read PlayDigiSound in nancy6
09a21ad755 NANCY: Set correct default textbox font
30d9732d20 NANCY: Cursor fixes
1689b6a2e9 NANCY: Support nancy4's voice mail system
e5d3c8614d NANCY: Fix sound interpolation between scenes


Commit: 9b07e45dc1df5b24c6749699665731a7f74509a4
    https://github.com/scummvm/scummvm/commit/9b07e45dc1df5b24c6749699665731a7f74509a4
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:21+03:00

Commit Message:
DEVTOOLS: Fix incorrect nancy3 data in nancy.dat

Fixed a couple of typos that would result in incorrect dialogue.

Changed paths:
    devtools/create_nancy/nancy3_data.h


diff --git a/devtools/create_nancy/nancy3_data.h b/devtools/create_nancy/nancy3_data.h
index baf58ef5d29..65d95dea2cb 100644
--- a/devtools/create_nancy/nancy3_data.h
+++ b/devtools/create_nancy/nancy3_data.h
@@ -64,7 +64,7 @@ const Common::Array<Common::Array<ConditionalDialogue>> _nancy3ConditionalDialog
 		{ { kEv, 211, true }, { kEv, 45, false }, { kEv, 109, false } } },
 	{	6, 1059, "NAS59",
 		{ { kEv, 146, true }, { kEv, 39, false }, { kEv, 218, false } } },
-	{	7, 1062, "NCL60",
+	{	7, 1062, "NLC60",
 		{ { kEv, 109, true }, { kEv, 43, false } } },
 	{	8, 1064, "NAS64",
 		{ { kEv, 218, true }, { kEv, 225, true }, { kEv, 209, true }, { kEv, 38, false } } },
@@ -207,7 +207,7 @@ const Common::Array<Common::Array<ConditionalDialogue>> _nancy3ConditionalDialog
 	{	72, 1566, "NAS54",
 		{ { kEv, 213, true }, { kEv, 160, false } } },
 	{	73, 1567, "NLC67",
-		{ { kEv, 169, true }, { kEv, 37, true }, { kEv, 160, false } } },
+		{ { kEv, 169, true }, { kEv, 37, true }, { kEv, 150, false } } },
 	{	74, 1568, "NLC68",
 		{ { kEv, 288, true }, { kEv, 153, false }, { kEv, 123, false }, { kEv, 157, true } } },
 },


Commit: 6b75ce4453c5568c729ecede0e880108aac43e3a
    https://github.com/scummvm/scummvm/commit/6b75ce4453c5568c729ecede0e880108aac43e3a
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:21+03:00

Commit Message:
NANCY: Fix HotMultiframeMultisceneChange in nancy3

Added support for nancy3's expanded format of the
HotMultiframeMultisceneChange action record.

Changed paths:
    engines/nancy/action/navigationrecords.cpp
    engines/nancy/action/navigationrecords.h
    engines/nancy/commontypes.cpp
    engines/nancy/commontypes.h


diff --git a/engines/nancy/action/navigationrecords.cpp b/engines/nancy/action/navigationrecords.cpp
index d62d8107668..db009a0d3f1 100644
--- a/engines/nancy/action/navigationrecords.cpp
+++ b/engines/nancy/action/navigationrecords.cpp
@@ -96,8 +96,14 @@ void Hot1FrSceneChange::execute() {
 }
 
 void HotMultiframeMultisceneChange::readData(Common::SeekableReadStream &stream) {
-	_onTrue.readData(stream);
-	_onFalse.readData(stream);
+	if (g_nancy->getGameType() <= kGameTypeNancy2) {
+		_onTrue._sceneChange.readData(stream);
+		_onFalse._sceneChange.readData(stream);
+	} else {
+		_onTrue.readData(stream, true);
+		_onFalse.readData(stream, true);
+	}
+	
 	_condType = stream.readByte();
 	_conditionID = stream.readUint16LE();
 	_conditionPayload = stream.readByte();
@@ -148,9 +154,9 @@ void HotMultiframeMultisceneChange::execute() {
 		}
 
 		if (conditionMet) {
-			NancySceneState.changeScene(_onTrue);
+			_onTrue.execute();
 		} else {
-			NancySceneState.changeScene(_onFalse);
+			_onFalse.execute();
 		}
 
 		break;
diff --git a/engines/nancy/action/navigationrecords.h b/engines/nancy/action/navigationrecords.h
index 1d1b33df51b..71ab8afe7ed 100644
--- a/engines/nancy/action/navigationrecords.h
+++ b/engines/nancy/action/navigationrecords.h
@@ -109,8 +109,8 @@ public:
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
 
-	SceneChangeDescription _onTrue;
-	SceneChangeDescription _onFalse;
+	SceneChangeWithFlag _onTrue;
+	SceneChangeWithFlag _onFalse;
 	byte _condType;
 	uint16 _conditionID;
 	byte _conditionPayload;
diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index a3a685d6e8a..a7fdf6db5cf 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -47,11 +47,37 @@ void SceneChangeDescription::readData(Common::SeekableReadStream &stream, bool l
 	}
 }
 
-void SceneChangeWithFlag::readData(Common::SeekableReadStream &stream, bool longFormat) {
-	_sceneChange.readData(stream, longFormat);
-	stream.skip(2); // shouldStopRendering
-	_flag.label = stream.readSint16LE();
-	_flag.flag = stream.readByte();
+void SceneChangeWithFlag::readData(Common::SeekableReadStream &stream, bool reverseFormat) {
+	_sceneChange.sceneID = stream.readUint16LE();
+	_sceneChange.frameID = stream.readUint16LE();
+	_sceneChange.verticalOffset = stream.readUint16LE();
+	_sceneChange.continueSceneSound = stream.readUint16LE();
+
+	if (reverseFormat) {
+		// NO shouldStopRendering
+		_flag.label = stream.readSint16LE();
+		_flag.flag = stream.readByte();
+
+		if (g_nancy->getGameType() >= kGameTypeNancy3) {
+			int32 x = stream.readSint32LE();
+			int32 y = stream.readSint32LE();
+			int32 z = stream.readSint32LE();
+			_sceneChange.listenerFrontVector.set(x, y, z);
+			_sceneChange.frontVectorFrameID = _sceneChange.frameID;
+		}
+	} else {
+		if (g_nancy->getGameType() >= kGameTypeNancy3) {
+			int32 x = stream.readSint32LE();
+			int32 y = stream.readSint32LE();
+			int32 z = stream.readSint32LE();
+			_sceneChange.listenerFrontVector.set(x, y, z);
+			_sceneChange.frontVectorFrameID = _sceneChange.frameID;
+		}
+
+		stream.skip(2); // shouldStopRendering
+		_flag.label = stream.readSint16LE();
+		_flag.flag = stream.readByte();
+	}
 }
 
 void SceneChangeWithFlag::execute() {
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index ef8827b0b2a..f963fd4854e 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -150,7 +150,7 @@ struct SceneChangeWithFlag {
 	SceneChangeDescription _sceneChange;
 	FlagDescription _flag;
 
-	void readData(Common::SeekableReadStream &stream, bool longFormat = false);
+	void readData(Common::SeekableReadStream &stream, bool reverseFormat = false);
 	void execute();
 };
 


Commit: 2e64313d914fa5cf85779532d6f233652ecc1fd2
    https://github.com/scummvm/scummvm/commit/2e64313d914fa5cf85779532d6f233652ecc1fd2
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:21+03:00

Commit Message:
NANCY: Add minimum allowed sound volume

Added a minimum volume for all sounds, which makes
sure all sounds can be heard, even if their volume in
the data is set to 0.

Changed paths:
    engines/nancy/sound.cpp


diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index 0f9ecc35e48..514a67196c8 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -302,6 +302,10 @@ void SoundManager::playSound(uint16 channelID) {
 	Channel &chan = _channels[channelID];
 	chan.stream->seek(0);
 
+	// Set a minimum volume (10 percent was chosen arbitrarily, but sounds reasonably close)
+	// Fix for nancy3 scene 6112, but NOT a hack; the original engine also set a minimum volume for all sounds
+	chan.volume = 10 + ((int)chan.volume * 90) / 100;
+
 	// Init 3D sound
 	if (chan.playCommands & ~kPlaySequential && chan.effectData) {
 		uint16 playCommands = chan.playCommands;
@@ -363,7 +367,7 @@ void SoundManager::playSound(uint16 channelID) {
 						&chan.handle,
 						Audio::makeLoopingAudioStream(chan.stream, numLoops),
 						channelID,
-						chan.volume * 255 / 100,
+						(int)chan.volume * 255 / 100,
 						0, DisposeAfterUse::NO);
 
 	soundEffectMaintenance(channelID, true);


Commit: 1d07ef258ba0d7738d11526575b058c91e55a746
    https://github.com/scummvm/scummvm/commit/1d07ef258ba0d7738d11526575b058c91e55a746
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:21+03:00

Commit Message:
NANCY: Remove items from inventory when held

Fixed an issue where RemoveInventoryNotHS would not
work correctly if the item was currently being held by the
player. This fixes the fire extinguisher in nancy3 remaining
in the inventory all the way until the end.

Changed paths:
    engines/nancy/state/scene.cpp
    engines/nancy/state/scene.h


diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index c7991644304..79f2b6e80aa 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -287,6 +287,8 @@ void Scene::removeItemFromInventory(uint16 id, bool pickUp) {
 
 	if (pickUp) {
 		setHeldItem(id);
+	} else if (getHeldItem() == id) {
+		setHeldItem(-1);
 	}
 	
 	g_nancy->_sound->playSound("BUOK");
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 18f99dc889d..a16139e4587 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -135,7 +135,7 @@ public:
 	void removeItemFromInventory(uint16 id, bool pickUp = true);
 	int16 getHeldItem() const { return _flags.heldItem; }
 	void setHeldItem(int16 id);
-	byte hasItem(int16 id) const { return _flags.items[id]; }
+	byte hasItem(int16 id) const { return _flags.items[id] || getHeldItem() == id; }
 
 	void installInventorySoundOverride(byte command, const SoundDescription &sound, const Common::String &caption, uint16 itemID);
 	void playItemCantSound(int16 itemID = -1);


Commit: cffac1e6aeafa05ffb03c78d6e58f4571890bf55
    https://github.com/scummvm/scummvm/commit/cffac1e6aeafa05ffb03c78d6e58f4571890bf55
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:21+03:00

Commit Message:
NANCY: Improve Overlay drawing accuracy

This is yet another attempt to fix all the issues caused by
the interaction between the multiple src rects in Overlay data.

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


diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index f28caddcd12..470e53c193e 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -288,14 +288,21 @@ void Overlay::setFrame(uint frame) {
 			srcRect.setHeight(_srcRects[0].height());
 		}
 	} else {
-		if (srcRect.isEmpty()) {
-			// In static mode the srcRect above may be empty (see "out of service" sign in nancy5 scenes 2056, 2075),
-			// in which case we need to take the rect from the bitmap struct instead. Note that this is a backup,
-			// since if we use the bitmap src rect in all cases rendering can be incorrect (see same sign in nancy5 scene 2000)
-			for (uint i = 0; i < _bitmaps.size(); ++i) {
-				if (_currentViewportFrame == _bitmaps[i].frameID) {
-					srcRect = _bitmaps[i].src;
-				}
+		// In static mode the animated srcRect above may or may not be valid.
+		// The way the original engine seems to work is that it creates an intermediate surface using
+		// the animation src bounds, and then copies from that surface to the screen using the static mode source
+		// rect below (or the other way around). We can achieve the same results by just offsetting one
+		// of the rects by the other's left/top coordinates, _provided they have the same dimensions_.
+		// Test cases for the way the two rects interact are nancy3 scene 3070, nancy5 scenes 2056, 2075, and 2000
+		for (uint i = 0; i < _bitmaps.size(); ++i) {
+			if (_currentViewportFrame == _bitmaps[i].frameID) {
+				Common::Rect staticSrc = _bitmaps[i].src;
+
+				// If this assertion fails, we need to start using an intermediate surface
+				assert((staticSrc.width() == srcRect.width() && staticSrc.height() == srcRect.height()) || srcRect.isEmpty());
+
+				staticSrc.translate(srcRect.left, srcRect.top);
+				srcRect = staticSrc;
 			}
 		}
 	}


Commit: 6cfc805477f5353301a2fad3d7e422892a9240c8
    https://github.com/scummvm/scummvm/commit/6cfc805477f5353301a2fad3d7e422892a9240c8
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:21+03:00

Commit Message:
NANCY: Rename data struct

Changed paths:
    engines/nancy/action/miscrecords.cpp
    engines/nancy/action/miscrecords.h
    engines/nancy/action/overlay.cpp
    engines/nancy/action/overlay.h
    engines/nancy/commontypes.cpp
    engines/nancy/commontypes.h


diff --git a/engines/nancy/action/miscrecords.cpp b/engines/nancy/action/miscrecords.cpp
index be22f79df9e..decee266fa2 100644
--- a/engines/nancy/action/miscrecords.cpp
+++ b/engines/nancy/action/miscrecords.cpp
@@ -315,7 +315,7 @@ void DifficultyLevel::execute() {
 void ShowInventoryItem::init() {
 	g_nancy->_resource->loadImage(_imageName, _fullSurface);
 
-	_drawSurface.create(_fullSurface, _bitmaps[0].src);
+	_drawSurface.create(_fullSurface, _blitDescriptions[0].src);
 
 	RenderObject::init();
 }
@@ -330,14 +330,14 @@ void ShowInventoryItem::readData(Common::SeekableReadStream &stream) {
 		stream.skip(2);
 	}
 
-	_bitmaps.resize(numFrames);
+	_blitDescriptions.resize(numFrames);
 	for (uint i = 0; i < numFrames; ++i) {
 		if (gameType <= kGameTypeNancy2) {
-			_bitmaps[i].readData(stream);
+			_blitDescriptions[i].readData(stream);
 		} else {
-			_bitmaps[i].frameID = i;
-			readRect(stream, _bitmaps[i].src);
-			readRect(stream, _bitmaps[i].dest);
+			_blitDescriptions[i].frameID = i;
+			readRect(stream, _blitDescriptions[i].src);
+			readRect(stream, _blitDescriptions[i].dest);
 		}
 	}
 }
@@ -352,8 +352,8 @@ void ShowInventoryItem::execute() {
 	case kRun: {
 		int newFrame = -1;
 
-		for (uint i = 0; i < _bitmaps.size(); ++i) {
-			if (_bitmaps[i].frameID == NancySceneState.getSceneInfo().frameID) {
+		for (uint i = 0; i < _blitDescriptions.size(); ++i) {
+			if (_blitDescriptions[i].frameID == NancySceneState.getSceneInfo().frameID) {
 				newFrame = i;
 				break;
 			}
@@ -364,9 +364,9 @@ void ShowInventoryItem::execute() {
 
 			if (newFrame != -1) {
 				_hasHotspot = true;
-				_hotspot = _bitmaps[newFrame].dest;
-				_drawSurface.create(_fullSurface, _bitmaps[newFrame].src);
-				_screenPosition = _bitmaps[newFrame].dest;
+				_hotspot = _blitDescriptions[newFrame].dest;
+				_drawSurface.create(_fullSurface, _blitDescriptions[newFrame].src);
+				_screenPosition = _blitDescriptions[newFrame].dest;
 				setVisible(true);
 			} else {
 				_hasHotspot = false;
diff --git a/engines/nancy/action/miscrecords.h b/engines/nancy/action/miscrecords.h
index e00c3714255..9d5fa5bf9a2 100644
--- a/engines/nancy/action/miscrecords.h
+++ b/engines/nancy/action/miscrecords.h
@@ -274,7 +274,7 @@ public:
 
 	uint16 _objectID = 0;
 	Common::String _imageName;
-	Common::Array<BitmapDescription> _bitmaps;
+	Common::Array<FrameBlitDescription> _blitDescriptions;
 
 	int16 _drawnFrameID = -1;
 	Graphics::ManagedSurface _fullSurface;
diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index 470e53c193e..a87f0509aaa 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -121,8 +121,8 @@ void Overlay::readData(Common::SeekableReadStream &stream) {
 
 	readRectArray(ser, _srcRects, numSrcRects);
 
-	_bitmaps.resize(numViewportFrames);
-	for (auto &bm : _bitmaps) {
+	_blitDescriptions.resize(numViewportFrames);
+	for (auto &bm : _blitDescriptions) {
 		bm.readData(stream, ser.getVersion() >= kGameTypeNancy2);
 	}
 }
@@ -169,9 +169,9 @@ void Overlay::execute() {
 					setVisible(false);
 					_hasHotspot = false;
 
-					for (uint i = 0; i < _bitmaps.size(); ++i) {
-						if (_currentViewportFrame == _bitmaps[i].frameID) {
-							moveTo(_bitmaps[i].dest);
+					for (uint i = 0; i < _blitDescriptions.size(); ++i) {
+						if (_currentViewportFrame == _blitDescriptions[i].frameID) {
+							moveTo(_blitDescriptions[i].dest);
 							setVisible(true);
 
 							if (_enableHotspot == kPlayOverlayWithHotspot) {
@@ -222,9 +222,9 @@ void Overlay::execute() {
 				setVisible(false);
 				_hasHotspot = false;
 
-				for (uint i = 0; i < _bitmaps.size(); ++i) {
-					if (_currentViewportFrame == _bitmaps[i].frameID) {
-						moveTo(_bitmaps[i].dest);
+				for (uint i = 0; i < _blitDescriptions.size(); ++i) {
+					if (_currentViewportFrame == _blitDescriptions[i].frameID) {
+						moveTo(_blitDescriptions[i].dest);
 						setVisible(true);
 
 						// In static mode every "animation" frame corresponds to a viewport frame
@@ -294,9 +294,9 @@ void Overlay::setFrame(uint frame) {
 		// rect below (or the other way around). We can achieve the same results by just offsetting one
 		// of the rects by the other's left/top coordinates, _provided they have the same dimensions_.
 		// Test cases for the way the two rects interact are nancy3 scene 3070, nancy5 scenes 2056, 2075, and 2000
-		for (uint i = 0; i < _bitmaps.size(); ++i) {
-			if (_currentViewportFrame == _bitmaps[i].frameID) {
-				Common::Rect staticSrc = _bitmaps[i].src;
+		for (uint i = 0; i < _blitDescriptions.size(); ++i) {
+			if (_currentViewportFrame == _blitDescriptions[i].frameID) {
+				Common::Rect staticSrc = _blitDescriptions[i].src;
 
 				// If this assertion fails, we need to start using an intermediate surface
 				assert((staticSrc.width() == srcRect.width() && staticSrc.height() == srcRect.height()) || srcRect.isEmpty());
diff --git a/engines/nancy/action/overlay.h b/engines/nancy/action/overlay.h
index 2339c64709b..b9b592de767 100644
--- a/engines/nancy/action/overlay.h
+++ b/engines/nancy/action/overlay.h
@@ -67,7 +67,7 @@ public:
 	Common::Array<Common::Rect> _srcRects;
 	// Describes how the animation will be displayed on a single
 	// frame of the viewport
-	Common::Array<BitmapDescription> _bitmaps;
+	Common::Array<FrameBlitDescription> _blitDescriptions;
 
 	int16 _currentFrame = -1;
 	int16 _currentViewportFrame = -1;
diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index a7fdf6db5cf..dc3e183fb6c 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -90,7 +90,7 @@ void HotspotDescription::readData(Common::SeekableReadStream &stream) {
 	readRect(stream, coords);
 }
 
-void BitmapDescription::readData(Common::SeekableReadStream &stream, bool frameIsLong) {
+void FrameBlitDescription::readData(Common::SeekableReadStream &stream, bool frameIsLong) {
 	if (!frameIsLong) {
 		frameID = stream.readUint16LE();
 	} else {
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index f963fd4854e..6c22826044e 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -162,9 +162,9 @@ struct HotspotDescription {
 	void readData(Common::SeekableReadStream &stream);
 };
 
-// Describes a single bitmap draw
-struct BitmapDescription {
-	uint16 frameID = 0;
+// Describes a blit operation, dependent on a background frame
+struct FrameBlitDescription {
+	uint16 frameID = 0; // Frame ID of the Scene background
 	Common::Rect src;
 	Common::Rect dest;
 


Commit: 29b80529586087aa420d80c6799a1106f8315bdf
    https://github.com/scummvm/scummvm/commit/29b80529586087aa420d80c6799a1106f8315bdf
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:22+03:00

Commit Message:
NANCY: Correctly read PlayDigiSound in nancy6

Added support for the extra flag to trigger a scene change
immediately, as introduced in nancy6. Also removed the
"AndDie" from the class name since it was renamed all
the way back in nancy3.

Changed paths:
    engines/nancy/action/arfactory.cpp
    engines/nancy/action/soundrecords.cpp
    engines/nancy/action/soundrecords.h


diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index da569c6daf0..3a0eaa1772f 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -186,9 +186,9 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
 	case 123:
 		return new InventorySoundOverride();
 	case 150:
-		return new PlayDigiSoundAndDie();
+		return new PlayDigiSound();
 	case 151:
-		return new PlayDigiSoundAndDie();
+		return new PlayDigiSound();
 	case 152:
 		return new PlaySoundPanFrameAnchorAndDie();
 	case 153:
diff --git a/engines/nancy/action/soundrecords.cpp b/engines/nancy/action/soundrecords.cpp
index 5043e3e6872..24faa9afa4d 100644
--- a/engines/nancy/action/soundrecords.cpp
+++ b/engines/nancy/action/soundrecords.cpp
@@ -30,26 +30,38 @@
 namespace Nancy {
 namespace Action {
 
-void PlayDigiSoundAndDie::readData(Common::SeekableReadStream &stream) {
+void PlayDigiSound::readData(Common::SeekableReadStream &stream) {
 	_sound.readDIGI(stream);
 
 	if (g_nancy->getGameType() >= kGameTypeNancy3) {
 		_soundEffect = new SoundEffectDescription;
 		_soundEffect->readData(stream);
+
+		if (g_nancy->getGameType() >= kGameTypeNancy6) {
+			_changeSceneImmediately = stream.readByte();
+		}
 	}
 
 	_sceneChange.readData(stream, g_nancy->getGameType() == kGameTypeVampire);
 
-	_flagOnTrigger.label = stream.readSint16LE();
-	_flagOnTrigger.flag = stream.readByte();
-	stream.skip(2);
+	_flagOnPlay.label = stream.readSint16LE();
+	_flagOnPlay.flag = stream.readByte();
+	stream.skip(2); // VIDEO_STOP_RENDERING, VIDEO_CONTINUE_RENDERING
 }
 
-void PlayDigiSoundAndDie::execute() {
+void PlayDigiSound::execute() {
 	switch (_state) {
 	case kBegin:
 		g_nancy->_sound->loadSound(_sound, &_soundEffect);
 		g_nancy->_sound->playSound(_sound);
+		NancySceneState.setEventFlag(_flagOnPlay);
+
+		if (_changeSceneImmediately) {
+			NancySceneState.changeScene(_sceneChange);
+			finishExecution();
+			break;
+		}
+
 		_state = kRun;
 		break;
 	case kRun:
@@ -63,7 +75,6 @@ void PlayDigiSoundAndDie::execute() {
 			NancySceneState.changeScene(_sceneChange);
 		}
 
-		NancySceneState.setEventFlag(_flagOnTrigger);
 		g_nancy->_sound->stopSound(_sound);
 
 		finishExecution();
@@ -71,8 +82,12 @@ void PlayDigiSoundAndDie::execute() {
 	}
 }
 
+Common::String PlayDigiSound::getRecordTypeName() const {
+	return g_nancy->getGameType() <= kGameTypeNancy2 ? "PlayDigiSoundAndDie" : "PlayDigiSound";
+}
+
 void PlayDigiSoundCC::readData(Common::SeekableReadStream &stream) {
-	PlayDigiSoundAndDie::readData(stream);
+	PlayDigiSound::readData(stream);
 
 	uint16 textSize = stream.readUint16LE();
 	if (textSize) {
@@ -88,7 +103,7 @@ void PlayDigiSoundCC::execute() {
 		NancySceneState.getTextbox().clear();
 		NancySceneState.getTextbox().addTextLine(_ccText);
 	}
-	PlayDigiSoundAndDie::execute();
+	PlayDigiSound::execute();
 }
 
 void PlaySoundPanFrameAnchorAndDie::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/action/soundrecords.h b/engines/nancy/action/soundrecords.h
index ae4fccd2db4..2811abf7158 100644
--- a/engines/nancy/action/soundrecords.h
+++ b/engines/nancy/action/soundrecords.h
@@ -27,24 +27,25 @@
 namespace Nancy {
 namespace Action {
 
-class PlayDigiSoundAndDie : public ActionRecord {
+class PlayDigiSound : public ActionRecord {
 public:
-	PlayDigiSoundAndDie() {}
-	~PlayDigiSoundAndDie() { delete _soundEffect; }
+	PlayDigiSound() {}
+	~PlayDigiSound() { delete _soundEffect; }
 	
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
 
 	SoundDescription _sound;
 	SoundEffectDescription *_soundEffect = nullptr;
+	bool _changeSceneImmediately = false;
 	SceneChangeDescription _sceneChange;
-	FlagDescription _flagOnTrigger;
+	FlagDescription _flagOnPlay;
 
 protected:
-	Common::String getRecordTypeName() const override { return "PlayDigiSoundAndDie"; }
+	Common::String getRecordTypeName() const override;
 };
 
-class PlayDigiSoundCC : public PlayDigiSoundAndDie {
+class PlayDigiSoundCC : public PlayDigiSound {
 public:
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;


Commit: 09a21ad755ab712f7ecf9ff5cbd0c425b5c6194a
    https://github.com/scummvm/scummvm/commit/09a21ad755ab712f7ecf9ff5cbd0c425b5c6194a
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:22+03:00

Commit Message:
NANCY: Set correct default textbox font

Modified the Textbox code so the conversation font is no
longer the default, but rather has to be requested by
Conversation types. This fixes the nancy6 tutorial having
a blue highlighted text while explicitly needing red.

Changed paths:
    engines/nancy/action/conversation.cpp
    engines/nancy/action/miscrecords.cpp
    engines/nancy/action/puzzle/riddlepuzzle.cpp
    engines/nancy/misc/hypertext.cpp
    engines/nancy/ui/textbox.cpp
    engines/nancy/ui/textbox.h


diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index f442be21a2f..0b07d70e926 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -169,7 +169,10 @@ void ConversationSound::execute() {
 	case kRun:
 		if (!_hasDrawnTextbox) {
 			_hasDrawnTextbox = true;
+			const TBOX *textboxData = (const TBOX *)g_nancy->getEngineData("TBOX");
+			assert(textboxData);
 			NancySceneState.getTextbox().clear();
+			NancySceneState.getTextbox().setOverrideFont(textboxData->conversationFontID);
 
 			if (ConfMan.getBool("subtitles")) {
 				NancySceneState.getTextbox().addTextLine(_text);
diff --git a/engines/nancy/action/miscrecords.cpp b/engines/nancy/action/miscrecords.cpp
index decee266fa2..0031134b6f5 100644
--- a/engines/nancy/action/miscrecords.cpp
+++ b/engines/nancy/action/miscrecords.cpp
@@ -113,9 +113,6 @@ void TextBoxWrite::readData(Common::SeekableReadStream &stream) {
 void TextBoxWrite::execute() {
 	auto &tb = NancySceneState.getTextbox();
 	tb.clear();
-	const TBOX *textboxData = (const TBOX *)g_nancy->getEngineData("TBOX");
-	assert(textboxData);
-	tb.overrideFontID(textboxData->defaultFontID);
 	tb.addTextLine(_text);
 	tb.setVisible(true);
 	finishExecution();
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.cpp b/engines/nancy/action/puzzle/riddlepuzzle.cpp
index fc8a24127fa..242e230b9a2 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.cpp
+++ b/engines/nancy/action/puzzle/riddlepuzzle.cpp
@@ -132,7 +132,7 @@ void RiddlePuzzle::execute() {
 		g_nancy->_sound->loadSound(_riddles[_riddleID].sound);
 		g_nancy->_sound->playSound(_riddles[_riddleID].sound);
 		NancySceneState.getTextbox().clear();
-		NancySceneState.getTextbox().overrideFontID(_textboxTextFontID);
+		NancySceneState.getTextbox().setOverrideFont(_textboxTextFontID);
 		NancySceneState.getTextbox().addTextLine(_riddles[_riddleID].text);
 
 		_state = kRun;
diff --git a/engines/nancy/misc/hypertext.cpp b/engines/nancy/misc/hypertext.cpp
index aea8faea3ec..8c47efbd5e3 100644
--- a/engines/nancy/misc/hypertext.cpp
+++ b/engines/nancy/misc/hypertext.cpp
@@ -131,7 +131,8 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 		font = g_nancy->_graphicsManager->getFont(curFontID);
 		highlightFont = g_nancy->_graphicsManager->getFont(highlightFontID);
 
-		// Do word wrapping on the text, sans tokens
+		// Do word wrapping on the text, sans tokens. This assumes
+		// all text uses fonts of the same width
 		Array<Common::String> wrappedLines;
 		font->wordWrap(currentLine, textBounds.width(), wrappedLines, 0);
 
diff --git a/engines/nancy/ui/textbox.cpp b/engines/nancy/ui/textbox.cpp
index 5d0b69396c5..f05ad9f3fb3 100644
--- a/engines/nancy/ui/textbox.cpp
+++ b/engines/nancy/ui/textbox.cpp
@@ -145,7 +145,7 @@ void Textbox::drawTextbox() {
 	textBounds.right -= tbox->rightOffset;
 
 	HypertextParser::drawAllText(	textBounds,															// bounds of text within full surface
-									_fontIDOverride != -1 ? _fontIDOverride : tbox->conversationFontID,	// font for basic text
+									_fontIDOverride != -1 ? _fontIDOverride : tbox->defaultFontID,	// font for basic text
 									tbox->highlightConversationFontID);									// font for highlight text
 
 	setVisible(true);
@@ -172,7 +172,7 @@ void Textbox::addTextLine(const Common::String &text, uint32 autoClearTime) {
 	}
 }
 
-void Textbox::overrideFontID(const uint fontID) {
+void Textbox::setOverrideFont(const uint fontID) {
 	const BSUM *bsum = (const BSUM *)g_nancy->getEngineData("BSUM");
 	assert(bsum);
 
diff --git a/engines/nancy/ui/textbox.h b/engines/nancy/ui/textbox.h
index fbcb0ab8f05..5866f92455f 100644
--- a/engines/nancy/ui/textbox.h
+++ b/engines/nancy/ui/textbox.h
@@ -49,7 +49,7 @@ public:
 	void clear() override;
 
 	void addTextLine(const Common::String &text, uint32 autoClearTime = 0);
-	void overrideFontID(const uint fontID);
+	void setOverrideFont(const uint fontID);
 
 private:
 	uint16 getInnerHeight() const;


Commit: 30d9732d20efd5c3905c11303cc281f210c61ee9
    https://github.com/scummvm/scummvm/commit/30d9732d20efd5c3905c11303cc281f210c61ee9
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:22+03:00

Commit Message:
NANCY: Cursor fixes

The forward and backward arrow cursors seem to have
been forgotten until now, so they have been implemented.
Also, the HotMultiframeSceneChange variants with specific
cursors now actually display those cursors.

Changed paths:
    engines/nancy/action/navigationrecords.h
    engines/nancy/cursor.cpp


diff --git a/engines/nancy/action/navigationrecords.h b/engines/nancy/action/navigationrecords.h
index 71ab8afe7ed..90978e6ef6b 100644
--- a/engines/nancy/action/navigationrecords.h
+++ b/engines/nancy/action/navigationrecords.h
@@ -46,6 +46,8 @@ public:
 	void readData(Common::SeekableReadStream &stream) override;
 	void execute() override;
 
+	CursorManager::CursorType getHoverCursor() const override { return _hoverCursor; }
+
 	Common::Array<HotspotDescription> _hotspots;
 
 protected:
diff --git a/engines/nancy/cursor.cpp b/engines/nancy/cursor.cpp
index 9a66a20a6b3..345f9ba3b55 100644
--- a/engines/nancy/cursor.cpp
+++ b/engines/nancy/cursor.cpp
@@ -185,6 +185,26 @@ void CursorManager::setCursor(CursorType type, int16 itemID) {
 			type = kMove;
 		}
 
+		break;
+	case kMoveForward:
+		// Only valid for nancy4 and up
+		if (gameType >= kGameTypeNancy4) {
+			_curCursorID = kMoveForward;
+			return;
+		} else {
+			type = kHotspot;
+		}
+
+		break;
+	case kMoveBackward:
+		// Only valid for nancy4 and up
+		if (gameType >= kGameTypeNancy4) {
+			_curCursorID = kMoveBackward;
+			return;
+		} else {
+			type = kHotspot;
+		}
+
 		break;
 	case kExit:
 		// Not valid in TVD


Commit: 1689b6a2e9e8c9194578d4d7de786a816aca369f
    https://github.com/scummvm/scummvm/commit/1689b6a2e9e8c9194578d4d7de786a816aca369f
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:22+03:00

Commit Message:
NANCY: Support nancy4's voice mail system

Made changes to the Telephone AR to support phone
numbers with 1 digit length. Also the ringing sound is
now correctly loaded from the static data, allowing for it
to be translated.

Changed paths:
    engines/nancy/action/puzzle/telephone.cpp
    engines/nancy/action/puzzle/telephone.h


diff --git a/engines/nancy/action/puzzle/telephone.cpp b/engines/nancy/action/puzzle/telephone.cpp
index c236c250ab0..f314a89c9d9 100644
--- a/engines/nancy/action/puzzle/telephone.cpp
+++ b/engines/nancy/action/puzzle/telephone.cpp
@@ -109,20 +109,75 @@ void Telephone::execute() {
 	case kRun:
 		switch (_callState) {
 		case kWaiting:
-			// Long phone numbers start with 1
-			if (_calledNumber.size() >= 11 || (_calledNumber.size() >= 7 && (_calledNumber[0] != 1))) {
-				NancySceneState.getTextbox().clear();
-				NancySceneState.getTextbox().addTextLine("ringing...<n><e>"); // Hardcoded in the original engine
-				g_nancy->_sound->loadSound(_ringSound);
-				g_nancy->_sound->playSound(_ringSound);
-				_callState = kRinging;
+			if (_checkNumbers) {
+				// Pressed a new button, check all numbers for match
+				// We do this before going to the ringing state to support nancy4's voice mail system,
+				// where call numbers can be 1 digit long
+				for (uint i = 0; i < _calls.size(); ++i) {
+					bool invalid = false;
+
+					for (uint j = 0; j < _calledNumber.size(); ++j) {
+						if (_calledNumber[j] != _calls[i].phoneNumber[j]) {
+							// Invalid number, move onto next
+							invalid = true;
+							break;
+						}
+					}
+
+					// We do not want to check for a terminator if the dialed number is of
+					// appropriate size (7 digits, or 11 when the number starts with '1')
+					bool checkNextDigit = true;
+					if (_calledNumber.size() >= 11 || (_calledNumber.size() >= 7 && (_calledNumber[0] != 1))) {
+						checkNextDigit = false;
+					}
+
+					if (!invalid && checkNextDigit) {
+						// Check if the next digit in the phone number is '10' (star). Presumably, that will never
+						// be contained in a valid phone number
+						if (_calls[i].phoneNumber[_calledNumber.size()] != 10) {
+							invalid = true;
+						}
+					}
+
+					if (!invalid) {
+						_selected = i;
+						break;
+					}
+				}
+
+				bool shouldRing = false;
+
+				if (_selected == -1) {
+					// Did not find a suitable match, check if the dialed number is above allowed size
+					if (_calledNumber.size() >= 11 || (_calledNumber.size() >= 7 && (_calledNumber[0] != 1))) {
+						shouldRing = true;
+					}
+				} else {
+					shouldRing = true;
+				}
+
+				if (shouldRing) {
+					if (_ringSound.name == "NO SOUND") {
+						// Will not ring, so skip text
+						_callState = kRinging;
+					} else {
+						NancySceneState.getTextbox().clear();
+						NancySceneState.getTextbox().addTextLine(g_nancy->getStaticData().ringingText);
+						g_nancy->_sound->loadSound(_ringSound);
+						g_nancy->_sound->playSound(_ringSound);
+						_callState = kRinging;
+					}
+				}
+
+				_checkNumbers = false;
 			}
 
 			break;
 		case kButtonPress:
 			if (!g_nancy->_sound->isSoundPlaying(_genericButtonSound)) {
 				g_nancy->_sound->stopSound(_genericButtonSound);
-				undrawButton(_selected);
+				undrawButton(_buttonLastPushed);
+				_buttonLastPushed = -1;
 				_callState = kWaiting;
 			}
 
@@ -130,41 +185,26 @@ void Telephone::execute() {
 		case kRinging:
 			if (!g_nancy->_sound->isSoundPlaying(_ringSound)) {
 				g_nancy->_sound->stopSound(_ringSound);
-				uint numberLength = _calledNumber[0] == 1 ? 11 : 7;
-
-				for (uint i = 0; i < _calls.size(); ++i) {
-					bool invalid = false;
-
-					for (uint j = 0; j < numberLength; ++j) {
-						if (_calledNumber[j] != _calls[i].phoneNumber[j]) {
-							// Invalid number, move onto next
-							invalid = true;
-							break;
-						}
-					}
-
-					if (invalid) {
-						continue;
-					}
 
+				if (_selected != -1) {
+					// Called a valid number
 					NancySceneState.getTextbox().clear();
-					NancySceneState.getTextbox().addTextLine(_calls[i].text);
-
-					_genericDialogueSound.name = _calls[i].soundName;
+					NancySceneState.getTextbox().addTextLine(_calls[_selected].text);
+					
+					_genericDialogueSound.name = _calls[_selected].soundName;
 					g_nancy->_sound->loadSound(_genericDialogueSound);
 					g_nancy->_sound->playSound(_genericDialogueSound);
-					_selected = i;
 					_callState = kCall;
+				} else {
+					// Called an invalid number
+					NancySceneState.getTextbox().clear();
+					NancySceneState.getTextbox().addTextLine(_dialAgainString);
 
-					return;
+					g_nancy->_sound->loadSound(_dialAgainSound);
+					g_nancy->_sound->playSound(_dialAgainSound);
+					_callState = kBadNumber;
 				}
 
-				NancySceneState.getTextbox().clear();
-				NancySceneState.getTextbox().addTextLine(_dialAgainString);
-
-				g_nancy->_sound->loadSound(_dialAgainSound);
-				g_nancy->_sound->playSound(_dialAgainSound);
-				_callState = kBadNumber;
 				return;
 			}
 
@@ -264,8 +304,8 @@ void Telephone::handleInput(NancyInput &input) {
 
 			drawButton(buttonNr);
 
-			_selected = buttonNr;
-
+			_buttonLastPushed = buttonNr;
+			_checkNumbers = true;
 			_callState = kButtonPress;
 		}
 	}
diff --git a/engines/nancy/action/puzzle/telephone.h b/engines/nancy/action/puzzle/telephone.h
index 74bff2bec2a..d6c17c47c4b 100644
--- a/engines/nancy/action/puzzle/telephone.h
+++ b/engines/nancy/action/puzzle/telephone.h
@@ -41,7 +41,9 @@ public:
 	Telephone() :
 		RenderActionRecord(7),
 		_callState(kWaiting),
-		_selected(0) {}
+		_buttonLastPushed(-1),
+		_selected(-1),
+		_checkNumbers(false) {}
 	virtual ~Telephone() {}
 
 	void init() override;
@@ -70,7 +72,9 @@ public:
 	Common::Array<byte> _calledNumber;
 	Graphics::ManagedSurface _image;
 	CallState _callState;
-	uint _selected;
+	int _buttonLastPushed;
+	int _selected;
+	bool _checkNumbers;
 
 protected:
 	Common::String getRecordTypeName() const override { return "Telephone"; }


Commit: e5d3c8614d47238a58fc178b879b67d21a8832f3
    https://github.com/scummvm/scummvm/commit/e5d3c8614d47238a58fc178b879b67d21a8832f3
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-20T16:16:22+03:00

Commit Message:
NANCY: Fix sound interpolation between scenes

Fixed a couple of errors made when implementing
3D sound interpolation.

Changed paths:
    engines/nancy/sound.cpp


diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index 514a67196c8..16f73c6d005 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -655,13 +655,13 @@ SoundManager::Channel::~Channel() {
 
 void SoundManager::soundEffectMaintenance() {
 	// Interpolate position and rotation when scene has changed to avoid audible chop in sound
-	if (_position != NancySceneState.getSceneSummary().listenerPosition) {
+	if (_position != NancySceneState.getSceneSummary().listenerPosition && _positionLerp == 0) {
 		++_positionLerp;
 	}
 
-	if (_positionLerp != 0) {
+	if (_positionLerp > 1) {
 		++_positionLerp;
-		if (_positionLerp == 10) {
+		if (_positionLerp > 10) {
 			_position = NancySceneState.getSceneSummary().listenerPosition;
 			_positionLerp = 0;
 		}
@@ -736,8 +736,8 @@ void SoundManager::soundEffectMaintenance(uint16 channelID, bool force) {
 		}
 	}
 
-	// Check if the player has moved OR if the sound itself has moved
-	if (!_shouldRecalculate && !hasStepped) {
+	// Check if the player has moved OR if the sound itself has moved, OR, if we're still interpolating
+	if (!_shouldRecalculate && !hasStepped && _positionLerp == 0) {
 		return;
 	}
 	




More information about the Scummvm-git-logs mailing list