[Scummvm-git-logs] scummvm master -> 3846488013b009a766dd6bed79b315f0fcd1ff4e

bluegr noreply at scummvm.org
Thu Jun 25 00:57:28 UTC 2026


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

Summary:
e7fce21378 NANCY: Map the AR records of Nancy12
16b1f97f58 NANCY: Implement processors for the Nancy12 EVNT and UIRC boot chunks
2594f9354b NANCY: Handle new signature of conversation XSheets in Nancy12
82d788a786 NANCY: Handle new signature of AVF videos for Nancy12
4904efac42 NANCY: More work on the Nancy12 AR types
3846488013 NANCY: Initial handling of event flag names in Nancy12


Commit: e7fce213784639ef87f915a664ab00487ca52e31
    https://github.com/scummvm/scummvm/commit/e7fce213784639ef87f915a664ab00487ca52e31
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-25T03:57:11+03:00

Commit Message:
NANCY: Map the AR records of Nancy12

This allows us to start a new game in Nancy12

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


diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index efa0523850b..347e10d6aef 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -285,6 +285,16 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 		return new ValueTest();
 	case 81:	// Nancy11
 		return new TextBoxWrite(true);
+	case 94:
+		// Nancy12: moved from 106
+		if (g_nancy->getGameType() >= kGameTypeNancy12)
+			return new EventFlagsMultiHS(false);
+		return nullptr;
+	case 95:
+		// Nancy12: moved from 107
+		if (g_nancy->getGameType() >= kGameTypeNancy12)
+			return new EventFlags();
+		return nullptr;
 	case 96:	// Nancy11
 		return new RandomizeEventFlags();
 	case 97:
@@ -366,17 +376,33 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 	case 131:
 		// Nancy 10+
 		return new AddSearchLink();
+	case 132:
+		// TODO: Nancy 12 - new action record (256-byte data block with an embedded string).
+		// Not yet identified or implemented.
+		return nullptr;
 	case 140:
-		return new SetVolume();
+		if (g_nancy->getGameType() >= kGameTypeNancy12)
+			return new SetPlayerClock();	// Moved from 170 in Nancy12
+		else
+			return new SetVolume();			// Legacy SetVolume slot (used up to Nancy8)
+	case 141:
+		// MakeScreenFile, moved here from 148 in Nancy12.
+		// Saves a cropped image of the screen to a bitmap/TGA file.
+		// TODO: debug-only feature, not implemented
+		return nullptr;
 	case 147:	// Nancy11
 		return new FadeSoundToSilence();
 	case 148:
+		if (g_nancy->getGameType() >= kGameTypeNancy12)
+			return new SetVolume();	// Moved from 149 in Nancy12
 		// MakeScreenFile - seems to save a cropped image of the screen in a bitmap file?
-		// TODO: Used in Nancy 9, sand castle puzzle
+		// TODO: Used in Nancy 9, sand castle puzzle. Moved to 141 in Nancy12.
 		return nullptr;
 	case 149:
-		if (g_nancy->getGameType() >= kGameTypeNancy9)
-			return new SetVolume();	// Moved from 140 in Nancy9
+		if (g_nancy->getGameType() >= kGameTypeNancy12)
+			return new PlaySoundEventFlagTerse();	// Moved from 161 in Nancy12
+		else if (g_nancy->getGameType() >= kGameTypeNancy9)
+			return new SetVolume();	// Moved from 140 in Nancy9, then to 148 in Nancy12
 		else
 			return nullptr;
 	case 150:
@@ -404,10 +430,42 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 	case 159:
 		return new PlaySoundTerse();
 	case 160:
+		// In Nancy12 the hint system was removed (the HINT boot chunk is gone) and this
+		// slot was reused for a new driving/racing puzzle.
+		// TODO: Nancy12 DrivingPuzzle (new), not implemented
+		if (g_nancy->getGameType() >= kGameTypeNancy12)
+			return nullptr;
 		return new HintSystem();
 	case 161:
+		// PlaySoundEventFlagTerse moved to 149 in Nancy12; this slot was reused for a new puzzle.
+		// TODO: Nancy12 MinigolfPuzzle (new), not implemented
+		if (g_nancy->getGameType() >= kGameTypeNancy12)
+			return nullptr;
 		return new PlaySoundEventFlagTerse();
