[Scummvm-git-logs] scummvm master -> 58e89ed1a95fb359e58fc87fafb0207058bfc820

fracturehill noreply at scummvm.org
Fri Sep 22 10:38:14 UTC 2023


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:
a864756a67 NANCY: Fix BSUM reading for most nancy3 versions
d35fc0d891 NANCY: Fix graphics on big endian systems
ca859337f2 NANCY: Static mode overlay fix
e9e832c0eb NANCY: Make sure all Telephone sounds are stopped
58e89ed1a9 NANCY: Make sure text color changes in correct positions


Commit: a864756a670c89b136d1a003d9fe4429a4cf24b8
    https://github.com/scummvm/scummvm/commit/a864756a670c89b136d1a003d9fe4429a4cf24b8
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-22T13:37:26+03:00

Commit Message:
NANCY: Fix BSUM reading for most nancy3 versions

It seems the version of nancy3 I use for testing is slightly
different from the one that was shipped originally, and the
one currently being sold on Steam. Notably, it features a
slightly different BSUM format not found in later games,
with the difference being there to support the Dreamcatcher
logo shown in the beginning. This commit fixes every other
version, which do not have that extra logo or bit.

Changed paths:
    engines/nancy/detection.cpp
    engines/nancy/detection.h
    engines/nancy/enginedata.cpp
    engines/nancy/nancy.cpp


diff --git a/engines/nancy/detection.cpp b/engines/nancy/detection.cpp
index 8d41a88e5ee..610ca4803d7 100644
--- a/engines/nancy/detection.cpp
+++ b/engines/nancy/detection.cpp
@@ -149,7 +149,7 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
 			AD_ENTRY1s("ciftree.dat", "ee5f8832226567c3610556497c451b09", 16256355),
 			Common::EN_ANY,
 			Common::kPlatformWindows,
-			ADGF_UNSTABLE | ADGF_DROPPLATFORM,
+			ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_PLG_BYTE_IN_BSUM,
 			GUIO2(GAMEOPTION_PLAYER_SPEECH, GAMEOPTION_CHARACTER_SPEECH)
 		},
 		Nancy::kGameTypeNancy3
@@ -176,7 +176,7 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
 			},
 			Common::EN_ANY,
 			Common::kPlatformWindows,
-			ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED,
+			ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED | Nancy::GF_PLG_BYTE_IN_BSUM,
 			GUIO2(GAMEOPTION_PLAYER_SPEECH, GAMEOPTION_CHARACTER_SPEECH)
 		},
 		Nancy::kGameTypeNancy3
