[Scummvm-git-logs] scummvm master -> 73b66c60f873e80f327ddafb052d07bc8da79615

fracturehill noreply at scummvm.org
Mon Oct 2 09:19:58 UTC 2023


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

Summary:
2d68dd87a3 NANCY: Main loop fixes
24f1044ed3 NANCY: Implement additional save dialogs
f504717f70 DEVTOOLS: Add nancy7 data to create_nancy
a4e7dfee97 NANCY: Block SoundManager from creating Scene state
ea1d0d2a5c NANCY: Init sound listener vector in conditional dialogue
5ecfef2a2e NANCY: Add support for TSUM chunks
7e6d37276b NANCY: Add support for nancy7's "More Nancy Drew!"
7aae7ec661 NANCY: Implement GotoMenu
73b66c60f8 BACKENDS: WII: Always retain cursor palette


Commit: 2d68dd87a305e22e7f66b260b550d2c15ec1a420
    https://github.com/scummvm/scummvm/commit/2d68dd87a305e22e7f66b260b550d2c15ec1a420
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:30+03:00

Commit Message:
NANCY: Main loop fixes

Made sure that the main loop doesn't run for a frame longer
than it should when quitting the game. Also fixed the checks
for suppressed graphics so they now actually work.

Changed paths:
    engines/nancy/nancy.cpp


diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 3e40ccb46bd..7d86c96dd8b 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -261,17 +261,21 @@ Common::Error NancyEngine::run() {
 		}
 	}
 
+	bool graphicsWereSuppressed = false;
+
 	// Main loop