+	// -- Nancy 12 new puzzles/action records --
+	case 162:
+		// TODO: Nancy12 - new puzzle (reuses the AT_DRIVING_PUZZLE debug string), not implemented
+		return nullptr;
+	case 163:
+		// TODO: Nancy12 MirrorLightPuzzle (new), not implemented
+		return nullptr;
+	case 164:
+		// TODO: Nancy12 BoardGamePuzzle (new), not implemented
+		return nullptr;
+	case 165:
+		// TODO: Nancy12 MindPuzzle (new), not implemented
+		return nullptr;
+	case 166:
+		// TODO: Nancy12 - new puzzle (unidentified, ~21KB data block), not implemented
+		return nullptr;
+	case 167:
+		// TODO: Nancy12 ChasePuzzle (new), not implemented
+		return nullptr;
+	case 168:
+		// TODO: Nancy12 - new 3D-sound positioning action record, not implemented
+		return nullptr;
 	case 170:
+		// Moved to 140 in Nancy12
 		return new SetPlayerClock();
 	case 200:
 		return new SoundEqualizerPuzzle();


Commit: 16b1f97f58972a12436d17cf6eec1ac986a3de7b
    https://github.com/scummvm/scummvm/commit/16b1f97f58972a12436d17cf6eec1ac986a3de7b
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-25T03:57:12+03:00

Commit Message:
NANCY: Implement processors for the Nancy12 EVNT and UIRC boot chunks

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 3cd219eb518..89e3e4a7822 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -1114,4 +1114,30 @@ UINB::UINB(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
 	readRect(*chunkStream, tabCaptionDestRect);
 }
 
+EVNT::EVNT(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
+	while (chunkStream->size() - chunkStream->pos() >= (int64)kEventRecordSize) {
+		EventRecord rec;
+		readFilename(*chunkStream, rec.name);
+		rec.id = chunkStream->readSint16LE();
+		events.push_back(rec);
+	}
+}
+
+UIRC::UIRC(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
+	while (chunkStream->size() - chunkStream->pos() >= (int64)kItemRecordSize) {
+		ItemRecord rec;
+		rec.id = chunkStream->readUint16LE();
+		readFilename(*chunkStream, rec.overlayName);
+		readRect(*chunkStream, rec.rect);
+		rec.unknown1 = chunkStream->readSint16LE();
+		rec.unknown2 = chunkStream->readSint16LE();
+		rec.soundChannel = chunkStream->readSint16LE();
+		rec.soundVolume = chunkStream->readSint16LE();
+		for (uint i = 0; i < kNumSounds; ++i) {
+			readFilename(*chunkStream, rec.soundNames[i]);
+		}
+		items.push_back(rec);
+	}
+}
+
 } // End of namespace Nancy
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index bf430b4a2e4..ad8656777f9 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -733,6 +733,46 @@ struct UINB : public EngineData {
 	Common::Array<Common::Rect> tabCaptionSrcRects;             // 2 entries
 	Common::Rect tabCaptionDestRect;                            // on-screen target
 };
