[Scummvm-git-logs] scummvm master -> 1b94ca4b2f1db0c7f0d2a1c9e314ddcea54ab1d2
bluegr
noreply at scummvm.org
Tue Apr 28 01:05:30 UTC 2026
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
78fa279001 NANCY: Properly handle the INV chunk for Nancy10+
0dbacb1043 NANCY: Add handling for the UIBW (web browser) chunk, used in Nancy10+
4f1f0822c6 NANCY: Introduce common types for Nancy10+ UI elements
eaa16ce997 NANCY: Add handling for the Nancy10+ UICO (conversation popup) chunk
db4a693481 NANCY: Add handling for the Nancy10+ TASK chunk (main UI)
4922da8092 NANCY: Add handling for the common UI button slot type
133ef5787a NANCY: Handle the Nancy10+ UIIV (inventory) and UINB (notebook) chunks
1b94ca4b2f NANCY: Add handling for the Nancy10+ UICL (cell phone) chunk
Commit: 78fa279001a60cef62e45a3f74c4a902c262e4c7
https://github.com/scummvm/scummvm/commit/78fa279001a60cef62e45a3f74c4a902c262e4c7
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:42+03:00
Commit Message:
NANCY: Properly handle the INV chunk for Nancy10+
Changed paths:
engines/nancy/enginedata.cpp
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 11ca6d02722..8146ca70ca1 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -223,10 +223,13 @@ INV::INV(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
item.cantSound.readNormal(*chunkStream);
} else if (s.getVersion() >= kGameTypeNancy9) {
for (int j = 0; j < 3; ++j) {
+ if (s.getVersion() >= kGameTypeNancy10)
+ readFilename(s, item.cantSounds[j].name);
s.syncBytes(textBuf, 60);
textBuf[59] = '\0';
assembleTextLine((char *)textBuf, item.cantTexts[j], 60);
- readFilename(s, item.cantSounds[j].name);
+ if (s.getVersion() == kGameTypeNancy9)
+ readFilename(s, item.cantSounds[j].name);
}
item.cantText = item.cantTexts[0]; // Default text is the first one
Commit: 0dbacb10431ea4086b4b7124698ef645dadc2484
https://github.com/scummvm/scummvm/commit/0dbacb10431ea4086b4b7124698ef645dadc2484
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:43+03:00
Commit Message:
NANCY: Add handling for the UIBW (web browser) chunk, used in Nancy10+
Changed paths:
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 8146ca70ca1..0ba65b5434f 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -877,7 +877,31 @@ TASK::TASK(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
UIBW::UIBW(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
readFilename(*chunkStream, imageName);
- // TODO
+
+ // Read URL records one at a time, stopping when the remaining bytes
+ // are no longer enough for a full record or when the record has an
+ // empty (zero-byte) name â the game pads the array with empty slots.
+ while (chunkStream->size() - chunkStream->pos() >= (int64)kUrlRecordSize) {
+ UrlPage page;
+ readFilename(*chunkStream, page.imageName);
+ if (page.imageName.empty()) {
+ // Skip the remainder of the (empty) record: 215 - 33 bytes.
+ chunkStream->skip(kUrlRecordSize - 33);
+ continue;
+ }
+
+ uint16 hotspotCount = chunkStream->readUint16LE();
+ for (uint i = 0; i < kMaxHotspotsPerPage; ++i) {
+ Hotspot h;
+ h.id = chunkStream->readUint16LE();
+ readRect(*chunkStream, h.rect);
+ if (i < hotspotCount) {
+ page.hotspots.push_back(h);
+ }
+ }
+
+ pages.push_back(page);
+ }
}
UICL::UICL(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index e6124a002b9..9ee4cc434f9 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -507,11 +507,26 @@ struct TASK : public EngineData {
Common::Path imageName;
};
-// New web browser UI. Introduced in Nancy 10
+// Web browser popup UI (used from the cell phone to view in-game "web
+// pages"). Introduced in Nancy 10
struct UIBW : public EngineData {
+ struct Hotspot {
+ uint16 id = 0;
+ Common::Rect rect;
+ };
+
+ struct UrlPage {
+ Common::Path imageName;
+ Common::Array<Hotspot> hotspots;
+ };
+
UIBW(Common::SeekableReadStream *chunkStream);
+ static const uint kUrlRecordSize = 215;
+ static const uint kMaxHotspotsPerPage = 10;
+
Common::Path imageName;
+ Common::Array<UrlPage> pages;
};
// New cell phone popup UI. Introduced in Nancy 10
Commit: 4f1f0822c601c00e960fd6e335db2dd8bb7d7039
https://github.com/scummvm/scummvm/commit/4f1f0822c601c00e960fd6e335db2dd8bb7d7039
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:44+03:00
Commit Message:
NANCY: Introduce common types for Nancy10+ UI elements
Changed paths:
engines/nancy/commontypes.h
engines/nancy/util.cpp
engines/nancy/util.h
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index c118303ad74..a8863e0531e 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -25,6 +25,7 @@
#include "common/rect.h"
#include "common/array.h"
#include "common/language.h"
+#include "common/path.h"
#include "common/str.h"
#include "math/vector3d.h"
@@ -348,6 +349,62 @@ struct StaticData {
void readData(Common::SeekableReadStream &stream, Common::Language language, uint32 endPos, int8 majorVersion, int8 minorVersion);
};
+// Reusable button widget embedded in Nancy 10+ popup UIs.
+struct UIButtonRecord {
+ static const uint kRecordSize = 239;
+ Common::Path primaryImageName;
+ Common::Path secondaryImageName;
+ uint32 id = 0;
+ Common::Rect sourceRects[4];
+ Common::Rect srcBackgroundRestore;
+ Common::Rect destRect;
+ uint32 destUsesGameFrameOffset = 0; // translate dest by game-frame origin when non-zero
+ uint32 hoverEnableFlag = 0;
+ uint32 hoverCursorFlag = 0; // swap cursor sprite on hover when set
+ uint32 secondaryStateField = 0;
+ uint32 initialState = 0; // 0=idle, 1=hover, 2=pressed, 3/4=disabled
+ uint32 reservedField = 0;
+ SoundDescription clickSound;
+};
+
+// Reusable slider widget embedded in Nancy 10+ popup UIs.
+struct UISliderRecord {
+ static const uint kRecordSize = 198;
+ Common::Path primaryImageName;
+ Common::Path secondaryImageName;
+ uint32 id = 0;
+ Common::Rect sourceRects[4];
+ Common::Rect srcBackgroundRestore;
+ Common::Rect destRect;
+ uint32 destUsesGameFrameOffset = 0; // translate dest by game-frame origin when non-zero
+ uint32 unknownA = 0;
+ uint32 isDraggable = 0; // when zero, the slider stays at its current value on click
+ uint32 unknownC = 0;
+ uint32 orientation = 0; // 0 = horizontal, 1 = vertical
+ uint32 positionHint = 0; // 0/1 left/right for horiz, 2/3 top/bottom for vert
+ uint32 secondaryStateField = 0;
+ uint32 initialState = 0; // 0=idle, 1=hover, 2=dragging
+};
+
+// Common header shared by all Nancy 10 popup-UI chunks
+// (UIIV, UICO, UICL, UINB).
+struct UIPopupHeader {
+ Common::Path imageName; // background image
+ uint32 unknownHeaderField = 0; // chunk version
+ int16 linkbackScene = 9999; // return scene; 9999 = none
+ Common::Rect normalSrcRect; // SRC rect on the popup overlay image when in state 2 (normal size)
+ Common::Rect maximizedSrcRect; // SRC rect on the popup overlay image when in state 3 (maximized size)
+ Common::Rect normalDestRect; // DEST rect on screen for state 2 (normal size)
+ Common::Rect maximizedDestRect; // DEST rect on screen for state 3 (maximized size)
+ uint32 overlayInGameFrame = 0; // if non-zero, both dest rects are translated during initialization
+ SoundDescription sounds[4]; // open/close/button-click sound slots
+
+ uint32 secondaryButtonEnabled = 0;
+ UIButtonRecord secondaryButton;
+ uint32 sliderEnabled = 0;
+ UISliderRecord slider;
+};
+
} // End of namespace Nancy
#endif // NANCY_COMMONYPES_H
diff --git a/engines/nancy/util.cpp b/engines/nancy/util.cpp
index 78d22d2b8ef..7f7906aa27d 100644
--- a/engines/nancy/util.cpp
+++ b/engines/nancy/util.cpp
@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "engines/nancy/enginedata.h"
#include "engines/nancy/nancy.h"
#include "engines/nancy/util.h"
#include "common/system.h"
@@ -247,6 +248,73 @@ void readFilenameArray(Common::Serializer &stream, Common::Array<Common::Path> &
}
}
+void readUIButton(Common::SeekableReadStream &stream, UIButtonRecord &dst) {
+ // Read common fields for both buttons and sliders
+ readFilename(stream, dst.primaryImageName);
+ readFilename(stream, dst.secondaryImageName);
+ dst.id = stream.readUint32LE();
+ for (int i = 0; i < 4; ++i) {
+ readRect(stream, dst.sourceRects[i]);
+ }
+ readRect(stream, dst.srcBackgroundRestore);
+ readRect(stream, dst.destRect);
+ dst.destUsesGameFrameOffset = stream.readUint32LE();
+
+ dst.hoverEnableFlag = stream.readUint32LE();
+ dst.hoverCursorFlag = stream.readUint32LE();
+ dst.secondaryStateField = stream.readUint32LE();
+ dst.initialState = stream.readUint32LE();
+ dst.reservedField = stream.readUint32LE();
+
+ dst.clickSound.readNormal(stream);
+}
+
+void readUISlider(Common::SeekableReadStream &stream, UISliderRecord &dst) {
+ // Read common fields for both buttons and sliders
+ readFilename(stream, dst.primaryImageName);
+ readFilename(stream, dst.secondaryImageName);
+ dst.id = stream.readUint32LE();
+ for (int i = 0; i < 4; ++i) {
+ readRect(stream, dst.sourceRects[i]);
+ }
+ readRect(stream, dst.srcBackgroundRestore);
+ readRect(stream, dst.destRect);
+ dst.destUsesGameFrameOffset = stream.readUint32LE();
+
+ dst.unknownA = stream.readUint32LE();
+ dst.isDraggable = stream.readUint32LE();
+ dst.unknownC = stream.readUint32LE();
+ dst.orientation = stream.readUint32LE();
+ dst.positionHint = stream.readUint32LE();
+ dst.secondaryStateField = stream.readUint32LE();
+ dst.initialState = stream.readUint32LE();
+}
+
+// Reads the base header that precedes every Nancy 10 popup-UI
+// chunk (UIIV, UICO, UICL, UINB).
+void readUIPopupHeader(Common::SeekableReadStream &stream, UIPopupHeader &dst) {
+ readFilename(stream, dst.imageName);
+ dst.unknownHeaderField = stream.readUint32LE();
+ dst.linkbackScene = stream.readSint16LE();
+ readRect(stream, dst.normalSrcRect);
+ readRect(stream, dst.maximizedSrcRect);
+ readRect(stream, dst.normalDestRect);
+ readRect(stream, dst.maximizedDestRect);
+ dst.overlayInGameFrame = stream.readUint32LE();
+
+ stream.skip(4);
+
+ for (int i = 0; i < 4; ++i) {
+ dst.sounds[i].readNormal(stream);
+ }
+
+ dst.secondaryButtonEnabled = stream.readUint32LE();
+ readUIButton(stream, dst.secondaryButton);
+
+ dst.sliderEnabled = stream.readUint32LE();
+ readUISlider(stream, dst.slider);
+}
+
// A text line will often be broken up into chunks separated by nulls, use
// this function to put it back together as a Common::String
void assembleTextLine(char *rawCaption, Common::String &output, uint size) {
diff --git a/engines/nancy/util.h b/engines/nancy/util.h
index ef1e97b32d1..a4efef64348 100644
--- a/engines/nancy/util.h
+++ b/engines/nancy/util.h
@@ -26,8 +26,14 @@
#include "common/rect.h"
#include "common/serializer.h"
+#include "engines/nancy/commontypes.h"
+
namespace Nancy {
+void readUIButton(Common::SeekableReadStream &stream, UIButtonRecord &dst);
+void readUISlider(Common::SeekableReadStream &stream, UISliderRecord &dst);
+void readUIPopupHeader(Common::SeekableReadStream &stream, UIPopupHeader &dst);
+
void readRect(Common::SeekableReadStream &stream, Common::Rect &inRect);
void readRect(Common::Serializer &stream, Common::Rect &inRect, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
void readRectArray(Common::SeekableReadStream &stream, Common::Array<Common::Rect> &inArray, uint num, uint totalNum = 0);
Commit: eaa16ce9974cdf3084dd563a753c572b13cf71c3
https://github.com/scummvm/scummvm/commit/eaa16ce9974cdf3084dd563a753c572b13cf71c3
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:45+03:00
Commit Message:
NANCY: Add handling for the Nancy10+ UICO (conversation popup) chunk
Changed paths:
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 0ba65b5434f..e78fce075a9 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -910,8 +910,8 @@ UICL::UICL(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
}
UICO::UICO(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
- readFilename(*chunkStream, imageName);
- // TODO
+ readUIPopupHeader(*chunkStream, header);
+ readRect(*chunkStream, textRect);
}
UIIV::UIIV(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index 9ee4cc434f9..252895cfb3e 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -23,6 +23,7 @@
#define NANCY_ENGINEDATA_H
#include "engines/nancy/commontypes.h"
+#include "engines/nancy/util.h"
#include "common/hash-str.h"
#include "common/path.h"
@@ -536,11 +537,16 @@ struct UICL : public EngineData {
Common::Path imageName;
};
-// New conversation popup UI. Introduced in Nancy 10
+// New conversation popup UI (the text strip that appears above the taskbar
+// when a character is speaking). Introduced in Nancy 10.
+// Note: response hotspots are NOT in this chunk â they live in a separate
+// TextBoxSummaryChunk, each carrying a response-sound filename referenced
+// by ProcessConversation when STOP_VIDEO transitions to PLAYER_RESPONSE_SOUND.
struct UICO : public EngineData {
UICO(Common::SeekableReadStream *chunkStream);
- Common::Path imageName;
+ UIPopupHeader header;
+ Common::Rect textRect; // Text-drawing rect inside the popup overlay
};
// New inventory UI. Introduced in Nancy 10
Commit: db4a693481da9d704580a1196eb86aafcaea1c64
https://github.com/scummvm/scummvm/commit/db4a693481da9d704580a1196eb86aafcaea1c64
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:46+03:00
Commit Message:
NANCY: Add handling for the Nancy10+ TASK chunk (main UI)
Changed paths:
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
engines/nancy/nancy.cpp
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index e78fce075a9..e3fc9a24541 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -870,9 +870,23 @@ SHUI::SHUI(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
}
TASK::TASK(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
- chunkStream->skip(97);
readFilename(*chunkStream, imageName);
- // TODO
+
+ readRect(*chunkStream, srcRect);
+ readRect(*chunkStream, dstRect);
+ readRect(*chunkStream, unkRect1);
+ readRect(*chunkStream, unkRect2);
+
+ char nameBuf[34];
+ for (uint i = 0; i < kNumButtons; ++i) {
+ readUIButton(*chunkStream, buttons[i].button);
+ chunkStream->read(buttons[i].unknownPad, sizeof(buttons[i].unknownPad));
+ for (uint s = 0; s < kNumAltSounds; ++s) {
+ chunkStream->read(nameBuf, 33);
+ nameBuf[33] = '\0';
+ buttons[i].clickSoundName[s] = nameBuf;
+ }
+ }
}
UIBW::UIBW(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index 252895cfb3e..f898e18f3d1 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -501,11 +501,37 @@ struct SCTB : public EngineData {
Common::Path imageName;
};
-// New task list UI. Introduced in Nancy 10
+enum TaskButton {
+ kTaskButtonMenu = 0,
+ kTaskButtonInventory = 1,
+ kTaskButtonNotebook = 2,
+ kTaskButtonCellphone = 3,
+ kTaskButtonHelp = 4
+};
+
+// Taskbar (the always-on strip at the bottom of the screen with MENU /
+// inventory / notebook / cellphone / HELP buttons). Introduced in Nancy 10.
struct TASK : public EngineData {
+ struct ButtonRecord {
+ UIButtonRecord button;
+ byte unknownPad[16];
+ Common::String clickSoundName[3];
+ };
+
TASK(Common::SeekableReadStream *chunkStream);
+ static const uint kNumButtons = 5;
+ static const uint kButtonRecordSize = 354;
+ static const uint kNumAltSounds = 3;
+
Common::Path imageName;
+
+ Common::Rect srcRect;
+ Common::Rect dstRect;
+ Common::Rect unkRect1;
+ Common::Rect unkRect2;
+
+ ButtonRecord buttons[kNumButtons];
};
// Web browser popup UI (used from the cell phone to view in-game "web
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 4a31155579c..16b4bf88b01 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -482,7 +482,7 @@ void NancyEngine::bootGameEngine() {
// FONT chunk has been moved into a separate file
// FR0 chunk has been removed
LOAD_BOOT(SHUI) // Shared UI elements
- LOAD_BOOT(TASK) // Task list UI
+ LOAD_BOOT(TASK) // Task bar (main UI)
LOAD_BOOT(UIIV) // Inventory UI
LOAD_BOOT(UICO) // Conversation UI
LOAD_BOOT(UICL) // Cell phone UI
Commit: 4922da80925634d893bd4c6ea6d2b2d7f62fd689
https://github.com/scummvm/scummvm/commit/4922da80925634d893bd4c6ea6d2b2d7f62fd689
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:47+03:00
Commit Message:
NANCY: Add handling for the common UI button slot type
Used for the notebook tab strip (UINB) and the inventory
category-filter strip (UIIV)
Changed paths:
engines/nancy/commontypes.h
engines/nancy/util.cpp
engines/nancy/util.h
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index a8863e0531e..8d1cf27be6f 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -367,6 +367,15 @@ struct UIButtonRecord {
SoundDescription clickSound;
};
+// A UIButton slot. Used for the notebook tab strip (UINB) and the
+// inventory category-filter strip (UIIV).
+struct UIButtonSlot {
+ static const uint kRecordSize = 247;
+ uint32 enabled = 0;
+ uint32 id = 0; // slot identifier (filter category / tab)
+ UIButtonRecord button;
+};
+
// Reusable slider widget embedded in Nancy 10+ popup UIs.
struct UISliderRecord {
static const uint kRecordSize = 198;
diff --git a/engines/nancy/util.cpp b/engines/nancy/util.cpp
index 7f7906aa27d..971d90a6df4 100644
--- a/engines/nancy/util.cpp
+++ b/engines/nancy/util.cpp
@@ -269,6 +269,12 @@ void readUIButton(Common::SeekableReadStream &stream, UIButtonRecord &dst) {
dst.clickSound.readNormal(stream);
}
+void readUIButtonSlot(Common::SeekableReadStream &stream, UIButtonSlot &dst) {
+ dst.enabled = stream.readUint32LE();
+ dst.id = stream.readUint32LE();
+ readUIButton(stream, dst.button);
+}
+
void readUISlider(Common::SeekableReadStream &stream, UISliderRecord &dst) {
// Read common fields for both buttons and sliders
readFilename(stream, dst.primaryImageName);
diff --git a/engines/nancy/util.h b/engines/nancy/util.h
index a4efef64348..3dc6ab1eaf5 100644
--- a/engines/nancy/util.h
+++ b/engines/nancy/util.h
@@ -30,10 +30,6 @@
namespace Nancy {
-void readUIButton(Common::SeekableReadStream &stream, UIButtonRecord &dst);
-void readUISlider(Common::SeekableReadStream &stream, UISliderRecord &dst);
-void readUIPopupHeader(Common::SeekableReadStream &stream, UIPopupHeader &dst);
-
void readRect(Common::SeekableReadStream &stream, Common::Rect &inRect);
void readRect(Common::Serializer &stream, Common::Rect &inRect, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
void readRectArray(Common::SeekableReadStream &stream, Common::Array<Common::Rect> &inArray, uint num, uint totalNum = 0);
@@ -63,6 +59,11 @@ void readFilenameArray(Common::Serializer &stream, Common::Array<Common::Path> &
void assembleTextLine(char *rawCaption, Common::String &output, uint size);
+void readUIButton(Common::SeekableReadStream &stream, UIButtonRecord &dst);
+void readUISlider(Common::SeekableReadStream &stream, UISliderRecord &dst);
+void readUIPopupHeader(Common::SeekableReadStream &stream, UIPopupHeader &dst);
+void readUIButtonSlot(Common::SeekableReadStream &stream, UIButtonSlot &dst);
+
// Abstract base class used for loading data that would take too much time in a single frame
class DeferredLoader {
public:
Commit: 133ef5787a7affc090c7eccf3169f1f30e35d585
https://github.com/scummvm/scummvm/commit/133ef5787a7affc090c7eccf3169f1f30e35d585
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:48+03:00
Commit Message:
NANCY: Handle the Nancy10+ UIIV (inventory) and UINB (notebook) chunks
Changed paths:
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index e3fc9a24541..62ac6854540 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -929,13 +929,48 @@ UICO::UICO(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
}
UIIV::UIIV(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
- readFilename(*chunkStream, imageName);
- // TODO
+ readUIPopupHeader(*chunkStream, header);
+
+ readRectArray(*chunkStream, slotSrcRects, 16);
+ readRectArray(*chunkStream, slotDestRects, 16);
+
+ chunkStream->skip(2);
+
+ for (uint i = 0; i < kNumFilters; ++i) {
+ readUIButtonSlot(*chunkStream, filters[i]);
+ }
+
+ readRectArray(*chunkStream, tabCaptionSrcRects, kNumFilters);
+
+ readRect(*chunkStream, tabCaptionDestRect);
}
UINB::UINB(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
- readFilename(*chunkStream, imageName);
- // TODO
+ readUIPopupHeader(*chunkStream, header);
+
+ for (uint i = 0; i < kNumTabs; ++i) {
+ readUIButtonSlot(*chunkStream, tabs[i]);
+ }
+
+ readRect(*chunkStream, textRect);
+ primaryFontID = chunkStream->readUint16LE();
+ secondaryFontAttr = chunkStream->readUint16LE();
+ useFilenameTextFlag = chunkStream->readUint16LE();
+ readFilename(*chunkStream, conditionalTextFilename);
+
+ // 3 sound names played at random when an item is marked complete
+ // (glyph attr -> 8)
+ for (uint i = 0; i < kNumPageSoundsPerSet; ++i) {
+ readFilename(*chunkStream, actionableClickSounds[i]);
+ }
+
+ // 3 sound names for no-action clicks
+ for (uint i = 0; i < kNumPageSoundsPerSet; ++i) {
+ readFilename(*chunkStream, noActionClickSounds[i]);
+ }
+
+ readRectArray(*chunkStream, tabCaptionSrcRects, kNumTabs);
+ readRect(*chunkStream, tabCaptionDestRect);
}
} // End of namespace Nancy
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index f898e18f3d1..ace098cebf9 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -575,18 +575,39 @@ struct UICO : public EngineData {
Common::Rect textRect; // Text-drawing rect inside the popup overlay
};
-// New inventory UI. Introduced in Nancy 10
+// New inventory popup UI (4x4 item grid with paging slider and category
+// filter tabs along the right edge). Introduced in Nancy 10.
struct UIIV : public EngineData {
UIIV(Common::SeekableReadStream *chunkStream);
- Common::Path imageName;
+ static const uint kNumFilters = 6;
+
+ UIPopupHeader header;
+ Common::Array<Common::Rect> slotSrcRects; // 16 entries (image coords)
+ Common::Array<Common::Rect> slotDestRects; // 16 entries (screen coords)
+ UIButtonSlot filters[kNumFilters]; // 6 entries
+ Common::Array<Common::Rect> tabCaptionSrcRects; // 6 entries
+ Common::Rect tabCaptionDestRect; // on-screen target
};
-// New notebook UI. Introduced in Nancy 10
+// New notebook UI. Introduced in Nancy 10.
struct UINB : public EngineData {
UINB(Common::SeekableReadStream *chunkStream);
- Common::Path imageName;
+ static const uint kNumTabs = 2;
+ static const uint kNumPageSoundsPerSet = 3;
+
+ UIPopupHeader header;
+ UIButtonSlot tabs[kNumTabs];
+ Common::Rect textRect;
+ uint16 primaryFontID = 0;
+ uint16 secondaryFontAttr = 0;
+ uint16 useFilenameTextFlag = 0;
+ Common::Path conditionalTextFilename;
+ Common::Path actionableClickSounds[kNumPageSoundsPerSet];
+ Common::Path noActionClickSounds[kNumPageSoundsPerSet];
+ Common::Array<Common::Rect> tabCaptionSrcRects; // 2 entries
+ Common::Rect tabCaptionDestRect; // on-screen target
};
} // End of namespace Nancy
Commit: 1b94ca4b2f1db0c7f0d2a1c9e314ddcea54ab1d2
https://github.com/scummvm/scummvm/commit/1b94ca4b2f1db0c7f0d2a1c9e314ddcea54ab1d2
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-04-28T03:58:49+03:00
Commit Message:
NANCY: Add handling for the Nancy10+ UICL (cell phone) chunk
Changed paths:
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 62ac6854540..d7beb0a3a53 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -919,8 +919,126 @@ UIBW::UIBW(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
}
UICL::UICL(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
- readFilename(*chunkStream, imageName);
- // TODO
+ readUIPopupHeader(*chunkStream, header);
+
+ readFilename(*chunkStream, overlayImageName);
+
+ // Skip shared UIButton template - the sub-fields data is read
+ // separately for each button record below.
+ chunkStream->skip(206);
+
+ for (uint i = 0; i < kNumDialPadSlots; ++i) {
+ readRect(*chunkStream, dialPadSlots[i].srcRect);
+ readRect(*chunkStream, dialPadSlots[i].destRect);
+ char nameBuf[34];
+ chunkStream->read(nameBuf, 33);
+ nameBuf[33] = '\0';
+ dialPadSlots[i].soundName = nameBuf;
+ }
+
+ // Screen-frame and label rects
+ readRect(*chunkStream, dialHilite.srcRect);
+ readRect(*chunkStream, dialHilite.destRect);
+ readRect(*chunkStream, screenOutSrcRect);
+ statusTextX = chunkStream->readSint32LE();
+ statusTextY = chunkStream->readSint32LE();
+ readRect(*chunkStream, welcomeScreen.srcRect);
+ readRect(*chunkStream, welcomeScreen.destRect);
+
+ char labelBuf[21];
+ for (uint i = 0; i < kNumStatusLabels; ++i) {
+ chunkStream->read(labelBuf, 20);
+ labelBuf[20] = '\0';
+ statusLabels[i] = labelBuf;
+ }
+
+ readRect(*chunkStream, dialLabel.srcRect);
+ readRect(*chunkStream, dialLabel.destRect);
+ readRect(*chunkStream, webLabel.srcRect);
+ readRect(*chunkStream, webLabel.destRect);
+ readRect(*chunkStream, dirLabel.srcRect);
+ readRect(*chunkStream, dirLabel.destRect);
+
+ // Call/hang-up widget (3 rects).
+ readRect(*chunkStream, callButton.srcRectIdle);
+ readRect(*chunkStream, callButton.srcRectPressed);
+ readRect(*chunkStream, callButton.destRect);
+
+ // Screen-content sprite block
+ readFilename(*chunkStream, phoneUseSound);
+ readRect(*chunkStream, signalSpriteSrc);
+ readRect(*chunkStream, signalSpriteSrcAlt);
+ readRect(*chunkStream, signalSpriteDest);
+ readRect(*chunkStream, batterySpriteSrc);
+ readRect(*chunkStream, batterySpriteSrcAlt);
+ readRect(*chunkStream, batterySpriteDest);
+ readRect(*chunkStream, typeMessage.srcRect);
+ readRect(*chunkStream, typeMessage.destRect);
+ readRect(*chunkStream, connectedLabel.srcRect);
+ readRect(*chunkStream, connectedLabel.destRect);
+ readRect(*chunkStream, connectingSpriteSrc);
+ readRect(*chunkStream, connectingSpriteSrcAlt);
+ readRect(*chunkStream, connectingSpriteDest);
+ readRect(*chunkStream, onlineHeading.srcRect);
+ readRect(*chunkStream, onlineHeading.destRect);
+ readRect(*chunkStream, fullEmptyScreenSrc);
+ readRect(*chunkStream, emailListContainer);
+ readRect(*chunkStream, dirArrowSrc);
+ readRect(*chunkStream, dirCursorSrc);
+ readRect(*chunkStream, dirHeading.srcRect);
+ readRect(*chunkStream, dirHeading.destRect);
+
+ for (uint i = 0; i < kNumSubButtons; ++i) {
+ readRect(*chunkStream, subButtons[i].srcRectIdle);
+ readRect(*chunkStream, subButtons[i].srcRectPressed);
+ readRect(*chunkStream, subButtons[i].destRect);
+ }
+
+ // Heading/icon rect pairs
+ readRect(*chunkStream, searchHeading.srcRect);
+ readRect(*chunkStream, searchHeading.destRect);
+ readRect(*chunkStream, emailIconUnread);
+ readRect(*chunkStream, emailIconSelected);
+ readRect(*chunkStream, emailHeading.srcRect);
+ readRect(*chunkStream, emailHeading.destRect);
+ readRect(*chunkStream, helpHeading.srcRect);
+ readRect(*chunkStream, helpHeading.destRect);
+ readRect(*chunkStream, browserHeading.srcRect);
+ readRect(*chunkStream, browserHeading.destRect);
+
+ readFilename(*chunkStream, holdMusicSound);
+ readFilename(*chunkStream, answeringMachineSound);
+ holdLink1 = chunkStream->readSint16LE();
+ holdLink2 = chunkStream->readSint16LE();
+ readFilename(*chunkStream, urlSound);
+ urlLink1 = chunkStream->readSint16LE();
+ urlLink2 = chunkStream->readSint16LE();
+ urlLink3 = chunkStream->readSint16LE();
+
+ fontId1 = chunkStream->readUint16LE();
+ fontId2 = chunkStream->readUint16LE();
+
+ readFilename(*chunkStream, outgoingRingSound);
+ readFilename(*chunkStream, pickupSound);
+ readFilename(*chunkStream, invalidNumberSound);
+
+ contactCount = chunkStream->readUint16LE();
+
+ const int64 maxEntries = (chunkStream->size() - chunkStream->pos()) / 41;
+ const uint16 entries = MIN<uint16>(contactCount, (uint16)maxEntries);
+ contacts.resize(entries);
+ for (uint i = 0; i < entries; ++i) {
+ Contact &c = contacts[i];
+
+ chunkStream->read(c.unknownPrefix, sizeof(c.unknownPrefix));
+
+ char nameBuf[21];
+ chunkStream->read(nameBuf, 20);
+ nameBuf[20] = '\0';
+ c.name = nameBuf;
+
+ chunkStream->read(c.unknownSuffix, sizeof(c.unknownSuffix));
+ }
}
UICO::UICO(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index ace098cebf9..e42db07bcdf 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -556,11 +556,102 @@ struct UIBW : public EngineData {
Common::Array<UrlPage> pages;
};
-// New cell phone popup UI. Introduced in Nancy 10
+// Cell-phone popup UI. Introduced in Nancy 10.
struct UICL : public EngineData {
+ struct DialPadSlot {
+ Common::Rect srcRect;
+ Common::Rect destRect;
+ Common::String soundName;
+ };
+
+ struct ThreeRectWidget {
+ Common::Rect srcRectIdle;
+ Common::Rect srcRectPressed;
+ Common::Rect destRect;
+ };
+
+ struct Contact {
+ byte unknownPrefix[13]; // 13 bytes preceding the name (purpose not yet determined)
+ Common::String name; // 20-byte null-terminated contact name
+ byte unknownSuffix[8]; // 8 bytes following the name (purpose not yet determined)
+ };
+
+ struct SrcDestRectPair {
+ Common::Rect srcRect;
+ Common::Rect destRect;
+ };
+
+ static const uint kNumDialPadSlots = 15;
+ static const uint kNumSubButtons = 10;
+ static const uint kNumStatusLabels = 3; // No Signal / No Access / Old Email Only
+
UICL(Common::SeekableReadStream *chunkStream);
- Common::Path imageName;
+ UIPopupHeader header;
+ Common::Path overlayImageName;
+ DialPadSlot dialPadSlots[kNumDialPadSlots];
+
+ // Screen-frame and label rects
+ SrcDestRectPair dialHilite;
+ Common::Rect screenOutSrcRect;
+ int32 statusTextX = 0; // text X-baseline
+ int32 statusTextY = 0; // text Y-baseline
+ SrcDestRectPair welcomeScreen;
+ Common::String statusLabels[kNumStatusLabels]; // "No Signal", "No Access", "Old Email Only"
+ SrcDestRectPair dialLabel;
+ SrcDestRectPair webLabel;
+ SrcDestRectPair dirLabel;
+
+ ThreeRectWidget callButton;
+
+ // Screen-content sprite block
+ Common::Path phoneUseSound;
+ Common::Rect signalSpriteSrc;
+ Common::Rect signalSpriteSrcAlt;
+ Common::Rect signalSpriteDest;
+ Common::Rect batterySpriteSrc;
+ Common::Rect batterySpriteSrcAlt;
+ Common::Rect batterySpriteDest;
+ SrcDestRectPair typeMessage;
+ SrcDestRectPair connectedLabel;
+ Common::Rect connectingSpriteSrc;
+ Common::Rect connectingSpriteSrcAlt; // state-8 variant
+ Common::Rect connectingSpriteDest;
+ SrcDestRectPair onlineHeading;
+ Common::Rect fullEmptyScreenSrc;
+ Common::Rect emailListContainer; // scrollbar/list container
+ Common::Rect dirArrowSrc;
+ Common::Rect dirCursorSrc;
+ SrcDestRectPair dirHeading;
+
+ ThreeRectWidget subButtons[kNumSubButtons];
+
+ // Heading/icon SRC+DEST pairs
+ SrcDestRectPair searchHeading;
+ Common::Rect emailIconUnread;
+ Common::Rect emailIconSelected;
+ SrcDestRectPair emailHeading;
+ SrcDestRectPair helpHeading;
+ SrcDestRectPair browserHeading;
+
+ Common::Path holdMusicSound;
+ Common::Path answeringMachineSound; // chunk+0xCE4 (33B): "SHAMA02"
+ int16 holdLink1 = 0;
+ int16 holdLink2 = 0;
+ Common::Path urlSound;
+ int16 urlLink1 = 0;
+ int16 urlLink2 = 0;
+ int16 urlLink3 = 0;
+
+ uint16 fontId1 = 0;
+ uint16 fontId2 = 0;
+
+ Common::Path outgoingRingSound; // Process case 2 (post-dial ring)
+ Common::Path pickupSound; // Process cases 0/4 (call connect)
+ Common::Path invalidNumberSound; // Process case 7 (try again)
+
+ uint16 contactCount = 0;
+ Common::Array<Contact> contacts;
};
// New conversation popup UI (the text strip that appears above the taskbar
More information about the Scummvm-git-logs
mailing list