-	while (!shouldQuit()) {
+	while (true) {
+		_input->processEvents();
+		if (shouldQuit()) {
+			break;
+		}
+
 		uint32 frameEndTime = _system->getMillis() + 16;
 
-		bool graphicsWereSuppressed = _graphicsManager->_isSuppressed;
 		if (!graphicsWereSuppressed) {
 			_cursorManager->setCursorType(CursorManager::kNormalArrow);
 		}
 
-		_input->processEvents();
-
 		State::State *s;
 
 		if (_gameFlow.changingState) {
@@ -288,6 +292,8 @@ Common::Error NancyEngine::run() {
 			s->process();
 		}
 
+		graphicsWereSuppressed = _graphicsManager->_isSuppressed;
+
 		_graphicsManager->draw();
 
 		if (_gameFlow.changingState) {
@@ -295,7 +301,7 @@ Common::Error NancyEngine::run() {
 
 			s = getStateObject(_gameFlow.prevState);
 			if (s) {
-				if(s->onStateExit(_gameFlow.prevState)) {
+				if (s->onStateExit(_gameFlow.prevState)) {
 					destroyState(_gameFlow.prevState);
 				}
 			}


Commit: 24f1044ed36d83c55c836fa1cccf1849960d1057
    https://github.com/scummvm/scummvm/commit/24f1044ed36d83c55c836fa1cccf1849960d1057
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:30+03:00

Commit Message:
NANCY: Implement additional save dialogs

Added support for the dialogs asking if you want to
overwrite an existing save, or load a save without saving first
(both introduced in nancy6).

Changed paths:
    engines/nancy/enginedata.cpp
    engines/nancy/enginedata.h
    engines/nancy/state/loadsave.cpp
    engines/nancy/state/loadsave.h
    engines/nancy/state/mainmenu.cpp
    engines/nancy/state/mainmenu.h
    engines/nancy/state/savedialog.cpp
    engines/nancy/state/savedialog.h


diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index e223dfe283b..36ccc7febc3 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -486,22 +486,28 @@ LOAD::LOAD(Common::SeekableReadStream *chunkStream) :
 }
 
 SDLG::SDLG(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
-	readFilename(*chunkStream, _imageName);
+	while (chunkStream->pos() < chunkStream->size()) {
+		dialogs.push_back(Dialog(chunkStream));
+	}
+}
+
+SDLG::Dialog::Dialog(Common::SeekableReadStream *chunkStream) {
+	readFilename(*chunkStream, imageName);
 	chunkStream->skip(16);
 
-	readRect(*chunkStream, _yesDest);
-	readRect(*chunkStream, _noDest);
-	readRect(*chunkStream, _cancelDest);
+	readRect(*chunkStream, yesDest);
+	readRect(*chunkStream, noDest);
+	readRect(*chunkStream, cancelDest);
 
 	chunkStream->skip(16);
 
-	readRect(*chunkStream, _yesHighlightSrc);
-	readRect(*chunkStream, _noHighlightSrc);
-	readRect(*chunkStream, _cancelHighlightSrc);
+	readRect(*chunkStream, yesHighlightSrc);
+	readRect(*chunkStream, noHighlightSrc);
+	readRect(*chunkStream, cancelHighlightSrc);
 
-	readRect(*chunkStream, _yesDownSrc);
-	readRect(*chunkStream, _noDownSrc);
-	readRect(*chunkStream, _cancelDownSrc);
+	readRect(*chunkStream, yesDownSrc);
+	readRect(*chunkStream, noDownSrc);
+	readRect(*chunkStream, cancelDownSrc);
 }
 
 HINT::HINT(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index ac5ddb5186b..22c2a0a7576 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -293,21 +293,27 @@ struct LOAD : public EngineData {
 // Contains data for the prompt that appears when exiting the game
 // without saving first. Introduced in nancy3.
 struct SDLG : public EngineData {
-	SDLG(Common::SeekableReadStream *chunkStream);
-
-	Common::String _imageName;
-
-	Common::Rect _yesDest;
-	Common::Rect _noDest;
-	Common::Rect _cancelDest;
+	struct Dialog {
+		Dialog(Common::SeekableReadStream *chunkStream);
+		
+		Common::String imageName;
+
+		Common::Rect yesDest;
+		Common::Rect noDest;
+		Common::Rect cancelDest;
+
+		Common::Rect yesHighlightSrc;
+		Common::Rect noHighlightSrc;
+		Common::Rect cancelHighlightSrc;
+
+		Common::Rect yesDownSrc;
+		Common::Rect noDownSrc;
+		Common::Rect cancelDownSrc;
+	};
 
-	Common::Rect _yesHighlightSrc;
-	Common::Rect _noHighlightSrc;
-	Common::Rect _cancelHighlightSrc;
+	SDLG(Common::SeekableReadStream *chunkStream);
 
-	Common::Rect _yesDownSrc;
-	Common::Rect _noDownSrc;
-	Common::Rect _cancelDownSrc;
+	Common::Array<Dialog> dialogs;
 };
 
 // Contains data for the hint system. Only used in nancy1.
diff --git a/engines/nancy/state/loadsave.cpp b/engines/nancy/state/loadsave.cpp
index 891eaa66853..725426f9720 100644
--- a/engines/nancy/state/loadsave.cpp
+++ b/engines/nancy/state/loadsave.cpp
@@ -85,11 +85,15 @@ void LoadSaveMenu::process() {
 	case kSuccess:
 		success();
 		break;
-	case kStop:
-		stop();
+	default:
 		break;
 	}
 
+	// Make sure stop runs on the same frame
+	if (_state == kStop) {
+		stop();
+	}
+
 	g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
 }
 
@@ -98,7 +102,7 @@ void LoadSaveMenu::onStateEnter(const NancyState::NancyState prevState) {
 }
 
 bool LoadSaveMenu::onStateExit(const NancyState::NancyState nextState) {
-	return true;
+	return _destroyOnExit;
 }
 
 void LoadSaveMenu::registerGraphics() {
@@ -130,6 +134,8 @@ void LoadSaveMenu::registerGraphics() {
 
 	_blinkingCursorOverlay.registerGraphics();
 	_successOverlay.registerGraphics();
+
+	g_nancy->_graphicsManager->redrawAll();
 }
 
 void LoadSaveMenu::init() {
@@ -443,6 +449,42 @@ void LoadSaveMenu::enterFilename() {
 }
 
 void LoadSaveMenu::save() {
+	const SDLG *sdlg = (const SDLG *)g_nancy->getEngineData("SDLG");
+
+	if (sdlg && sdlg->dialogs.size() > 1) {
+		// nancy6 added a "Do you want to overwrite this save" dialog.
+		// First, check if we are actually overwriting
+		SaveStateDescriptor desc = g_nancy->getMetaEngine()->querySaveMetaInfos(ConfMan.getActiveDomainName().c_str(), _selectedSave + 1);
+		if (desc.isValid()) {
+			if (!ConfMan.hasKey("sdlg_return", ConfMan.kTransientDomain)) {
+				// Request the dialog
+				ConfMan.setInt("sdlg_id", 1, ConfMan.kTransientDomain);
+				_destroyOnExit = false;
+				g_nancy->setState(NancyState::kSaveDialog);
+				return;
+			} else {
+				// Dialog has returned
+				g_nancy->_graphicsManager->suppressNextDraw();
+				_destroyOnExit = true;
+				uint ret = ConfMan.getInt("sdlg_return", ConfMan.kTransientDomain);
+				ConfMan.removeKey("sdlg_return", ConfMan.kTransientDomain);
+				switch (ret) {
+				case 1 :
+					// "No" keeps us in the LoadSave state but doesn't save
+					_state = kRun;
+					return;
+				case 2 :
+					// "Cancel" returns to the main menu
+					g_nancy->setState(NancyState::kMainMenu);
+					return;
+				default:
+					// "Yes" actually saves
+					break;
+				}
+			}
+		}
+	}
+	
 	// Improvement: not providing a name doesn't result in the
 	// savefile being named "--- Empty ---" or "Nothing Saved Here".
 	// Instead, we use ScummVM's built-in save name generator
@@ -468,6 +510,38 @@ void LoadSaveMenu::save() {
 }
 
 void LoadSaveMenu::load() {
+	const SDLG *sdlg = (const SDLG *)g_nancy->getEngineData("SDLG");
+
+	if (sdlg && sdlg->dialogs.size() > 1 && Nancy::State::Scene::hasInstance() && !g_nancy->_hasJustSaved) {
+		// nancy6 added a "Do you want load without saving" dialog.
+		if (!ConfMan.hasKey("sdlg_return", ConfMan.kTransientDomain)) {
+			// Request the dialog
+			ConfMan.setInt("sdlg_id", 2, ConfMan.kTransientDomain);
+			_destroyOnExit = false;
+			g_nancy->setState(NancyState::kSaveDialog);
+			return;
+		} else {
+			// Dialog has returned
+			_destroyOnExit = true;
+			g_nancy->_graphicsManager->suppressNextDraw();
+			uint ret = ConfMan.getInt("sdlg_return", ConfMan.kTransientDomain);
+			ConfMan.removeKey("sdlg_return", ConfMan.kTransientDomain);
+			switch (ret) {
+			case 1 :
+				// "No" keeps us in the LoadSave state but doesn't load
+				_state = kRun;
+				return;
+			case 2 :
+				// "Cancel" returns to the main menu
+				g_nancy->setState(NancyState::kMainMenu);
+				return;
+			default:
+				// "Yes" actually loads
+				break;
+			}
+		}
+	}
+
 	if (Nancy::State::Scene::hasInstance()) {
 		Nancy::State::Scene::destroy();
 	}
diff --git a/engines/nancy/state/loadsave.h b/engines/nancy/state/loadsave.h
index ecf1cec2d6f..dd40bf33813 100644
--- a/engines/nancy/state/loadsave.h
+++ b/engines/nancy/state/loadsave.h
@@ -93,6 +93,8 @@ private:
 	bool _enteringNewState;
 	uint32 _nextBlink;
 
+	bool _destroyOnExit = true;
+
 	const LOAD *_loadSaveData;
 };
 
diff --git a/engines/nancy/state/mainmenu.cpp b/engines/nancy/state/mainmenu.cpp
index f4de3c2688b..4cde537e4b5 100644
--- a/engines/nancy/state/mainmenu.cpp
+++ b/engines/nancy/state/mainmenu.cpp
@@ -24,6 +24,7 @@
 #include "engines/nancy/sound.h"
 #include "engines/nancy/input.h"
 #include "engines/nancy/util.h"
+#include "engines/nancy/graphics.h"
 
 #include "engines/nancy/state/mainmenu.h"
 #include "engines/nancy/state/scene.h"
@@ -63,7 +64,7 @@ void MainMenu::onStateEnter(const NancyState::NancyState prevState) {
 }
 
 bool MainMenu::onStateExit(const NancyState::NancyState nextState) {
-	return true;
+	return _destroyOnExit;
 }
 
 void MainMenu::registerGraphics() {
@@ -72,6 +73,8 @@ void MainMenu::registerGraphics() {
 	for (auto *button : _buttons) {
 		button->registerGraphics();
 	}
+
+	g_nancy->_graphicsManager->redrawAll();
 }
 
 void MainMenu::clearButtonState() {
@@ -188,8 +191,40 @@ void MainMenu::stop() {
 	case 6:
 		// Exit Game
 		if (g_nancy->getEngineData("SDLG") && Nancy::State::Scene::hasInstance() && !g_nancy->_hasJustSaved) {
-			g_nancy->setState(NancyState::kSaveDialog);
+			if (!ConfMan.hasKey("sdlg_return", ConfMan.kTransientDomain)) {
+				// Request the "Do you want to save before quitting" dialog
+				ConfMan.setInt("sdlg_id", 0, ConfMan.kTransientDomain);
+				_destroyOnExit = false;
+				g_nancy->setState(NancyState::kSaveDialog);
+			} else {
+				// Dialog has returned
+				_destroyOnExit = true;
+				g_nancy->_graphicsManager->suppressNextDraw();
+				uint ret = ConfMan.getInt("sdlg_return", ConfMan.kTransientDomain);
+				ConfMan.removeKey("sdlg_return", ConfMan.kTransientDomain);
+				switch (ret) {
+				case 0 :
+					// "Yes" switches to LoadSave
+					g_nancy->setState(NancyState::kLoadSave);
+					break;
+				case 1 :
+					// "No" quits the game
+					g_nancy->quitGame();
+					break;
+				case 2 :
+					// "Cancel" keeps us in the main menu
+					_selected = -1;
+					for (uint i = 0; i < _buttons.size(); ++i) {
+						_buttons[i]->_isClicked = false;
+					}
+					_state = kRun;
+					break;
+				default:
+					break;
+				}
+			}
 		} else {
+			// Earlier games had no "Do you want to save before quitting" dialog, directly quit
 			g_nancy->quitGame();
 		}
 		
diff --git a/engines/nancy/state/mainmenu.h b/engines/nancy/state/mainmenu.h
index 0a270498e71..f92e9b88bf5 100644
--- a/engines/nancy/state/mainmenu.h
+++ b/engines/nancy/state/mainmenu.h
@@ -64,6 +64,8 @@ private:
 
 	Common::Array<UI::Button *> _buttons;
 
+	bool _destroyOnExit = true;
+
 	const MENU *_menuData;
 };
 
diff --git a/engines/nancy/state/savedialog.cpp b/engines/nancy/state/savedialog.cpp
index 1e89f607ef4..eea07a9362a 100644
--- a/engines/nancy/state/savedialog.cpp
+++ b/engines/nancy/state/savedialog.cpp
@@ -29,6 +29,8 @@
 #include "engines/nancy/state/scene.h"
 #include "engines/nancy/ui/button.h"
 
+#include "common/config-manager.h"
+
 namespace Common {
 DECLARE_SINGLETON(Nancy::State::SaveDialog);
 }
@@ -87,14 +89,17 @@ void SaveDialog::registerGraphics() {
 }
 
 void SaveDialog::init() {
-	_dialogData = (const SDLG*)g_nancy->getEngineData("SDLG");
-	assert(_dialogData);
+	const SDLG* sdlg = (const SDLG*)g_nancy->getEngineData("SDLG");
+	assert(sdlg);
+
+	_dialogData = &sdlg->dialogs[ConfMan.getInt("sdlg_id", ConfMan.kTransientDomain)];
+	ConfMan.removeKey("sdlg_id", ConfMan.kTransientDomain);
 
-	_background.init(_dialogData->_imageName);
+	_background.init(_dialogData->imageName);
 
-	_yesButton = new UI::Button(1, _background._drawSurface, _dialogData->_yesDownSrc, _dialogData->_yesDest, _dialogData->_yesHighlightSrc);
-	_noButton = new UI::Button(1, _background._drawSurface, _dialogData->_noDownSrc, _dialogData->_noDest, _dialogData->_noHighlightSrc);
-	_cancelButton = new UI::Button(1, _background._drawSurface, _dialogData->_cancelDownSrc, _dialogData->_cancelDest, _dialogData->_cancelHighlightSrc);
+	_yesButton = new UI::Button(1, _background._drawSurface, _dialogData->yesDownSrc, _dialogData->yesDest, _dialogData->yesHighlightSrc);
+	_noButton = new UI::Button(1, _background._drawSurface, _dialogData->noDownSrc, _dialogData->noDest, _dialogData->noHighlightSrc);
+	_cancelButton = new UI::Button(1, _background._drawSurface, _dialogData->cancelDownSrc, _dialogData->cancelDest, _dialogData->cancelHighlightSrc);
 
 	registerGraphics();
 
@@ -127,19 +132,8 @@ void SaveDialog::run() {
 }
 
 void SaveDialog::stop() {
-	switch (_selected) {
-	case 0 :
-		g_nancy->setState(NancyState::kLoadSave);
-		break;
-	case 1 :
-		g_nancy->quitGame();
-		break;
-	case 2 :
-		g_nancy->setToPreviousState();
-		break;
-	default:
-		break;
-	}
+	ConfMan.setInt("sdlg_return", _selected, ConfMan.kTransientDomain);
+	g_nancy->setToPreviousState();
 }
 
 } // End of namespace State
diff --git a/engines/nancy/state/savedialog.h b/engines/nancy/state/savedialog.h
index 270e577a4cd..0a31ccbe082 100644
--- a/engines/nancy/state/savedialog.h
+++ b/engines/nancy/state/savedialog.h
@@ -65,7 +65,7 @@ private:
 	UI::Button *_noButton;
 	UI::Button *_cancelButton;
 
-	const SDLG *_dialogData;
+	const SDLG::Dialog *_dialogData;
 };
 
 } // End of namespace State


Commit: f504717f7085a68bcf98aa0c3df0227a4a4f6f03
    https://github.com/scummvm/scummvm/commit/f504717f7085a68bcf98aa0c3df0227a4a4f6f03
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:30+03:00

Commit Message:
DEVTOOLS: Add nancy7 data to create_nancy

Changed paths:
  A devtools/create_nancy/nancy7_data.h
    devtools/create_nancy/create_nancy.cpp
    devtools/create_nancy/nancy3_data.h


diff --git a/devtools/create_nancy/create_nancy.cpp b/devtools/create_nancy/create_nancy.cpp
index e426f1dcf87..9735ac6d6e0 100644
--- a/devtools/create_nancy/create_nancy.cpp
+++ b/devtools/create_nancy/create_nancy.cpp
@@ -27,11 +27,12 @@
 #include "nancy4_data.h"
 #include "nancy5_data.h"
 #include "nancy6_data.h"
+#include "nancy7_data.h"
 
 #define NANCYDAT_MAJOR_VERSION 1
 #define NANCYDAT_MINOR_VERSION 0
 
-#define NANCYDAT_NUM_GAMES 7
+#define NANCYDAT_NUM_GAMES 8
 
 /**
  * Format specifications for nancy.dat:
@@ -66,6 +67,7 @@
  * 		Nancy Drew: Treasure in the Royal Tower
  * 		Nancy Drew: The Final Scene
  * 		Nancy Drew: Secret of the Scarlet Hand
+ * 		Nancy Drew: Ghost Dogs of Moon Lake
 */
 
 // Add the offset to the next tagged section before the section itself for easier navigation
@@ -211,7 +213,7 @@ int main(int argc, char *argv[]) {
 	// Nancy Drew: Message in a Haunted Mansion data
 	gameOffsets.push_back(output.pos());
 	WRAPWITHOFFSET(writeConstants(output, _nancy3Constants))
-	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to6SoundChannelInfo))
+	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to7SoundChannelInfo))
 	WRAPWITHOFFSET(writeLanguages(output, _nancy3LanguagesOrder))
 	WRAPWITHOFFSET(writeConditionalDialogue(output, _nancy3ConditionalDialogue, _nancy3ConditionalDialogueTexts))
 	WRAPWITHOFFSET(writeGoodbyes(output, _nancy3Goodbyes, _nancy3GoodbyeTexts))
@@ -222,7 +224,7 @@ int main(int argc, char *argv[]) {
 	// Nancy Drew: Treasure in the Royal Tower data
 	gameOffsets.push_back(output.pos());
 	WRAPWITHOFFSET(writeConstants(output, _nancy4Constants))
-	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to6SoundChannelInfo))
+	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to7SoundChannelInfo))
 	WRAPWITHOFFSET(writeLanguages(output, _nancy4LanguagesOrder))
 	WRAPWITHOFFSET(writeConditionalDialogue(output, _nancy4ConditionalDialogue, _nancy4ConditionalDialogueTexts))
 	WRAPWITHOFFSET(writeGoodbyes(output, _nancy4Goodbyes, _nancy4GoodbyeTexts))
@@ -233,7 +235,7 @@ int main(int argc, char *argv[]) {
 	// Nancy Drew: The Final Scene data
 	gameOffsets.push_back(output.pos());
 	WRAPWITHOFFSET(writeConstants(output, _nancy5Constants))
-	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to6SoundChannelInfo))
+	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to7SoundChannelInfo))
 	WRAPWITHOFFSET(writeLanguages(output, _nancy5LanguagesOrder))
 	WRAPWITHOFFSET(writeConditionalDialogue(output, _nancy5ConditionalDialogue, _nancy5ConditionalDialogueTexts))
 	WRAPWITHOFFSET(writeGoodbyes(output, _nancy5Goodbyes, _nancy5GoodbyeTexts))
