[Scummvm-git-logs] scummvm master -> 9043be28b5a40d42f55c33eed9d5f530811504d3

bluegr noreply at scummvm.org
Sat Jul 11 11:23:06 UTC 2026


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

Summary:
b54f73f187 NANCY: NANCY10: Use a common SearchLink structure for cellphone entries
7133a3481e NANCY: NANCY10: Use the correct line height for journal and task list
9043be28b5 NANCY: NANCY10: Fix cursors set from terse HotMultiframeSceneChange


Commit: b54f73f187993f1564b98945cccc6579adc64eab
    https://github.com/scummvm/scummvm/commit/b54f73f187993f1564b98945cccc6579adc64eab
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-11T14:22:54+03:00

Commit Message:
NANCY: NANCY10: Use a common SearchLink structure for cellphone entries

Changed paths:
    engines/nancy/action/miscrecords.cpp
    engines/nancy/action/miscrecords.h
    engines/nancy/commontypes.h
    engines/nancy/enginedata.cpp
    engines/nancy/enginedata.h
    engines/nancy/puzzledata.cpp
    engines/nancy/puzzledata.h
    engines/nancy/ui/cellphonepopup.cpp
    engines/nancy/ui/cellphonepopup.h


diff --git a/engines/nancy/action/miscrecords.cpp b/engines/nancy/action/miscrecords.cpp
index 70fcc76d3d4..8b5f3fc3920 100644
--- a/engines/nancy/action/miscrecords.cpp
+++ b/engines/nancy/action/miscrecords.cpp
@@ -310,17 +310,16 @@ void UIPopupPrepScene::execute() {
 void AddSearchLink::readData(Common::SeekableReadStream &stream) {
 	_mode = stream.readSint16LE();
 
-	readFilename(stream, _key);
-	readFilename(stream, _value);
+	readFilename(stream, _link.key);
+	readFilename(stream, _link.value);
 
-	_extra  = stream.readSint16LE();
-	_flag = stream.readSint16LE();
-	_eventFlag = stream.readSint16LE();
+	_link.extra = stream.readSint16LE();
+	_link.flag = stream.readSint16LE();
+	_link.eventFlag = stream.readSint16LE();
 }
 
 void AddSearchLink::execute() {
-	NancySceneState.getCellPhonePopup().addSearchLink(
-		_mode, _key, _value, _extra, _flag, _eventFlag);
+	NancySceneState.getCellPhonePopup().addSearchLink(_mode, _link);
 
 	// Cellphone taskbar badge: mode 0 = new email (sub-cat 1), mode != 0
 	// = new web search topic (sub-cat 2).
diff --git a/engines/nancy/action/miscrecords.h b/engines/nancy/action/miscrecords.h
index 8a0fd3030c2..6391919dad2 100644
--- a/engines/nancy/action/miscrecords.h
+++ b/engines/nancy/action/miscrecords.h
@@ -185,15 +185,11 @@ public:
 	void execute() override;
 
 	int16 _mode = 0;
-	Common::String _key;          // CVTX key for the list row text (both modes)
-	Common::String _value;        // body CVTX key (mode 0/email); unused for mode 1
-	int16 _extra = 0;             // page index (mode 1); unused for mode 0
-	int16 _flag = 0;              // stored but unused by the original; reserved
-	int16 _eventFlag = 0;         // event-flag index set when the entry is opened
+	SearchLink _link;
 
 	Common::String getRecordExtraInfo() const override {
 		return Common::String::format("Key: %s, Value: %s, Mode: %d, Extra: %d, Flag: %d, EventFlag: %d",
-			_key.c_str(), _value.c_str(), _mode, _extra, _flag, _eventFlag);
+			_link.key.c_str(), _link.value.c_str(), _mode, _link.extra, _link.flag, _link.eventFlag);
 	}
 
 protected:
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 4b5b58d3c63..83cfe74af9c 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -212,6 +212,20 @@ struct MultiEventFlagDescription {
 	void execute();
 };
 
+// A Nancy 10+ cellphone list entry: an email message (mode 0) or a web-search
+// link (mode 1). Added at runtime by AR 131 (AddSearchLink); the first entry of
+// each list may instead be embedded in the UICL chunk. Which fields are used
+// depends on the mode (see CellPhonePopup). The byte layout differs per source,
+// so each site fills the fields itself rather than sharing a readData.
+struct SearchLink {
+	Common::String key;       // CVTX key whose looked-up text is the list row
+	Common::String value;     // body CVTX key (email); unused for search
+	int16 extra = 0;          // page index (search); unused for email
+	int16 flag = 0;           // stored by the original but unused; reserved
+	int16 eventFlag = -1;     // event-flag index set when the entry is opened
+	bool read = false;        // email only: set once the message is opened
+};
+
 struct SecondaryVideoDescription {
 	int16 frameID = kFrNoFrame;
 	Common::Rect srcRect;
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index a6d0e1bb5f7..d355a9e4704 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -1041,14 +1041,14 @@ UICL::UICL(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
 	// Initial email entry (key + value + flag + event flag), then initial
 	// web-search entry (key + extra + flag + event flag). Both are optional;
 	// an empty key marks an absent entry. CellPhonePopup seeds these on init.
-	readFilename(*chunkStream, initialEmailKey);
-	readFilename(*chunkStream, initialEmailValue);
-	initialEmailFlag = chunkStream->readSint16LE();
-	initialEmailEventFlag = chunkStream->readSint16LE();
-	readFilename(*chunkStream, initialSearchKey);
-	initialSearchExtra = chunkStream->readSint16LE();
-	initialSearchFlag = chunkStream->readSint16LE();
-	initialSearchEventFlag = chunkStream->readSint16LE();
+	readFilename(*chunkStream, initialEmail.key);
+	readFilename(*chunkStream, initialEmail.value);
+	initialEmail.flag = chunkStream->readSint16LE();
+	initialEmail.eventFlag = chunkStream->readSint16LE();
+	readFilename(*chunkStream, initialSearch.key);
+	initialSearch.extra = chunkStream->readSint16LE();
+	initialSearch.flag = chunkStream->readSint16LE();
+	initialSearch.eventFlag = chunkStream->readSint16LE();
 
 	fontId1 = chunkStream->readUint16LE();
 	fontId2 = chunkStream->readUint16LE();
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index f46d1e0afd7..57afd709651 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -677,14 +677,8 @@ struct UICL : public EngineData {
 	// One initial email entry and one initial web-search entry can be baked
 	// into the UICL chunk itself; the original seeds them at new-game init
 	// (its cellphone reset). An empty key means the game ships that list empty.
-	Common::String initialEmailKey;           // email entry CVTX key
-	Common::String initialEmailValue;         // email entry CVTX body/value
-	int16 initialEmailFlag = 0;
-	int16 initialEmailEventFlag = 0;
-	Common::String initialSearchKey;          // web-search entry CVTX key
-	int16 initialSearchExtra = 0;
-	int16 initialSearchFlag = 0;
-	int16 initialSearchEventFlag = 0;
+	SearchLink initialEmail;
+	SearchLink initialSearch;
 
 	uint16 fontId1 = 0;
 	uint16 fontId2 = 0;
diff --git a/engines/nancy/puzzledata.cpp b/engines/nancy/puzzledata.cpp
index 3da8d93012a..fb27477f6db 100644
--- a/engines/nancy/puzzledata.cpp
+++ b/engines/nancy/puzzledata.cpp
@@ -336,7 +336,7 @@ void CellPhoneData::synchronize(Common::Serializer &ser) {
 	syncLinkArray(ser, searchLinks);
 }
 
-void CellPhoneData::syncLinkArray(Common::Serializer &ser, Common::Array<LinkEntry> &arr) {
+void CellPhoneData::syncLinkArray(Common::Serializer &ser, Common::Array<SearchLink> &arr) {
 	uint16 n = (uint16)arr.size();
 	ser.syncAsUint16LE(n);
 	if (ser.isLoading()) {
diff --git a/engines/nancy/puzzledata.h b/engines/nancy/puzzledata.h
index 2d02b0da929..429cf6b94b0 100644
--- a/engines/nancy/puzzledata.h
+++ b/engines/nancy/puzzledata.h
@@ -222,15 +222,6 @@ struct TableData : public PuzzleData {
 // SetCellPhoneBatteryAndSignal and AddSearchLink action records,
 // persisted between saves.
 struct CellPhoneData : public PuzzleData {
-	struct LinkEntry {
-		Common::String key;       // CVTX key whose looked-up text is shown in the list
-		Common::String value;     // CVTX key for the body (email only); unused for search
-		int16 extra = 0;          // search mode: page index (mode-1 only); unused for email
-		int16 flag = -1;          // stored by the AR but unused by the original; reserved
-		int16 eventFlag = -1;     // event-flag index set when the entry is opened
-		bool read = false;        // email only: set once the message is opened
-	};
-
 	CellPhoneData() {}
 	virtual ~CellPhoneData() {}
 
@@ -247,11 +238,11 @@ struct CellPhoneData : public PuzzleData {
 	// Populated by AR 131 (AddSearchLink). Mode 0 → emailMessages (each
 	// with a body-text CVTX key + read flag); any non-zero mode →
 	// searchLinks (web search topics).
-	Common::Array<LinkEntry> emailMessages;
-	Common::Array<LinkEntry> searchLinks;
+	Common::Array<SearchLink> emailMessages;
+	Common::Array<SearchLink> searchLinks;
 
 private:
-	void syncLinkArray(Common::Serializer &ser, Common::Array<LinkEntry> &arr);
+	void syncLinkArray(Common::Serializer &ser, Common::Array<SearchLink> &arr);
 };
 
 // Nancy 11+ AR 69 (TimerControl). 10 software timers, each counting up from
diff --git a/engines/nancy/ui/cellphonepopup.cpp b/engines/nancy/ui/cellphonepopup.cpp
index 8a0d0f6d2b5..539a5d5cf55 100644
--- a/engines/nancy/ui/cellphonepopup.cpp
+++ b/engines/nancy/ui/cellphonepopup.cpp
@@ -121,14 +121,11 @@ void CellPhonePopup::init() {
 			// The UICL chunk can ship one initial email and one initial
 			// web-search entry, populated at new-game start (an empty key
 			// means none). addSearchLink appends into cellData's lists.
-			if (!_uiclData->initialEmailKey.empty()) {
-				addSearchLink(0, _uiclData->initialEmailKey, _uiclData->initialEmailValue,
-					0, _uiclData->initialEmailFlag, _uiclData->initialEmailEventFlag);
+			if (!_uiclData->initialEmail.key.empty()) {
+				addSearchLink(0, _uiclData->initialEmail);
 			}
-			if (!_uiclData->initialSearchKey.empty()) {
-				addSearchLink(1, _uiclData->initialSearchKey, Common::String(),
-					_uiclData->initialSearchExtra, _uiclData->initialSearchFlag,
-					_uiclData->initialSearchEventFlag);
+			if (!_uiclData->initialSearch.key.empty()) {
+				addSearchLink(1, _uiclData->initialSearch);
 			}
 		}
 		_contacts = cellData->contacts;
@@ -179,9 +176,7 @@ void CellPhonePopup::setBatteryLow(bool low) {
 	}
 }
 
-void CellPhonePopup::addSearchLink(int16 mode, const Common::String &key,
-									const Common::String &value, int16 extra,
-									int16 flag, int16 eventFlag) {
+void CellPhonePopup::addSearchLink(int16 mode, const SearchLink &link) {
 	CellPhoneData *cellData = (CellPhoneData *)NancySceneState.getPuzzleData(CellPhoneData::getTag());
 	if (!cellData) {
 		return;
@@ -190,24 +185,18 @@ void CellPhonePopup::addSearchLink(int16 mode, const Common::String &key,
 	// Original (AddSearchLink @ 004dac11) branches on `mode == 0` (email)
 	// vs anything else (search) — not specifically mode == 1.
 	const bool isSearch = (mode != 0);
-	Common::Array<CellPhoneData::LinkEntry> &list =
+	Common::Array<SearchLink> &list =
 		isSearch ? cellData->searchLinks : cellData->emailMessages;
 
 	// Skip duplicates (matched by key) so re-running the scene doesn't
 	// pile up the same entries.
 	for (uint i = 0; i < list.size(); ++i) {
-		if (list[i].key.equalsIgnoreCase(key)) {
+		if (list[i].key.equalsIgnoreCase(link.key)) {
 			return;
 		}
 	}
 
-	CellPhoneData::LinkEntry e;
-	e.key = key;
-	e.value = value;
-	e.extra = extra;
-	e.flag = flag;
-	e.eventFlag = eventFlag;
-	list.push_back(e);
+	list.push_back(link);
 
 	if (_isVisible &&
 			((isSearch && _screenState == kWebList) ||
@@ -807,7 +796,7 @@ void CellPhonePopup::drawLinkList() {
 	if (!cellData) {
 		return;
 	}
-	const Common::Array<CellPhoneData::LinkEntry> &list =
+	const Common::Array<SearchLink> &list =
 		_screenState == kWebList ? cellData->searchLinks : cellData->emailMessages;
 	const Common::Array<uint> visible = listVisibleIndices();
 	if (visible.empty()) {
@@ -1933,7 +1922,7 @@ void CellPhonePopup::handleInput(NancyInput &input) {
 		if (row != (uint)-1 && row >= titleRows) {
 			const uint entryRow = row - titleRows;
 			CellPhoneData *cellData = (CellPhoneData *)NancySceneState.getPuzzleData(CellPhoneData::getTag());
-			Common::Array<CellPhoneData::LinkEntry> *list = nullptr;
+			Common::Array<SearchLink> *list = nullptr;
 			if (cellData) {
 				list = (_screenState == kWebList) ? &cellData->searchLinks
 												  : &cellData->emailMessages;
@@ -1948,7 +1937,7 @@ void CellPhonePopup::handleInput(NancyInput &input) {
 					// Move the selection indicator to the clicked row, then
 					// act on the entry.
 					_directorySelection = entryRow;
-					CellPhoneData::LinkEntry &e = (*list)[absolute];
+					SearchLink &e = (*list)[absolute];
 					// Original sets the event flag when an entry is opened;
 					// it does not scene-change from a list click.
 					if (e.eventFlag != -1) {
diff --git a/engines/nancy/ui/cellphonepopup.h b/engines/nancy/ui/cellphonepopup.h
index 45e532aa78d..25a6156f8cf 100644
--- a/engines/nancy/ui/cellphonepopup.h
+++ b/engines/nancy/ui/cellphonepopup.h
@@ -59,11 +59,10 @@ public:
 	// Used by AR 130 to add/modify entries at runtime.
 	void upsertContact(const UICL::Contact &c);
 
-	// Append an entry to the search/email results list (mode 0) or the
-	// web bookmarks list (mode 1). Driven by AR 131 (AddSearchLink).
-	void addSearchLink(int16 mode, const Common::String &key,
-						const Common::String &value, int16 extra,
-						int16 flag, int16 eventFlag);
+	// Append an entry to the email results list (mode 0) or the web
+	// bookmarks list (mode 1). Driven by AR 131 (AddSearchLink) and the
+	// UICL chunk's initial entries.
+	void addSearchLink(int16 mode, const SearchLink &link);
 
 	// Phone-call return scene. Set before jumping into a conversation scene
 	// so AR 128 (CellPhonePopCellSceneFromStack) can return there without


Commit: 7133a3481ee61791cf35a5d5d7106e166346b7a7
    https://github.com/scummvm/scummvm/commit/7133a3481ee61791cf35a5d5d7106e166346b7a7
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-11T14:22:57+03:00

Commit Message:
NANCY: NANCY10: Use the correct line height for journal and task list

Fix #16909

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 2f4fcd63bed..830a42c8d07 100644
--- a/engines/nancy/font.cpp
+++ b/engines/nancy/font.cpp
@@ -158,6 +158,10 @@ int Font::getCharWidth(uint32 chr) const {
 	return getCharacterSourceRect(chr).width() + _charSpace;
 }
 
+int Font::getLineHeight() const {
+	return _characterRects.empty() ? getFontHeight() : _characterRects[0].height();
+}
+
 void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
 	Common::Rect srcRect = getCharacterSourceRect(chr);
 	if (color == 0) {
diff --git a/engines/nancy/font.h b/engines/nancy/font.h
index 60c4b6301cb..52fffab58f5 100644
--- a/engines/nancy/font.h
+++ b/engines/nancy/font.h
@@ -44,6 +44,10 @@ public:
 	void read(Common::SeekableReadStream &stream);
 
 	int getFontHeight() const override { return _fontHeight - 1; }
+
+	// The vertical advance between text lines (height of the first glyph).
+	int getLineHeight() const;
+
 	int getMaxCharWidth() const override { return _maxCharWidth; }
 	int getCharWidth(uint32 chr) const override;
 	int getKerningOffset(uint32 left, uint32 right) const override { return 0; }
diff --git a/engines/nancy/misc/hypertext.cpp b/engines/nancy/misc/hypertext.cpp
index a01671b29e0..cd77a5133f4 100644
--- a/engines/nancy/misc/hypertext.cpp
+++ b/engines/nancy/misc/hypertext.cpp
@@ -60,11 +60,12 @@ void HypertextParser::setImageName(const Common::Path &name) {
 	_imageName = name;
 }
 
-static uint lineStep(const Graphics::Font *font) {
-	const uint h = font->getFontHeight();
-	if (g_nancy->getGameType() >= kGameTypeNancy10)
+static uint lineStep(const Font *font) {
+	if (g_nancy->getGameType() >= kGameTypeNancy10) {
+		const uint h = font->getLineHeight();
 		return h + h / 9;
-	return h;
+	}
+	return font->getFontHeight();
 }
 
 void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffsetNonNewline, uint fontID, uint highlightFontID) {


Commit: 9043be28b5a40d42f55c33eed9d5f530811504d3
    https://github.com/scummvm/scummvm/commit/9043be28b5a40d42f55c33eed9d5f530811504d3
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-07-11T14:22:57+03:00

Commit Message:
NANCY: NANCY10: Fix cursors set from terse HotMultiframeSceneChange

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


diff --git a/engines/nancy/action/navigationrecords.h b/engines/nancy/action/navigationrecords.h
index 4c3999c1743..c6e9cb512d4 100644
--- a/engines/nancy/action/navigationrecords.h
+++ b/engines/nancy/action/navigationrecords.h
@@ -79,6 +79,7 @@ public:
 	void execute() override;
 
 	CursorManager::CursorType getHoverCursor() const override { return _hoverCursor; }
+	bool cursorSetFromScript() const override { return _isTerse; }
 
 	Common::Array<HotspotDescription> _hotspots;
 	bool _isTerse = false;




More information about the Scummvm-git-logs mailing list