+
+// Named-event table. Introduced in Nancy 12. Empty in Secret of the Old Clock
+// (the engine registers several built-in event categories at runtime on top of
+// whatever this chunk provides). Each record is a name followed by an id.
+struct EVNT : public EngineData {
+	struct EventRecord {
+		Common::String name;
+		int16 id = 0;
+	};
+
+	EVNT(Common::SeekableReadStream *chunkStream);
+
+	static const uint kEventRecordSize = 35;
+
+	Common::Array<EventRecord> events;
+};
+
+// UI overlay element table. Introduced in Nancy 12. Each record describes one UI
+// element: the shared overlay image it belongs to, its on-screen rect and up to
+// six associated sound cues. Unused slots use the name "NO_UI_ITEM", and slots
+// without a given sound use "NO SOUND".
+struct UIRC : public EngineData {
+	struct ItemRecord {
+		uint16 id = 0;
+		Common::Path overlayName;
+		Common::Rect rect;
+		int16 unknown1 = 0;
+		int16 unknown2 = 0;
+		int16 soundChannel = 0;
+		int16 soundVolume = 0;
+		Common::String soundNames[6];
+	};
+
+	UIRC(Common::SeekableReadStream *chunkStream);
+
+	static const uint kNumSounds = 6;
+	static const uint kItemRecordSize = 257;
+
+	Common::Array<ItemRecord> items;
+};
 } // End of namespace Nancy
 
 #endif // NANCY_ENGINEDATA_H
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index ff4da9ff9bb..6cb1ff0f96c 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -495,9 +495,9 @@ void NancyEngine::bootGameEngine() {
 	LOAD_BOOT(SCTB)	// Scrollable text box UI
 
 	// Nancy 12+
-	// HINT chunk has been removed
-	// LOAD_BOOT(EVNT)
-	// LOAD_BOOT(UIRC)
+	// HINT chunk has been removed (the hint system and its action record were dropped in Nancy12)
+	LOAD_BOOT(EVNT)	// Named-event table (empty in Nancy 12)
+	LOAD_BOOT(UIRC)	// UI overlay element table
 
 	// Nancy 13+
 	// RCPR and RCLB chunks have been removed


Commit: 2594f9354b0e069e0274e92c572c672c6b768e08
    https://github.com/scummvm/scummvm/commit/2594f9354b0e069e0274e92c572c672c6b768e08
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-25T03:57:12+03:00

Commit Message:
NANCY: Handle new signature of conversation XSheets in Nancy12

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


diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index 1fc655a56e8..f4370ebc9c5 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -853,8 +853,9 @@ void ConversationCel::readXSheet(Common::SeekableReadStream &stream, const Commo
 	// Read the xsheet and load all images into the arrays
 	// Completely unoptimized, the original engine uses a buffer
 	xsheet->seek(0);
-	Common::String signature = xsheet->readString('\0', 18);
-	if (signature != "XSHEET WayneSikes") {
+	const uint16 sigLength = g_nancy->getGameType() <= kGameTypeNancy11 ? 18 : 22;
+	Common::String signature = xsheet->readString('\0', sigLength);
+	if (signature != "XSHEET WayneSikes" && signature != "XSHEET HerInteractive") {
 		warning("XSHEET signature doesn't match!");
 		return;
 	}


Commit: 82d788a786c23540d65861cfb567396e83841047
    https://github.com/scummvm/scummvm/commit/82d788a786c23540d65861cfb567396e83841047
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-25T03:57:14+03:00

Commit Message:
NANCY: Handle new signature of AVF videos for Nancy12

Changed paths:
    engines/nancy/video.cpp


diff --git a/engines/nancy/video.cpp b/engines/nancy/video.cpp
index 5d4359c5b58..f9ae5b89383 100644
--- a/engines/nancy/video.cpp
+++ b/engines/nancy/video.cpp
@@ -78,15 +78,12 @@ AVFDecoder::~AVFDecoder() {
 bool AVFDecoder::loadStream(Common::SeekableReadStream *stream) {
 	close();
 
-	char id[15];
-	stream->read(id, 15);
-	id[14] = 0;
-	Common::String idString = id;
-
+	Common::String idString = stream->readString('\0', 16);
+	
 	bool earlyHeaderFormat = false;
 
-	if (idString == "AVF WayneSikes") {
-		stream->skip(1); // Unknown
+	if (idString == "AVF WayneSikes" || idString == "AVF HerInter") {
+		// Normal header format
 	} else if (idString.hasPrefix("ALG")) {
 		earlyHeaderFormat = true;
 		stream->seek(10, SEEK_SET);


Commit: 4904efac42fb70b2ea9fed899ceb6b6e26ebbfb2
    https://github.com/scummvm/scummvm/commit/4904efac42fb70b2ea9fed899ceb6b6e26ebbfb2
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-25T03:57:15+03:00

Commit Message:
NANCY: More work on the Nancy12 AR types

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


diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 347e10d6aef..25600ac762e 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -377,8 +377,9 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 		// Nancy 10+
 		return new AddSearchLink();
 	case 132:
-		// TODO: Nancy 12 - new action record (256-byte data block with an embedded string).
-		// Not yet identified or implemented.
+		// ResourceUse ("UIResource Adjust") - adjusts a UI overlay resource (see the UIRC
+		// boot chunk) at runtime. Added in Nancy12.
+		// TODO: not implemented
 		return nullptr;
 	case 140:
 		if (g_nancy->getGameType() >= kGameTypeNancy12)
@@ -456,8 +457,9 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 		// TODO: Nancy12 MindPuzzle (new), not implemented
 		return nullptr;
 	case 166:
-		// TODO: Nancy12 - new puzzle (unidentified, ~21KB data block), not implemented
-		return nullptr;
+		// OneBuildPuzzle, moved here from 234 in Nancy12.
+		// TODO: verify the Nancy12 data layout against OneBuildPuzzle::readData
+		return new OneBuildPuzzle();
 	case 167:
 		// TODO: Nancy12 ChasePuzzle (new), not implemented
 		return nullptr;
@@ -536,6 +538,7 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
 	case 233:
 		return new SoundMatchPuzzle();
 	case 234:
+		// Moved to 166 in Nancy12
 		return new OneBuildPuzzle();
 	case 235:
 		return new MultiBuildPuzzle();


Commit: 3846488013b009a766dd6bed79b315f0fcd1ff4e
    https://github.com/scummvm/scummvm/commit/3846488013b009a766dd6bed79b315f0fcd1ff4e
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-25T03:57:17+03:00

Commit Message:
NANCY: Initial handling of event flag names in Nancy12

- Event flag names have been moved from the executable to the EVNT
  chunk
- Added a getter for event flag names, which will handle these strings
  internally
- Event flags start from 2000 in Nancy12

This is still not finished, as generic event flags will need to be
separated from normal event flags in Nancy12+

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


diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 82b06b4f2ca..ad1170d92ec 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -504,41 +504,41 @@ void NancyConsole::recursePrintDependencies(const Action::DependencyRecord &reco
 	for (const DependencyRecord &dep : record.children) {
 		debugPrintf("\n\t\t");
 		switch (dep.type) {
-		case DependencyType::kNone :
+		case DependencyType::kNone:
 			debugPrintf("kNone");
 			break;
-		case DependencyType::kInventory :
+		case DependencyType::kInventory:
 			debugPrintf("kInventory, item %u, %s, %s",
 				dep.label,
 				inventoryData->itemDescriptions[dep.label].name.c_str(),
 				dep.condition == g_nancy->_true ? "true" : "false");
 			break;
-		case DependencyType::kEvent :
+		case DependencyType::kEvent:
 			debugPrintf("kEvent, flag %u, %s, %s",
 				dep.label,
-				g_nancy->getStaticData().eventFlagNames[dep.label >= 1000 ? dep.label - 1000 : dep.label].c_str(),
+				g_nancy->getEventFlagName(dep.label).c_str(),
 				dep.condition == g_nancy->_true ? "true" : "false");
 			break;
-		case DependencyType::kLogic :
+		case DependencyType::kLogic:
 			debugPrintf("kLogic, flag %u, %s",
 				dep.label,
 				dep.condition == g_nancy->_true ? "used" : "not used");
 			break;
-		case DependencyType::kElapsedGameTime :
+		case DependencyType::kElapsedGameTime:
 			debugPrintf("kElapsedGameTime, %i hours, %i minutes, %i seconds, %i milliseconds",
 				dep.hours,
 				dep.minutes,
 				dep.seconds,
 				dep.milliseconds);
 			break;
-		case DependencyType::kElapsedSceneTime :
+		case DependencyType::kElapsedSceneTime:
 			debugPrintf("kElapsedSceneTime, %i hours, %i minutes, %i seconds, %i milliseconds",
 				dep.hours,
 				dep.minutes,
 				dep.seconds,
 				dep.milliseconds);
 			break;
-		case DependencyType::kElapsedPlayerTime :
+		case DependencyType::kElapsedPlayerTime:
 			debugPrintf("kPlayerTime, player time %s %i hours, %i minutes, %i seconds, %i milliseconds",
 				dep.condition == 0 ? "greater than" : (dep.condition == 1 ? "less than" : "equals"),
 				dep.hours,
@@ -546,45 +546,45 @@ void NancyConsole::recursePrintDependencies(const Action::DependencyRecord &reco
 				dep.seconds,
 				dep.milliseconds);
 			break;
-		case DependencyType::kSceneCount :
+		case DependencyType::kSceneCount:
 			debugPrintf("kSceneCount, scene ID %i, hit count %s %i",
 				dep.hours,
 				dep.milliseconds == 1 ? ">" : dep.milliseconds == 2 ? "<" : "==",
 				dep.minutes);
 			break;
-		case DependencyType::kElapsedPlayerDay :
+		case DependencyType::kElapsedPlayerDay:
 			debugPrintf("kElapsedPlayerDay");
 			break;
-		case DependencyType::kCursorType :
+		case DependencyType::kCursorType:
 			debugPrintf("kCursorType, item %u, %s",
 				dep.label,
 				inventoryData->itemDescriptions[dep.label].name.c_str());
 			break;
-		case DependencyType::kPlayerTOD :
+		case DependencyType::kPlayerTOD:
 			debugPrintf("kPlayerTOD, %s",
 				dep.label == 0 ? "kPlayerDay" : dep.label == 1 ? "kPLayerNight" : "kPLayerDuskDawn");
 			break;
-		case DependencyType::kTimerLessThanDependencyTime :
+		case DependencyType::kTimerLessThanDependencyTime:
 			debugPrintf("kTimerLessThanDependencyTime");
 			break;
-		case DependencyType::kTimerGreaterThanDependencyTime :
+		case DependencyType::kTimerGreaterThanDependencyTime:
 			debugPrintf("kTimerGreaterThanDependencyTime");
 			break;
-		case DependencyType::kDifficultyLevel :
+		case DependencyType::kDifficultyLevel:
 			debugPrintf("kDifficultyLevel, level %i", dep.condition);
 			break;
-		case DependencyType::kClosedCaptioning :
+		case DependencyType::kClosedCaptioning:
 			debugPrintf("kClosedCaptioning, %s", dep.condition == 2 ? "true" : "false");
 			break;
-		case DependencyType::kSound :
+		case DependencyType::kSound:
 			debugPrintf("kSound, channel %i", dep.condition);
 			break;
-		case DependencyType::kOpenParenthesis :
+		case DependencyType::kOpenParenthesis:
 			debugPrintf("((((((((\n");
 			recursePrintDependencies(dep);
 			debugPrintf("\n))))))))");
 			break;
-		case DependencyType::kRandom :
+		case DependencyType::kRandom:
 			debugPrintf("kRandom, chance %i", dep.condition);
 			break;
 		default:
@@ -783,7 +783,7 @@ bool NancyConsole::Cmd_getEventFlags(int argc, const char **argv) {
 		for (uint i = 0; i < numEventFlags; ++i) {
 			debugPrintf("\nFlag %u, %s, %s",
 				i,
-				g_nancy->getStaticData().eventFlagNames[i].c_str(),
+				g_nancy->getEventFlagName(i).c_str(),
 				NancySceneState.getEventFlag(i, g_nancy->_true) == true ? "true" : "false");
 		}
 	} else {
@@ -795,7 +795,7 @@ bool NancyConsole::Cmd_getEventFlags(int argc, const char **argv) {
 			}
 			debugPrintf("\nFlag %u, %s, %s",
 				flagID,
-				g_nancy->getStaticData().eventFlagNames[flagID].c_str(),
+				g_nancy->getEventFlagName(flagID).c_str(),
 				NancySceneState.getEventFlag(flagID, g_nancy->_true) == true ? "true" : "false");
 
 		}
@@ -824,12 +824,12 @@ bool NancyConsole::Cmd_setEventFlags(int argc, const char **argv) {
 			NancySceneState.setEventFlag(flagID, g_nancy->_true);
 			debugPrintf("Set flag %i, %s, to true\n",
 				flagID,
-				g_nancy->getStaticData().eventFlagNames[flagID].c_str());
+				g_nancy->getEventFlagName(flagID).c_str());
 		} else if (Common::String(argv[i + 1]).compareTo("false") == 0) {
 			NancySceneState.setEventFlag(flagID, g_nancy->_false);
 			debugPrintf("Set flag %i, %s, to false\n",
 				flagID,
-				g_nancy->getStaticData().eventFlagNames[flagID].c_str());
+				g_nancy->getEventFlagName(flagID).c_str());
 		} else {
 			debugPrintf("Invalid value %s\n", argv[i + 1]);
 			continue;
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 89e3e4a7822..ba4c5db2d83 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -1115,11 +1115,15 @@ UINB::UINB(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
 }
 
 EVNT::EVNT(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
-	while (chunkStream->size() - chunkStream->pos() >= (int64)kEventRecordSize) {
-		EventRecord rec;
-		readFilename(*chunkStream, rec.name);
-		rec.id = chunkStream->readSint16LE();
-		events.push_back(rec);
+	Common::String name;
+	const uint16 count = (uint16)(chunkStream->size() / (int64)kEventRecordSize);
+
+	eventFlagNames.resize(count);
+
+	for (uint16 i = 0; i < count; ++i) {
+		readFilename(*chunkStream, name);
+		chunkStream->skip(2);	// flag ID (starting from 2000)
+		eventFlagNames[i] = name;
 	}
 }
 
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index ad8656777f9..05d7d363ba9 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -738,16 +738,11 @@ struct UINB : public EngineData {
 // (the engine registers several built-in event categories at runtime on top of
 // whatever this chunk provides). Each record is a name followed by an id.
 struct EVNT : public EngineData {
-	struct EventRecord {
-		Common::String name;
-		int16 id = 0;
-	};
-
 	EVNT(Common::SeekableReadStream *chunkStream);
 
 	static const uint kEventRecordSize = 35;
 
-	Common::Array<EventRecord> events;
+	Common::Array<Common::String> eventFlagNames;
 };
 
 // UI overlay element table. Introduced in Nancy 12. Each record describes one UI
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 6cb1ff0f96c..752918875b1 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -220,6 +220,29 @@ const EngineData *NancyEngine::getEngineData(const Common::String &name) const {
 	return nullptr;
 }
 
+const Common::String NancyEngine::getEventFlagName(uint flagID) const {
+	if (getGameType() <= kGameTypeNancy11) {
+		if (flagID >= 1000) {
+			// In nancy3 and onwards flags begin from 1000
+			flagID -= 1000;
+		}
+		return (flagID < _staticData.eventFlagNames.size()) ? _staticData.eventFlagNames[flagID] : "";
+	} else {
+		if (flagID >= 2000) {
+			flagID -= 2000;
+
+			auto flagNames = ((EVNT *)getEngineData("EVNT"))->eventFlagNames;
+			return (flagID < flagNames.size()) ? flagNames[flagID] : "";
+		} else {
+			if (flagID >= 1000) {
+				flagID -= 1000;
+			}
+
+			return Common::String::format("Generic%d", flagID);
+		}
+	}
+}
+
 void NancyEngine::setState(NancyState::NancyState state, NancyState::NancyState overridePrevious) {
 	// Handle special cases first
 	switch (state) {
@@ -441,12 +464,21 @@ void NancyEngine::bootGameEngine() {
 
 	// Load BOOT chunks data
 	Common::SeekableReadStream *chunkStream = nullptr;
-	#define LOAD_BOOT_L(t, s) if (chunkStream = iff->getChunkStream(s), chunkStream) {	\
-								_engineData.setVal(s, new t(chunkStream));				\
-								delete chunkStream;										\
-							}
+	#define LOAD_BOOT_L(t, s)	if (chunkStream = iff->getChunkStream(s), chunkStream) {	\
+									_engineData.setVal(s, new t(chunkStream));				\
+									delete chunkStream;										\
+								}
 	#define LOAD_BOOT(t) LOAD_BOOT_L(t, #t)
 
+	#define LOAD_CHUNK(n, t, s, k)	iff = _resource->loadIFF(n);								\
+									if (!iff)													\
+										error("Failed to load %s", n);							\
+									if (chunkStream = iff->getChunkStream(s), chunkStream) {	\
+										_engineData.setVal(k, new t(chunkStream));				\
+										delete chunkStream;										\
+									}															\
+									delete iff;
+
 	LOAD_BOOT_L(ImageChunk, "OB0")
 	LOAD_BOOT_L(ImageChunk, "FR0")
 	LOAD_BOOT_L(ImageChunk, "LG0")
@@ -496,7 +528,7 @@ void NancyEngine::bootGameEngine() {
 
 	// Nancy 12+
 	// HINT chunk has been removed (the hint system and its action record were dropped in Nancy12)
-	LOAD_BOOT(EVNT)	// Named-event table (empty in Nancy 12)
+	// EVNT chunk added, which contains event flag names (loaded below)
 	LOAD_BOOT(UIRC)	// UI overlay element table
 
 	// Nancy 13+
@@ -535,32 +567,15 @@ void NancyEngine::bootGameEngine() {
 
 	delete iff;
 
+	if (getGameType() >= kGameTypeNancy12) {
+		LOAD_CHUNK("FLAGS", EVNT, "EVNT", "EVNT")
+	}
+
 	// Load convo texts and autotext
 	auto *bsum = GetEngineData(BSUM);
 	if (bsum && !bsum->conversationTextsFilename.empty() && !bsum->autotextFilename.empty()) {
-		iff = _resource->loadIFF(bsum->conversationTextsFilename);
-		if (!iff) {
-			error("Could not load CONVO IFF");
-		}
-
-		if (chunkStream = iff->getChunkStream("CVTX"), chunkStream) {
-			_engineData.setVal("CONVO", new CVTX(chunkStream));
-			delete chunkStream;
-		}
-
-		delete iff;
-
-		iff = _resource->loadIFF(bsum->autotextFilename);
-		if (!iff) {
-			error("Could not load AUTOTEXT IFF");
-		}
-
-		if (chunkStream = iff->getChunkStream("CVTX"), chunkStream) {
-			_engineData.setVal("AUTOTEXT", new CVTX(chunkStream));
-			delete chunkStream;
-		}
-
-		delete iff;
+		LOAD_CHUNK(bsum->conversationTextsFilename.toString().c_str(), CVTX, "CVTX", "CONVO")
+		LOAD_CHUNK(bsum->autotextFilename.toString().c_str(), CVTX, "CVTX", "AUTOTEXT")
 	}
 
 	#undef LOAD_BOOT_L
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index 142465a4624..39722253d4d 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -98,6 +98,7 @@ public:
 
 	const StaticData &getStaticData() const;
 	const EngineData *getEngineData(const Common::String &name) const;
+	const Common::String getEventFlagName(uint flagID) const;
 
 	void setState(NancyState::NancyState state, NancyState::NancyState overridePrevious = NancyState::kNone);
 	NancyState::NancyState getState() { return _gameFlow.curState; }
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 66c2405d07f..88f17c4d29e 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -542,8 +542,15 @@ void Scene::playItemCantSound(int16 itemID, bool notHoldingSound) {
 }
 
 void Scene::setEventFlag(int16 label, byte flag) {
+	if (label >= 2000) {
+		// In nancy12 and onwards flags begin from 2000
+		label -= 2000;
+	}
+
 	if (label >= 1000) {
 		// In nancy3 and onwards flags begin from 1000
+		// TODO: We need to separate the generic event flags
+		// from the normal event flags in Nancy12+
 		label -= 1000;
 	}
 
@@ -557,8 +564,15 @@ void Scene::setEventFlag(FlagDescription eventFlag) {
 }
 
 bool Scene::getEventFlag(int16 label, byte flag) const {
+	if (label >= 2000) {
+		// In nancy12 and onwards flags begin from 2000
+		label -= 2000;
+	}
+
 	if (label >= 1000) {
 		// In nancy3 and onwards flags begin from 1000
+		// TODO: We need to separate the generic event flags
+		// from the normal event flags in Nancy12+
 		label -= 1000;
 	}
 




More information about the Scummvm-git-logs mailing list