@@ -244,7 +246,7 @@ int main(int argc, char *argv[]) {
 	// Nancy Drew: Secret of the Scarlet Hand
 	gameOffsets.push_back(output.pos());
 	WRAPWITHOFFSET(writeConstants(output, _nancy6Constants))
-	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to6SoundChannelInfo))
+	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to7SoundChannelInfo))
 	WRAPWITHOFFSET(writeLanguages(output, _nancy6LanguagesOrder))
 	WRAPWITHOFFSET(writeConditionalDialogue(output, _nancy6ConditionalDialogue))
 	WRAPWITHOFFSET(writeGoodbyes(output, _nancy6Goodbyes))
@@ -252,6 +254,16 @@ int main(int argc, char *argv[]) {
 	WRAPWITHOFFSET(writeEmptySaveTexts(output, _nancy6EmptySaveStrings))
 	WRAPWITHOFFSET(writeEventFlagNames(output, _nancy6EventFlagNames))
 
+	// Nancy Drew: Ghost Dogs of Moon Lake
+	gameOffsets.push_back(output.pos());
+	WRAPWITHOFFSET(writeConstants(output, _nancy7Constants))
+	WRAPWITHOFFSET(writeSoundChannels(output, _nancy3to7SoundChannelInfo))
+	WRAPWITHOFFSET(writeLanguages(output, _nancy7LanguagesOrder))
+	WRAPWITHOFFSET(writeConditionalDialogue(output, _nancy7ConditionalDialogue))
+	WRAPWITHOFFSET(writeGoodbyes(output, _nancy7Goodbyes))
+	WRAPWITHOFFSET(writeRingingTexts(output, _nancy7TelephoneRinging))
+	WRAPWITHOFFSET(writeEventFlagNames(output, _nancy7EventFlagNames))
+
 	// Write the offsets for each game in the header
 	output.seek(offsetsOffset);
 	for (uint i = 0; i < gameOffsets.size(); ++i) {
diff --git a/devtools/create_nancy/nancy3_data.h b/devtools/create_nancy/nancy3_data.h
index 65d95dea2cb..28b96d55eb1 100644
--- a/devtools/create_nancy/nancy3_data.h
+++ b/devtools/create_nancy/nancy3_data.h
@@ -36,7 +36,7 @@ const GameConstants _nancy3Constants = {
 	4000
 };
 
-const SoundChannelInfo _nancy3to6SoundChannelInfo = {
+const SoundChannelInfo _nancy3to7SoundChannelInfo = {
 	32, 14,
 	{ 12, 13, 30 },
 	{ 0, 1, 2, 3, 19, 26, 27, 29 },
diff --git a/devtools/create_nancy/nancy7_data.h b/devtools/create_nancy/nancy7_data.h
new file mode 100644
index 00000000000..f0181895e6d
--- /dev/null
+++ b/devtools/create_nancy/nancy7_data.h
@@ -0,0 +1,899 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef NANCY7DATA_H
+#define NANCY7DATA_H
+
+#include "types.h"
+
+const GameConstants _nancy7Constants ={
+	41,
+	576,
+	{ }, // No Map state
+	{	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+		11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+		21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
+	60,
+	7,
+	4000
+};
+
+const Common::Array<Common::Language> _nancy7LanguagesOrder = {
+	Common::Language::EN_ANY,
+	Common::Language::RU_RUS
+};
+
+const Common::Array<Common::Array<ConditionalDialogue>> _nancy7ConditionalDialogue = {
+{	// Emily, 15 responses + 2 repeats
+	{	0, 1050, "NES50",
+		{ { kEv, 221, true }, { kEv, 116, false } } },
+	{	0, 1052, "NES52",
+		{ { kEv, 450, true }, { kEv, 106, false } } },
+	{	0, 1053, "NES53",
+		{ { kEv, 324, true }, { kEv, 185, false }, { kEv, 122, false }, { kEv, 263, false }, { kEv, 286, false } } },
+	{	0, 1055, "NES55",
+		{ { kEv, 312, true }, { kEv, 105, false }, { kEv, 117, false } } },
+	{	0, 1056, "NES56",
+		{ { kEv, 321, true }, { kEv, 113, false } } },
+	{	0, 1068, "NES57",
+		{ { kEv, 391, false } } },
+	{	0, 1058, "NES58",
+		{ { kEv, 120, true }, { kEv, 109, false } } },
+	{	0, 1060, "NES60",
+		{ { kEv, 302, true }, { kEv, 102, false } } },
+	{	0, 1060, "NES60",
+		{ { kEv, 456, true }, { kEv, 102, false } } },
+	{	0, 1060, "NES60",
+		{ { kEv, 262, true }, { kEv, 102, false } } },
+	{	0, 1061, "NES61",
+		{ { kEv, 262, true }, { kEv, 102, true }, { kEv, 103, false } } },
+	{	0, 1062, "NES62",
+		{ { kEv, 308, true }, { kEv, 111, false }, { kEv, 191, false } } },
+	{	0, 1063, "NES63",
+		{ { kEv, 124, false }, { kEv, 204, false }, { kIn, 23, true } } },
+	{	0, 1065, "NES65",
+		{ { kEv, 323, true }, { kEv, 112, false } } },
+	{	0, 1063, "NES63",
+		{ { kEv, 456, true }, { kEv, 102, true }, { kEv, 119, false } } },
+	{	0, 1067, "NES67",
+		{ { kEv, 302, true }, { kEv, 102, true }, { kEv, 121, false } } },
+	{	0, 1072, "NES72",
+		{ { kEv, 123, false } } }
+},
+{	// Jeff, 23 responses + 3 repeats
+	{	0, 1217, "NJS17",
+		{ { kEv, 288, true }, { kEv, 198, false } } },
+	{	0, 1250, "NJS50",
+		{ { kEv, 184, false }, { kEv, 187, false } } },
+	{	0, 1251, "NJS51",
+		{ { kEv, 187, true }, { kEv, 184, false } } },
+	{	0, 1253, "NJS53",
+		{ { kEv, 324, true }, { kEv, 185, false } } },
+	{	0, 1253, "NJS53",
+		{ { kEv, 263, true }, { kEv, 185, false } } },
+	{	0, 1253, "NJS53",
+		{ { kEv, 122, true }, { kEv, 185, false } } },
+	{	0, 1253, "NJS53",
+		{ { kEv, 285, true }, { kEv, 185, false } } },
+	{	0, 1254, "NJS54",
+		{ { kEv, 189, false } } },
+	{	0, 1256, "NJS56",
+		{ { kEv, 325, true }, { kEv, 208, false } } },
+	{	0, 1257, "NJS57",
+		{ { kEv, 208, true }, { kEv, 494, false }, { kEv, 178, false } } },
+	{	0, 1258, "NJS58",
+		{ { kEv, 292, true }, { kEv, 174, false } } },
+	{	0, 1261, "NJS61",
+		{ { kEv, 195, false } } },
+	{	0, 1263, "NJS63",
+		{ { kEv, 309, true }, { kEv, 194, false } } },
+	{	0, 1264, "NJS64",
+		{ { kEv, 175, true }, { kEv, 206, false } } },
+	{	0, 1265, "NJS65",
+		{ { kEv, 175, true }, { kEv, 181, false } } },
+	{	0, 1266, "NJS66",
+		{ { kEv, 435, true }, { kEv, 204, false } } },
+	{	0, 1267, "NJS67",
+		{ { kEv, 287, true }, { kEv, 172, false } } },
+	{	0, 1268, "NJS68",
+		{ { kEv, 104, true }, { kEv, 194, true }, { kEv, 323, true }, { kEv, 200, false } } },
+	{	0, 1269, "NJS69",
+		{ { kEv, 315, true }, { kEv, 201, false } } },
+	{	0, 1270, "NJS70",
+		{ { kEv, 304, true }, { kEv, 192, false } } },
+	{	0, 1271, "NJS71",
+		{ { kEv, 304, true }, { kEv, 205, true }, { kEv, 182, false } } },
+	{	0, 1276, "NJS76",
+		{ { kEv, 199, false }, { kIn, 28, true } } },
+	{	0, 1281, "NJS81",
+		{ { kEv, 210, true }, { kEv, 190, false } } },
+	{	0, 1282, "NJS82",
+		{ { kEv, 411, true }, { kEv, 202, false } } },
+	{	0, 1285, "NJS85",
+		{ { kEv, 262, true }, { kEv, 197, false }, { kEv, 402, false } } },
+	{	0, 1288, "NJS88",
+		{ { kEv, 196, true }, { kEv, 212, false } } }
+},
+{
+	// Red (forest), no responses
+},
+{	// Red (blind), 11 responses
+	{	0, 1550, "NRB50",
+		{ { kEv, 324, true }, { kEv, 185, false }, { kEv, 263, false } } },
+	{	0, 1551, "NRB51",
+		{ { kEv, 66, true }, { kEv, 262, false } } },
+	{	0, 1552, "NRB52",
+		{ { kEv, 119, true }, { kEv, 261, false } } },
+	{	0, 1553, "NRB53",
+		{ { kEv, 304, true }, { kEv, 256, false } } },
+	{	0, 1554, "NRB54",
+		{ { kEv, 301, true }, { kEv, 255, false } } },
+	{	0, 1559, "NRB59",
+		{ { kEv, 265, true }, { kEv, 258, false } } },
+	{	0, 1562, "NRB62",
+		{ { kEv, 258, true }, { kEv, 266, true }, { kEv, 253, false } } },
+	{	0, 1565, "NRB62",
+		{ { kEv, 258, true }, { kEv, 267, true }, { kEv, 254, false } } },
+	{	0, 1567, "NRB67",
+		{ { kEv, 452, true }, { kEv, 252, false }, { kEv, 419, false }, { kEv, 399, false } } },
+	{	0, 1570, "NRB68b",
+		{ { kEv, 406, true }, { kEv, 245, false } } },
+	{	0, 1571, "NRB71",
+		{ { kEv, 245, true }, { kEv, 243, false } } }
+},
+{	// Bess & George, 18 responses + 3 repeats
+	{	0, 1750, "NBG50",
+		{ { kEv, 222, false }, { kEv, 303, false }, { kEv, 223, true }, { kEv, 41, false } } },
+	{	0, 1751, "NBG51",
+		{ { kEv, 303, true }, { kEv, 41, true }, { kEv, 65, false } } },
+	{	0, 1752, "NBG52",
+		{ { kEv, 303, true }, { kEv, 41, false }, { kEv, 65, false }, { kEv, 38, false } } },
+	{	0, 1753, "NBG53",
+		{ { kEv, 38, true }, { kEv, 291, true }, { kEv, 312, true }, { kEv, 39, false } } },
+	{	0, 1755, "NBG55",
+		{ { kEv, 220, true }, { kEv, 217, true }, { kEv, 59, false } } },
+	{	0, 1756, "NBG56a",
+		{ { kEv, 62, true }, { kEv, 116, true }, { kEv, 221, true }, { kEv, 394, false }, { kEv, 61, false }, { kEv, 60, false } } },
+	{	0, 1757, "NBG57",
+		{ { kEv, 217, true }, { kEv, 188, true }, { kEv, 62, true }, { kEv, 52, false } } },
+	{	0, 1759, "NBG59",
+		{ { kEv, 217, true }, { kEv, 103, true }, { kEv, 180, true }, { kEv, 40, false } } },
+	{	0, 1760, "NBG60",
+		{ { kEv, 324, true }, { kEv, 185, true }, { kEv, 221, true }, { kEv, 44, false }, { kEv, 45, false }, { kEv, 48, false } } },
+	{	0, 1760, "NBG60",
+		{ { kEv, 324, true }, { kEv, 185, true }, { kEv, 122, true }, { kEv, 44, false }, { kEv, 45, false }, { kEv, 48, false } } },
+	{	0, 1761, "NBG61",
+		{ { kEv, 44, true }, { kEv, 198, true }, { kEv, 57, false } } },
+	{	0, 1761, "NBG61",
+		{ { kEv, 45, true }, { kEv, 198, true }, { kEv, 57, false } } },
+	{	0, 1761, "NBG61",
+		{ { kEv, 47, true }, { kEv, 198, true }, { kEv, 57, false } } },
+	{	0, 1762, "NBG62",
+		{ { kEv, 308, true }, { kEv, 313, true }, { kEv, 59, true }, { kEv, 56, false } } },
+	{	0, 1763, "NBG63",
+		{ { kEv, 304, true }, { kEv, 46, false } } },
+	{	0, 1765, "NBG65",
+		{ { kEv, 81, true }, { kEv, 54, true }, { kEv, 221, false }, { kEv, 64, false } } },
+	{	0, 1766, "NBG66",
+		{ { kEv, 224, true }, { kEv, 304, true }, { kEv, 478, true }, { kEv, 315, false }, { kEv, 55, false } } },
+	{	0, 1767, "NBG60",
+		{ { kEv, 173, true }, { kEv, 198, false }, { kEv, 44, false }, { kEv, 45, false } } },
+	{	0, 1768, "NBG60",
+		{ { kEv, 198, true }, { kEv, 44, false }, { kEv, 45, false }, { kEv, 48, false } } },
+	{	0, 1770, "NBG70",
+		{ { kEv, 216, true }, { kEv, 43, false }, { kDi, 2, true } } },
+	{	0, 1771, "NBG70",
+		{ { kEv, 216, true }, { kDi, 0, true } } }
+},
+{	// Frank & Jo, 8 responses
+	{	0, 1850, "NFJ50",
+		{ { kEv, 318, true }, { kEv, 323, false }, { kEv, 151, false } } },
+	{	0, 1851, "NFJ51",
+		{ { kEv, 480, true }, { kEv, 420, false }, { kEv, 155, false }, { kIn, 16, false } } },
+	{	0, 1852, "NFJ52",
+		{ { kEv, 501, true }, { kEv, 502, true }, { kEv, 304, true }, { kEv, 148, true }, { kEv, 214, false }, { kEv, 213, false }, { kEv, 154, false }, { kIn, 9, true } } },
+	{	0, 1853, "NFJ53",
+		{ { kEv, 304, true }, { kEv, 148, false } } },
+	{	0, 1854, "NFJ54",
+		{ { kEv, 148, true }, { kEv, 315, false }, { kEv, 152, false } } },
+	{	0, 1855, "NFJ55",
+		{ { kEv, 148, true }, { kEv, 155, true }, { kEv, 315, true }, { kEv, 297, true }, { kEv, 298, true }, { kEv, 296, true }, { kEv, 294, true }, { kEv, 156, false } } },
+	{	0, 1870, "NFJ70",
+		{ { kEv, 220, true }, { kEv, 217, true }, { kEv, 158, true }, { kIn, 147, false } } },
+	{	0, 1871, "NFJ70",
+		{ { kEv, 220, true }, { kEv, 217, true }, { kEv, 158, true }, { kIn, 147, true } } }
+},
+{	// Vivian, 14 responses
+	{	0, 1950, "NVW50",
+		{ { kEv, 487, true }, { kEv, 488, false }, { kEv, 412, false } } },
+	{	0, 1951, "NVW51",
+		{ { kEv, 488, true }, { kEv, 480, false } } },
+	{	0, 1952, "NVW52",
+		{ { kEv, 487, true }, { kEv, 482, false } } },
+	{	0, 1953, "NVW53",
+		{ { kEv, 482, true }, { kEv, 480, true }, { kEv, 479, false } } },
+	{	0, 1954, "NVW54",
+		{ { kEv, 304, true }, { kEv, 473, false } } },
+	{	0, 1955, "NVW55",
+		{ { kEv, 476, true }, { kEv, 478, false } } },
+	{	0, 1956, "NVW56",
+		{ { kEv, 476, true }, { kEv, 474, false } } },
+	{	0, 1957, "NVW57",
+		{ { kEv, 466, true }, { kEv, 470, false }, { kIn, 16, true } } },
+	{	0, 1958, "NVW58",
+		{ { kEv, 470, true }, { kEv, 466, true }, { kEv, 484, false }, { kIn, 16, true } } },
+	{	0, 1959, "NVW05b",
+		{ { kEv, 480, true }, { kEv, 481, false }, { kEv, 488, false } } },
+	{	0, 1960, "NVW60",
+		{ { kEv, 484, true }, { kEv, 475, true }, { kEv, 486, true }, { kEv, 471, false } } },
+	{	0, 1961, "NVW61",
+		{ { kEv, 296, true }, { kEv, 478, true }, { kEv, 213, false }, { kEv, 475, false } } },
+	{	0, 1962, "NVW62",
+		{ { kEv, 297, true }, { kEv, 214, false }, { kEv, 486, false } } },
+	{	0, 1963, "NVW63",
+		{ { kEv, 298, true }, { kEv, 215, false }, { kEv, 489, false } } }
+},
+{	// Sally, + 3 repeats
+	{	0, 1650, "NSM50",
+		{ { kEv, 369, true }, { kEv, 388, false } } },
+	{	0, 1651, "NSM51",
+		{ { kEv, 461, true }, { kEv, 221, false }, { kEv, 380, false } } },
+	{	0, 1652, "NSM52",
+		{ { kEv, 456, true }, { kEv, 217, true }, { kEv, 119, false }, { kEv, 381, false } } },
+	{	0, 1653, "NSM52",
+		{ { kEv, 456, true }, { kEv, 217, false }, { kEv, 386, false } } },
+	{	0, 1654, "NSM54a",
+		{ { kEv, 217, false }, { kEv, 386, false } } },
+	{	0, 1655, "NSM55",
+		{ { kEv, 119, true }, { kEv, 373, false } } },
+	{	0, 1655, "NSM56",
+		{ { kEv, 324, true }, { kEv, 122, false }, { kEv, 185, false }, { kEv, 378, false }, { kEv, 244, false } } },
+	{	0, 1655, "NSM56",
+		{ { kEv, 388, true }, { kEv, 122, false }, { kEv, 185, false }, { kEv, 378, false }, { kEv, 244, false } } },
+	{	0, 1657, "NSM57",
+		{ { kEv, 187, true }, { kEv, 376, false } } },
+	{	0, 1658, "NSM58",
+		{ { kEv, 198, true }, { kEv, 368, false } } },
+	{	0, 1659, "NSM59",
+		{ { kEv, 306, true }, { kEv, 401, false }, { kEv, 382, false } } },
+	{	0, 1660, "NSM60",
+		{ { kEv, 304, true }, { kEv, 112, true }, { kEv, 315, false }, { kEv, 377, false } } },
+	{	0, 1660, "NSM60",
+		{ { kEv, 304, true }, { kEv, 192, true }, { kEv, 315, false }, { kEv, 377, false } } },
+	{	0, 1660, "NSM60",
+		{ { kEv, 304, true }, { kEv, 256, true }, { kEv, 315, false }, { kEv, 377, false } } },
+	{	0, 1661, "NSM61",
+		{ { kEv, 389, true }, { kEv, 376, false } } },
+	{	0, 1662, "NSM62",
+		{ { kEv, 401, true }, { kEv, 375, false }, { kIn, 11, false } } },
+	{	0, 1663, "NSM63",
+		{ { kEv, 221, true }, { kEv, 247, true }, { kEv, 245, false }, { kEv, 384, false } } },
+	{	0, 1664, "NSM64",
+		{ { kEv, 457, true }, { kEv, 409, false }, { kEv, 383, false }, { kIn, 27, true } } },
+	{	0, 1665, "NSM65",
+		{ { kEv, 322, true }, { kEv, 390, false } } },
+	{	0, 1666, "NSM66",
+		{ { kEv, 310, true }, { kEv, 295, true }, { kEv, 401, false }, { kEv, 371, false } } },
+	{	0, 1667, "NSM67",
+		{ { kEv, 315, true }, { kEv, 387, false } } },
+	{	0, 1668, "NSM68",
+		{ { kEv, 190, true }, { kEv, 379, false } } },
+	{	0, 1669, "NSM69",
+		{ { kEv, 292, true }, { kEv, 370, false } } },
+}
+};
+
+const Common::Array<Goodbye> _nancy7Goodbyes = {
+	{ "NES90", { { { 1090, 1091, 1092, 1093, 1094 }, {}, NOFLAG } } },	// Emily
+	{ "NJS90", { { { 1290, 1291, 1292 }, {}, NOFLAG } } },				// Jeff
+	{ "", { { {}, {}, NOFLAG } } },										// Red (forest), no goodbye
+	{ "NRB90", { { { 1590, 1591, 1592, 1593, 1594 }, {}, NOFLAG } } },	// Red (blind)
+	{ "NBG90", { { { 1790, 1791, 1792, 1793 }, {}, NOFLAG } } },		// Bess & George
+	{ "NFJ90", { { { 1890, 1891, 1892, 1893 }, {}, NOFLAG } } },		// Frank & Jo
+	{ "NVW90", { { { 1990, 1991, 1992, 1993, 1994 }, {}, NOFLAG } } },	// Vivian
+	{ "NSM90", { { { 1690, 1691, 1692, 1693 }, {}, NOFLAG } } }			// Sally
+};
+
+const Common::Array<const char *> _nancy7TelephoneRinging = {
+	"ringing...<n><e>", // English
+	"\xc3\xf3\xe4\xea\xe8...  <n><e>" // Russian
+};
+
+const Common::Array<const char *> _nancy7EventFlagNames = {
+	"EV_Generic0",
+	"EV_Generic1",
+	"EV_Generic2",
+	"EV_Generic3",
+	"EV_Generic4",
+	"EV_Generic5",
+	"EV_Generic6",
+	"EV_Generic7",
+	"EV_Generic8",
+	"EV_Generic9",
+	"EV_Generic10",
+	"EV_Generic11",
+	"EV_Generic12",
+	"EV_Generic13",
+	"EV_Generic14",
+	"EV_Generic15",
+	"EV_Generic16",
+	"EV_Generic17",
+	"EV_Generic18",
+	"EV_Generic19",
+	"EV_Generic20",
+	"EV_Generic21",
+	"EV_Generic22",
+	"EV_Generic23",
+	"EV_Generic24",
+	"EV_Generic25",
+	"EV_Generic26",
+	"EV_Generic27",
+	"EV_Generic28",
+	"EV_Generic29",
+	"EV_Generic30",
+	"EV_TimeForEndgame",
+	"EV_PlayerWonGame",
+	"EV_StopPlayerScrolling",
+	"EV_Easter_Eggs",
+	"EV_Bail_Level01",
+	"EV_Bail_Level02",
+	"EV_Bail_Level03",
+	"EV_BG_Said_Attack",
+	"EV_BG_Said_Creepy",
+	"EV_BG_Said_Emily_Motive",
+	"EV_BG_Said_Fight",
+	"EV_BG_Said_Found_Map",
+	"EV_BG_Said_Fresh",
+	"EV_BG_Said_Get_Tested",
+	"EV_BG_Said_Getting_Tested",
+	"EV_BG_Said_Gold_Motive",
+	"EV_BG_Said_Got_Results",
+	"EV_BG_Said_Got_Tested",
+	"EV_BG_Said_Graves",
+	"EV_BG_Said_Hardy",
+	"EV_BG_Said_Hole_Heist",
+	"EV_BG_Said_JA_Has_Motive",
+	"EV_BG_Said_Message",
+	"EV_BG_Said_No_Red",
+	"EV_BG_Said_Paintings_Clue",
+	"EV_BG_Said_Paper",
+	"EV_BG_Said_Poison",
+	"EV_BG_Said_Prints",
+	"EV_BG_Said_Ranger",
+	"EV_BG_Said_Red_Fanatic",
+	"EV_BG_Said_Red_Grump",
+	"EV_BG_Said_Scare_Sally",
+	"EV_BG_Said_Used_To",
+	"EV_BG_Said_Vampire",
+	"EV_BG_Said_Wolves",
+	"EV_Bird_Flies",
+	"EV_Broke_Toolbox",
+	"EV_Bucket_Full",
+	"EV_Clock01",
+	"EV_Clock02",
+	"EV_Clock03",
+	"EV_Clock04",
+	"EV_Clock05",
+	"EV_Clock06",
+	"EV_Clock07",
+	"EV_Clock08",
+	"EV_Clock09",
+	"EV_Clock10",
+	"EV_Clock11",
+	"EV_Clock12",
+	"EV_Day",
+	"EV_Day_Needed",
+	"EV_Dog_Unstuck",
+	"EV_DogI_Pos01",
+	"EV_DogI_Pos02",
+	"EV_DogI_Pos03",
+	"EV_DogI_Pos04",
+	"EV_DogL_Pos01",
+	"EV_DogL_Pos02",
+	"EV_DogL_Pos03",
+	"EV_DogL_Pos04",
+	"EV_DogV_Pos01",
+	"EV_DogV_Pos02",
+	"EV_DogV_Pos03",
+	"EV_DogV_Pos04",
+	"EV_DogX_Pos01",
+	"EV_DogX_Pos02",
+	"EV_DogX_Pos03",
+	"EV_DogX_Pos04",
+	"EV_Drain_Grate_Open",
+	"EV_Drain_Open",
+	"EV_EG_Said_Barter",
+	"EV_EG_Said_Camos",
+	"EV_EG_Said_Daddy_Joe",
+	"EV_EG_Said_Dogs_Back",
+	"EV_EG_Said_Drummer",
+	"EV_EG_Said_Good_Job",
+	"EV_EG_Said_Howl",
+	"EV_EG_Said_Jeff_Motive",
+	"EV_EG_Said_Last_Time",
+	"EV_EG_Said_Newspaper",
+	"EV_EG_Said_No_Gold",
+	"EV_EG_Said_No_Waldo",
+	"EV_EG_Said_Pasta",
+	"EV_EG_Said_Pin",
+	"EV_EG_Said_Player",
+	"EV_EG_Said_Prints",
+	"EV_EG_Said_Red",
+	"EV_EG_Said_Sandpaper",
+	"EV_EG_Said_Squeaky",
+	"EV_EG_Said_Stack",
+	"EV_EG_Said_Test",
+	"EV_EG_Said_Tucker",
+	"EV_EG_Said_Viv_Picture",
+	"EV_EG_Said_Wells",
+	"EV_Emily_Chase01",
+	"EV_Emily_Chase02",
+	"EV_Emily_Chase03",
+	"EV_Emily_Chase04",
+	"EV_Emily_Chase05",
+	"EV_Emily_Chase06",
+	"EV_Emily_Chase07",
+	"EV_Emily_Chase08",
+	"EV_Emily_Chase09",
+	"EV_Emily_Chase10",
+	"EV_Emily_Chase11",
+	"EV_Emily_Chase12",
+	"EV_Emily_Chase13",
+	"EV_Emily_Chase14",
+	"EV_Emily_Chase15",
+	"EV_Emily_Chase16",
+	"EV_Emily_Chase17",
+	"EV_Emily_Chase18",
+	"EV_Emily_Chase19",
+	"EV_Emily_Chase20",
+	"EV_Fixed_Flashlight",
+	"EV_FJ_Said_Easy",
+	"EV_FJ_Said_Fortune",
+	"EV_FJ_Said_Grandfather",
+	"EV_FJ_Said_Habit",
+	"EV_FJ_Said_Inscriptions",
+	"EV_FJ_Said_Inside_Out",
+	"EV_FJ_Said_Motive",
+	"EV_FJ_Said_No_Running",
+	"EV_FJ_Said_No_See_Speakeasy",
+	"EV_FJ_Said_Nothing",
+	"EV_FJ_Said_Rain",
+	"EV_FJ_Said_Ranger",
+	"EV_FJ_Said_Sandwich",
+	"EV_FJ_Said_Smart_Perp",
+	"EV_Gave_Sample",
+	"EV_Gold_Grate_Open",
+	"EV_Heard_Bird1",
+	"EV_Heard_Bird2",
+	"EV_Heard_Bird3",
+	"EV_Heard_Bird4",
+	"EV_Heard_Bird5",
+	"EV_Heard_Bird6",
+	"EV_Heard_Squeaking",
+	"EV_Intake_Closed",
+	"EV_JA_Said_Apology",
+	"EV_JA_Said_Busy",
+	"EV_JA_Said_Care",
+	"EV_JA_Said_Cemetery",
+	"EV_JA_Said_Denies",
+	"EV_JA_Said_Diet",
+	"EV_JA_Said_Dog_Prob",
+	"EV_JA_Said_Dog_Run",
+	"EV_JA_Said_Dogs_Trained",
+	"EV_JA_Said_Emily_Motive",
+	"EV_JA_Said_Gang_Gone",
+	"EV_JA_Said_Gold_Rumor",
+	"EV_JA_Said_Grandfather",
+	"EV_JA_Said_Just_Dogs",
+	"EV_JA_Said_Kit",
+	"EV_JA_Said_Lie",
+	"EV_JA_Said_Litter",
+	"EV_JA_Said_Motive",
+	"EV_JA_Said_Museum",
+	"EV_JA_Said_Mystery",
+	"EV_JA_Said_Newspaper",
+	"EV_JA_Said_No_Gold",
+	"EV_JA_Said_No_Waldo",
+	"EV_JA_Said_Not",
+	"EV_JA_Said_Please",
+	"EV_JA_Said_PO",
+	"EV_JA_Said_Red_Motive",
+	"EV_JA_Said_Results",
+	"EV_JA_Said_Sample",
+	"EV_JA_Said_Son",
+	"EV_JA_Said_Speakeasy_Sealed",
+	"EV_JA_Said_Thanks",
+	"EV_JA_Said_Tourists",
+	"EV_JA_Said_Viv_Picture",
+	"EV_JA_Said_WA_Grandfather",
+	"EV_JA_Said_When_Arrested",
+	"EV_JA_Said_Will_Do",
+	"EV_JA_Said_Yogi",
+	"EV_JA_Said_Yogi_Innocent",
+	"EV_Jeff_Discovers_Vivian",
+	"EV_Left_Msg01",
+	"EV_Mailed_Letter",
+	"EV_Map_Marked_L",
+	"EV_Map_Marked_V",
+	"EV_Map_Marked_X",
+	"EV_Met_BG",
+	"EV_Met_EG_Shop",
+	"EV_Met_Eustacia",
+	"EV_Met_FJ",
+	"EV_Met_JA",
+	"EV_Met_RKB",
+	"EV_Met_RKF",
+	"EV_Met_Sally",
+	"EV_Met_Vivian",
+	"EV_Missed_Bait01",
+	"EV_Missed_Bait02",
+	"EV_Missed_Bait03",
+	"EV_Missed_Bait04",
+	"EV_Missed_Bait05",
+	"EV_Missed_Bait06",
+	"EV_Missed_Cardinal",
+	"EV_Missed_Goldfinch",
+	"EV_Missed_Jay",
+	"EV_Missed_Robin",
+	"EV_Missed_Tanager",
+	"EV_Night",
+	"EV_Night_Needed",
+	"EV_Placed_Bucket",
+	"EV_Placed_Screw_As_Peg",
+	"EV_Placed_Wheel",
+	"EV_Placed_Wheel_Drain",
+	"EV_Placed_Wheel_Gold",
+	"EV_Red_Said_Ran_Out",
+	"EV_Red_Said_Test",
+	"EV_Red_Said_Thanks",
+	"EV_Red_Took_Spark1",
+	"EV_Red_Took_Spark2",
+	"EV_Red_Took_Spark3",
+	"EV_RK_Available",
+	"EV_RK_Said_Attacked_House",
+	"EV_RK_Said_Bucket",
+	"EV_RK_Said_Early",
+	"EV_RK_Said_Forget01",
+	"EV_RK_Said_Forget02",
+	"EV_RK_Said_Muffs",
+	"EV_RK_Said_No_Gold",
+	"EV_RK_Said_Old_Map",
+	"EV_RK_Said_Quid",
+	"EV_RK_Said_Ruth",
+	"EV_RK_Said_Sally_Attacked",
+	"EV_RK_Said_Sandpaper",
+	"EV_RK_Said_Scares_Birds",
+	"EV_RK_Said_Test",
+	"EV_Said_Comment01",
+	"EV_Said_Comment02",
+	"EV_Said_Comment03",
+	"EV_Said_Comment04",
+	"EV_Said_Comment05",
+	"EV_Said_Comment06",
+	"EV_Said_Comment07",
+	"EV_Said_Comment08",
+	"EV_Said_Comment09",
+	"EV_Said_Comment10",
+	"EV_Said_Comment11",
+	"EV_Said_Comment12",
+	"EV_Said_Comment13",
+	"EV_Said_Comment14",
+	"EV_Said_Comment15",
+	"EV_Said_Comment16",
+	"EV_Said_Comment17",
+	"EV_Said_Comment18",
+	"EV_Said_Comment19",
+	"EV_Said_Comment20",
+	"EV_Said_Engine",
+	"EV_Sally_Said_Kit",
+	"EV_Sally_Said_Tasks",
+	"EV_Sample_Time1",
+	"EV_Sample_Time2",
+	"EV_Saw_Archive_Lucy",
+	"EV_Saw_Archive_Waldo",
+	"EV_Saw_Article_Lucy",
+	"EV_Saw_Cemetery",
+	"EV_Saw_Clock",
+	"EV_Saw_Dog_Iggy",
+	"EV_Saw_Dog_Levers",
+	"EV_Saw_Dog_Lucy",
+	"EV_Saw_Dog_Vitus",
+	"EV_Saw_Dog_Xander_Bad",
+	"EV_Saw_Dog_Xander_Good",
+	"EV_Saw_Dredge_Law",
+	"EV_Saw_Five_Birds",
+	"EV_Saw_Flashlight_Die",
+	"EV_Saw_Ghost_Cine1",
+	"EV_Saw_Gold_Bar_Story",
+	"EV_Saw_Hawk",
+	"EV_Saw_Hidden_Door",
+	"EV_Saw_Malone_Arrest",
+	"EV_Saw_Newspaper_Malone",
+	"EV_Saw_Newspaper_WA",
+	"EV_Saw_Poem",
+	"EV_Saw_Prime_Info",
+	"EV_Saw_Prints",
+	"EV_Saw_Safe",
+	"EV_Saw_Spark_Gone",
+	"EV_Saw_Speakeasy",
+	"EV_Saw_Speakers",
+	"EV_Saw_Squeak_Note",
+	"EV_Saw_Tomb_Dogs",
+	"EV_Saw_Tomb_Lock",
+	"EV_Saw_Tomb_Malone",
+	"EV_Saw_Tomb_Waldo",
+	"EV_Saw_Tool_Shed",
+	"EV_Saw_WA_Journal",
+	"EV_Saw_Water_Note",
+	"EV_Saw_Yogi",
+	"EV_Screw1_Minus",
+	"EV_Screw1_Out",
+	"EV_Screw1_Plus",
+	"EV_Screw1_Zero",
+	"EV_Screw2_Minus",
+	"EV_Screw2_Out",
+	"EV_Screw2_Plus",
+	"EV_Screw2_Zero",
+	"EV_Screw3_Minus",
+	"EV_Screw3_Out",
+	"EV_Screw3_Plus",
+	"EV_Screw3_Zero",
+	"EV_Screw4_Minus",
+	"EV_Screw4_Out",
+	"EV_Screw4_Plus",
+	"EV_Screw4_Zero",
+	"EV_ScrewLoose0",
+	"EV_ScrewLoose1",
+	"EV_ScrewLoose2",
+	"EV_ScrewLoose3",
+	"EV_ScrewLoose4",
+	"EV_ScrewLoose5",
+	"EV_Sent_Photo",
+	"EV_Shed_Fire_Near_Bug",
+	"EV_Shed_Fire_Pos01",
+	"EV_Shed_Fire_Pos02",
+	"EV_Shed_Fire_Pos03",
+	"EV_Shed_Fire_Pos04",
+	"EV_Shed_Fire_Pos05",
+	"EV_Shed_Fire_PosA",
+	"EV_Shed_Fire_PosB",
+	"EV_Shed_Fire_PosC",
+	"EV_Shed_Fire_PosD",
+	"EV_Shed_Gnome_Land",
+	"EV_Shed_Gnome_Move",
+	"EV_Shed_Jack_Pos01",
+	"EV_Shed_Jack_Pos02",
+	"EV_Shed_Jack_Pos03",
+	"EV_Shed_Lost",
+	"EV_Shed_Rake_Fire",
+	"EV_Shed_Rake_Move",
+	"EV_Shed_Twine_Fire",
+	"EV_SM_Said_Arsenic",
+	"EV_SM_Said_Break",
+	"EV_SM_Said_Cemetery",
+	"EV_SM_Said_Dog_Levers",
+	"EV_SM_Said_Dread",
+	"EV_SM_Said_EG_Irks",
+	"EV_SM_Said_Ex",
+	"EV_SM_Said_Flashlight",
+	"EV_SM_Said_JA_Dislikes",
+	"EV_SM_Said_Joke",
+	"EV_SM_Said_Kit",
+	"EV_SM_Said_Name",
+	"EV_SM_Said_No_Plug",
+	"EV_SM_Said_No_Sandpaper",
+	"EV_SM_Said_Outdoor",
+	"EV_SM_Said_Prime",
+	"EV_SM_Said_Red",
+	"EV_SM_Said_RK",
+	"EV_SM_Said_See_EG",
+	"EV_SM_Said_Speakeasy",
+	"EV_SM_Said_Tasks",
+	"EV_SM_Said_Three",
+	"EV_SM_Said_Tool_Shed",
+	"EV_Sneezed",
+	"EV_Solved_Bail",
+	"EV_Solved_Bait",
+	"EV_Solved_Birds",
+	"EV_Solved_Board01",
+	"EV_Solved_Board02",
+	"EV_Solved_Board03",
+	"EV_Solved_Boards",
+	"EV_Solved_Cardinal",
+	"EV_Solved_Cassette",
+	"EV_Solved_Dog_Levers",
+	"EV_Solved_Fire",
+	"EV_Solved_Floor",
+	"EV_Solved_Gold_Door",
+	"EV_Solved_Goldfinch",
+	"EV_Solved_Hawk",
+	"EV_Solved_Historical",
+	"EV_Solved_Jay",
+	"EV_Solved_Prime",
+	"EV_Solved_Robin",
+	"EV_Solved_Roman",
+	"EV_Solved_Safe",
+	"EV_Solved_Screws",
+	"EV_Solved_Shed_Escape",
+	"EV_Solved_Spark",
+	"EV_Solved_Spigot",
+	"EV_Solved_Spigot_Switch",
+	"EV_Solved_Stack",
+	"EV_Solved_Tanager",
+	"EV_Solved_Tomb",
+	"EV_Solved_Tomb_Lock",
+	"EV_Solved_Toolbox",
+	"EV_Solved_Tumbler",
+	"EV_Solved_Water_Sample",
+	"EV_Took_Board01",
+	"EV_Took_Board02",
+	"EV_Took_Board03",
+	"EV_Took_Bucket",
+	"EV_Took_Camo",
+	"EV_Took_Package",
+	"EV_Took_Screwdriver",
+	"EV_Took_Spark",
+	"EV_Took_Tape",
+	"EV_Took_Toolbox_Key",
+	"EV_Took_Viv_Photo",
+	"EV_Took_Wheel",
+	"EV_TookBait01",
+	"EV_TookBait02",
+	"EV_TookBait03",
+	"EV_TookBait04",
+	"EV_TookBait05",
+	"EV_TookBait06",
+	"EV_TookBait07",
+	"EV_TookBait08",
+	"EV_TookBait09",
+	"EV_TookBait10",
+	"EV_TookBait11",
+	"EV_TookBait12",
+	"EV_Tool_Shed_Fire",
+	"EV_Tree_Block1",
+	"EV_Tried_Bail",
+	"EV_Tried_Bird_Task",
+	"EV_Tried_Engine",
+	"EV_Tried_Floor",
+	"EV_Tried_Historical",
+	"EV_Tried_Levers",
+	"EV_Tried_Pump",
+	"EV_Tried_Roman",
+	"EV_Tried_Safe",
+	"EV_Tried_Screws",
+	"EV_Tried_Spark",
+	"EV_Tried_Spigot",
+	"EV_Tried_Spigot_Switch",
+	"EV_Tried_Stack",
+	"EV_Tried_Tomb",
+	"EV_Tried_Tomb_Lock",
+	"EV_Tried_Toolbox",
+	"EV_Tried_Tumbler",
+	"EV_Viv_Package_Available",
+	"EV_Viv_Said_Baldo",
+	"EV_Viv_Said_Cruise",
+	"EV_Viv_Said_EA_Hi",
+	"EV_Viv_Said_Gold",
+	"EV_Viv_Said_Iggy",
+	"EV_Viv_Said_Lucy_Boat",
+	"EV_Viv_Said_Map",
+	"EV_Viv_Said_Mathias",
+	"EV_Viv_Said_Paintings",
+	"EV_Viv_Said_Send_Key",
+	"EV_Viv_Said_Speakeasy",
+	"EV_Viv_Said_Superstitious",
+	"EV_Viv_Said_Tomb_Lock",
+	"EV_Viv_Said_Trusted",
+	"EV_Viv_Said_Tunnels",
+	"EV_Viv_Said_Unlucky",
+	"EV_Viv_Said_Vitus_Tree",
+	"EV_Viv_Said_Willy",
+	"EV_Viv_Said_Willy_Safe",
+	"EV_Viv_Said_Xander",
+	"EV_VW_Said_Send_Photo",
+	"EV_Well_Door_Unlocked",
+	"EV_Well_Empty",
+	"EV_Wheels_Unlocked",
+	"EV_Yogi_Available",
+	"EV_Skip1",
+	"EV_Skip2",
+	"EV_Skip3",
+	"EV_Skip4",
+	"EV_Skip5",
+	"EV_Skip6",
+	"EV_Empty1",
+	"EV_Empty2",
+	"EV_Empty3",
+	"EV_Empty4",
+	"EV_Empty5",
+	"EV_Empty6",
+	"EV_Empty7",
+	"EV_Empty8",
+	"EV_Empty9",
+	"EV_Empty10",
+	"EV_Empty11",
+	"EV_Empty12",
+	"EV_Empty13",
+	"EV_Empty14",
+	"EV_Empty15",
+	"EV_Empty16",
+	"EV_Empty17",
+	"EV_Empty18",
+	"EV_Empty19",
+	"EV_Empty20",
+	"EV_Empty21",
+	"EV_Empty22",
+	"EV_Empty23",
+	"EV_Empty24",
+	"EV_Empty25",
+	"EV_Empty26",
+	"EV_Empty27",
+	"EV_Empty28",
+	"EV_Empty29",
+	"EV_Empty30",
+	"EV_Empty31",
+	"EV_Empty32",
+	"EV_Empty33",
+	"EV_Empty34",
+	"EV_Empty35",
+	"EV_Empty36",
+	"EV_Empty37",
+	"EV_Empty38",
+	"EV_Empty39",
+	"EV_Empty40",
+	"EV_Empty41",
+	"EV_Empty42",
+	"EV_Empty43",
+	"EV_Empty44",
+	"EV_Empty45",
+	"EV_Empty46",
+	"EV_Empty47",
+	"EV_Empty48",
+	"EV_Empty49",
+	"EV_Empty50",
+	"EV_Empty51",
+	"EV_Empty52",
+	"EV_Empty53",
+	"EV_Empty54",
+	"EV_Empty55",
+	"EV_Empty56",
+	"EV_Empty57",
+	"EV_Empty58",
+	"EV_Empty59",
+	"EV_Empty60",
+	"EV_Empty61",
+	"EV_Empty62",
+	"EV_Empty63",
+	"EV_Empty64",
+	"EV_Empty65",
+	"EV_Empty66",
+	"EV_Empty67",
+	"EV_Empty68",
+	"EV_Empty69",
+	"EV_Empty70",
+	"EV_Empty71",
+	"EV_Empty72",
+	"EV_Empty73",
+	"EV_Empty74",
+	"EV_Empty75"
+};
+
+#endif // NANCY7DATA_H


Commit: a4e7dfee97e9848c07fae34fa0c2e6ce6d5fe8f6
    https://github.com/scummvm/scummvm/commit/a4e7dfee97e9848c07fae34fa0c2e6ce6d5fe8f6
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:30+03:00

Commit Message:
NANCY: Block SoundManager from creating Scene state

Added a check inside SoundManager that makes sure it
doesn't prematurely create a new Scene state. This fixes
the chain reaction that results in the load/save menu having
clickable Save buttons.

Changed paths:
    engines/nancy/sound.cpp


diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index b348387ced1..a8c4adda1ad 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -759,7 +759,8 @@ void SoundManager::soundEffectMaintenance(uint16 channelID, bool force) {
 	}
 
 	// Check if the player has moved OR if the sound itself has moved, OR, if we're still interpolating
-	if (!_shouldRecalculate && !hasStepped && _positionLerp == 0) {
+	// Also, make sure we don't accidentally create a Scene state during game startup
+	if (!State::Scene::hasInstance() || (!_shouldRecalculate && !hasStepped && _positionLerp == 0)) {
 		return;
 	}
 	


Commit: ea1d0d2a5ce2ff8d51eae2582643fd05ae17524b
    https://github.com/scummvm/scummvm/commit/ea1d0d2a5ce2ff8d51eae2582643fd05ae17524b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:30+03:00

Commit Message:
NANCY: Init sound listener vector in conditional dialogue

Added default sound vectors for all conditional dialogue
and goodbyes. This _probably_ doesn't affect much, but
is still good to have.

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


diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index bf3de91a32f..a7748341dc5 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -347,6 +347,7 @@ void ConversationSound::addConditionalDialogue() {
 			
 			newResponse.sceneChange.sceneID = res.sceneID;
 			newResponse.sceneChange.continueSceneSound = kContinueSceneSound;
+			newResponse.sceneChange.listenerFrontVector.set(0, 0, 1);
 
 			// Check if the response is a repeat. This can happen when multiple condition combinations
 			// trigger the same response.
@@ -429,12 +430,12 @@ void ConversationSound::addGoodbye() {
 
 	// The reply from the character is picked randomly
 	newResponse.sceneChange.sceneID = sceneChange.sceneIDs[g_nancy->_randomSource->getRandomNumber(sceneChange.sceneIDs.size() - 1)];
+	newResponse.sceneChange.continueSceneSound = kContinueSceneSound;
+	newResponse.sceneChange.listenerFrontVector.set(0, 0, 1);
 
 	// Set an event flag if applicable
 	// Assumes flagToSet is an event flag
 	NancySceneState.setEventFlag(sceneChange.flagToSet.label, sceneChange.flagToSet.flag);
-
-	newResponse.sceneChange.continueSceneSound = kContinueSceneSound;
 }
 
 void ConversationSound::ConversationFlag::read(Common::SeekableReadStream &stream) {


Commit: 5ecfef2a2eee3d81af202b64a553a3e14d9d6cff
    https://github.com/scummvm/scummvm/commit/5ecfef2a2eee3d81af202b64a553a3e14d9d6cff
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:31+03:00

Commit Message:
NANCY: Add support for TSUM chunks

Added support for the short variant of a scene summary,
as introduced in nancy7.

Changed paths:
    engines/nancy/commontypes.h
    engines/nancy/state/scene.cpp
    engines/nancy/state/scene.h
    engines/nancy/ui/viewport.h


diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 5528fd0ec60..8f204114ae4 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -63,6 +63,11 @@ static const byte kFlagEvent						= 1;
 static const byte kFlagInventory					= 2;
 static const byte kFlagCursor						= 3;
 
+// Scene panning
+static const byte kPanNone							= 0;
+static const byte kPan360							= 1;
+static const byte kPanLeftRight						= 2;
+
 // Scene sound flags
 static const byte kContinueSceneSound				= 1;
 static const byte kLoadSceneSound					= 0;
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 2ed63f6ca0d..87d6283d835 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -100,6 +100,18 @@ void Scene::SceneSummary::read(Common::SeekableReadStream &stream) {
 	delete[] buf;
 }
 
+void Scene::SceneSummary::readTerse(Common::SeekableReadStream &stream) {
+	char *buf = new char[0x32];
+	stream.read(buf, 0x32);
+	description = buf;
+	readFilename(stream, videoFile);
+	readFilename(stream, sound.name);
+	sound.channelID = stream.readUint16LE();
+	sound.numLoops = stream.readUint32LE();
+	sound.volume = stream.readUint16LE();
+	stream.skip(2);
+}
+
 Scene::Scene() :
 		_state (kInit),
 		_lastHintCharacter(-1),
@@ -802,13 +814,19 @@ void Scene::load() {
 	}
 
 	Common::SeekableReadStream *sceneSummaryChunk = sceneIFF.getChunkStream("SSUM");
+	if (sceneSummaryChunk) {
+		_sceneState.summary.read(*sceneSummaryChunk);
+	} else {
+		sceneSummaryChunk = sceneIFF.getChunkStream("TSUM");
+		if (sceneSummaryChunk) {
+			_sceneState.summary.readTerse(*sceneSummaryChunk);
+		}
+	}
 
 	if (!sceneSummaryChunk) {
 		error("Invalid IFF Chunk SSUM");
 	}
 
-	_sceneState.summary.read(*sceneSummaryChunk);
-
 	delete sceneSummaryChunk;
 
 	debugC(0, kDebugScene, "Loading new scene %i: description \"%s\", frame %i, vertical scroll %i, %s",
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 363b6dec8b2..94b19bf9589 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -85,30 +85,32 @@ public:
 		kMap = 1 << 6
 	};
 
-	struct SceneSummary { // SSUM
+	struct SceneSummary {
+		// SSUM and TSUM
+		// Default values set to match those applied when loading from a TSUM chunk
 		Common::String description;
 		Common::String videoFile;
 		
-		uint16 videoFormat;
+		uint16 videoFormat = kLargeVideoFormat;
 		Common::Array<Common::String> palettes;
-		Common::String audioFile;
 		SoundDescription sound;
 		
-		byte panningType;
-		uint16 numberOfVideoFrames;
-		uint16 degreesPerRotation;
-		uint16 totalViewAngle;
-		uint16 horizontalScrollDelta;
-		uint16 verticalScrollDelta;
-		uint16 horizontalEdgeSize;
-		uint16 verticalEdgeSize;
-		Time slowMoveTimeDelta;
-		Time fastMoveTimeDelta;
+		byte panningType = kPan360;
+		uint16 numberOfVideoFrames = 0;
+		uint16 degreesPerRotation = 18;
+		uint16 totalViewAngle = 0;
+		uint16 horizontalScrollDelta = 1;
+		uint16 verticalScrollDelta = 10;
+		uint16 horizontalEdgeSize = 15;
+		uint16 verticalEdgeSize = 15;
+		Time slowMoveTimeDelta = 400;
+		Time fastMoveTimeDelta = 66;
 		
 		// Sound start vectors, used in nancy3 and up
 		Math::Vector3d listenerPosition;
 
 		void read(Common::SeekableReadStream &stream);
+		void readTerse(Common::SeekableReadStream &stream);
 	};
 
 	Scene();
diff --git a/engines/nancy/ui/viewport.h b/engines/nancy/ui/viewport.h
index 9dec16f17ca..a8373630f18 100644
--- a/engines/nancy/ui/viewport.h
+++ b/engines/nancy/ui/viewport.h
@@ -40,10 +40,6 @@ namespace UI {
 
 class Viewport : public Nancy::RenderObject {
 public:
-	static const byte kPanNone		= 0;
-	static const byte kPan360		= 1;
-	static const byte kPanLeftRight	= 2;
-
 	Viewport() :
 		RenderObject(6),
 		_movementLastFrame(0),


Commit: 7e6d37276bc1d6df0d0c9ed62279c0d434bbd9c7
    https://github.com/scummvm/scummvm/commit/7e6d37276bc1d6df0d0c9ed62279c0d434bbd9c7
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:31+03:00

Commit Message:
NANCY: Add support for nancy7's "More Nancy Drew!"

Made changes to BSUM reading, MainMenu and Scene states
needed to support the promo button in nancy7's main menu.

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


diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 56a9c85d1f1..9defb007242 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -685,8 +685,9 @@ bool NancyConsole::Cmd_scanForActionRecordType(int argc, const char **argv) {
 	}
 
 	Common::Array<Common::String> list;
-	// Action records only appear in the ciftree
+	// Action records only appear in the ciftree and promotree
 	g_nancy->_resource->list("ciftree", list, ResourceManager::kResTypeScript);
+	g_nancy->_resource->list("promotree", list, ResourceManager::kResTypeScript);
 
 	char descBuf[0x30];
 
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 36ccc7febc3..6cfcb3ce6ab 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -54,6 +54,10 @@ BSUM::BSUM(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
 	s.syncAsUint16LE(startTimeHours);
 	s.syncAsUint16LE(startTimeMinutes);
 
+	s.syncAsUint16LE(adScene.sceneID, kGameTypeNancy7);
+	s.syncAsUint16LE(adScene.frameID, kGameTypeNancy7);
+	s.syncAsUint16LE(adScene.verticalOffset, kGameTypeNancy7);
+
 	s.skip(0xA4, kGameTypeVampire, kGameTypeNancy2);
 	s.skip(3); // Number of object, frame, and logo images
 	if (g_nancy->getGameFlags() & GF_PLG_BYTE_IN_BSUM) {
@@ -369,7 +373,7 @@ MENU::MENU(Common::SeekableReadStream *chunkStream) : EngineData(chunkStream) {
 
 	ser.skip(22);
 
-	uint numOptions = 8;
+	uint numOptions = g_nancy->getGameType() <= kGameTypeNancy6 ? 8 : 9;
 
 	readRectArray16(ser, _buttonDests, numOptions, numOptions, kGameTypeVampire, kGameTypeNancy1);
 	readRectArray16(ser, _buttonDownSrcs, numOptions, numOptions, kGameTypeVampire, kGameTypeNancy1);
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index 22c2a0a7576..84b255b87c3 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -47,6 +47,9 @@ struct BSUM : public EngineData {
 	uint16 startTimeHours;
 	uint16 startTimeMinutes;
 
+	// More Nancy Drew! scene
+	SceneChangeDescription adScene;
+
 	// UI
 	Common::Rect extraButtonHotspot;	// Extra button is map in tvd, clock in nancy2 and up
 	Common::Rect extraButtonHighlightDest;
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 7d86c96dd8b..b35465b30e2 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -126,7 +126,8 @@ bool NancyEngine::canSaveGameStateCurrently() {
 	// TODO also disable during secondary movie
 	return State::Scene::hasInstance() &&
 			NancySceneState._state == State::Scene::kRun &&
-			NancySceneState.getActiveConversation() == nullptr;
+			NancySceneState.getActiveConversation() == nullptr &&
+			!NancySceneState.isRunningAd();
 }
 
 void NancyEngine::secondChance() {
diff --git a/engines/nancy/resource.cpp b/engines/nancy/resource.cpp
index 50e97c7547e..720e4bc06f7 100644
--- a/engines/nancy/resource.cpp
+++ b/engines/nancy/resource.cpp
@@ -631,6 +631,10 @@ void ResourceManager::initialize() {
 	if (g_nancy->getGameType() != kGameTypeVampire) {
 		loadCifTree("ciftree", "dat");
 	}
+
+	if (g_nancy->getGameType() >= kGameTypeNancy7) {
+		loadCifTree("promotree", "dat");
+	}
 }
 
 bool ResourceManager::getCifInfo(const Common::String &name, CifInfo &info) const {
diff --git a/engines/nancy/state/mainmenu.cpp b/engines/nancy/state/mainmenu.cpp
index 4cde537e4b5..0e05748bbbd 100644
--- a/engines/nancy/state/mainmenu.cpp
+++ b/engines/nancy/state/mainmenu.cpp
@@ -113,6 +113,11 @@ void MainMenu::init() {
 	// Perhaps could be enabled always, and just load the latest save?
 	if (!Scene::hasInstance()) {
 		_buttons[3]->setDisabled(true);
+	} else {
+		if (NancySceneState.isRunningAd() && ConfMan.hasKey("restore_after_ad", ConfMan.kTransientDomain)) {
+			// Force immediate load of second chance save, if we need to restore the game that was running
+			g_nancy->loadGameState(g_nancy->getMetaEngine()->getMaximumSaveSlot());
+		}
 	}
 
 	_state = kRun;
@@ -233,6 +238,18 @@ void MainMenu::stop() {
 		// Help
 		g_nancy->setState(NancyState::kHelp);
 		break;
+	case 8:
+		// More Nancy Drew!
+		if (Scene::hasInstance()) {
+			// The second chance slot is used as temporary save
+			g_nancy->secondChance();
+			NancySceneState.destroy();
+			ConfMan.setBool("restore_after_ad", true, ConfMan.kTransientDomain);
+		}
+
+		ConfMan.setBool("load_ad", true, ConfMan.kTransientDomain);
+		g_nancy->setState(NancyState::kScene);
+		break;
 	}
 }
 
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 87d6283d835..9ff039d7be1 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -132,6 +132,7 @@ Scene::Scene() :
 		_activeConversation(nullptr),
 		_lightning(nullptr),
 		_destroyOnExit(false),
+		_isRunningAd(false),
 		_hotspotDebug(50) {}
 
 Scene::~Scene()  {
@@ -699,6 +700,9 @@ void Scene::synchronize(Common::Serializer &ser) {
 		}
 	}
 
+	_isRunningAd = false;
+	ConfMan.removeKey("restore_after_ad", ConfMan.kTransientDomain);
+
 	g_nancy->_graphicsManager->suppressNextDraw();
 }
 
@@ -725,7 +729,13 @@ void Scene::init() {
 	_timers.playerTimeNextMinute = 0;
 	_timers.pushedPlayTime = 0;
 
-	changeScene(bootSummary->firstScene);
+	if (ConfMan.hasKey("load_ad", ConfMan.kTransientDomain)) {
+		changeScene(bootSummary->adScene);
+		ConfMan.removeKey("load_ad", ConfMan.kTransientDomain);
+		_isRunningAd = true;
+	} else {
+		changeScene(bootSummary->firstScene);
+	}
 
 	if (hintData) {
 		_hintsRemaining.clear();
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 94b19bf9589..4c911dda345 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -124,6 +124,8 @@ public:
 	// Used when winning/losing game
 	void setDestroyOnExit() { _destroyOnExit = true; }
 
+	bool isRunningAd() { return _isRunningAd; }
+
 	void changeScene(const SceneChangeDescription &sceneDescription);
 	void pushScene();
 	void popScene();
@@ -295,6 +297,7 @@ private:
 	RenderObject _hotspotDebug;
 
 	bool _destroyOnExit;
+	bool _isRunningAd;
 
 	State _state;
 };


Commit: 7aae7ec661abfdb51a3f06da2deaba0ce21b1072
    https://github.com/scummvm/scummvm/commit/7aae7ec661abfdb51a3f06da2deaba0ce21b1072
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:31+03:00

Commit Message:
NANCY: Implement GotoMenu

Added support for an action record that boots the player
to the main menu.

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


diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 7fd617dea69..e5ca8641ff7 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -174,7 +174,11 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
 	case 107:
 		return new EventFlags();
 	case 108:
-		return new OrderingPuzzle(OrderingPuzzle::kOrdering);
+		if (g_nancy->getGameType() <= kGameTypeNancy6) {
+			return new OrderingPuzzle(OrderingPuzzle::kOrdering);
+		} else {
+			return new GotoMenu();
+		}
 	case 109:
 		return new LoseGame();
 	case 110:
@@ -195,6 +199,12 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
 		return new SliderPuzzle();
 	case 118:
 		return new PasswordPuzzle();
+	case 119:
+		if (g_nancy->getGameType() >= kGameTypeNancy7) {
+			// This got moved in nancy7
+			return new OrderingPuzzle(OrderingPuzzle::kOrdering);
+		}
+		return nullptr;
 	case 120:
 		return new AddInventoryNoHS();
 	case 121:
diff --git a/engines/nancy/action/miscrecords.cpp b/engines/nancy/action/miscrecords.cpp
index 831565cc0d3..d5df596b3ab 100644
--- a/engines/nancy/action/miscrecords.cpp
+++ b/engines/nancy/action/miscrecords.cpp
@@ -308,6 +308,23 @@ void EventFlagsMultiHS::execute() {
 	}
 }
 
+void GotoMenu::readData(Common::SeekableReadStream &stream) {
+	stream.skip(1);
+}
+
+void GotoMenu::execute() {
+	if (!ConfMan.hasKey("original_menus") || ConfMan.getBool("original_menus")) {
+		g_nancy->setState(NancyState::kMainMenu);
+	} else {
+		Common::Event ev;
+		ev.type = Common::EVENT_RETURN_TO_LAUNCHER;
+		g_system->getEventManager()->pushEvent(ev);
+	}
+
+	_isDone = true;
+}
+
+
 void LoseGame::readData(Common::SeekableReadStream &stream) {
 	stream.skip(1);
 }
diff --git a/engines/nancy/action/miscrecords.h b/engines/nancy/action/miscrecords.h
index 00793052e20..cd0dc23f0db 100644
--- a/engines/nancy/action/miscrecords.h
+++ b/engines/nancy/action/miscrecords.h
@@ -231,6 +231,16 @@ protected:
 	Common::String getRecordTypeName() const override { return _isCursor ? "EventFlagsCursorHS" : "EventFlagsMultiHS"; }
 };
 
+// Returns the player back to the main menu
+class GotoMenu : public ActionRecord {
+public:
+	void readData(Common::SeekableReadStream &stream) override;
+	void execute() override;
+
+protected:
+	Common::String getRecordTypeName() const override { return "GotoMenu"; }
+};
+
 // Stops the game and boots the player back to the Menu screen, while also making sure
 // they can't Continue. The devs took care to add Second Chance saves before every one
 // of these, to make sure the player can return to a state just before the dangerous part.


Commit: 73b66c60f873e80f327ddafb052d07bc8da79615
    https://github.com/scummvm/scummvm/commit/73b66c60f873e80f327ddafb052d07bc8da79615
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-10-02T12:19:31+03:00

Commit Message:
BACKENDS: WII: Always retain cursor palette

Calling setMouseCursor with a non-palette cursor no longer
clears the cursor palette, allowing a subsequent call with a
paletted cursor to re-use it. This fixes Trac defect #13895.
The approach taken was to just copy what the OpenGL
backend was doing in the same situation.

Changed paths:
    backends/platform/wii/osystem_gfx.cpp


diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp
index 4c32bf7d000..bc5c10b1688 100644
--- a/backends/platform/wii/osystem_gfx.cpp
+++ b/backends/platform/wii/osystem_gfx.cpp
@@ -334,8 +334,13 @@ void OSystem_Wii::updateMousePalette() {
 	printf("%s() _cursorPaletteDisabled:%d\n", __func__, _cursorPaletteDisabled);
 #endif
 
-	if (_texMouse.palette && _cursorPaletteDisabled) {
-		memcpy(_texMouse.palette, _cursorPalette, 256 * 2);
+	if (_texMouse.palette) {
+		if (!_cursorPaletteDisabled) {
+			memcpy(_texMouse.palette, _cursorPalette, 256 * 2);
+		} else {
+			memcpy(_texMouse.palette, _texGame.palette, 256 * 2);
+		}
+
 		_cursorPaletteDirty = true;
 	}
 }
@@ -357,20 +362,7 @@ void OSystem_Wii::setPalette(const byte *colors, uint start, uint num) {
 
 	gfx_tex_flush_palette(&_texGame);
 
-	s = colors;
-	d = _cursorPalette;
-
-	for (uint i = 0; i < num; ++i, s += 3) {
-		d[start + i] = _pfRGB3444.ARGBToColor(0xff, s[0], s[1], s[2]);
-	}
-
-	if (_cursorPaletteDisabled) {
-		assert(_texMouse.palette);
-
-		memcpy((u8 *)_texMouse.palette + start * 2, (u8 *)_cursorPalette + start * 2, num * 2);
-
-		_cursorPaletteDirty = true;
-	}
+	updateMousePalette();
 }
 
 void OSystem_Wii::grabPalette(byte *colors, uint start, uint num) const {
@@ -407,18 +399,16 @@ void OSystem_Wii::setCursorPalette(const byte *colors, uint start, uint num) {
 		gfx_tex_set_bilinear_filter(&_texMouse, _bilinearFilter);
 	}
 
-	if (_cursorPaletteDisabled) {
-		memcpy(_cursorPalette, _texMouse.palette, 256 * 2);
-		_cursorPaletteDisabled = false;
-	}
+	_cursorPaletteDisabled = false;
 
 	const byte *s = colors;
-	u16 *d = _texMouse.palette;
+	u16 *d = _cursorPalette;
 
-	for (uint i = 0; i < num; ++i, s += 3)
+	for (uint i = 0; i < num; ++i, s += 3) {
 		d[start + i] = _pfRGB3444.ARGBToColor(0xff, s[0], s[1], s[2]);
+	}
 
-	_cursorPaletteDirty = true;
+	updateMousePalette();
 }
 
 void OSystem_Wii::copyRectToScreen(const void *buf, int pitch, int x, int y,
@@ -788,6 +778,6 @@ void OSystem_Wii::setMouseCursor(const void *buf, uint w, uint h, int hotspotX,
 	_mouseHotspotY = hotspotY;
 	_cursorDontScale = dontScale;
 
-	if ((_texMouse.palette) && (oldKeycolor != _mouseKeyColor))
-		_cursorPaletteDirty = true;
+	if (_pfCursor.bytesPerPixel == 1 && oldKeycolor != _mouseKeyColor)
+		updateMousePalette();
 }




More information about the Scummvm-git-logs mailing list