diff --git a/engines/nancy/detection.h b/engines/nancy/detection.h
index ce721356cca..af92635621f 100644
--- a/engines/nancy/detection.h
+++ b/engines/nancy/detection.h
@@ -41,7 +41,8 @@ enum GameType {
 };
 
 enum NancyGameFlags {
-	GF_COMPRESSED = 1 << 0
+	GF_COMPRESSED 		= 1 << 0,
+	GF_PLG_BYTE_IN_BSUM	= 1 << 1
 };
 
 struct NancyGameDescription {
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index f9a70fbffb6..c805cae6160 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -54,9 +54,14 @@ BSUM::BSUM(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
 	s.syncAsUint16LE(startTimeHours);
 	s.syncAsUint16LE(startTimeMinutes);
 
-	s.skip(0xA7, kGameTypeVampire, kGameTypeNancy2);
-	s.skip(4, kGameTypeNancy3, kGameTypeNancy3);
-	s.skip(3, kGameTypeNancy4);
+	s.skip(0xA4, kGameTypeVampire, kGameTypeNancy2);
+	s.skip(3); // Number of object, frame, and logo images
+	if (g_nancy->getGameFlags() & GF_PLG_BYTE_IN_BSUM) {
+		// There's a weird version of nancy3 with an extra byte counting the number of partner logos.
+		// On first glance this seems to be the only difference, but it'll need to be checked more thoroughly
+		// TODO
+		s.skip(1);
+	}
 
 	s.skip(8, kGameTypeVampire, kGameTypeVampire);
 	readRect(s, extraButtonHotspot, kGameTypeVampire, kGameTypeVampire);
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 7902bd65f38..44a7e0043bc 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -100,7 +100,7 @@ NancyEngine::~NancyEngine() {
 }
 
 NancyEngine *NancyEngine::create(GameType type, OSystem *syst, const NancyGameDescription *gd) {
-	if (type >= kGameTypeVampire && type <= kGameTypeNancy6) {
+	if (type >= kGameTypeVampire && type <= kGameTypeNancy9) {
 		return new NancyEngine(syst, gd);
 	}
 


Commit: d35fc0d891fe59feead1cba3212d860c012b03b0
    https://github.com/scummvm/scummvm/commit/d35fc0d891fe59feead1cba3212d860c012b03b0
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-22T13:37:27+03:00

Commit Message:
NANCY: Fix graphics on big endian systems

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


diff --git a/engines/nancy/resource.cpp b/engines/nancy/resource.cpp
index 0fad3e15210..50e97c7547e 100644
--- a/engines/nancy/resource.cpp
+++ b/engines/nancy/resource.cpp
@@ -753,11 +753,12 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::Surface &s
 	surf.free();
 
 	byte *buf = nullptr;
+	uint bufSize = 0;
 
 	if (treeName.size()) {
-		buf = getCifData(treeName, name, info);
+		buf = getCifData(treeName, name, info, &bufSize);
 	} else {
-		buf = getCifData(name, info);
+		buf = getCifData(name, info, &bufSize);
 	}
 
 	if (!buf && treeName.size() > 0) {
@@ -802,6 +803,13 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::Surface &s
 	surf.pitch = info.pitch;
 	surf.setPixels(buf);
 	surf.format = g_nancy->_graphicsManager->getInputPixelFormat();
+	#ifdef SCUMM_BIG_ENDIAN
+	if (info.depth == 16) {
+		for (uint i = 0; i < bufSize / 2; ++i) {
+			((uint16 *)buf)[i] = SWAP_BYTES_16(((uint16 *)buf)[i]);
+		}
+	}
+	#endif
 	return true;
 }
 
@@ -810,11 +818,12 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
 	surf.free();
 
 	byte *buf = nullptr;
+	uint bufSize = 0;
 
 	if (treeName.size()) {
-		buf = getCifData(treeName, name, info);
+		buf = getCifData(treeName, name, info, &bufSize);
 	} else {
-		buf = getCifData(name, info);
+		buf = getCifData(name, info, &bufSize);
 	}
 
 	if (!buf) {
@@ -854,6 +863,14 @@ bool ResourceManager::loadImage(const Common::String &name, Graphics::ManagedSur
 			*outDest = info.dest;
 		}
 
+		#ifdef SCUMM_BIG_ENDIAN
+		if (info.depth == 16) {
+			for (uint i = 0; i < bufSize / 2; ++i) {
+				((uint16 *)buf)[i] = SWAP_BYTES_16(((uint16 *)buf)[i]);
+			}
+		}
+		#endif
+
 		GraphicsManager::copyToManaged(buf, surf, info.width, info.height, g_nancy->_graphicsManager->getInputPixelFormat());
 		return true;
 	}
diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index 4a9113bd612..a4f90229b79 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -347,6 +347,15 @@ const Graphics::Surface *AVFDecoder::AVFVideoTrack::decodeFrame(uint frameNr)  {
 		delete[] decompBuf;
 	}
 
+	#ifdef SCUMM_BIG_ENDIAN
+	byte *buf = (byte *)frameInCache.getPixels();
+	if (g_nancy->_graphicsManager->getInputPixelFormat().bytesPerPixel == 2) {
+		for (int i = 0; i < frameInCache.pitch * frameInCache.h / 2; ++i) {
+			((uint16 *)buf)[i] = SWAP_BYTES_16(((uint16 *)buf)[i]);
+		}
+	}
+	#endif
+
 	return &frameInCache;
 }
 


Commit: ca859337f2215d4c25c2c8a9092048fdd0e60726
    https://github.com/scummvm/scummvm/commit/ca859337f2215d4c25c2c8a9092048fdd0e60726
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-22T13:37:27+03:00

Commit Message:
NANCY: Static mode overlay fix

Added support for another edge case in static mode Overlays

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


diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index 1d36a347522..f0aae790d70 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -296,26 +296,32 @@ void Overlay::setFrame(uint frame) {
 		// Static mode overlays are an absolute mess, and use both the general source rects (_srcRects),
 		// and the ones inside the blit description struct corresponding to the current scene background.
 
-		// Firstly, the order of the blit descriptions does not necessarily correspond to the order of
-		// the general rects, as the general rects are ordered based on the scene's background frame id,
-		// while the blit descriptions can be in arbitrary order. 
-		// An example is nancy4 scene 3500, where the overlay appears on background frames 0, 1, 2, 18 and 19,
-		// while the blit descriptions are in order 18, 19, 0, 1, 2. Thus, if we don't do the counting below
-		// we get wildly inaccurate results.
-		uint srcID = 0;
-
-		for (int i = 0; i < _currentViewportFrame; ++i) {
-			for (uint j = 0; j < _blitDescriptions.size(); ++j) {
-				if (_blitDescriptions[j].frameID == i) {
-					++srcID;
-					continue;
+		if (_srcRects.size() > 1) {
+			// First, the order of the blit descriptions does not necessarily correspond to the order of
+			// the general rects, as the general rects are ordered based on the scene's background frame id,
+			// while the blit descriptions can be in arbitrary order. 
+			// An example is nancy4 scene 3500, where the overlay appears on background frames 0, 1, 2, 18 and 19,
+			// while the blit descriptions are in order 18, 19, 0, 1, 2. Thus, if we don't do the counting below
+			// we get wildly inaccurate results.
+			uint srcID = 0;
+
+			for (int i = 0; i < _currentViewportFrame; ++i) {
+				for (uint j = 0; j < _blitDescriptions.size(); ++j) {
+					if (_blitDescriptions[j].frameID == i) {
+						++srcID;
+						continue;
+					}
 				}
 			}
-		}
 
-		srcRect = _srcRects[srcID];
+			srcRect = _srcRects[srcID];
+		} else {
+			// Second, the number of general source rects may also be just one, in which case it's valid
+			// for every blit description (nancy4 scene 1300)
+			srcRect = _srcRects[0];
+		}
 
-		// Second, the general source rect we just got may also be completely empty (nancy5 scenes 2056, 2057),
+		// 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.


Commit: e9e832c0eb0d0476160d337982c08811d499e8d2
    https://github.com/scummvm/scummvm/commit/e9e832c0eb0d0476160d337982c08811d499e8d2
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-22T13:37:27+03:00

Commit Message:
NANCY: Make sure all Telephone sounds are stopped

Fixed an issue where the dial tone sound would keep
playing even after exiting the telephone scene.

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


diff --git a/engines/nancy/action/puzzle/telephone.cpp b/engines/nancy/action/puzzle/telephone.cpp
index f314a89c9d9..f1b0c20f093 100644
--- a/engines/nancy/action/puzzle/telephone.cpp
+++ b/engines/nancy/action/puzzle/telephone.cpp
@@ -211,24 +211,18 @@ void Telephone::execute() {
 			break;
 		case kBadNumber:
 			if (!g_nancy->_sound->isSoundPlaying(_dialAgainSound)) {
-				g_nancy->_sound->stopSound(_dialAgainSound);
-
 				_state = kActionTrigger;
 			}
 
 			break;
 		case kCall:
 			if (!g_nancy->_sound->isSoundPlaying(_genericDialogueSound)) {
-				g_nancy->_sound->stopSound(_genericDialogueSound);
-
 				_state = kActionTrigger;
 			}
 
 			break;
 		case kHangUp:
 			if (!g_nancy->_sound->isSoundPlaying(_hangUpSound)) {
-				g_nancy->_sound->stopSound(_hangUpSound);
-
 				_state = kActionTrigger;
 			}
 
@@ -259,6 +253,13 @@ void Telephone::execute() {
 			break;
 		}
 
+				g_nancy->_sound->stopSound(_hangUpSound);
+				g_nancy->_sound->stopSound(_genericDialogueSound);
+				g_nancy->_sound->stopSound(_genericButtonSound);
+				g_nancy->_sound->stopSound(_dialAgainSound);
+				g_nancy->_sound->stopSound(_ringSound);
+				g_nancy->_sound->stopSound(_dialToneSound);
+
 		finishExecution();
 	}
 }


Commit: 58e89ed1a95fb359e58fc87fafb0207058bfc820
    https://github.com/scummvm/scummvm/commit/58e89ed1a95fb359e58fc87fafb0207058bfc820
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-09-22T13:37:27+03:00

Commit Message:
NANCY: Make sure text color changes in correct positions

Fixed (hopefully) all issues with color changes in text being
in incorrect positions. The new algorithm ignores all
whitespace characters when counting how much has been
drawn on screen, as they, combined with word wrapping,
were the source of the miscounting.

Changed paths:
    engines/nancy/font.cpp
    engines/nancy/font.h
    engines/nancy/misc/hypertext.cpp


diff --git a/engines/nancy/font.cpp b/engines/nancy/font.cpp
index a442a4f1b3d..7e0addf76b2 100644
--- a/engines/nancy/font.cpp
+++ b/engines/nancy/font.cpp
@@ -24,6 +24,7 @@
 #include "engines/nancy/resource.h"
 #include "engines/nancy/graphics.h"
 #include "engines/nancy/util.h"
+#include "engines/nancy/enginedata.h"
 
 namespace Nancy {
 
@@ -114,6 +115,9 @@ void Font::read(Common::SeekableReadStream &stream) {
 		_maxCharWidth = MAX<int>(cur.width(), _maxCharWidth);
 		_fontHeight = MAX<int>(cur.height(), _fontHeight);
 	}
+
+	_textboxData = (const TBOX *)g_nancy->getEngineData("TBOX");
+	assert(_textboxData);
 }
 
 int Font::getCharWidth(uint32 chr) const {
@@ -303,6 +307,9 @@ Common::Rect Font::getCharacterSourceRect(char chr) const {
 		offset = chr + _lowercaseOffset - 0x61;
 	} else if (isDigit(chr)) {
 		offset = chr + _digitOffset - 0x30;
+	} else if (chr == '\t') {
+		ret.setWidth((_spaceWidth - 1) * _textboxData->tabWidth);
+		return ret;
 	} else if (isSpace(chr)) {
 		ret.setWidth(_spaceWidth - 1);
 		return ret;
diff --git a/engines/nancy/font.h b/engines/nancy/font.h
index 7e7ac37077d..b3d8dfdba08 100644
--- a/engines/nancy/font.h
+++ b/engines/nancy/font.h
@@ -116,9 +116,11 @@ private:
 
 	Graphics::ManagedSurface _image;
 
-	int _fontHeight;
-	int _maxCharWidth;
-	uint _transColor;
+	const struct TBOX *_textboxData = nullptr;
+
+	int _fontHeight = 0;
+	int _maxCharWidth = 0;
+	uint _transColor = 0;
 };
 
 } // End of namespace Nancy
diff --git a/engines/nancy/misc/hypertext.cpp b/engines/nancy/misc/hypertext.cpp
index 8c47efbd5e3..92074cb2f40 100644
--- a/engines/nancy/misc/hypertext.cpp
+++ b/engines/nancy/misc/hypertext.cpp
@@ -53,10 +53,6 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 	const Font *font = nullptr;
 	const Font *highlightFont = nullptr;
 
-	// Used to get tab width
-	const TBOX *tbox = (const TBOX *)g_nancy->getEngineData("TBOX");
-	assert(tbox);
-
 	_numDrawnLines = 0;
 
 	for (uint lineID = 0; lineID < _textLines.size(); ++lineID) {
@@ -65,6 +61,7 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 		Rect hotspot;
 		Common::Queue<ColorChange> colorChanges;
 		int curFontID = fontID;
+		uint numNonSpaceChars = 0;
 
 		// Token braces plus invalid characters that are known to appear in strings
 		Common::StringTokenizer tokenizer(_textLines[lineID], "<>\"");
@@ -99,18 +96,16 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 					continue;
 				case 't' :
 					// Tab
-					for (uint i = 0; i < tbox->tabWidth; ++i) {
-						currentLine += " ";
-					}
+					currentLine += '\t';
 					continue;
 				case 'c' :
 					// Color tokens
-					// We keep the positions and colors of the color tokens in a queue
+					// We keep the positions (excluding spaces) and colors of the color tokens in a queue
 					if (curToken.size() != 2) {
 						break;
 					}
 					
-					colorChanges.push({currentLine.size(), (byte)(curToken[1] - 48)});
+					colorChanges.push({numNonSpaceChars, (byte)(curToken[1] - 48)});
 					continue;
 				case 'f' :
 					// Font token
@@ -125,6 +120,15 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 				}
 			}
 
+			// Count the number of non-space characters. We use this to keep track
+			// of where color changes should happen, since including whitespaces
+			// presents a lot of edge cases when combined with word wrapping
+			for (uint i = 0; i < curToken.size(); ++i) {
+				if (curToken[i] != ' ') {
+					++numNonSpaceChars;
+				}
+			}
+
 			currentLine += curToken;
 		}
 		
@@ -151,19 +155,20 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 		for (Common::String &line : wrappedLines) {
 			uint horizontalOffset = 0;
 
-			// Trim whitespaces at end of wrapped lines to make counting
-			// of characters consistent. We do this manually since we _want_
-			// some whitespaces at the beginning of a line (e.g. tabs)
-			if (Common::isSpace(line.lastChar())) {
+			// Trim whitespaces (only) at beginning and end of wrapped lines
+			while (line.lastChar() == ' ') {
 				line.deleteLastChar();
 			}
 
+			while (line.firstChar() == ' ') {
+				line.deleteChar(0);
+			}
+
 			// Set the width of the hotspot
 			if (hasHotspot) {
 				hotspot.setWidth(MAX<int16>(hotspot.width(), font->getStringWidth(line)));
 			}
 
-			bool hasSplit = false;
 			while (!line.empty()) {
 				Common::String subLine;
 
@@ -179,20 +184,12 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 						// There's a token inside the current line, so split off the part before it
 						subLine = line.substr(0, colorChanges.front().numChars - totalCharsDrawn);
 						line = line.substr(subLine.size());
-						hasSplit = true;
 					}
 				}
 
 				// Choose whether to draw the subLine, or the full line
 				Common::String &stringToDraw = subLine.size() ? subLine : line;
 
-				// Clear (single!) whitespace from beginning of line. We do this after
-				bool clearedSpaceAtStart = false;
-				if (!hasSplit && line.firstChar() == ' ' && line.size() > 1 && line[1] != ' ') {
-					line.deleteChar(0);
-					clearedSpaceAtStart = true;
-				}
-
 				// Draw the normal text
 				font->drawString(				&_fullSurface,
 												stringToDraw,
@@ -211,21 +208,21 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint fontID, u
 												colorID);
 				}
 
-				// Account for space cleared at start to make sure color calculations are correct
-				if (clearedSpaceAtStart) {
-					++totalCharsDrawn;
+				// Count number of non-space characters drawn. Used for color.
+				// Note that we use isSpace() specifically to exclude the tab character
+				for (uint i = 0; i < stringToDraw.size(); ++i) {
+					if (!isSpace(stringToDraw[i])) {
+						++totalCharsDrawn;
+					}
 				}
 
 				if (subLine.size()) {
 					horizontalOffset += font->getStringWidth(subLine);
-					totalCharsDrawn += subLine.size();
 				} else {
-					totalCharsDrawn += line.size();
 					break;
 				}
 			}
 
-			++totalCharsDrawn; // Account for newlines, which are removed from the string when doing word wrap
 			++_numDrawnLines;
 
 			// Record the height of the text currently drawn. Used for textbox scrolling




More information about the Scummvm-git-logs mailing list