[Scummvm-git-logs] scummvm master -> 53f8b4efa4b78a671c1a37e3b84ae8715dcbb989
fracturehill
noreply at scummvm.org
Wed May 10 13:59:35 UTC 2023
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
0919ee559f NANCY: Implement scene counts
95f4158697 NANCY: Implement kSound dependency
cb23c11061 NANCY: Fix kElapsedPlayerTime dependency
130209f89d NANCY: Implement nancy3 dependency tree
3a39e75388 NANCY: Correct reading of filenames in nancy3
685eccf1c2 NANCY: Separate SoundDescription reading functions
150d0d5c6b NANCY: Improve reading of nancy3 files
dff9cbe272 NANCY: Use correct values for nancy3's flags
15afae7277 NANCY: Add detection for Russian nancy 3/4 variants
53f8b4efa4 DEVTOOLS: Add nancy3 data to create_nancy
Commit: 0919ee559f74b77c3dda0c361827f8a89cb420cb
https://github.com/scummvm/scummvm/commit/0919ee559f74b77c3dda0c361827f8a89cb420cb
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:31+03:00
Commit Message:
NANCY: Implement scene counts
The counters for how many times each scene has been hit
now actually work, instead of always being 0. The data type
storing them has been changed to a HashMap to save
on memory.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/state/scene.cpp
engines/nancy/state/scene.h
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 84abe63d7b2..6851fd9e837 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -238,24 +238,26 @@ void ActionManager::processActionRecords() {
}
break;
- case DependencyType::kSceneCount:
+ case DependencyType::kSceneCount: {
+ // Check how many times a scene has been visited.
// This dependency type keeps its data in the time variables
- // Also, I'm pretty sure it never gets used
+ int count = NancySceneState._flags.sceneCounts.contains(dep.hours) ?
+ NancySceneState._flags.sceneCounts[dep.hours] : 0;
switch (dep.milliseconds) {
case 1:
- if (dep.seconds < NancySceneState._flags.sceneHitCount[dep.hours]) {
+ if (dep.seconds < count) {
dep.satisfied = true;
}
break;
case 2:
- if (dep.seconds > NancySceneState._flags.sceneHitCount[dep.hours]) {
+ if (dep.seconds > count) {
dep.satisfied = true;
}
break;
case 3:
- if (dep.seconds == NancySceneState._flags.sceneHitCount[dep.hours]) {
+ if (dep.seconds == count) {
dep.satisfied = true;
}
@@ -263,6 +265,7 @@ void ActionManager::processActionRecords() {
}
break;
+ }
case DependencyType::kElapsedPlayerDay:
if (record->_days == -1) {
record->_days = NancySceneState._timers.playerTime.getDays();
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index f1ef5a129e7..aeae4841845 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -486,7 +486,27 @@ void Scene::synchronize(Common::Serializer &ser) {
ser.syncArray(_flags.eventFlags.data(), g_nancy->getStaticData().numEventFlags, Common::Serializer::Byte);
- ser.syncArray<uint16>(_flags.sceneHitCount, (uint16)2001, Common::Serializer::Uint16LE);
+ // Skip empty sceneCount array
+ ser.skip(2001 * 2, 0, 2);
+
+ uint numSceneCounts = _flags.sceneCounts.size();
+ ser.syncAsUint16LE(numSceneCounts);
+
+ if (ser.isSaving()) {
+ uint16 key;
+ for (auto &entry : _flags.sceneCounts) {
+ key = entry._key;
+ ser.syncAsUint16LE(key);
+ ser.syncAsUint16LE(entry._value);
+ }
+ } else {
+ uint16 key, val;
+ for (uint i = 0; i < numSceneCounts; ++i) {
+ ser.syncAsUint16LE(key);
+ ser.syncAsUint16LE(val);
+ _flags.sceneCounts.setVal(key, val);
+ }
+ }
ser.syncAsUint16LE(_difficulty);
ser.syncArray<uint16>(_hintsRemaining.data(), _hintsRemaining.size(), Common::Serializer::Uint16LE);
@@ -532,10 +552,7 @@ void Scene::synchronize(Common::Serializer &ser) {
void Scene::init() {
_flags.eventFlags.resize(g_nancy->getStaticData().numEventFlags, kEvNotOccurred);
- // Does this ever get used?
- for (uint i = 0; i < 2001; ++i) {
- _flags.sceneHitCount[i] = 0;
- }
+ _flags.sceneCounts.clear();
_flags.items.resize(g_nancy->getStaticData().numItems, kInvEmpty);
@@ -689,6 +706,8 @@ void Scene::load() {
_timers.sceneTime = 0;
+ _flags.sceneCounts.getOrCreateVal(_sceneState.currentScene.sceneID)++;
+
if (_specialEffect) {
_specialEffect->afterSceneChange();
}
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index da17783563b..995d23ce20e 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -240,7 +240,7 @@ private:
LogicCondition logicConditions[30];
Common::Array<byte> eventFlags;
- uint16 sceneHitCount[2001];
+ Common::HashMap<uint16, uint16> sceneCounts;
Common::Array<byte> items;
int16 heldItem = -1;
int16 primaryVideoResponsePicked = -1;
Commit: 95f415869714d86815f3d570d72379ad04841eed
https://github.com/scummvm/scummvm/commit/95f415869714d86815f3d570d72379ad04841eed
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:31+03:00
Commit Message:
NANCY: Implement kSound dependency
Implemented the Sound dependency type, which checks
if a given sound channel is currently playing.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/action/actionrecord.h
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 6851fd9e837..fe316d3cb96 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -338,6 +338,15 @@ void ActionManager::processActionRecords() {
dep.satisfied = true;
}
}
+
+ break;
+ case DependencyType::kSound:
+ if (g_nancy->_sound->isSoundPlaying(dep.label)) {
+ dep.satisfied = dep.condition == 1;
+ } else {
+ dep.satisfied = dep.condition == 0;
+ }
+
break;
default:
warning("Unimplemented Dependency type %i", (int)dep.type);
diff --git a/engines/nancy/action/actionrecord.h b/engines/nancy/action/actionrecord.h
index c548bee75f1..b7ad4a7e9af 100644
--- a/engines/nancy/action/actionrecord.h
+++ b/engines/nancy/action/actionrecord.h
@@ -57,7 +57,7 @@ enum struct DependencyType : int16 {
kTimerGreaterThanDependencyTime = 14,
kDifficultyLevel = 15,
kClosedCaptioning = 16,
- kSound = 17, // Not implemented
+ kSound = 17,
kOpenParentheses = 18, // Not implemented
kCloseParentheses = 19 // Not implemented
};
Commit: cb23c110617307322b78aa94fa3cc3bd31a8da8a
https://github.com/scummvm/scummvm/commit/cb23c110617307322b78aa94fa3cc3bd31a8da8a
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:32+03:00
Commit Message:
NANCY: Fix kElapsedPlayerTime dependency
Fixed the way the kElapsedPlayerTime dependency is handled,
so it ignores days and milliseconds. Also added support for
the conditions added in nancy3.
Changed paths:
engines/nancy/action/actionmanager.cpp
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index fe316d3cb96..4cb30449866 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -150,7 +150,14 @@ bool ActionManager::addNewActionRecord(Common::SeekableReadStream &inputData) {
dep.seconds = inputData.readSint16LE();
dep.milliseconds = inputData.readSint16LE();
- if (dep.type != DependencyType::kSceneCount || dep.hours != -1 || dep.minutes != -1 || dep.seconds != -1) {
+ if (dep.type == DependencyType::kElapsedPlayerTime) {
+ dep.timeData = dep.hours * 3600000 + dep.minutes * 60000;
+
+ if (g_nancy->getGameType() < kGameTypeNancy3) {
+ // Older titles only checked if the time is less than the one in the dependency
+ dep.condition = 0;
+ }
+ } else if (dep.type != DependencyType::kSceneCount || dep.hours != -1 || dep.minutes != -1 || dep.seconds != -1) {
dep.timeData = ((dep.hours * 60 + dep.minutes) * 60 + dep.seconds) * 1000 + dep.milliseconds;
}
}
@@ -232,12 +239,23 @@ void ActionManager::processActionRecords() {
}
break;
- case DependencyType::kElapsedPlayerTime:
- if (NancySceneState._timers.playerTime >= dep.timeData) {
- dep.satisfied = true;
+ case DependencyType::kElapsedPlayerTime: {
+ // We're only interested in the hours and minutes
+ Time playerTime = NancySceneState._timers.playerTime.getHours() * 3600000 +
+ NancySceneState._timers.playerTime.getMinutes() * 60000;
+ switch (dep.condition) {
+ case 0:
+ dep.satisfied = dep.timeData < playerTime;
+ break;
+ case 1:
+ dep.satisfied = dep.timeData > playerTime;
+ break;
+ case 2:
+ dep.satisfied = dep.timeData == playerTime;
}
break;
+ }
case DependencyType::kSceneCount: {
// Check how many times a scene has been visited.
// This dependency type keeps its data in the time variables
@@ -346,7 +364,7 @@ void ActionManager::processActionRecords() {
} else {
dep.satisfied = dep.condition == 0;
}
-
+
break;
default:
warning("Unimplemented Dependency type %i", (int)dep.type);
Commit: 130209f89d271600016d44bcf099fbaf31e5f192
https://github.com/scummvm/scummvm/commit/130209f89d271600016d44bcf099fbaf31e5f192
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:32+03:00
Commit Message:
NANCY: Implement nancy3 dependency tree
Nancy3 introduced the kOpenParenthesis and
kCloseParenthesis dependency types, which allow for
more complicated dependency logic. This commit changes
the structure of the DependencyRecord type to support
parent-child relationships similar to the ones found
inside the original implementation's code. Also introduced
is the static canHaveHotspot() function in ActionRecord,
which is used to correctly implement cursor dependencies.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/action/actionmanager.h
engines/nancy/action/actionrecord.cpp
engines/nancy/action/actionrecord.h
engines/nancy/action/overlay.h
engines/nancy/action/recordtypes.h
engines/nancy/action/secondaryvideo.h
engines/nancy/console.cpp
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 4cb30449866..a64c1f17c5e 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -20,6 +20,7 @@
*/
#include "common/serializer.h"
+#include "common/stack.h"
#include "common/config-manager.h"
#include "engines/nancy/nancy.h"
@@ -46,49 +47,35 @@ void ActionManager::handleInput(NancyInput &input) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
input.input &= ~NancyInput::kLeftMouseButtonUp;
- bool shouldTrigger = false;
- int16 heldItem = NancySceneState.getHeldItem();
- if (rec->_itemRequired != -1) {
- if (heldItem == -1 && rec->_itemRequired == -2) {
- shouldTrigger = true;
- } else {
- if (rec->_itemRequired <= 100) {
- if (heldItem == rec->_itemRequired) {
- shouldTrigger = true;
- }
- } else if (rec->_itemRequired <= 110 && rec->_itemRequired - 100 != heldItem) {
- // IDs 100 - 110 mean the record will activate when the object is _not_ the specified one
- shouldTrigger = true;
- }
- }
+ processDependency(rec->_dependencies, *rec, false);
- if (!shouldTrigger) {
- if (g_nancy->getGameType() >= kGameTypeNancy2) {
- SoundDescription &sound = g_nancy->_inventoryData->itemDescriptions[rec->_itemRequired].specificCantSound;
- g_nancy->_sound->loadSound(sound);
- g_nancy->_sound->playSound(sound);
- } else {
- g_nancy->_sound->playSound("CANT");
- }
+ if (!rec->_dependencies.satisfied) {
+ if (g_nancy->getGameType() >= kGameTypeNancy2 && rec->_cursorDependency != nullptr) {
+ SoundDescription &sound = g_nancy->_inventoryData->itemDescriptions[rec->_cursorDependency->label].specificCantSound;
+ g_nancy->_sound->loadSound(sound);
+ g_nancy->_sound->playSound(sound);
+ } else {
+ g_nancy->_sound->playSound("CANT");
}
} else {
- shouldTrigger = true;
- }
- if (shouldTrigger) {
rec->_state = ActionRecord::ExecutionState::kActionTrigger;
- if (rec->_itemRequired > 100 && rec->_itemRequired <= 110) {
- rec->_itemRequired -= 100;
- }
-
- // Re-add the object to the inventory unless it's marked as a one-time use
- if (rec->_itemRequired == heldItem && rec->_itemRequired != -1) {
- if (g_nancy->_inventoryData->itemDescriptions[heldItem].keepItem == kInvItemKeepAlways) {
- NancySceneState.addItemToInventory(heldItem);
+ if (rec->_cursorDependency) {
+ int16 item = rec->_cursorDependency->label;
+ if (item > 100 && item <= (100 + g_nancy->getStaticData().numItems)) {
+ item -= 100;
}
- NancySceneState.setHeldItem(-1);
+ // Re-add the object to the inventory unless it's marked as a one-time use
+ if (item == NancySceneState.getHeldItem() && item != -1) {
+ if (g_nancy->_inventoryData->itemDescriptions[item].keepItem == kInvItemKeepAlways) {
+ NancySceneState.addItemToInventory(item);
+ }
+
+ NancySceneState.setHeldItem(-1);
+ }
}
+
}
break;
@@ -125,13 +112,19 @@ bool ActionManager::addNewActionRecord(Common::SeekableReadStream &inputData) {
if (depsDataSize % singleDepSize) {
error("Action record type %s has incorrect read size", newRecord->getRecordTypeName().c_str());
}
+
+ if (numDependencies == 0) {
+ newRecord->_dependencies.satisfied = true;
+ }
+
+ Common::Stack<DependencyRecord *> depStack;
+ depStack.push(&newRecord->_dependencies);
// Initialize the dependencies data
inputData.seek(localChunkSize);
- newRecord->_dependencies.reserve(numDependencies);
for (uint16 i = 0; i < numDependencies; ++i) {
- newRecord->_dependencies.push_back(DependencyRecord());
- DependencyRecord &dep = newRecord->_dependencies.back();
+ depStack.top()->children.push_back(DependencyRecord());
+ DependencyRecord &dep = depStack.top()->children.back();
if (singleDepSize == 12) {
dep.type = (DependencyType)inputData.readByte();
@@ -150,15 +143,30 @@ bool ActionManager::addNewActionRecord(Common::SeekableReadStream &inputData) {
dep.seconds = inputData.readSint16LE();
dep.milliseconds = inputData.readSint16LE();
- if (dep.type == DependencyType::kElapsedPlayerTime) {
+ switch (dep.type) {
+ case DependencyType::kElapsedPlayerTime:
dep.timeData = dep.hours * 3600000 + dep.minutes * 60000;
if (g_nancy->getGameType() < kGameTypeNancy3) {
// Older titles only checked if the time is less than the one in the dependency
dep.condition = 0;
}
- } else if (dep.type != DependencyType::kSceneCount || dep.hours != -1 || dep.minutes != -1 || dep.seconds != -1) {
- dep.timeData = ((dep.hours * 60 + dep.minutes) * 60 + dep.seconds) * 1000 + dep.milliseconds;
+
+ break;
+ case DependencyType::kSceneCount:
+ break;
+ case DependencyType::kOpenParenthesis:
+ depStack.push(&dep);
+ break;
+ case DependencyType::kCloseParenthesis:
+ depStack.pop();
+ break;
+ default:
+ if (dep.hours != -1 || dep.minutes != -1 || dep.seconds != -1) {
+ dep.timeData = ((dep.hours * 60 + dep.minutes) * 60 + dep.seconds) * 1000 + dep.milliseconds;
+ }
+
+ break;
}
}
} else {
@@ -178,226 +186,245 @@ void ActionManager::processActionRecords() {
}
if (!record->_isActive) {
- for (uint i = 0; i < record->_dependencies.size(); ++i) {
- DependencyRecord &dep = record->_dependencies[i];
-
- if (!dep.satisfied) {
- switch (dep.type) {
- case DependencyType::kNone:
- dep.satisfied = true;
- break;
- case DependencyType::kInventory:
- switch (dep.condition) {
- case kInvEmpty:
- // Item not in possession or held
- if (NancySceneState._flags.items[dep.label] == kInvEmpty &&
- dep.label != NancySceneState._flags.heldItem) {
- dep.satisfied = true;
- }
+ processDependency(record->_dependencies, *record, record->canHaveHotspot());
+ if (record->_dependencies.satisfied) {
+ record->_isActive = true;
+ }
+ }
- break;
- case kInvHolding:
- if (NancySceneState._flags.items[dep.label] == kInvHolding ||
- dep.label == NancySceneState._flags.heldItem) {
- dep.satisfied = true;
- }
+ if (record->_isActive) {
+ record->execute();
+ }
+ }
+}
- break;
- default:
- break;
- }
+void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &record, bool doNotCheckCursor) {
+ if (dep.children.size()) {
+ // Recursively process child dependencies
+ for (uint i = 0; i < dep.children.size(); ++i) {
+ processDependency(dep.children[i], record, doNotCheckCursor);
+ }
- break;
- case DependencyType::kEvent:
- if (NancySceneState.getEventFlag(dep.label, dep.condition)) {
- // nancy1 has code for some timer array that never gets used
- // and is discarded from nancy2 onward
- dep.satisfied = true;
- }
+ // An orFlag marks that its corresponding dependency and the one after it
+ // mutually satisfy each other; if one is satisfied, so is the other
+ for (uint i = 1; i < dep.children.size(); ++i) {
+ if (dep.children[i - 1].orFlag) {
+ if (dep.children[i - 1].satisfied)
+ dep.children[i].satisfied = true;
+ if (dep.children[i].satisfied)
+ dep.children[i - 1].satisfied = true;
+ }
+ }
- break;
- case DependencyType::kLogic:
- if (NancySceneState._flags.logicConditions[dep.label].flag == dep.condition) {
- // Wait for specified time before satisfying dependency condition
- Time elapsed = NancySceneState._timers.lastTotalTime - NancySceneState._flags.logicConditions[dep.label].timestamp;
+ // If all children are satisfied, so is the parent
+ dep.satisfied = true;
+ for (uint i = 0; i < dep.children.size(); ++i) {
+ if (!dep.children[i].satisfied) {
+ dep.satisfied = false;
+ break;
+ }
+ }
+ } else {
+ switch (dep.type) {
+ case DependencyType::kNone:
+ dep.satisfied = true;
+ break;
+ case DependencyType::kInventory:
+ switch (dep.condition) {
+ case kInvEmpty:
+ // Item not in possession or held
+ if (NancySceneState._flags.items[dep.label] == kInvEmpty &&
+ dep.label != NancySceneState._flags.heldItem) {
+ dep.satisfied = true;
+ }
- if (elapsed >= dep.timeData) {
- dep.satisfied = true;
- }
- }
+ break;
+ case kInvHolding:
+ if (NancySceneState._flags.items[dep.label] == kInvHolding ||
+ dep.label == NancySceneState._flags.heldItem) {
+ dep.satisfied = true;
+ }
- break;
- case DependencyType::kElapsedGameTime:
- if (NancySceneState._timers.lastTotalTime >= dep.timeData) {
- dep.satisfied = true;
- }
+ break;
+ default:
+ break;
+ }
- break;
- case DependencyType::kElapsedSceneTime:
- if (NancySceneState._timers.sceneTime >= dep.timeData) {
- dep.satisfied = true;
- }
+ break;
+ case DependencyType::kEvent:
+ if (NancySceneState.getEventFlag(dep.label, dep.condition)) {
+ // nancy1 has code for some timer array that never gets used
+ // and is discarded from nancy2 onward
+ dep.satisfied = true;
+ }
- break;
- case DependencyType::kElapsedPlayerTime: {
- // We're only interested in the hours and minutes
- Time playerTime = NancySceneState._timers.playerTime.getHours() * 3600000 +
- NancySceneState._timers.playerTime.getMinutes() * 60000;
- switch (dep.condition) {
- case 0:
- dep.satisfied = dep.timeData < playerTime;
- break;
- case 1:
- dep.satisfied = dep.timeData > playerTime;
- break;
- case 2:
- dep.satisfied = dep.timeData == playerTime;
- }
+ break;
+ case DependencyType::kLogic:
+ if (NancySceneState._flags.logicConditions[dep.label].flag == dep.condition) {
+ // Wait for specified time before satisfying dependency condition
+ Time elapsed = NancySceneState._timers.lastTotalTime - NancySceneState._flags.logicConditions[dep.label].timestamp;
- break;
- }
- case DependencyType::kSceneCount: {
- // Check how many times a scene has been visited.
- // This dependency type keeps its data in the time variables
- int count = NancySceneState._flags.sceneCounts.contains(dep.hours) ?
- NancySceneState._flags.sceneCounts[dep.hours] : 0;
- switch (dep.milliseconds) {
- case 1:
- if (dep.seconds < count) {
- dep.satisfied = true;
- }
+ if (elapsed >= dep.timeData) {
+ dep.satisfied = true;
+ }
+ }
- break;
- case 2:
- if (dep.seconds > count) {
- dep.satisfied = true;
- }
+ break;
+ case DependencyType::kElapsedGameTime:
+ if (NancySceneState._timers.lastTotalTime >= dep.timeData) {
+ dep.satisfied = true;
+ }
- break;
- case 3:
- if (dep.seconds == count) {
- dep.satisfied = true;
- }
+ break;
+ case DependencyType::kElapsedSceneTime:
+ if (NancySceneState._timers.sceneTime >= dep.timeData) {
+ dep.satisfied = true;
+ }
- break;
- }
+ break;
+ case DependencyType::kElapsedPlayerTime: {
+ // We're only interested in the hours and minutes
+ Time playerTime = NancySceneState._timers.playerTime.getHours() * 3600000 +
+ NancySceneState._timers.playerTime.getMinutes() * 60000;
+ switch (dep.condition) {
+ case 0:
+ dep.satisfied = dep.timeData < playerTime;
+ break;
+ case 1:
+ dep.satisfied = dep.timeData > playerTime;
+ break;
+ case 2:
+ dep.satisfied = dep.timeData == playerTime;
+ }
- break;
- }
- case DependencyType::kElapsedPlayerDay:
- if (record->_days == -1) {
- record->_days = NancySceneState._timers.playerTime.getDays();
- dep.satisfied = true;
- break;
- }
+ break;
+ }
+ case DependencyType::kSceneCount: {
+ // Check how many times a scene has been visited.
+ // This dependency type keeps its data in the time variables
+ int count = NancySceneState._flags.sceneCounts.contains(dep.hours) ?
+ NancySceneState._flags.sceneCounts[dep.hours] : 0;
+ switch (dep.milliseconds) {
+ case 1:
+ if (dep.seconds < count) {
+ dep.satisfied = true;
+ }
- if (record->_days < NancySceneState._timers.playerTime.getDays()) {
- record->_days = NancySceneState._timers.playerTime.getDays();
- for (uint j = 0; j < record->_dependencies.size(); ++j) {
- if (record->_dependencies[j].type == DependencyType::kElapsedPlayerTime) {
- record->_dependencies[j].satisfied = false;
- }
- }
- }
+ break;
+ case 2:
+ if (dep.seconds > count) {
+ dep.satisfied = true;
+ }
- break;
- case DependencyType::kCursorType: {
- bool hasUnsatisfiedDeps = false;
- for (uint j = 0; j < record->_dependencies.size(); ++j) {
- if (j != i && record->_dependencies[j].satisfied == false) {
- hasUnsatisfiedDeps = true;
- }
- }
+ break;
+ case 3:
+ if (dep.seconds == count) {
+ dep.satisfied = true;
+ }
- if (hasUnsatisfiedDeps) {
- break;
- }
+ break;
+ }
- record->_itemRequired = dep.label;
+ break;
+ }
+ case DependencyType::kElapsedPlayerDay:
+ if (record._days == -1) {
+ record._days = NancySceneState._timers.playerTime.getDays();
+ dep.satisfied = true;
+ break;
+ }
- if (dep.condition == kCursInvNotHolding) {
- record->_itemRequired += kCursInvNotHoldingOffset;
- }
+ if (record._days < NancySceneState._timers.playerTime.getDays()) {
+ record._days = NancySceneState._timers.playerTime.getDays();
- dep.satisfied = true;
- break;
+ // This is not used in nancy3 and up, so it's a safe assumption that we
+ // do not need to check types recursively
+ for (uint j = 0; j < record._dependencies.children.size(); ++j) {
+ if (record._dependencies.children[j].type == DependencyType::kElapsedPlayerTime) {
+ record._dependencies.children[j].satisfied = false;
}
- case DependencyType::kPlayerTOD:
- if (dep.label == NancySceneState.getPlayerTOD()) {
- dep.satisfied = true;
- }
-
- break;
- case DependencyType::kTimerLessThanDependencyTime:
- if (NancySceneState._timers.timerTime <= dep.timeData) {
- dep.satisfied = true;
- }
+ }
+ }
- break;
- case DependencyType::kTimerGreaterThanDependencyTime:
- if (NancySceneState._timers.timerTime > dep.timeData) {
- dep.satisfied = true;
+ break;
+ case DependencyType::kCursorType: {
+ if (doNotCheckCursor) {
+ dep.satisfied = true;
+ record._cursorDependency = &dep;
+ } else {
+ bool isSatisfied = false;
+ int heldItem = NancySceneState.getHeldItem();
+ if (heldItem == -1 && dep.label == -2) {
+ isSatisfied = true;
+ } else {
+ if (dep.label <= 100) {
+ if (heldItem == dep.label) {
+ isSatisfied = true;
}
+ } else if (dep.label - 100 != heldItem) {
+ // IDs above 100 mean the record will activate when the object is _not_ the specified one
+ isSatisfied = true;
+ }
+ }
- break;
- case DependencyType::kDifficultyLevel:
- if (dep.condition == NancySceneState._difficulty) {
- dep.satisfied = true;
- }
+ if (isSatisfied) {
+ dep.satisfied = true;
+ record._cursorDependency = nullptr;
+ } else {
+ dep.satisfied = false;
+ record._cursorDependency = &dep;
+ }
+ }
+
+ break;
+ }
+ case DependencyType::kPlayerTOD:
+ if (dep.label == NancySceneState.getPlayerTOD()) {
+ dep.satisfied = true;
+ }
- break;
- case DependencyType::kClosedCaptioning:
- if (ConfMan.getBool("subtitles")) {
- if (dep.condition == 2) {
- dep.satisfied = true;
- }
- } else {
- if (dep.condition == 1) {
- dep.satisfied = true;
- }
- }
+ break;
+ case DependencyType::kTimerLessThanDependencyTime:
+ if (NancySceneState._timers.timerTime <= dep.timeData) {
+ dep.satisfied = true;
+ }
- break;
- case DependencyType::kSound:
- if (g_nancy->_sound->isSoundPlaying(dep.label)) {
- dep.satisfied = dep.condition == 1;
- } else {
- dep.satisfied = dep.condition == 0;
- }
+ break;
+ case DependencyType::kTimerGreaterThanDependencyTime:
+ if (NancySceneState._timers.timerTime > dep.timeData) {
+ dep.satisfied = true;
+ }
- break;
- default:
- warning("Unimplemented Dependency type %i", (int)dep.type);
- break;
- }
- }
+ break;
+ case DependencyType::kDifficultyLevel:
+ if (dep.condition == NancySceneState._difficulty) {
+ dep.satisfied = true;
}
- // An orFlag marks that its corresponding dependency and the one after it
- // mutually satisfy each other; if one is satisfied, so is the other
- for (uint i = 1; i < record->_dependencies.size(); ++i) {
- if (record->_dependencies[i - 1].orFlag) {
- if (record->_dependencies[i - 1].satisfied)
- record->_dependencies[i].satisfied = true;
- if (record->_dependencies[i].satisfied)
- record->_dependencies[i - 1].satisfied = true;
+ break;
+ case DependencyType::kClosedCaptioning:
+ if (ConfMan.getBool("subtitles")) {
+ if (dep.condition == 2) {
+ dep.satisfied = true;
+ }
+ } else {
+ if (dep.condition == 1) {
+ dep.satisfied = true;
}
}
- // Check if all dependencies have been satisfied, and activate the record if they have
- uint satisfied = 0;
- for (uint i = 0; i < record->_dependencies.size(); ++i) {
- if (record->_dependencies[i].satisfied)
- ++satisfied;
+ break;
+ case DependencyType::kSound:
+ if (g_nancy->_sound->isSoundPlaying(dep.label)) {
+ dep.satisfied = dep.condition == 1;
+ } else {
+ dep.satisfied = dep.condition == 0;
}
- if (satisfied == record->_dependencies.size())
- record->_isActive = true;
-
- }
-
- if (record->_isActive) {
- record->execute();
+ break;
+ default:
+ warning("Unimplemented Dependency type %i", (int)dep.type);
+ break;
}
}
}
diff --git a/engines/nancy/action/actionmanager.h b/engines/nancy/action/actionmanager.h
index f4307583416..14657d90da1 100644
--- a/engines/nancy/action/actionmanager.h
+++ b/engines/nancy/action/actionmanager.h
@@ -42,6 +42,7 @@ class Scene;
namespace Action {
class ActionRecord;
+struct DependencyRecord;
// The class that handles ActionRecords and their execution
class ActionManager {
@@ -59,6 +60,8 @@ public:
void handleInput(NancyInput &input);
void processActionRecords();
+ void processDependency(DependencyRecord &dep, ActionRecord &record, bool doNotCheckCursor);
+
bool addNewActionRecord(Common::SeekableReadStream &inputData);
Common::Array<ActionRecord *> &getActionRecords() { return _records; }
ActionRecord *getActionRecord(uint id) { if (id < _records.size()) return _records[id]; else return nullptr;}
diff --git a/engines/nancy/action/actionrecord.cpp b/engines/nancy/action/actionrecord.cpp
index 7ab05b76e72..8cb1ff40c64 100644
--- a/engines/nancy/action/actionrecord.cpp
+++ b/engines/nancy/action/actionrecord.cpp
@@ -19,27 +19,34 @@
*
*/
+#include "common/stack.h"
#include "engines/nancy/action/actionrecord.h"
namespace Nancy {
namespace Action {
+void DependencyRecord::reset() {
+ satisfied = false;
+ for (auto &child : children) {
+ child.reset();
+ }
+}
+
void ActionRecord::finishExecution() {
switch (_execType) {
case kOneShot:
_isDone = true;
_state = kBegin;
break;
- case kRepeating:
+ case kRepeating: {
_isDone = false;
_isActive = false;
_state = kBegin;
- for (uint i = 0; i < _dependencies.size(); ++i) {
- _dependencies[i].satisfied = false;
- }
+ _dependencies.reset();
break;
+ }
default:
_state = kBegin;
break;
diff --git a/engines/nancy/action/actionrecord.h b/engines/nancy/action/actionrecord.h
index b7ad4a7e9af..70020605386 100644
--- a/engines/nancy/action/actionrecord.h
+++ b/engines/nancy/action/actionrecord.h
@@ -58,24 +58,30 @@ enum struct DependencyType : int16 {
kDifficultyLevel = 15,
kClosedCaptioning = 16,
kSound = 17,
- kOpenParentheses = 18, // Not implemented
- kCloseParentheses = 19 // Not implemented
+ kOpenParenthesis = 18,
+ kCloseParenthesis = 19
};
// Describes a condition that needs to be fulfilled before the
// action record can be executed
struct DependencyRecord {
- DependencyType type; // 0x00
- int16 label; // 0x01
- int16 condition; // 0x02
- bool orFlag; // 0x03
- int16 hours; // 0x04
- int16 minutes; // 0x06
- int16 seconds; // 0x08
- int16 milliseconds; // 0x0A
-
- bool satisfied;
+ DependencyType type = DependencyType::kNone;
+ int16 label = -1;
+ int16 condition = -1;
+ bool orFlag = false;
+ int16 hours = -1;
+ int16 minutes = -1;
+ int16 seconds = -1;
+ int16 milliseconds = -1;
+
+ bool satisfied = false;
Time timeData;
+
+ // Used to support the dependency tree structure in nancy3 and up
+ // The only valid field in dependencies with children is the orFlag
+ Common::Array<DependencyRecord> children;
+
+ void reset();
};
// Describes a single action that will be performed on every update.
@@ -98,7 +104,7 @@ public:
_hasHotspot(false),
_state(ExecutionState::kBegin),
_days(-1),
- _itemRequired(-1) {}
+ _cursorDependency(nullptr) {}
virtual ~ActionRecord() {}
virtual void readData(Common::SeekableReadStream &stream) = 0;
@@ -110,27 +116,28 @@ public:
protected:
void finishExecution();
+ virtual bool canHaveHotspot() const { return false; } // Used for handling kCursorType dependency
// Used for debugging
virtual Common::String getRecordTypeName() const = 0;
public:
- Common::String _description; // 0x00
- byte _type; // 0x30
- ExecutionType _execType; // 0x31
+ Common::String _description;
+ byte _type;
+ ExecutionType _execType;
// 0x32 data
- Common::Array<DependencyRecord> _dependencies; // 0x36
+ DependencyRecord _dependencies;
// 0x3A numDependencies
- bool _isActive; // 0x3B
+ bool _isActive;
// 0x3C satisfiedDependencies[]
// 0x48 timers[]
// 0x78 orFlags[]
- bool _isDone; // 0x84
- bool _hasHotspot; // 0x85
- Common::Rect _hotspot; // 0x89
- ExecutionState _state; // 0x91
- int16 _days; // 0x95
- int8 _itemRequired; // 0x97
+ bool _isDone;
+ bool _hasHotspot;
+ Common::Rect _hotspot;
+ ExecutionState _state;
+ int16 _days;
+ DependencyRecord *_cursorDependency;
};
// Base class for visual ActionRecords
diff --git a/engines/nancy/action/overlay.h b/engines/nancy/action/overlay.h
index 2f2af35e2f3..d5fe78396b9 100644
--- a/engines/nancy/action/overlay.h
+++ b/engines/nancy/action/overlay.h
@@ -92,6 +92,7 @@ public:
bool _isInterruptible;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override;
bool isViewportRelative() const override { return true; }
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index 1949f229ac5..14b8f69b26b 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -53,6 +53,7 @@ public:
Common::Array<HotspotDescription> _hotspots;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return "HotMultiframeSceneChange"; }
};
@@ -64,6 +65,7 @@ public:
HotspotDescription _hotspotDesc;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return "Hot1FrSceneChange"; }
};
@@ -87,6 +89,7 @@ public:
Common::Array<HotspotDescription> _hotspots;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return "HotMultiframeMultisceneChange"; }
};
@@ -160,6 +163,7 @@ public:
HotspotDescription _hotspotDesc;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return "MapCallHot1Fr"; }
};
@@ -171,6 +175,7 @@ public:
Common::Array<HotspotDescription> _hotspots;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return "MapCallHotMultiframe"; }
};
@@ -270,6 +275,7 @@ public:
Common::Array<HotspotDescription> _hotspots;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return "EventFlagsMultiHS"; }
};
@@ -361,6 +367,7 @@ public:
Graphics::ManagedSurface _fullSurface;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return "ShowInventoryItem"; }
bool isViewportRelative() const override { return true; }
};
diff --git a/engines/nancy/action/secondaryvideo.h b/engines/nancy/action/secondaryvideo.h
index adfa6fb628e..a1d04066f6d 100644
--- a/engines/nancy/action/secondaryvideo.h
+++ b/engines/nancy/action/secondaryvideo.h
@@ -67,6 +67,7 @@ public:
Common::Array<SecondaryVideoDescription> _videoDescs;
protected:
+ bool canHaveHotspot() const override { return true; }
Common::String getRecordTypeName() const override { return Common::String::format("PlaySecondaryVideoChan%i", channel); }
bool isViewportRelative() const override { return true; }
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index b6829ee100b..a2d0367e2d6 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -449,10 +449,10 @@ bool NancyConsole::Cmd_listAcionRecords(int argc, const char **argv) {
rec->getRecordTypeName().c_str(),
rec->_execType == ActionRecord::kRepeating ? "kRepeating" : "kOneShot");
- if (rec->_dependencies.size()) {
+ if (rec->_dependencies.children.size()) {
debugPrintf("\n\tDependencies:");
- for (DependencyRecord &dep : rec->_dependencies) {
+ for (DependencyRecord &dep : rec->_dependencies.children) {
debugPrintf("\n\t\t");
switch (dep.type) {
case DependencyType::kNone :
Commit: 3a39e75388e38df4650cd517b4f0cc02a4fc2c08
https://github.com/scummvm/scummvm/commit/3a39e75388e38df4650cd517b4f0cc02a4fc2c08
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:32+03:00
Commit Message:
NANCY: Correct reading of filenames in nancy3
Changed paths:
engines/nancy/util.cpp
diff --git a/engines/nancy/util.cpp b/engines/nancy/util.cpp
index e13cdfd64b8..dce9817d73a 100644
--- a/engines/nancy/util.cpp
+++ b/engines/nancy/util.cpp
@@ -78,21 +78,40 @@ void readRectArray(Common::Serializer &stream, Common::Array<Common::Rect> &inAr
}
}
-// Reads an 8-character filename from a 10-character source
+
void readFilename(Common::SeekableReadStream &stream, Common::String &inString) {
- char buf[10];
- stream.read(buf, 10);
- buf[9] = '\0';
+ char buf[33];
+
+ if (g_nancy->getGameType() <= kGameTypeNancy2) {
+ // Older games only support 8-character filenames, and stored them in a 10 char buffer
+ stream.read(buf, 10);
+ buf[9] = '\0';
+ } else {
+ // Later games support 32-character filenames
+ stream.read(buf, 33);
+ buf[32] = '\0';
+ }
+
inString = buf;
}
+
// Reads an 8-character filename from a 10-character source
void readFilename(Common::Serializer &stream, Common::String &inString, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
Common::Serializer::Version version = stream.getVersion();
if (version >= minVersion && version <= maxVersion) {
- char buf[10];
- stream.syncBytes((byte *)buf, 10);
- buf[9] = '\0';
+ char buf[33];
+
+ if (version <= kGameTypeNancy2) {
+ // Older games only support 8-character filenames, and stored them in a 10 char buffer
+ stream.syncBytes((byte *)buf, 10);
+ buf[9] = '\0';
+ } else {
+ // Later games support 32-character filenames
+ stream.syncBytes((byte *)buf, 33);
+ buf[32] = '\0';
+ }
+
inString = buf;
}
}
@@ -108,10 +127,19 @@ void readFilenameArray(Common::Serializer &stream, Common::Array<Common::String>
Common::Serializer::Version version = stream.getVersion();
if (version >= minVersion && version <= maxVersion) {
inArray.resize(num);
- char buf[10];
+ char buf[33];
+
for (Common::String &str : inArray) {
- stream.syncBytes((byte *)buf, 10);
- buf[9] = '\0';
+ if (version <= kGameTypeNancy2) {
+ // Older games only support 8-character filenames, and stored them in a 10 char buffer
+ stream.syncBytes((byte *)buf, 10);
+ buf[9] = '\0';
+ } else {
+ // Later games support 32-character filenames
+ stream.syncBytes((byte *)buf, 33);
+ buf[32] = '\0';
+ }
+
str = buf;
}
}
Commit: 685eccf1c2f57aec3f77e614f4b5ea77dc9a60db
https://github.com/scummvm/scummvm/commit/685eccf1c2f57aec3f77e614f4b5ea77dc9a60db
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:33+03:00
Commit Message:
NANCY: Separate SoundDescription reading functions
Changed paths:
engines/nancy/action/bombpuzzle.cpp
engines/nancy/action/conversation.cpp
engines/nancy/action/leverpuzzle.cpp
engines/nancy/action/orderingpuzzle.cpp
engines/nancy/action/overlay.cpp
engines/nancy/action/overridelockpuzzle.cpp
engines/nancy/action/passwordpuzzle.cpp
engines/nancy/action/recordtypes.cpp
engines/nancy/action/riddlepuzzle.cpp
engines/nancy/action/rippedletterpuzzle.cpp
engines/nancy/action/rotatinglockpuzzle.cpp
engines/nancy/action/secondarymovie.cpp
engines/nancy/action/sliderpuzzle.cpp
engines/nancy/action/telephone.cpp
engines/nancy/action/towerpuzzle.cpp
engines/nancy/commontypes.cpp
engines/nancy/commontypes.h
engines/nancy/enginedata.cpp
engines/nancy/sound.cpp
engines/nancy/state/scene.cpp
diff --git a/engines/nancy/action/bombpuzzle.cpp b/engines/nancy/action/bombpuzzle.cpp
index 7f27504ed0f..3d46607b198 100644
--- a/engines/nancy/action/bombpuzzle.cpp
+++ b/engines/nancy/action/bombpuzzle.cpp
@@ -64,17 +64,17 @@ void BombPuzzle::readData(Common::SeekableReadStream &stream) {
_solveOrder[i] = stream.readByte();
}
- _snipSound.readData(stream, SoundDescription::kNormal);
- _noToolSound.readData(stream, SoundDescription::kNormal);
+ _snipSound.readNormal(stream);
+ _noToolSound.readNormal(stream);
_toolID = stream.readUint16LE();
_solveSceneChange.readData(stream);
stream.skip(2);
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_failSceneChange.readData(stream);
stream.skip(2);
- _failSound.readData(stream, SoundDescription::kNormal);
+ _failSound.readNormal(stream);
switch (NancySceneState.getDifficulty()) {
case 0:
diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index 9ba1b7376c0..c480d234d0e 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -58,7 +58,7 @@ void ConversationSound::readData(Common::SeekableReadStream &stream) {
ser.setVersion(g_nancy->getGameType());
if (ser.getVersion() >= kGameTypeNancy2) {
- _sound.readData(stream, SoundDescription::kNormal);
+ _sound.readNormal(stream);
}
char *rawText = new char[1500];
@@ -67,10 +67,10 @@ void ConversationSound::readData(Common::SeekableReadStream &stream) {
delete[] rawText;
if (ser.getVersion() <= kGameTypeNancy1) {
- _sound.readData(stream, SoundDescription::kNormal);
+ _sound.readNormal(stream);
}
- _responseGenericSound.readData(stream, SoundDescription::kNormal);
+ _responseGenericSound.readNormal(stream);
ser.skip(1);
ser.syncAsByte(_conditionalResponseCharacterID);
ser.syncAsByte(_goodbyeResponseCharacterID);
diff --git a/engines/nancy/action/leverpuzzle.cpp b/engines/nancy/action/leverpuzzle.cpp
index 31248c34271..fc7a0ffd04f 100644
--- a/engines/nancy/action/leverpuzzle.cpp
+++ b/engines/nancy/action/leverpuzzle.cpp
@@ -79,11 +79,11 @@ void LeverPuzzle::readData(Common::SeekableReadStream &stream) {
_correctSequence.push_back(stream.readByte());
}
- _moveSound.readData(stream, SoundDescription::kNormal);
- _noMoveSound.readData(stream, SoundDescription::kNormal);
+ _moveSound.readNormal(stream);
+ _noMoveSound.readNormal(stream);
_solveExitScene.readData(stream);
_solveSoundDelay = stream.readUint16LE();
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
}
diff --git a/engines/nancy/action/orderingpuzzle.cpp b/engines/nancy/action/orderingpuzzle.cpp
index 7e0ae7b8f8e..624807d86be 100644
--- a/engines/nancy/action/orderingpuzzle.cpp
+++ b/engines/nancy/action/orderingpuzzle.cpp
@@ -101,12 +101,12 @@ void OrderingPuzzle::readData(Common::SeekableReadStream &stream) {
ser.skip(15 - _sequenceLength, kGameTypeNancy1);
if (ser.getVersion() != kGameTypeVampire) {
- _clickSound.readData(stream, SoundDescription::kNormal);
+ _clickSound.readNormal(stream);
}
_solveExitScene.readData(stream, ser.getVersion() == kGameTypeVampire);
ser.syncAsUint16LE(_solveSoundDelay);
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_exitScene.readData(stream, ser.getVersion() == kGameTypeVampire);
readRect(stream, _exitHotspot);
}
diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index 01b45423474..f6e35dd9b9a 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -85,7 +85,7 @@ void Overlay::readData(Common::SeekableReadStream &stream) {
_sceneChange.readData(stream);
_flagsOnTrigger.readData(stream);
- _sound.readData(stream, SoundDescription::kNormal);
+ _sound.readNormal(stream);
uint numViewportFrames = stream.readUint16LE();
if (_overlayType == kPlayOverlayAnimated) {
diff --git a/engines/nancy/action/overridelockpuzzle.cpp b/engines/nancy/action/overridelockpuzzle.cpp
index f3fccc02227..505ff445644 100644
--- a/engines/nancy/action/overridelockpuzzle.cpp
+++ b/engines/nancy/action/overridelockpuzzle.cpp
@@ -67,13 +67,13 @@ void OverrideLockPuzzle::readData(Common::SeekableReadStream &stream) {
readRectArray(stream, _lightDests, num);
stream.skip((10 - num) * 16);
- _buttonSound.readData(stream, SoundDescription::kNormal);
- _wrongSound.readData(stream, SoundDescription::kNormal);
+ _buttonSound.readNormal(stream);
+ _wrongSound.readNormal(stream);
_buttonPopTime = stream.readUint16LE();
_solveExitScene.readData(stream);
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
diff --git a/engines/nancy/action/passwordpuzzle.cpp b/engines/nancy/action/passwordpuzzle.cpp
index bf877a92046..0a8c99dddfb 100644
--- a/engines/nancy/action/passwordpuzzle.cpp
+++ b/engines/nancy/action/passwordpuzzle.cpp
@@ -56,9 +56,9 @@ void PasswordPuzzle::readData(Common::SeekableReadStream &stream) {
buf[19] = '\0';
_password = buf;
_solveExitScene.readData(stream);
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_failExitScene.readData(stream);
- _failSound.readData(stream, SoundDescription::kNormal);
+ _failSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
}
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index 375ec74599e..fd7be9214aa 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -554,7 +554,7 @@ void ShowInventoryItem::execute() {
}
void PlayDigiSoundAndDie::readData(Common::SeekableReadStream &stream) {
- _sound.readData(stream, SoundDescription::kDIGI);
+ _sound.readDIGI(stream);
_sceneChange.readData(stream, g_nancy->getGameType() == kGameTypeVampire);
_flagOnTrigger.label = stream.readSint16LE();
@@ -589,7 +589,7 @@ void PlayDigiSoundAndDie::execute() {
}
void PlaySoundPanFrameAnchorAndDie::readData(Common::SeekableReadStream &stream) {
- _sound.readData(stream, SoundDescription::kDIGI);
+ _sound.readDIGI(stream);
stream.skip(2);
}
@@ -600,7 +600,7 @@ void PlaySoundPanFrameAnchorAndDie::execute() {
}
void PlaySoundMultiHS::readData(Common::SeekableReadStream &stream) {
- _sound.readData(stream, SoundDescription::kNormal);
+ _sound.readNormal(stream);
if (g_nancy->getGameType() != kGameTypeVampire) {
_sceneChange.readData(stream);
@@ -653,7 +653,7 @@ void PlaySoundMultiHS::execute() {
void HintSystem::readData(Common::SeekableReadStream &stream) {
_characterID = stream.readByte();
- _genericSound.readData(stream, SoundDescription::kNormal);
+ _genericSound.readNormal(stream);
}
void HintSystem::execute() {
diff --git a/engines/nancy/action/riddlepuzzle.cpp b/engines/nancy/action/riddlepuzzle.cpp
index 064f48b0db5..c9b94b9b5a1 100644
--- a/engines/nancy/action/riddlepuzzle.cpp
+++ b/engines/nancy/action/riddlepuzzle.cpp
@@ -53,13 +53,13 @@ void RiddlePuzzle::readData(Common::SeekableReadStream &stream) {
_textboxTextFontID = stream.readUint16LE();
_cursorBlinkTime = stream.readUint16LE();
readRect(stream, _screenPosition);
- _typeSound.readData(stream, SoundDescription::kNormal);
- _eraseSound.readData(stream, SoundDescription::kNormal);
- _enterSound.readData(stream, SoundDescription::kNormal);
+ _typeSound.readNormal(stream);
+ _eraseSound.readNormal(stream);
+ _enterSound.readNormal(stream);
_successSceneChange.readData(stream);
- _successSound.readData(stream, SoundDescription::kNormal);
+ _successSound.readNormal(stream);
_exitSceneChange.readData(stream);
- _exitSound.readData(stream, SoundDescription::kNormal);
+ _exitSound.readNormal(stream);
readRect(stream, _exitHotspot);
_riddles.resize(stream.readUint16LE()) ;
@@ -72,7 +72,7 @@ void RiddlePuzzle::readData(Common::SeekableReadStream &stream) {
stream.read(buf, 128);
buf[127] = '\0';
riddle.text = buf;
- riddle.sound.readData(stream, SoundDescription::kNormal);
+ riddle.sound.readNormal(stream);
for (uint j = 0; j < 8; ++j) {
stream.read(buf, 20);
@@ -84,9 +84,9 @@ void RiddlePuzzle::readData(Common::SeekableReadStream &stream) {
}
riddle.sceneIncorrect.readData(stream);
- riddle.soundIncorrect.readData(stream, SoundDescription::kNormal);
+ riddle.soundIncorrect.readNormal(stream);
riddle.sceneCorrect.readData(stream);
- riddle.soundCorrect.readData(stream, SoundDescription::kNormal);
+ riddle.soundCorrect.readNormal(stream);
}
}
diff --git a/engines/nancy/action/rippedletterpuzzle.cpp b/engines/nancy/action/rippedletterpuzzle.cpp
index 640d6345ce8..726df97e2ca 100644
--- a/engines/nancy/action/rippedletterpuzzle.cpp
+++ b/engines/nancy/action/rippedletterpuzzle.cpp
@@ -88,12 +88,12 @@ void RippedLetterPuzzle::readData(Common::SeekableReadStream &stream) {
_solveRotations[i] = stream.readByte();
}
- _takeSound.readData(stream, SoundDescription::kNormal);
- _dropSound.readData(stream, SoundDescription::kNormal);
- _rotateSound.readData(stream, SoundDescription::kNormal);
+ _takeSound.readNormal(stream);
+ _dropSound.readNormal(stream);
+ _rotateSound.readNormal(stream);
_solveExitScene.readData(stream);
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
diff --git a/engines/nancy/action/rotatinglockpuzzle.cpp b/engines/nancy/action/rotatinglockpuzzle.cpp
index 6b897884f8d..f61ce6503e5 100644
--- a/engines/nancy/action/rotatinglockpuzzle.cpp
+++ b/engines/nancy/action/rotatinglockpuzzle.cpp
@@ -92,10 +92,10 @@ void RotatingLockPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip(8 - numDials);
- _clickSound.readData(stream, SoundDescription::kNormal);
+ _clickSound.readNormal(stream);
_solveExitScene.readData(stream);
_solveSoundDelay = stream.readUint16LE();
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index 22de5a70c5c..f662b47e557 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -74,7 +74,7 @@ void PlaySecondaryMovie::readData(Common::SeekableReadStream &stream) {
}
_triggerFlags.readData(stream);
- _sound.readData(stream, SoundDescription::kNormal);
+ _sound.readNormal(stream);
_sceneChange.readData(stream, ser.getVersion() == kGameTypeVampire);
uint16 numVideoDescs;
diff --git a/engines/nancy/action/sliderpuzzle.cpp b/engines/nancy/action/sliderpuzzle.cpp
index 4715ae965ca..5dc9a70e076 100644
--- a/engines/nancy/action/sliderpuzzle.cpp
+++ b/engines/nancy/action/sliderpuzzle.cpp
@@ -104,9 +104,9 @@ void SliderPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip((6 - _height) * 6 * 2);
- _clickSound.readData(stream, SoundDescription::kNormal);
+ _clickSound.readNormal(stream);
_solveExitScene.readData(stream);
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
}
diff --git a/engines/nancy/action/telephone.cpp b/engines/nancy/action/telephone.cpp
index 0e0e75fa13a..9b269f2b728 100644
--- a/engines/nancy/action/telephone.cpp
+++ b/engines/nancy/action/telephone.cpp
@@ -65,12 +65,12 @@ void Telephone::readData(Common::SeekableReadStream &stream) {
}
}
- _genericDialogueSound.readData(stream, SoundDescription::kNormal);
- _genericButtonSound.readData(stream, SoundDescription::kNormal);
- _ringSound.readData(stream, SoundDescription::kNormal);
- _dialToneSound.readData(stream, SoundDescription::kNormal);
- _dialAgainSound.readData(stream, SoundDescription::kNormal);
- _hangUpSound.readData(stream, SoundDescription::kNormal);
+ _genericDialogueSound.readNormal(stream);
+ _genericButtonSound.readNormal(stream);
+ _ringSound.readNormal(stream);
+ _dialToneSound.readNormal(stream);
+ _dialAgainSound.readNormal(stream);
+ _hangUpSound.readNormal(stream);
_buttonSoundNames.reserve(12);
for (uint i = 0; i < 12; ++i) {
diff --git a/engines/nancy/action/towerpuzzle.cpp b/engines/nancy/action/towerpuzzle.cpp
index 145cd289f69..2c7c612d6e4 100644
--- a/engines/nancy/action/towerpuzzle.cpp
+++ b/engines/nancy/action/towerpuzzle.cpp
@@ -81,12 +81,12 @@ void TowerPuzzle::readData(Common::SeekableReadStream &stream) {
}
}
- _takeSound.readData(stream, SoundDescription::kNormal);
- _dropSound.readData(stream, SoundDescription::kNormal);
+ _takeSound.readNormal(stream);
+ _dropSound.readNormal(stream);
_solveExitScene._sceneChange.readData(stream);
stream.skip(2);
- _solveSound.readData(stream, SoundDescription::kNormal);
+ _solveSound.readNormal(stream);
_solveExitScene._flag.label = stream.readSint16LE();
_solveExitScene._flag.flag = stream.readByte();
diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index fad15b0ac2a..f82bdfe2154 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -86,19 +86,17 @@ void SecondaryVideoDescription::readData(Common::SeekableReadStream &stream) {
stream.skip(0x20);
}
-void SoundDescription::readData(Common::SeekableReadStream &stream, Type type) {
+void SoundDescription::readNormal(Common::SeekableReadStream &stream) {
Common::Serializer s(&stream, nullptr);
- s.setVersion(type);
+ s.setVersion(g_nancy->getGameType());
readFilename(s, name);
- s.skip(4, kScene, kScene);
s.syncAsUint16LE(channelID);
s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
- s.skip(4, kNormal, kNormal);
- s.skip(2, kMenu, kMenu);
+ s.skip(4);
s.syncAsUint16LE(numLoops);
uint16 loopType;
@@ -111,10 +109,83 @@ void SoundDescription::readData(Common::SeekableReadStream &stream, Type type) {
s.syncAsUint16LE(volume);
s.skip(2); // Second volume, always (?) same as the first
- s.syncAsUint32LE(samplesPerSec, kNormal, kNormal);
- s.syncAsUint16LE(panAnchorFrame, kDIGI, kDIGI);
- s.skip(2, kDIGI, kDIGI);
- s.skip(4, kMenu, kScene);
+ s.syncAsUint32LE(samplesPerSec);
+}
+
+void SoundDescription::readDIGI(Common::SeekableReadStream &stream) {
+ Common::Serializer s(&stream, nullptr);
+ s.setVersion(g_nancy->getGameType());
+
+ readFilename(s, name);
+
+ s.syncAsUint16LE(channelID);
+
+ s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
+ s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
+
+ s.syncAsUint16LE(numLoops);
+ uint16 loopType;
+ s.syncAsUint16LE(loopType);
+ if (loopType != 0) { // LOOP_ONCE = 1, LOOP_INFINITE = 0
+ numLoops = 0;
+ }
+
+ s.skip(2);
+ s.syncAsUint16LE(volume);
+ s.skip(2); // Second volume, always (?) same as the first
+
+ s.syncAsUint16LE(panAnchorFrame);
+ s.skip(2);
+}
+
+void SoundDescription::readMenu(Common::SeekableReadStream &stream) {
+ Common::Serializer s(&stream, nullptr);
+ s.setVersion(g_nancy->getGameType());
+
+ readFilename(s, name);
+
+ s.syncAsUint16LE(channelID);
+
+ s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
+ s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
+ s.skip(2);
+
+ s.syncAsUint16LE(numLoops);
+ uint16 loopType;
+ s.syncAsUint16LE(loopType);
+ if (loopType != 0) { // LOOP_ONCE = 1, LOOP_INFINITE = 0
+ numLoops = 0;
+ }
+
+ s.skip(2);
+ s.syncAsUint16LE(volume);
+ s.skip(2); // Second volume, always (?) same as the first
+ s.skip(4);
+}
+
+void SoundDescription::readScene(Common::SeekableReadStream &stream) {
+ Common::Serializer s(&stream, nullptr);
+ s.setVersion(g_nancy->getGameType());
+
+ readFilename(s, name);
+
+ s.skip(4);
+ s.syncAsUint16LE(channelID);
+
+ s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
+ s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
+
+ s.syncAsUint16LE(numLoops);
+ uint16 loopType;
+ s.syncAsUint16LE(loopType);
+ if (loopType != 0) { // LOOP_ONCE = 1, LOOP_INFINITE = 0
+ numLoops = 0;
+ }
+
+ s.skip(2);
+ s.syncAsUint16LE(volume);
+ s.skip(2); // Second volume, always (?) same as the first
+ s.skip(4);
}
void ConditionalDialogue::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index c1f1c0db5b3..45f69837ab0 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -172,8 +172,6 @@ struct SecondaryVideoDescription {
// Descrbes a single sound. Combines four different structs found in the data in one
struct SoundDescription {
- enum Type { kNormal = 0, kDIGI = 1, kMenu = 2, kScene = 3 };
-
Common::String name;
uint16 channelID = 0;
uint16 numLoops = 0;
@@ -181,7 +179,10 @@ struct SoundDescription {
uint16 panAnchorFrame = 0;
uint32 samplesPerSec = 0;
- void readData(Common::SeekableReadStream &stream, Type type);
+ void readNormal(Common::SeekableReadStream &stream);
+ void readDIGI(Common::SeekableReadStream &stream);
+ void readMenu(Common::SeekableReadStream &stream);
+ void readScene(Common::SeekableReadStream &stream);
};
// Structs inside nancy.dat, which contains all the data that was
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index b7a3cd9fcbd..849bcdab9d7 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -124,7 +124,7 @@ INV::INV(Common::SeekableReadStream *chunkStream) {
byte textBuf[60];
if (s.getVersion() >= kGameTypeNancy2) {
- cantSound.readData(*chunkStream, SoundDescription::kNormal);
+ cantSound.readNormal(*chunkStream);
s.syncBytes(textBuf, 60);
textBuf[59] = '\0';
cantText = (char *)textBuf;
@@ -167,14 +167,14 @@ INV::INV(Common::SeekableReadStream *chunkStream) {
textBuf[59] = '\0';
item.generalCantText = (char *)textBuf;
- item.specificCantSound.readData(*chunkStream, SoundDescription::kNormal);
- item.generalCantSound.readData(*chunkStream, SoundDescription::kNormal);
+ item.specificCantSound.readNormal(*chunkStream);
+ item.generalCantSound.readNormal(*chunkStream);
} else if (s.getVersion() >= kGameTypeNancy3) {
s.syncBytes(textBuf, 60);
textBuf[59] = '\0';
item.specificCantText = (char *)textBuf;
- item.specificCantSound.readData(*chunkStream, SoundDescription::kNormal);
+ item.specificCantSound.readNormal(*chunkStream);
}
}
@@ -246,7 +246,7 @@ MAP::MAP(Common::SeekableReadStream *chunkStream) {
sounds.resize(numMaps);
for (uint i = 0; i < numMaps; ++i) {
- sounds[i].readData(*chunkStream, SoundDescription::kMenu);
+ sounds[i].readMenu(*chunkStream);
}
s.skip(0x20);
@@ -345,7 +345,7 @@ CRED::CRED(Common::SeekableReadStream *chunkStream) {
updateTime = chunkStream->readUint16LE();
pixelsToScroll = chunkStream->readUint16LE();
- sound.readData(*chunkStream, SoundDescription::kMenu);
+ sound.readMenu(*chunkStream);
delete chunkStream;
}
diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index 4cec07ddc46..6dd1b011fa0 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -264,7 +264,7 @@ void SoundManager::loadCommonSounds(IFF *boot) {
chunk = boot->getChunkStream(s);
if (chunk) {
SoundDescription &desc = _commonSounds.getOrCreateVal(s);
- desc.readData(*chunk, SoundDescription::kNormal);
+ desc.readNormal(*chunk);
g_nancy->_sound->loadSound(desc);
_channels[desc.channelID].isPersistent = true;
@@ -276,7 +276,7 @@ void SoundManager::loadCommonSounds(IFF *boot) {
chunk = boot->getChunkStream("MSND"); // channel 28
if (chunk) {
SoundDescription &desc = _commonSounds.getOrCreateVal("MSND");
- desc.readData(*chunk, SoundDescription::kMenu);
+ desc.readMenu(*chunk);
g_nancy->_sound->loadSound(desc);
_channels[desc.channelID].isPersistent = true;
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index aeae4841845..04997944a81 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -74,7 +74,7 @@ void Scene::SceneSummary::read(Common::SeekableReadStream &stream) {
readFilename(stream, palettes[2]);
}
- sound.readData(stream, SoundDescription::kScene);
+ sound.readScene(stream);
ser.skip(6);
ser.syncAsUint16LE(panningType);
Commit: 150d0d5c6bd0f523ba99f5a822249e53723fa972
https://github.com/scummvm/scummvm/commit/150d0d5c6bd0f523ba99f5a822249e53723fa972
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:33+03:00
Commit Message:
NANCY: Improve reading of nancy3 files
Improved the reading of SoundDescriptions, SceneSummaries,
and SceneChangeDescriptions so nancy3 no longer crashes
on the first scene.
Changed paths:
engines/nancy/commontypes.cpp
engines/nancy/enginedata.cpp
engines/nancy/state/scene.cpp
diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index f82bdfe2154..5bf711a5cf2 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -36,6 +36,10 @@ void SceneChangeDescription::readData(Common::SeekableReadStream &stream, bool l
stream.skip(2);
}
continueSceneSound = stream.readUint16LE();
+
+ if (g_nancy->getGameType() >= kGameTypeNancy3) {
+ stream.skip(12); // 3D sound listener position
+ }
}
void SceneChangeWithFlag::readData(Common::SeekableReadStream &stream, bool longFormat) {
@@ -96,20 +100,18 @@ void SoundDescription::readNormal(Common::SeekableReadStream &stream) {
s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
- s.skip(4);
- s.syncAsUint16LE(numLoops);
- uint16 loopType;
- s.syncAsUint16LE(loopType);
- if (loopType != 0) { // LOOP_ONCE = 1, LOOP_INFINITE = 0
- numLoops = 0;
- }
+ s.skip(4, kGameTypeVampire, kGameTypeNancy2);
+
+ s.syncAsUint32LE(numLoops);
s.skip(2);
+
s.syncAsUint16LE(volume);
s.skip(2); // Second volume, always (?) same as the first
- s.syncAsUint32LE(samplesPerSec);
+ s.skip(4, kGameTypeVampire, kGameTypeNancy1); // Prior to nancy2 this field was used for something else
+ s.syncAsUint32LE(samplesPerSec, kGameTypeNancy2, kGameTypeNancy2);
}
void SoundDescription::readDIGI(Common::SeekableReadStream &stream) {
@@ -123,19 +125,16 @@ void SoundDescription::readDIGI(Common::SeekableReadStream &stream) {
s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
- s.syncAsUint16LE(numLoops);
- uint16 loopType;
- s.syncAsUint16LE(loopType);
- if (loopType != 0) { // LOOP_ONCE = 1, LOOP_INFINITE = 0
- numLoops = 0;
- }
+ s.syncAsUint32LE(numLoops);
- s.skip(2);
+ s.skip(2, kGameTypeVampire, kGameTypeNancy2);
s.syncAsUint16LE(volume);
s.skip(2); // Second volume, always (?) same as the first
- s.syncAsUint16LE(panAnchorFrame);
- s.skip(2);
+ s.syncAsUint16LE(panAnchorFrame, kGameTypeVampire, kGameTypeNancy2);
+ s.skip(2, kGameTypeVampire, kGameTypeNancy2);
+
+ s.skip(0x61, kGameTypeNancy3);
}
void SoundDescription::readMenu(Common::SeekableReadStream &stream) {
@@ -148,19 +147,17 @@ void SoundDescription::readMenu(Common::SeekableReadStream &stream) {
s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
- s.skip(2);
- s.syncAsUint16LE(numLoops);
- uint16 loopType;
- s.syncAsUint16LE(loopType);
- if (loopType != 0) { // LOOP_ONCE = 1, LOOP_INFINITE = 0
- numLoops = 0;
- }
+ s.skip(2, kGameTypeVampire, kGameTypeNancy2);
+
+ s.syncAsUint32LE(numLoops);
- s.skip(2);
+ s.skip(2, kGameTypeVampire, kGameTypeNancy2);
+
s.syncAsUint16LE(volume);
s.skip(2); // Second volume, always (?) same as the first
- s.skip(4);
+
+ s.skip(4, kGameTypeVampire, kGameTypeNancy2);
}
void SoundDescription::readScene(Common::SeekableReadStream &stream) {
@@ -172,20 +169,21 @@ void SoundDescription::readScene(Common::SeekableReadStream &stream) {
s.skip(4);
s.syncAsUint16LE(channelID);
- s.skip(2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
- s.skip(2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
+ s.skip(2, kGameTypeVampire, kGameTypeNancy2); // PLAY_SOUND_FROM_HD = 1, PLAY_SOUND_FROM_CDROM = 2
+ s.skip(2, kGameTypeVampire, kGameTypeNancy2); // PLAY_SOUND_AS_DIGI = 1, PLAY_SOUND_AS_STREAM = 2
- s.syncAsUint16LE(numLoops);
- uint16 loopType;
- s.syncAsUint16LE(loopType);
- if (loopType != 0) { // LOOP_ONCE = 1, LOOP_INFINITE = 0
- numLoops = 0;
- }
+ s.skip(2, kGameTypeNancy3);
+
+ s.syncAsUint32LE(numLoops);
- s.skip(2);
+ s.skip(2, kGameTypeVampire, kGameTypeNancy2);
s.syncAsUint16LE(volume);
s.skip(2); // Second volume, always (?) same as the first
- s.skip(4);
+ s.skip(2);
+ s.skip(4, kGameTypeVampire, kGameTypeNancy2); // Panning, always? at center
+ s.syncAsUint32LE(samplesPerSec, kGameTypeVampire, kGameTypeNancy2);
+
+ s.skip(14, kGameTypeNancy3);
}
void ConditionalDialogue::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 849bcdab9d7..cacd1d5a341 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -113,6 +113,8 @@ INV::INV(Common::SeekableReadStream *chunkStream) {
readRect(s, curtainsScreenPosition);
s.syncAsUint16LE(curtainsFrameTime);
+ s.skip(2, kGameTypeNancy3); // Unknown, 3000
+
readFilename(s, inventoryBoxIconsImageName);
readFilename(s, inventoryCursorsImageName);
@@ -255,9 +257,9 @@ MAP::MAP(Common::SeekableReadStream *chunkStream) {
readRectArray(s, globeSrcs, 8, kGameTypeVampire, kGameTypeVampire);
readRect(s, globeDest, kGameTypeVampire, kGameTypeVampire);
- s.skip(2, kGameTypeNancy1, kGameTypeNancy1);
- readRect(s, buttonSrc, kGameTypeNancy1, kGameTypeNancy1);
- readRect(s, buttonDest, kGameTypeNancy1, kGameTypeNancy1);
+ s.skip(2, kGameTypeNancy1);
+ readRect(s, buttonSrc, kGameTypeNancy1);
+ readRect(s, buttonDest, kGameTypeNancy1);
locations.resize(numLocations);
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 04997944a81..7f239e833e4 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -57,9 +57,7 @@ void Scene::SceneSummary::read(Common::SeekableReadStream &stream) {
ser.syncBytes((byte *)buf, 0x32);
description = Common::String(buf);
- ser.syncBytes((byte *)buf, 10);
- buf[9] = 0;
- videoFile = Common::String(buf);
+ readFilename(stream, videoFile);
// skip 2 unknown bytes
ser.skip(2);
@@ -67,22 +65,16 @@ void Scene::SceneSummary::read(Common::SeekableReadStream &stream) {
// Load the palette data in The Vampire Diaries
ser.skip(4, kGameTypeVampire, kGameTypeVampire);
- if (ser.getVersion() == kGameTypeVampire) {
- palettes.resize(3);
- readFilename(stream, palettes[0]);
- readFilename(stream, palettes[1]);
- readFilename(stream, palettes[2]);
- }
+ readFilenameArray(ser, palettes, 3, kGameTypeVampire, kGameTypeVampire);
sound.readScene(stream);
- ser.skip(6);
ser.syncAsUint16LE(panningType);
ser.syncAsUint16LE(numberOfVideoFrames);
- ser.syncAsUint16LE(soundPanPerFrame);
- ser.syncAsUint16LE(totalViewAngle);
- ser.syncAsUint16LE(horizontalScrollDelta);
- ser.syncAsUint16LE(verticalScrollDelta);
+ ser.syncAsUint16LE(soundPanPerFrame, kGameTypeVampire, kGameTypeNancy2);
+ ser.syncAsUint16LE(totalViewAngle, kGameTypeVampire, kGameTypeNancy2);
+ ser.syncAsUint16LE(horizontalScrollDelta, kGameTypeVampire, kGameTypeNancy2); // horizontalScrollDelta
+ ser.syncAsUint16LE(verticalScrollDelta, kGameTypeVampire, kGameTypeNancy2); // verticalScrollDelta
ser.syncAsUint16LE(horizontalEdgeSize);
ser.syncAsUint16LE(verticalEdgeSize);
ser.syncAsUint16LE((uint32 &)slowMoveTimeDelta);
Commit: dff9cbe272e90a5bc7f5e16f9881c6c0f6b2a692
https://github.com/scummvm/scummvm/commit/dff9cbe272e90a5bc7f5e16f9881c6c0f6b2a692
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:33+03:00
Commit Message:
NANCY: Use correct values for nancy3's flags
Nancy3 did away with earlier versions of the engine's usage
of 1 and 2 as false/true values. This commit adds two
new values to NancyEngine: _true and _false, which hold
the correct values used by different versions of the engine.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/action/conversation.cpp
engines/nancy/action/overlay.cpp
engines/nancy/action/recordtypes.cpp
engines/nancy/commontypes.h
engines/nancy/console.cpp
engines/nancy/misc/lightning.cpp
engines/nancy/nancy.cpp
engines/nancy/nancy.h
engines/nancy/state/map.cpp
engines/nancy/state/scene.cpp
engines/nancy/state/scene.h
engines/nancy/ui/textbox.cpp
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index a64c1f17c5e..afc1aab5431 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -230,24 +230,17 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
dep.satisfied = true;
break;
case DependencyType::kInventory:
- switch (dep.condition) {
- case kInvEmpty:
+ if (dep.condition == g_nancy->_false) {
// Item not in possession or held
- if (NancySceneState._flags.items[dep.label] == kInvEmpty &&
+ if (NancySceneState._flags.items[dep.label] == g_nancy->_false &&
dep.label != NancySceneState._flags.heldItem) {
dep.satisfied = true;
}
-
- break;
- case kInvHolding:
- if (NancySceneState._flags.items[dep.label] == kInvHolding ||
+ } else {
+ if (NancySceneState._flags.items[dep.label] == g_nancy->_true ||
dep.label == NancySceneState._flags.heldItem) {
dep.satisfied = true;
}
-
- break;
- default:
- break;
}
break;
@@ -260,14 +253,20 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
break;
case DependencyType::kLogic:
- if (NancySceneState._flags.logicConditions[dep.label].flag == dep.condition) {
- // Wait for specified time before satisfying dependency condition
- Time elapsed = NancySceneState._timers.lastTotalTime - NancySceneState._flags.logicConditions[dep.label].timestamp;
-
- if (elapsed >= dep.timeData) {
- dep.satisfied = true;
+ if (g_nancy->getGameType() <= kGameTypeNancy2) {
+ // First few games used 2 for false and 1 for true, but we store them the
+ // other way around here. So, we need to check for inequality
+ if (!NancySceneState.getLogicCondition(dep.label, dep.condition)) {
+ // Wait for specified time before satisfying dependency condition
+ Time elapsed = NancySceneState._timers.lastTotalTime - NancySceneState._flags.logicConditions[dep.label].timestamp;
+
+ if (elapsed >= dep.timeData) {
+ dep.satisfied = true;
+ }
}
- }
+ } else {
+ dep.satisfied = NancySceneState.getLogicCondition(dep.label, dep.condition);
+ }
break;
case DependencyType::kElapsedGameTime:
diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index c480d234d0e..e0c26254aa1 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -215,7 +215,7 @@ void ConversationSound::execute() {
} else {
// NPC has finished talking, we have responses
for (uint i = 0; i < 30; ++i) {
- if (NancySceneState.getLogicCondition(i, kLogUsed)) {
+ if (NancySceneState.getLogicCondition(i, g_nancy->_true)) {
int pickedOnScreenResponse = _pickedResponse = i;
// Adjust to account for hidden responses
@@ -384,7 +384,7 @@ void ConversationSound::ConversationFlag::set() const {
NancySceneState.setEventFlag(flag);
break;
case kFlagInventory:
- if (flag.flag == kInvHolding) {
+ if (flag.flag == g_nancy->_true) {
NancySceneState.addItemToInventory(flag.label);
} else {
NancySceneState.removeItemFromInventory(flag.label);
diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index f6e35dd9b9a..f9f2bf5ff13 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -80,7 +80,7 @@ void Overlay::readData(Common::SeekableReadStream &stream) {
ser.syncAsUint16LE(_interruptCondition.flag);
} else {
_interruptCondition.label = kEvNoEvent;
- _interruptCondition.flag = kEvNotOccurred;
+ _interruptCondition.flag = g_nancy->_false;
}
_sceneChange.readData(stream);
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index fd7be9214aa..158b4b6e4b2 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -458,7 +458,7 @@ void AddInventoryNoHS::readData(Common::SeekableReadStream &stream) {
}
void AddInventoryNoHS::execute() {
- if (NancySceneState.hasItem(_itemID) == kInvEmpty) {
+ if (NancySceneState.hasItem(_itemID) == g_nancy->_false) {
NancySceneState.addItemToInventory(_itemID);
}
@@ -470,7 +470,7 @@ void RemoveInventoryNoHS::readData(Common::SeekableReadStream &stream) {
}
void RemoveInventoryNoHS::execute() {
- if (NancySceneState.hasItem(_itemID) == kInvHolding) {
+ if (NancySceneState.hasItem(_itemID) == g_nancy->_true) {
NancySceneState.removeItemFromInventory(_itemID, false);
}
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 45f69837ab0..258775139c3 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -46,18 +46,6 @@ static const int8 kFlagNoLabel = -1;
static const int8 kEvNoEvent = -1;
static const int8 kFrNoFrame = -1;
-// Event flags
-static const byte kEvNotOccurred = 1;
-static const byte kEvOccurred = 2;
-
-// Logic conditions
-static const byte kLogUsed = 1;
-static const byte kLogNotUsed = 2;
-
-// Inventory items flags
-static const byte kInvEmpty = 1;
-static const byte kInvHolding = 2;
-
// Inventory items use types
static const byte kInvItemUseThenLose = 0;
static const byte kInvItemKeepAlways = 1;
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index a2d0367e2d6..7fdd00fddfe 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -462,18 +462,18 @@ bool NancyConsole::Cmd_listAcionRecords(int argc, const char **argv) {
debugPrintf("kInventory, item %u, %s, %s",
dep.label,
g_nancy->_inventoryData->itemDescriptions[dep.label].name.c_str(),
- dep.condition == kInvHolding ? "kInvHolding" : "kInvEmpty");
+ dep.condition == g_nancy->_true ? "true" : "false");
break;
case DependencyType::kEvent :
debugPrintf("kEvent, flag %u, %s, %s",
dep.label,
g_nancy->getStaticData().eventFlagNames[dep.label].c_str(),
- dep.condition == kEvOccurred ? "kEvOccurred" : "kEvNotOccurred");
+ dep.condition == g_nancy->_true ? "true" : "false");
break;
case DependencyType::kLogic :
debugPrintf("kLogic, flag %u, %s",
dep.label,
- dep.condition == kLogUsed ? "kLogUsed" : "kLogNotUsed");
+ dep.condition == g_nancy->_true ? "used" : "not used");
break;
case DependencyType::kElapsedGameTime :
debugPrintf("kElapsedGameTime, %i hours, %i minutes, %i seconds, %i milliseconds",
@@ -602,7 +602,7 @@ bool NancyConsole::Cmd_getEventFlags(int argc, const char **argv) {
debugPrintf("\nFlag %u, %s, %s",
i,
g_nancy->getStaticData().eventFlagNames[i].c_str(),
- NancySceneState.getEventFlag(i) == true ? "kEvOccurred" : "kEvNotOccurred");
+ NancySceneState.getEventFlag(i, g_nancy->_true) == true ? "true" : "false");
}
} else {
for (int i = 1; i < argc; ++i) {
@@ -614,7 +614,7 @@ bool NancyConsole::Cmd_getEventFlags(int argc, const char **argv) {
debugPrintf("\nFlag %u, %s, %s",
flagID,
g_nancy->getStaticData().eventFlagNames[flagID].c_str(),
- NancySceneState.getEventFlag(flagID) == true ? "kEvOccurred" : "kEvNotOccurred");
+ NancySceneState.getEventFlag(flagID, g_nancy->_true) == true ? "true" : "false");
}
}
@@ -639,13 +639,13 @@ bool NancyConsole::Cmd_setEventFlags(int argc, const char **argv) {
}
if (Common::String(argv[i + 1]).compareTo("true") == 0) {
- NancySceneState.setEventFlag(flagID, kEvOccurred);
- debugPrintf("Set flag %i, %s, to kEvOccurred\n",
+ NancySceneState.setEventFlag(flagID, g_nancy->_true);
+ debugPrintf("Set flag %i, %s, to g_nancy->_true\n",
flagID,
g_nancy->getStaticData().eventFlagNames[flagID].c_str());
} else if (Common::String(argv[i + 1]).compareTo("false") == 0) {
- NancySceneState.setEventFlag(flagID, kEvNotOccurred);
- debugPrintf("Set flag %i, %s, to kEvNotOccurred\n",
+ NancySceneState.setEventFlag(flagID, g_nancy->_false);
+ debugPrintf("Set flag %i, %s, to g_nancy->_false\n",
flagID,
g_nancy->getStaticData().eventFlagNames[flagID].c_str());
} else {
@@ -672,7 +672,7 @@ bool NancyConsole::Cmd_getInventory(int argc, const char **argv) {
debugPrintf("\nItem %u, %s, %s",
i,
g_nancy->_inventoryData->itemDescriptions[i].name.c_str(),
- NancySceneState.hasItem(i) == kInvHolding ? "kInvHolding" : "kInvEmpty");
+ NancySceneState.hasItem(i) == g_nancy->_true ? "true" : "false");
}
} else {
for (int i = 1; i < argc; ++i) {
@@ -684,7 +684,7 @@ bool NancyConsole::Cmd_getInventory(int argc, const char **argv) {
debugPrintf("\nItem %u, %s, %s",
flagID,
g_nancy->_inventoryData->itemDescriptions[flagID].name.c_str(),
- NancySceneState.hasItem(i) == kInvHolding ? "kInvHolding" : "kInvEmpty");
+ NancySceneState.hasItem(i) == g_nancy->_true ? "true" : "false");
}
}
diff --git a/engines/nancy/misc/lightning.cpp b/engines/nancy/misc/lightning.cpp
index 6ba0d9af2e9..c0ed5ea03ec 100644
--- a/engines/nancy/misc/lightning.cpp
+++ b/engines/nancy/misc/lightning.cpp
@@ -85,7 +85,7 @@ void Lightning::run() {
switch (_state) {
case kNotRunning: {
// Check if the endgame has started
- if (NancySceneState.getEventFlag(82)) {
+ if (NancySceneState.getEventFlag(82, g_nancy->_true)) {
uint16 sceneID = NancySceneState.getSceneInfo().sceneID;
// Check if we're inside an appropriate scene
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index dabc048bc80..7f5afc3b112 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -54,7 +54,9 @@ NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
_gameDescription(gd),
_system(syst),
_datFileMajorVersion(0),
- _datFileMinorVersion(2) {
+ _datFileMinorVersion(2),
+ _false(gd->gameType <= kGameTypeNancy2 ? 1 : 0),
+ _true(gd->gameType <= kGameTypeNancy2 ? 2 : 1) {
g_nancy = this;
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index 4e6856f587e..c76ef1de754 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -101,6 +101,11 @@ public:
void setMouseEnabled(bool enabled);
+ // The first few games used 1/2 for false/true in
+ // inventory, logic conditions, and event flags
+ const byte _true;
+ const byte _false;
+
// Managers
ResourceManager *_resource;
GraphicsManager *_graphicsManager;
diff --git a/engines/nancy/state/map.cpp b/engines/nancy/state/map.cpp
index c6a855d8422..636ecbc4536 100644
--- a/engines/nancy/state/map.cpp
+++ b/engines/nancy/state/map.cpp
@@ -219,7 +219,7 @@ void TVDMap::load() {
Map::load();
// Determine which version of the map will be shown
- if (NancySceneState.getEventFlag(82, kEvOccurred)) {
+ if (NancySceneState.getEventFlag(82, g_nancy->_true)) {
_mapID = 3; // Storm
//
} else {
@@ -387,8 +387,8 @@ void Nancy1Map::load() {
Map::load();
// Determine which version of the map will be shown
- if (NancySceneState.getEventFlag(40, kEvOccurred) && // Has set up sting
- NancySceneState.getEventFlag(95, kEvOccurred)) { // Connie chickens
+ if (NancySceneState.getEventFlag(40, g_nancy->_true) && // Has set up sting
+ NancySceneState.getEventFlag(95, g_nancy->_true)) { // Connie chickens
_mapID = 1; // Night
_activeLocations[1] = _activeLocations[3] = false;
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 7f239e833e4..1f306a413da 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -285,7 +285,7 @@ byte Scene::getPlayerTOD() const {
}
void Scene::addItemToInventory(uint16 id) {
- _flags.items[id] = kInvHolding;
+ _flags.items[id] = g_nancy->_true;
if (_flags.heldItem == id) {
setHeldItem(-1);
}
@@ -294,7 +294,7 @@ void Scene::addItemToInventory(uint16 id) {
}
void Scene::removeItemFromInventory(uint16 id, bool pickUp) {
- _flags.items[id] = kInvEmpty;
+ _flags.items[id] = g_nancy->_false;
if (pickUp) {
setHeldItem(id);
@@ -323,7 +323,7 @@ void Scene::setEventFlag(FlagDescription eventFlag) {
}
bool Scene::getEventFlag(int16 label, byte flag) const {
- if (label > 1000) {
+ if (label >= 1000) {
// In nancy3 and onwards flags begin from 1000
label -= 1000;
}
@@ -341,7 +341,7 @@ bool Scene::getEventFlag(FlagDescription eventFlag) const {
void Scene::setLogicCondition(int16 label, byte flag) {
if (label > kEvNoEvent) {
- if (label > 2000) {
+ if (label >= 2000) {
// In nancy3 and onwards logic conditions begin from 2000
label -= 2000;
}
@@ -360,7 +360,7 @@ bool Scene::getLogicCondition(int16 label, byte flag) const {
void Scene::clearLogicConditions() {
for (auto &cond : _flags.logicConditions) {
- cond.flag = kLogNotUsed;
+ cond.flag = g_nancy->_false;
cond.timestamp = 0;
}
}
@@ -542,11 +542,11 @@ void Scene::synchronize(Common::Serializer &ser) {
}
void Scene::init() {
- _flags.eventFlags.resize(g_nancy->getStaticData().numEventFlags, kEvNotOccurred);
+ _flags.eventFlags.resize(g_nancy->getStaticData().numEventFlags, g_nancy->_false);
_flags.sceneCounts.clear();
- _flags.items.resize(g_nancy->getStaticData().numItems, kInvEmpty);
+ _flags.items.resize(g_nancy->getStaticData().numItems, g_nancy->_false);
_timers.lastTotalTime = 0;
_timers.playerTime = g_nancy->_bootSummary->startTimeHours * 3600000;
@@ -887,7 +887,7 @@ void Scene::initStaticData() {
void Scene::clearSceneData() {
// Clear generic flags only
for (uint16 id : g_nancy->getStaticData().genericEventFlags) {
- _flags.eventFlags[id] = kEvNotOccurred;
+ _flags.eventFlags[id] = g_nancy->_false;
}
clearLogicConditions();
@@ -904,5 +904,7 @@ void Scene::clearPuzzleData() {
}
}
+Scene::PlayFlags::LogicCondition::LogicCondition() : flag(g_nancy->_false) {}
+
} // End of namespace State
} // End of namespace Nancy
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 995d23ce20e..8255c876a3b 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -142,13 +142,13 @@ public:
void setHeldItem(int16 id);
byte hasItem(int16 id) const { return _flags.items[id]; }
- void setEventFlag(int16 label, byte flag = kEvOccurred);
+ void setEventFlag(int16 label, byte flag);
void setEventFlag(FlagDescription eventFlag);
- bool getEventFlag(int16 label, byte flag = kEvOccurred) const;
+ bool getEventFlag(int16 label, byte flag) const;
bool getEventFlag(FlagDescription eventFlag) const;
- void setLogicCondition(int16 label, byte flag = kLogUsed);
- bool getLogicCondition(int16 label, byte flag = kLogUsed) const;
+ void setLogicCondition(int16 label, byte flag);
+ bool getLogicCondition(int16 label, byte flag) const;
void clearLogicConditions();
void setDifficulty(uint difficulty) { _difficulty = difficulty; }
@@ -234,7 +234,8 @@ private:
struct PlayFlags {
struct LogicCondition {
- byte flag = kLogNotUsed;
+ LogicCondition();
+ byte flag;
Time timestamp;
};
diff --git a/engines/nancy/ui/textbox.cpp b/engines/nancy/ui/textbox.cpp
index 4c12ad1659a..d954e948292 100644
--- a/engines/nancy/ui/textbox.cpp
+++ b/engines/nancy/ui/textbox.cpp
@@ -125,7 +125,7 @@ void Textbox::handleInput(NancyInput &input) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
input.input &= ~NancyInput::kLeftMouseButtonUp;
NancySceneState.clearLogicConditions();
- NancySceneState.setLogicCondition(i);
+ NancySceneState.setLogicCondition(i, g_nancy->_true);
}
break;
Commit: 15afae7277666a40531e7ae3894ef05552966767
https://github.com/scummvm/scummvm/commit/15afae7277666a40531e7ae3894ef05552966767
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:34+03:00
Commit Message:
NANCY: Add detection for Russian nancy 3/4 variants
Also added entries in the GameType enum for games 4-6.
Changed paths:
engines/nancy/detection.cpp
engines/nancy/detection.h
engines/nancy/nancy.cpp
diff --git a/engines/nancy/detection.cpp b/engines/nancy/detection.cpp
index 1170651de6f..f2f9a8e160c 100644
--- a/engines/nancy/detection.cpp
+++ b/engines/nancy/detection.cpp
@@ -88,9 +88,9 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
{
"nancy1", nullptr,
{
- { "data1.hdr", 0, "39b33ad649d3e7261508d3c6907f237f", 139814},
- { "data1.cab", 0, "f900861c47b0cb88191f5c6189db6cb1", 1916153},
- { "data2.cab", 0, "9c652edb9846a721839cb7e1dcc94a3e", 462008320},
+ { "data1.hdr", 0, "39b33ad649d3e7261508d3c6907f237f", 139814 },
+ { "data1.cab", 0, "f900861c47b0cb88191f5c6189db6cb1", 1916153 },
+ { "data2.cab", 0, "9c652edb9846a721839cb7e1dcc94a3e", 462008320 },
AD_LISTEND
},
Common::RU_RUS,
@@ -126,10 +126,10 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
{
"nancy2", nullptr,
{
- {"data1.hdr", 0, "af916152b6cbf1810076517897585f62", 227999},
- {"data1.cab", 0, "8139908ecba23f6cf58711ebd59c5b8b", 3854339},
- {"data2.cab", 0, "99926a30ced5af845220a96d3b657498", 459982848},
- {"data3.cab", 0, "39d396865ab10f908d55eb2ec733cb45", 60604580},
+ { "data1.hdr", 0, "af916152b6cbf1810076517897585f62", 227999 },
+ { "data1.cab", 0, "8139908ecba23f6cf58711ebd59c5b8b", 3854339 },
+ { "data2.cab", 0, "99926a30ced5af845220a96d3b657498", 459982848 },
+ { "data3.cab", 0, "39d396865ab10f908d55eb2ec733cb45", 60604580 },
},
Common::RU_RUS,
Common::kPlatformWindows,
@@ -153,9 +153,9 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
{
"nancy3", nullptr,
{
- { "data1.hdr", 0, "44906f3d2242f73f16feb8eb6a5161cb", 207327},
- { "data1.cab", 0, "e258cc871e5de5ae004d03c4e31431c7", 1555916},
- { "data2.cab", 0, "364dfd25677026da505f1fa6edd5571f", 137373135},
+ { "data1.hdr", 0, "44906f3d2242f73f16feb8eb6a5161cb", 207327 },
+ { "data1.cab", 0, "e258cc871e5de5ae004d03c4e31431c7", 1555916 },
+ { "data2.cab", 0, "364dfd25677026da505f1fa6edd5571f", 137373135 },
AD_LISTEND
},
Common::EN_ANY,
@@ -165,6 +165,33 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
},
Nancy::kGameTypeNancy3
},
+ { // MD5 by fracturehill
+ {
+ "nancy3", nullptr,
+ AD_ENTRY1s("ciftree.dat", "6b379f9d8edfb2d439062122e08f785c", 16161148),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM | ADGF_DROPPLATFORM,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy3
+ },
+ { // MD5 by fracturehill
+ {
+ "nancy3", nullptr,
+ {
+ { "data1.hdr", 0, "9da72fec24e1ca4f8f6b563bbdab3276", 237686 },
+ { "data1.cab", 0, "a7a259e45ae643aed63fa958531cc318", 3473219 },
+ { "data2.cab", 0, "cb709fba73605814f9dda823b1cfaf85", 433625036 },
+ AD_LISTEND
+ },
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy3
+ },
{ // MD5 by waltervn
{
"nancy4", nullptr,
@@ -174,15 +201,15 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
ADGF_UNSTABLE | ADGF_DROPPLATFORM,
GUIO0()
},
- Nancy::kGameTypeNancy3
+ Nancy::kGameTypeNancy4
},
{ // MD5 by waltervn
{
"nancy4", nullptr,
{
- { "data1.hdr", 0, "fa4e7a1c411053557169a7731f287012", 263443},
- { "data1.cab", 0, "8f689f92fcca443d6a03faa5de7e2f1c", 1568756},
- { "data2.cab", 0, "5525aa428041f3f1421a6fb5d1b8dba1", 140518758},
+ { "data1.hdr", 0, "fa4e7a1c411053557169a7731f287012", 263443 },
+ { "data1.cab", 0, "8f689f92fcca443d6a03faa5de7e2f1c", 1568756 },
+ { "data2.cab", 0, "5525aa428041f3f1421a6fb5d1b8dba1", 140518758 },
AD_LISTEND
},
Common::EN_ANY,
@@ -190,7 +217,35 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED,
GUIO0()
},
- Nancy::kGameTypeNancy3
+ Nancy::kGameTypeNancy4
+ },
+ { // MD5 by fracturehill
+ {
+ "nancy4", nullptr,
+ AD_ENTRY1s("ciftree.dat", "8645fad8c3fb8c0ee13e7a0a75902782", 9714463),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy4
+ },
+ { // MD5 by fracturehill
+ {
+ "nancy4", nullptr,
+ {
+ { "data1.hdr", 0, "229ab8e318a0fd0f0db366d854be2a20", 277512 },
+ { "data1.cab", 0, "156a26646f48e73c578373694cfd632d", 3466411 },
+ { "data2.cab", 0, "3db8fcd5414be1b704bef52d300a7fc1", 460324864 },
+ { "data3.cab", 0, "8e40909e6946cd45aa949e3db1b970ac", 127118355 },
+ AD_LISTEND
+ },
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy4
},
{ // MD5 by waltervn
{
@@ -201,15 +256,15 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
ADGF_UNSTABLE | ADGF_DROPPLATFORM,
GUIO0()
},
- Nancy::kGameTypeNancy3
+ Nancy::kGameTypeNancy5
},
{ // MD5 by waltervn
{
"nancy5", nullptr,
{
- { "data1.hdr", 0, "261105fba2a1226eedb090c2ce79fd35", 284091},
- { "data1.cab", 0, "7d27bb947ef7305831f1faaf1512a598", 1446301},
- { "data2.cab", 0, "00719c86cab733c1094b27079ce030f3", 145857935},
+ { "data1.hdr", 0, "261105fba2a1226eedb090c2ce79fd35", 284091 },
+ { "data1.cab", 0, "7d27bb947ef7305831f1faaf1512a598", 1446301 },
+ { "data2.cab", 0, "00719c86cab733c1094b27079ce030f3", 145857935 },
AD_LISTEND
},
Common::EN_ANY,
@@ -217,15 +272,15 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED,
GUIO0()
},
- Nancy::kGameTypeNancy3
+ Nancy::kGameTypeNancy5
},
{ // MD5 by clone2727
{
"nancy5", nullptr,
{
- { "data1.hdr", 0, "258e27792fa7cc7a7125fd74d89f8487", 284091},
- { "data1.cab", 0, "70433b30b6114031d54d0c991ad44577", 1446301},
- { "data2.cab", 0, "66f47e4f5e6d431f815aa5250eb044bc", 145857937},
+ { "data1.hdr", 0, "258e27792fa7cc7a7125fd74d89f8487", 284091 },
+ { "data1.cab", 0, "70433b30b6114031d54d0c991ad44577", 1446301 },
+ { "data2.cab", 0, "66f47e4f5e6d431f815aa5250eb044bc", 145857937 },
AD_LISTEND
},
Common::EN_ANY,
@@ -233,7 +288,7 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED,
GUIO0()
},
- Nancy::kGameTypeNancy3
+ Nancy::kGameTypeNancy5
},
{ // MD5 by Strangerke
{
@@ -244,7 +299,7 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
ADGF_UNSTABLE | ADGF_DROPPLATFORM,
GUIO0()
},
- Nancy::kGameTypeNancy3
+ Nancy::kGameTypeNancy6
},
{ AD_TABLE_END_MARKER, Nancy::kGameTypeNone }
};
diff --git a/engines/nancy/detection.h b/engines/nancy/detection.h
index 6036e321a2b..a90c7a9894a 100644
--- a/engines/nancy/detection.h
+++ b/engines/nancy/detection.h
@@ -31,7 +31,10 @@ enum GameType {
kGameTypeVampire = 1,
kGameTypeNancy1 = 2,
kGameTypeNancy2 = 3,
- kGameTypeNancy3 = 4
+ kGameTypeNancy3 = 4,
+ kGameTypeNancy4 = 5,
+ kGameTypeNancy5 = 6,
+ kGameTypeNancy6 = 7
};
enum NancyGameFlags {
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 7f5afc3b112..dff85eb5f86 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -105,18 +105,11 @@ NancyEngine::~NancyEngine() {
}
NancyEngine *NancyEngine::create(GameType type, OSystem *syst, const NancyGameDescription *gd) {
- switch (type) {
- case kGameTypeVampire:
+ if (type >= kGameTypeVampire && type <= kGameTypeNancy6) {
return new NancyEngine(syst, gd);
- case kGameTypeNancy1:
- return new NancyEngine(syst, gd);
- case kGameTypeNancy2:
- return new NancyEngine(syst, gd);
- case kGameTypeNancy3:
- return new NancyEngine(syst, gd);
- default:
- error("Unknown GameType");
}
+
+ error("Unknown GameType");
}
Common::Error NancyEngine::loadGameStream(Common::SeekableReadStream *stream) {
@@ -511,7 +504,7 @@ void NancyEngine::readDatFile() {
uint16 numGames = datFile->readUint16LE();
if (getGameType() > numGames) {
- warning("Data for game type %d is not in nancy.dat", numGames);
+ warning("Data for game type %d is not in nancy.dat", getGameType());
return;
}
Commit: 53f8b4efa4b78a671c1a37e3b84ae8715dcbb989
https://github.com/scummvm/scummvm/commit/53f8b4efa4b78a671c1a37e3b84ae8715dcbb989
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-05-10T16:57:34+03:00
Commit Message:
DEVTOOLS: Add nancy3 data to create_nancy
Changed paths:
A devtools/create_nancy/nancy3_data.h
devtools/create_nancy/create_nancy.cpp
devtools/create_nancy/types.h
diff --git a/devtools/create_nancy/create_nancy.cpp b/devtools/create_nancy/create_nancy.cpp
index 3a9d73ede9e..3a90c19e8e7 100644
--- a/devtools/create_nancy/create_nancy.cpp
+++ b/devtools/create_nancy/create_nancy.cpp
@@ -23,11 +23,12 @@
#include "tvd_data.h"
#include "nancy1_data.h"
#include "nancy2_data.h"
+#include "nancy3_data.h"
#define NANCYDAT_MAJOR_VERSION 0
#define NANCYDAT_MINOR_VERSION 2
-#define NANCYDAT_NUM_GAMES 3
+#define NANCYDAT_NUM_GAMES 4
/**
* Format specifications for nancy.dat:
@@ -60,6 +61,8 @@
* Game order:
* The Vampire Diaries
* Nancy Drew: Secrets Can Kill
+ * Nancy Drew: Stay Tuned for Danger
+ * Nancy Drew: Message in a Haunted Mansion
*/
void NORETURN_PRE error(const char *s, ...) {
@@ -206,6 +209,20 @@ int main(int argc, char *argv[]) {
nullptr,
&_nancy2TelephoneRinging,
_nancy2EventFlagNames);
+
+ // Nancy Drew: Message in a Haunted Mansion data
+ gameOffsets.push_back(output.pos());
+ writeGameData( output,
+ _nancy3Constants,
+ _nancy3LanguagesOrder,
+ &_nancy3ConditionalDialogue,
+ &_nancy3Goodbyes,
+ nullptr,
+ &_nancy3ConditionalDialogueTexts,
+ &_nancy3GoodbyeTexts,
+ nullptr,
+ &_nancy3TelephoneRinging,
+ _nancy3EventFlagNames);
// Write the offsets for each game in the header
output.seek(offsetsOffset);
diff --git a/devtools/create_nancy/nancy3_data.h b/devtools/create_nancy/nancy3_data.h
new file mode 100644
index 00000000000..49a95343fe3
--- /dev/null
+++ b/devtools/create_nancy/nancy3_data.h
@@ -0,0 +1,934 @@
+/* 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 NANCY3DATA_H
+#define NANCY3DATA_H
+
+#include "types.h"
+
+const GameConstants _nancy3Constants ={
+ 18,
+ 336,
+ { }, // 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 },
+ 24,
+ 7,
+ 7000
+};
+
+const Common::Array<Common::Language> _nancy3LanguagesOrder = {
+ Common::Language::EN_ANY,
+ Common::Language::RU_RUS
+};
+
+const Common::Array<Common::Array<ConditionalDialogue>> _nancy3ConditionalDialogue = {
+{ // Abby, 13 responses
+ { 0, 1050, "NAS50",
+ { { 215, true }, { 49, false }, { 218, false } },
+ { } },
+ { 1, 1053, "NAS53",
+ { { 169, true }, { 37, false } },
+ { } },
+ { 2, 1054, "NAS54",
+ { { 213, true }, { 46, false } },
+ { } },
+ { 3, 1055, "NAS55",
+ { { 171, true }, { 44, false } },
+ { } },
+ { 4, 1056, "NAS56",
+ { { 173, true }, { 50, false } },
+ { } },
+ { 5, 1057, "NAS57",
+ { { 211, true }, { 45, false }, { 109, false } },
+ { } },
+ { 6, 1059, "NAS59",
+ { { 146, true }, { 39, false }, { 218, false } },
+ { } },
+ { 7, 1062, "NCL60",
+ { { 109, true }, { 43, false } },
+ { } },
+ { 8, 1064, "NAS64",
+ { { 218, true }, { 225, true }, { 209, true }, { 38, false } },
+ { } },
+ { 9, 1067, "NAS67",
+ { { 223, true }, { 37, true }, { 36, false } },
+ { } },
+ { 10, 1070, "NAS70",
+ { { 37, true }, { 53, false } },
+ { } },
+ { 11, 1071, "NAS71",
+ { { 46, true }, { 41, false } },
+ { } },
+ { 12, 1074, "NAS74",
+ { { 191, true }, { 37, true }, { 218, false }, { 294, false } },
+ { { 13, false } } },
+ { 13, 1075, "NAS75",
+ { { 220, true }, { 51, false }, { 45, false }, { 218, false } },
+ { } }
+},
+{ // Bess & George, 11 responses
+ { 14, 1120, "NBG20",
+ { { 169, true }, { 72, false } },
+ { } },
+ { 15, 1121, "NBG21",
+ { { 171, true }, { 77, false }, { 208, false } },
+ { } },
+ { 16, 1122, "NBG22",
+ { { 197, true }, { 73, false }, { 248, false } },
+ { } },
+ { 17, 1124, "NBG24",
+ { { 73, true }, { 75, false }, { 202, true }, { 246, false } },
+ { } },
+ { 18, 1125, "NBG25",
+ { { 222, true }, { 79, false }, { 218, false } },
+ { } },
+ { 19, 1126, "NBG26",
+ { { 241, true }, { 74, false } },
+ { } },
+ { 20, 1127, "NBG27",
+ { { 223, true }, { 80, false }, { 72, true } },
+ { } },
+ { 21, 1130, "NBG30",
+ { { 208, true }, { 77, true }, { 203, false }, { 295, false } },
+ { } },
+ { 22, 1131, "NBG31",
+ { { 203, true }, { 76, false } },
+ { } },
+ { 23, 1132, "NBG32",
+ { { 297, true }, { 71, false }, { 208, false } },
+ { } },
+ { 24, 1133, "NBG33",
+ { { 168, true } },
+ { } }
+},
+{ // Charlie, 13 responses
+ { 25, 1250, "NCM50",
+ { { 171, true }, { 93, false }, { 298, false } },
+ { } },
+ { 26, 1253, "NCM53",
+ { { 173, true }, { 84, false }, { 223, false } },
+ { } },
+ { 27, 1254, "NCM54",
+ { { 228, true }, { 100, false }, { 219, false } },
+ { } },
+ { 28, 1255, "NCM55",
+ { { 223, true }, { 299, true }, { 97, false } },
+ { } },
+ { 29, 1257, "NCM57",
+ { { 167, true }, { 83, false } },
+ { } },
+ { 30, 1260, "NCM60",
+ { { 219, true }, { 87, false } },
+ { } },
+ { 31, 1263, "NEF40",
+ { { 109, true }, { 91, false } },
+ { } },
+ { 32, 1265, "NCM65",
+ { { 183, true }, { 94, false } },
+ { { 13, false } } },
+ { 33, 1267, "NCM67",
+ { { 145, true }, { 300, false }, { 122, false }, { 218, false } },
+ { } },
+ { 34, 1269, "NCM69",
+ { { 241, true }, { 301, false } },
+ { } },
+ { 35, 1270, "NCM70",
+ { { 297, true }, { 302, false } },
+ { } },
+ { 36, 1273, "NCM73",
+ { { 213, true }, { 303, false } },
+ { } },
+ { 37, 1274, "NCM74",
+ { { 304, true }, { 240, false }, { 305, false } },
+ { } }
+},
+{ // Emily, 10 responses
+ { 38, 1330, "NEF30",
+ { { 204, true }, { 110, false } },
+ { } },
+ { 39, 1331, "NEF31",
+ { { 200, true }, { 108, false } },
+ { } },
+ { 40, 1332, "NEF32",
+ { { 205, true }, { 157, false }, { 111, false } },
+ { } },
+ { 41, 1333, "NEF33",
+ { { 197, true }, { 107, false } },
+ { } },
+ { 42, 1334, "NEF34",
+ { { 171, true }, { 113, false } },
+ { } },
+ { 43, 1335, "NEF35",
+ { { 206, true }, { 112, false } },
+ { } },
+ { 44, 1338, "NEF38",
+ { { 234, true }, { 106, false } },
+ { } },
+ { 45, 1340, "NEF40",
+ { { 203, true }, { 109, false } },
+ { } },
+ { 46, 1341, "NEF41",
+ { { 307, true }, { 118, false } },
+ { } },
+ { 47, 1344, "NEF44",
+ { { 167, true }, { 116, false }, { 107, false } },
+ { } }
+},
+{ // Hannah, 12 responses
+ { 48, 1420, "NHG20",
+ { { 167, true }, { 218, false }, { 129, false } },
+ { } },
+ { 49, 1423, "NHG23",
+ { { 169, true }, { 131, false } },
+ { } },
+ { 50, 1426, "NHG26",
+ { { 171, true }, { 136, false } },
+ { } },
+ { 51, 1429, "NHG29",
+ { { 222, true }, { 140, false } },
+ { } },
+ { 52, 1433, "NHG33",
+ { { 140, true }, { 215, false }, { 139, false } },
+ { } },
+ { 53, 1434, "NHG34",
+ { { 234, true }, { 130, false } },
+ { } },
+ { 54, 1437, "NHG37",
+ { { 241, true }, { 133, false } },
+ { } },
+ { 55, 1438, "NHG38",
+ { { 133, true }, { 214, false }, { 138, false } },
+ { } },
+ { 56, 1439, "NHG39",
+ { { 131, true }, { 223, true }, { 141, false }, { 97, false } },
+ { } },
+ { 57, 1440, "NHG40",
+ { { 208, true }, { 143, false } },
+ { } },
+ { 58, 1441, "NHG41",
+ { { 143, true }, { 203, true }, { 134, false }, { 109, false } },
+ { } },
+ { 59, 1442, "NHG42",
+ { { 97, true }, { 141, true }, { 132, false } },
+ { } }
+},
+{ // Louis, 15 responses
+ { 60, 1550, "NLC50",
+ { { 211, true }, { 165, false } },
+ { } },
+ { 61, 1551, "NLC51",
+ { { 287, true }, { 151, false }, { 241, false} },
+ { } },
+ { 62, 1552, "NLC52",
+ { { 171, true }, { 148, false }, { 98, false } },
+ { } },
+ { 63, 1553, "NLC53",
+ { { 173, true }, { 154, false }, { 148, false } },
+ { } },
+ { 64, 1554, "NLC54",
+ { { 191, true }, { 161, false } },
+ { { 13, false } } },
+ { 65, 1555, "NLC55",
+ { { 213, true }, { 159, false }, { 160, true } },
+ { } },
+ { 66, 1557, "NLC57",
+ { { 95, true }, { 162, false } },
+ { } },
+ { 67, 1558, "NLC58",
+ { { 98, true }, { 164, false } },
+ { } },
+ { 68, 1559, "NLC59",
+ { { 190, true }, { 163, false } },
+ { } },
+ { 69, 1560, "NLC60",
+ { { 109, true }, { 153, false } },
+ { } },
+ { 70, 1562, "NLC62",
+ { { 206, true }, { 157, false } },
+ { } },
+ { 71, 1565, "NLC65",
+ { { 205, true }, { 156, false }, { 165, true } },
+ { } },
+ { 72, 1566, "NAS54",
+ { { 213, true }, { 160, false } },
+ { } },
+ { 73, 1567, "NLC67",
+ { { 169, true }, { 37, true }, { 160, false } },
+ { } },
+ { 74, 1568, "NLC68",
+ { { 288, true }, { 153, false }, { 123, false }, { 157, true } },
+ { } },
+},
+{ // Ned, 0 responses
+},
+{ // Rose,
+ { 75, 1750, "NRM17",
+ { { 211, true }, { 186, false } },
+ { } },
+ { 76, 1751, "NRM18",
+ { { 169, true }, { 179, false } },
+ { } },
+ { 77, 1752, "NRM19",
+ { { 171, true }, { 185, false } },
+ { } },
+ { 78, 1753, "NRM20",
+ { { 167, true }, { 177, false } },
+ { } },
+ { 79, 1754, "NRM21",
+ { { 241, true }, { 214, true }, { 187, false } },
+ { } },
+ { 80, 1755, "NRM55",
+ { { 196, true }, { 178, false } },
+ { } },
+ { 81, 1757, "NRM22",
+ { { 206, true }, { 184, false } },
+ { } },
+ { 82, 1758, "NRM23",
+ { { 167, true }, { 222, false }, { 192, false } },
+ { } },
+ { 83, 1759, "NRM24",
+ { { 213, true }, { 227, true }, { 188, false } },
+ { } },
+ { 84, 1761, "NRM25",
+ { { 84, true }, { 308, false }, { 179, true } },
+ { } },
+ { 85, 1762, "NAS67",
+ { { 84, true }, { 97, false }, { 299, false }, { 179, true } },
+ { } },
+ { 86, 1763, "NRM27",
+ { { 225, true }, { 38, false }, { 309, false }, { 310, true } },
+ { } },
+ { 87, 1764, "NRM28",
+ { { 311, true }, { 312, false }, { 171, false } },
+ { } },
+ { 88, 1765, "NRM29",
+ { { 220, true }, { 38, false }, { 310, false } },
+ { } },
+ { 89, 1756, "NLC60",
+ { { 203, true }, { 124, false } },
+ { } },
+}
+};
+
+const Common::Array<Goodbye> _nancy3Goodbyes = {
+ { "NAS90", { { { 1090, 1091, 1092, 1093, 1094, 1095, 1096 }, {}, NOFLAG } } }, // Abby
+ { "NBG90", { { { 1190, 1191, 1192, 1193, 1194 }, {}, NOFLAG } } }, // Bess & George
+ { "NCM90", { { { 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298 }, {}, NOFLAG } } }, // Charlie
+ { "NEF90", { { { 1390, 1391, 1392, 1393, 1394 }, {}, NOFLAG } } }, // Emily
+ { "NHG90", { { { 1490, 1491, 1492, 1493, 1494 }, {}, NOFLAG } } }, // Hannah
+ { "NLC90", { { { 1590, 1591, 1592, 1593, 1594 }, {}, NOFLAG } } }, // Louis
+ { "NNN90", { { { 1690, 1691, 1692, 1693, 1694 }, {}, NOFLAG } } }, // Ned
+ { "NRG90", { { { 1790, 1791, 1792, 1793, 1795, 1796 }, {}, NOFLAG } } }, // Rose
+};
+
+const Common::Array<Common::Array<const char *>> _nancy3ConditionalDialogueTexts {
+{ // English
+ // 00
+ "I found out how you rigged the seance table with the projector. That was a pretty good show you gave.<h><n>", // NAS50
+ "What kind of person is Charlie? He seems to feel bad about all of these mishaps.<h><n>", // NAS53
+ "Have you seen the poem in my room?<h><n>", // NAS54
+ "Do you know much about Louis? It must be great having your own expert on Victorians.<h><n>", // NAS55
+ "How long have you known Rose?<h><n>", // NAS56
+ // 05
+ "I saw those papers in the parlor. Where did you find them?<h><n>", // NAS57
+ "I heard someone crying in the hallway. Was that you?<h><n>", // NAS59
+ "Do you know what 'Gum Bo Fu' means?<h><n>", // NLC60
+ "I found out how you wired the house to make it 'haunted'. The only ghost who walks these halls is you, Abby.<h><n>", // NAS64
+ "Does Charlie live around here?<h><n>", // NAS67
+ // 10
+ "You mentioned Charlie was 'suspicious'. How so?<h><n>", // NAS70
+ "Did the house come with a lot of furniture?<h><n>", // NAS71
+ "Do you know where I can find a paintscraper?<h><n>", // NAS74
+ "Have you noticed the dead flowers in the parlor?<h><n>", // NAS75
+ "I met the 'resident handyman', Charlie. He's pretty young and I don't think he has much experience.<h><n>", // NBG20
+ // 15
+ "Rose is really lucky. This antique dealer, Louis Chandler, is helping her out - although he doesn't know very much about the house's history.<h><n>", // NBG21
+ "Listen to this. I found a secret attic and an old desk. It looks like no one's been in there for years.<h><n>", // NBG22
+ "I found some letters written by E. Valdez. I guess he was the owner of a hotel named 'The Golden Gardenia'.<h><n>", // NBG24
+ "Abby hosted a seance and contacted the spirit who's haunting the house.<h><n>", // NBG25
+ "There was a small fire in the house but luckily I put it out. But the old papers that Abby found were destroyed.<h><n>", // NBG26
+ // 20
+ "I found a secret room in the basement and it looks like someone is living there.<h><n>", // NBG27
+ "I was spying on Louis and saw him take a book from the library. He put it in his briefcase.<h><n>", // NBG30
+ "Do either of you know what 'gum bo fu' means?<h><n>", // NBG31
+ "I found a hidden passageway in the library.<h><n>", // NBG32
+ "Can you guys give me a clue? I'm not sure what to do next.<h><n>", // NGB33
+ // 25
+ "Have you met Louis Chandler? What do you know about him?<h><n>", // NCM50
+ "Can you tell me more about the accidents?<h><n>", // NCM53
+ "Have you ever heard of someone named, Valdez?<h><n>", // NCM54
+ "Charlie, I know your secret. I know you're living in the hidden room behind the saloon.<h><n>", // NCM55
+ "How do you like working for Abby?<h><n>", // NCM57
+ // 30
+ "Charlie, I found this diskette. I think it's yours.<h><n>", // NCM60
+ "Do you know what the words, 'gum bo fu' mean?<h><n>", // NEF40
+ "Charlie, do you know where I can find a paint scraper?<h><n>", // NCM65
+ "Do you know how I can get into Abby's room?<h><n>", // NCM67
+ "Who was the last person you saw in the parlor before the fire?<h><n>", // NCM69
+ // 35
+ "Have you come across any hidden passageways down here?<h><n>", // NCM70
+ "Have you seen the poem in the Chinese room?<h><n>", // NCM73
+ "What is that small closet in the hallway for?<h><n>", // NCM74
+ "Can you tell me about the Chinese writing system? I seem to come across a lot of Chinese symbols.<h><n>", // NEF30
+ "I found some old papers in the house, plus a page from a phone directory dated 1894.<h><n>" // NEF31
+ // 40
+ "Have you ever heard of the Ladies Protection Society?<h><n>", // NEF32
+ "What do you know about 'The Bandit's Treasure'?<h><n>", // NEF33
+ "Have you heard of an antique dealer named Louis Chandler?<h><n>", // NEF34
+ "Have you heard of an actress, Lizzie Applegate?<h><n>", // NEF35
+ "Have you ever come across hidden rooms in Victorian mansions?<h><n>", // NEF38
+ // 45
+ "Do you know what the words, 'gum bo fu' mean?<h><n>", // NEF40
+ "Do you know where Yerba Buena town is?<h><n>", // NEF41
+ "Do you know anything about 'Valdez'?<h><n>" // NEF44
+ "Abby is very strange. She really is convinced there's a ghost somewhere in the house.<h><n>", // NHG20
+ "I met Rose's handyman, Charlie. He seems nice.<h><n>", // NHG23
+ // 50
+ "Did you know Rose has a resident expert on Victorians?<h><n>", // NHG26
+ "Have you heard about the seance Abby hosted for Rose and me?<h><n>" // NHG29
+ "Abby faked the seance. She rigged a table with a projector.<h><n>", // NHG33
+ "I just found a hidden attic. I wonder if it has anything to do with all these accidents.<h><n>" // NHG34
+ "There was a fire in the parlor but I put it out in time.<h><n>" // NHG37
+ // 55
+ "Hannah, do you think Rose could have started the fire to collect the insurance on the house?<h><n>" // NHG38
+ "This house is full of surprises. I found a secret room in the basement where someone's been living.<h><n>", // NHG39
+ "Louis is up to something. I saw him take a book from the library.<h><n>", // NHG40
+ "Louis's book mentioned that this house was once called 'gum bo fu' in the 1800's.<h><n>", // NHG41
+ "It turns out Charlie is the one living in the basement.<h><n>", // NHG42
+ // 60
+ "I was wondering whether you knew anything about someone named 'E. Valdez'?<h><n>", // NLC50
+ "Have you ever heard of the Great Christmas gold robbery?<h><n>" // NLC51
+ "What kind of antique store do you own?<h><n>", // NLC52
+ "Was this house once a hotel?<h><n>" // NLC53
+ "Have you seen a paint scraper anywhere?<h><n>", // NLC54
+ // 65
+ "Do you know what a phoenix is?<h><n>", // NLC55
+ "Do you know why the fireplace in the parlor didn't have a screen?<h><n>", // NLC57
+ "Have you found any secret passage ways in this house?<h><n>", // NLC58
+ "Do you think Rose should sell the house?<h><n>" // NLC59
+ "Do you know what 'gum bo fu' means?<h><n>", // NLC60
+ // 70
+ "Do you know who Lizzie Applegate was?<h><n>", // NLC62
+ "What was the Ladies Protection Society?<h><n>", // NLC65
+ "Have you seen the poem in my room?<h><n>", // NAS54
+ "Do you think Charlie is doing a good job?<h><n>", // NLC67
+ "Did Lizzie ever wear men's clothing?<h><n>" // NLC68
+ // 75
+ "Where did Abby find those papers that are in the parlor?<h><n>" // NRM17
+ "How did you find Charlie?<h><n>", // NRM18
+ "How do you know Louis?<h><n>", // NRM19
+ "How did you meet Abby?<h><n>", // NRM20
+ "Excuse me for prying, but why did you spend so much money to insure the house against fire?<h><n>", // NRM21
+ // 80
+ "Are you missing any papers?<h><n>", // NRM55
+ "Have you heard of someone named Lizzie Applegate?<h><n>", // NRM22
+ "What is Abby planning for tonight?<h><n>", // NRM23
+ "Have you found any rainbow designs in the house?<h><n>" // NRM24
+ "Do you think Charlie is responsible for these accidents?<h><n>" // NRM25
+ // 85
+ "Does Charlie live around here?<h><n>", // NAS67
+ "Do you know why there's a speaker in the air vent?<h><n>", // NRM27
+ "Whose laptop is that in the library?<h><n>" // NRM28
+ "Why are there dead roses in the parlor?<h><n>", // NRM29
+ "Do you know what 'gum bo fu' means?<h><n>", // NLC60
+},
+{ // Russian
+ // 00
+ "Z pyf-, xnj ds gjlcnhjbkb ctfyc. Kjdrj ghblevfyj.<h><n>", // NAS50
+ "Ds vj&tnt hfccrfpfnm j XfhkbM Rf&tncz, jy jxtym hfccnhjty bpSpf dctuj ghjbc(jlzotuj.<h><n>", // NAS53
+ "Ds dbltkb gj?ve d vjtq rjvyfntM<h><n>", // NAS54
+ "Pljhjdj, yfdthyjt, xnj dfv gjvjuftn ?rcgthn gj Dbrnjhbfycrjq ?gj(t.<h><n>", // NAS55
+ "Rfr lfdyj ds pyfrjvs c HjepM<h><n>", // NAS56
+ // 05
+ "Z ghjcvjnhtkf ljrevtyns d ujcnbyjq. Ult ds b( yfikbM<h><n>", // NAS57
+ "Z cksifkf d rjhbljht xtqSnj gkfx. Rnj ?nj vju ;snmM<h><n>", // NAS59
+ "Ds pyftnt, xnj nfrjt 'Ufv /j Ae'M<h><n>", // NLC60
+ "Z yfikf fggfhfnehe, c gjvjom- rjnjhjq ds j;vfysdfkb yfc. Tckb d ?njv ljvt b tcnm ghbphfr, nfr ?nj S ds, =;;b.<h><n>", // NAS64
+ "Xfhkb ytlfktrj &bdtnM<h><n>", // NAS67
+ // 10
+ "Ds ujdjhbkb, xnj d Xfhkb tcnm xnjSnj gjljphbntkmyjt. GjxtveM<h><n>", // NAS70
+ "Ds regbkb ljv dvtcnt c vt;tkm-M<h><n>", // NAS71
+ "Ds yt gjlcrf&tnt, ult vj&yj yfqnb igfntkmM<h><n>", // NAS74
+ "Ds pfvtnbkb, xnj wdtns d ujcnbyjq lfdyj pfdzkbM<h><n>", // NAS75
+ "Z gjpyfrjvbkfcm c hf;jxbv, Xfhkb. Jy ljdjkmyj vjkjl. Yj vyt rf&tncz, xnj tve yt (dfnftn jgsnf.<h><n>", // NBG20
+ // 15
+ "Hjep jxtym gjdtpkj. Tq gjvjuftn njhujdtw fynbrdfhbfnjv, Kebc Xtylkth. +jnz jy b yt jxtym (jhjij pyftn bcnjhb- jcj;yzrf.<h><n>", // NBG21
+ "Pyftnt, z yfikf xthlfr b cnfhbyysq ctrhtnth. Rf&tncz, nelf ybrnj yt pfukzlsdfk djn e&t ytcrjkmrj ktn.<h><n>", // NBG22
+ "Z yfikf gbcmvf c gjlgbcm- =. Dfkmltp. Levf-, xnj ?njn xtkjdtr ;sk dkfltkmwtv jntkz 'Pjkjnfz ufhltybz'.<h><n>", // NBG24
+ "=;;b ecnhjbkf cgbhbnbxtcrbq ctfyc b ghbpdfkf le(f, rjnjhsq &bdtn d jcj;yzrt.<h><n>", // NBG25
+ "Pltcm ghjbpjitk yt;jkmijq gj&fh, yj vyt elfkjcm tuj gjneibnm. Ghfdlf, ljrevtyns, rjnjhst yfikf =;;b, ;skb eybxnj&tys.<h><n>", // NBG26
+ // 20
+ "..Z yfikf gjnfqye- rjvyfne d gjldfkt. Rf&tncz, nfv rnjSnj &bdtn.<h><n>", // NBG27
+ "Z dbltkf, rfr Kebc dpzk jlye bp rybu d ;b;kbjntrt. Jy gjkj&bk tt d cdjq lbgkjvfn.<h><n>", // NBG30
+ "Ds pyftnt, xnj nfrjt 'Ufv /j Ae'M<h><n>", // NBG31
+ "Z yfikf gjnfqye- rjvyfne d ;b;kbjntrt.<h><n>", // NBG32
+ "Ds yt vjukb ;s lfnm vyt gjlcrfpreM<h><n>", // NBG33
+ // 25
+ "Ns e&t dcnhtxfk Kebcf XtylkthfM Ns xnjSyb;elm j ytv pyftimM<h><n>", // NCM50
+ "Ns vj&tim hfccrfpfnm vyt ;jkmit j ytcxfcnys( ckexfz(M<h><n>", // NCM53
+ "Ns pyftim xnjSyb;elm j xtkjdtrt gj bvtyb DfkmltpM<h><n>", // NCM54
+ "Xfhkb, z pyf- ndjq ctrhtn. Z pyf-, xnj ns &bdtim d gjnfqyjq rjvyfnt d gjldfkt.<h><n>", // NCM55
+ "Nt;t yhfdbncz hf;jnfnm yf =;;bM<h><n>", // NCM57
+ // 30
+ "Xfhkb, z yfikf ?ne lbcrtne. Levf-, jyf ndjz.<h><n>", // NCM60
+ "Ns pyftim, xnj nfrjt 'Ufv /j Ae'M<h><n>", // NEF40
+ "Xfhkb, ns pyftim, ult vj&yj dpznm igfntkmM<h><n>", // NCM65
+ "Ns pyftim, rfr gjgfcnm d rjvyfne =;;bM<h><n>", // NCM67
+ "Ns dbltk rjujSyb;elm d ujcnbyjq gthtl gj&fhjvM<h><n>", // NCM69
+ // 35
+ "Ns yf(jlbk d jcj;yzrt nfqyst (jlsM<h><n>", // NCM70
+ "Ns dbltk gj?ve d rbnfqcrjq rjvyfntM<h><n>", // NCM73
+ "Ns pyftim, xnj crhsdftncz pf yt;jkmijq ldthwtq d rjhbljhtM<h><n>", // NCM74
+ "Ns yt vjukf ;s hfccrfpfnm j rbnfqcrjq cbcntvt gbcmvfM Ytlfdyj vyt pltcm gjgfkbcm bthjukbas.<h><n>", // NEF30
+ "Z yfikf cnfhst ljrevtyns d ljvt b cnhfybwe ntktajyyjuj cghfdjxybrf 1894 u.<h><n>", // NEF31
+ // 40
+ "Ns cksifkf j; J;otcndt pfobns &tyobyM<h><n>", // NEF32
+ "Xnj nt;t bpdtcnyj j 'Cjrhjdbot ;fylbnf'M<h><n>", // NEF33
+ "Ns cksifkf j njhujdwt fynbrdfhbfnjv Kebct XtylkthtM<h><n>", // NEF34
+ "Nt;t pyfrjvf frnhbcf Kbppb =ggkutqnM<h><n>", // NEF35
+ "Ns cksifkf j gjnfqys( rjvyfnf( d dbrnjhbfycrb( jcj;yzrf(M<h><n>", // NEF38
+ // 45
+ "Ns pyftim, xnj pyfxbn ckjdj 'Ufv /j Ae'M<h><n>", // NEF40
+ "Ns cksifkf j ujhjlt Qth;f /e?yfM<h><n>", // NEF41
+ "Nt;t xnjSyb;elm bpdtcnyj j<n>DfkmltptM<h><n>", // NEF44
+ "=;;b nfrfz cnhfyyfz. Jyf ltqcndbntkmyj dthbn d nj, xnj d ljvt &bdtn ghbphfr.<h><n>", // NHG20
+ "E Hjep tcnm jlby hf;jnybr. Tuj pjden Xfhkb.<h><n>", // NHG23
+ // 50
+ "Ns pyfkf, xnj e Hjep tcnm ?rcgthn gj Dbrnjhbfycrjq ?gj(tM<h><n>", // NHG26
+ "=;;b ghjdtkf lkz yfc c Hjep ctfyc dspsdfybz le(jd.<h><n>", // NHG29
+ "Ctfyc =;;b jrfpfkcz abrwbtq. Gjl cnjkjv cnjzk ghjtrnjh.<h><n>", // NHG33
+ "Z yfikf rjvyfne yf xthlfrt. Bynthtcyj, cdzpfyf kb jyf c gjcktlybvb cj;snbzvbM<h><n>", // NHG34
+ "Ujcnbyfz xenm yt cujhtkf, yj z gjneibkf gj&fh.<h><n>", // NHG37
+ // 55
+ "+fyyf, Hjep vjukf ecnhjbnm gj&fh, xnj;s gjkexbnm cnhf(jdreM<h><n>", // NHG38
+ "=njn ljv gjkjy c-hghbpjd. Z yfikf d gjldfkt nfqye- rjvyfne, d rjnjhjq rnjSnj &bdtn.<h><n>", // NHG39
+ "Kebc xnjSnj pfvsikztn. Z dbltkf, rfr jy ;hfk rybue d ;b;kbjntrt.<h><n>", // NHG40
+ "D rybut Kebcf yfgbcfyj, xnj d 19 dtrt ?njn ljv yfpsdfkcz 'Ufv /j Ae'.<h><n>", // NHG41
+ "Jrfpfkjcm, xnj Xfhkb &bdtn d gjldfkt ljvf.<h><n>", // NHG42
+ // 60
+ "Z (jntkf cghjcbnm, ds pyftnt xnjSyb;elm j xtkjdtrt gj bvtyb =. DfkmltpM<h><n>", // NLC50
+ "Ds cksifkb j Dtkbrjv hj<cndtycrjv juhf;ktybbM<h><n>", // NLC51
+ "E dfc tcnm cj;cndtyysq fynbrdfhysq vfufpbyM<h><n>", // NLC52
+ "Ds pyftnt, hfymit pltcm ;skf ujcnbybwfM<h><n>", // NLC53
+ "Ds dbltkb ultSyb;elm igfntkmM<h><n>", // NLC54
+ // 65
+ "Ds pyftnt, xnj nfrjt atybrcM<h><n>", // NLC55
+ "Ds pyftnt, gjxtve e rfvbyf d ujcnbyjq ytn pfobnyjuj ?rhfyfM<h><n>", // NLC57
+ "Ds dbltkb d ?njv ljvt gjnfqyst rjvyfnsM<h><n>", // NLC58
+ "Ds levftnt, xnj Hjep kexit ghjlfnm ljvM<h><n>", // NLC59
+ "Ds pyftnt, xnj nfrjt 'Ufv /j Ae'M<h><n>", // NLC60
+ // 70
+ "Ds pyftnt, rnj nfrfz Kbppb =ggkutqnM<h><n>", // NLC62
+ "Ds pyftnt j; J;otcndt pfobns &tyobyM<h><n>", // NLC65
+ "Ds dbltkb gj?ve d vjtq rjvyfntM<h><n>", // NAS54
+ "GjSdfitve, Xfhkb (jhjij hf;jnftnM<h><n>", // NLC67
+ "Kbppb yjcbkf ve&cre- jlt&leM<h><n>", // NLC68
+ // 75
+ "Ult =;;b yfikf ;evfub, rjnjhst kt&fn d ujcnbyjqM<h><n>", // NRM17
+ "Rfr ds yfikb XfhkbM<h><n>", // NRM18
+ "Jnrelf ds pyftnt KebcfM<h><n>", // NRM19
+ "Ult ds dcnhtnbkb =;;bM<h><n>", // NRM20
+ "Ghjcnbnt pf k-;jgsncndj, yj gjxtve ds gjnhfnbkb nfr vyjuj ltytu yf cnhf(jdre jn gj&fhfM<h><n>", // NRM21
+ // 80
+ "E dfc yt ghjgflfkb ;evfubM<h><n>", // NRM55
+ "Ds cksifkb j Kbppb =ggkutqnM<h><n>", // NRM22
+ "Xnj =;;b gkfybhetn yf dtxthM<h><n>", // NRM23
+ "Ds dbltkb d ljvt bpj;hf&tybz hfleubM<h><n>", // NRM24
+ "Ds levftnt, xnj d gjcktlyb( cj;snbz( dbyjdfn XfhkbM<h><n>", // NRM25
+ // 85
+ "Xfhkb ytlfktrj &bdtnM<h><n>", // NAS67
+ "Pfxtv d rjhbljht ecnfyjdkty lbyfvbrM<h><n>", // NRM27
+ "Xtq yjen;er cnjbn d ;b;kbjntrtM<h><n>", // NRM28
+ "Gjxtve d ujcnbyjq cnjzn edzlibt hjpsM<h><n>", // NRM29
+ "Ds pyftnt, xnj nfrjt 'Ufv /j Ae'M<h><n>" // NLC60
+}
+};
+
+const Common::Array<Common::Array<const char *>> _nancy3GoodbyeTexts = {
+{ // English
+ "I'll let you get back to what you were doing.<h>", // NAS90
+ "I should get going. Talk to you later.<h>", // NBG90
+ "I'll let you get back to your renovation.<h>", // NCM90
+ "I should get going. Goodbye, Emily.<h>" // NEF90
+ "I should get back to work. Goodbye.<h>" // NHG90
+ "I won't keep you any longer.<h>", // NLC90
+ "Goodbye, Ned.<h>", // NNN90
+ "I can see you're busy - I'll let you go.<h>" // NRG90
+},
+{ // Russian
+ "Yt ;ele dfv ;jkmit vtifnm.<h>", // NAS90
+ "Vyt gjhf blnb. Tot edblbvcz.<h>", // NBG90
+ "Vyt gjhf blnb. Tot edblbvcz.<h>", // NCM90
+ "Vyt ye&yj blnb. Lj cdblfybz, =vbkb.<h>", // NEF90
+ "Vyt e&t gjhf. Lj cdblfybz.<h>", // NHG90
+ "/jkmit yt ;ele vtifnm.<h>", // NLC90
+ "Gjrf, Y?l.<h>", // NNN90
+ "Ye, yt ;ele ;jkmit vtifnm.<h>" // NRG90
+}
+};
+
+const Common::Array<const char *> _nancy3TelephoneRinging = {
+ "ringing...<n><e>", // English
+ "Cjtlbytybt...<n><e>" // Russian
+};
+
+const Common::Array<const char *> _nancy3EventFlagNames = {
+ "Generic 0",
+ "Generic 1",
+ "Generic 2",
+ "Generic 3",
+ "Generic 4",
+ "Generic 5",
+ "Generic 6",
+ "Generic 7",
+ "Generic 8",
+ "Generic 9",
+ "Generic 10",
+ "Generic 11",
+ "Generic 12",
+ "Generic 13",
+ "Generic 14",
+ "Generic 15",
+ "Generic 16",
+ "Generic 17",
+ "Generic 18",
+ "Generic 19",
+ "Generic 20",
+ "Generic 21",
+ "Generic 22",
+ "Generic 23",
+ "Generic 24",
+ "Generic 25",
+ "Generic 26",
+ "Generic 27",
+ "Generic 28",
+ "Generic 29",
+ "Generic 30",
+ "time for end game",
+ "player won game",
+ "stop player scrolling",
+ "easter eggs",
+ "A said accident",
+ "A said address",
+ "A said Charlie",
+ "A said confess",
+ "A said crying",
+ "A said fire",
+ "A said furniture",
+ "A said ghost",
+ "A said gumbo ",
+ "A said Louis",
+ "A said papers",
+ "A said poem",
+ "A said publicity",
+ "A said rents",
+ "A said rig",
+ "A said rose",
+ "A said roses",
+ "A said seance",
+ "A said sneaky",
+ "Abby available",
+ "attic rope broke",
+ "attic tile01 off",
+ "attic tile02 off",
+ "attic tile03 off",
+ "attic tile04 off",
+ "attic tile05 off",
+ "attic tile06 off",
+ "attic tile07 off",
+ "attic tile08 off",
+ "attic tile09 off",
+ "attic tile10 off",
+ "attic tile11 off",
+ "attic tile12 off",
+ "attic tile13 off",
+ "attic tile14 off",
+ "attic tile15 off",
+ "BG said bookcase",
+ "BG said Charlie",
+ "BG said desk",
+ "BG said fire",
+ "BG said gardenia",
+ "BG said gumbo",
+ "BG said Louis",
+ "BG said policy",
+ "BG said seance",
+ "BG said secret",
+ "BG said steal",
+ "bookshelf open",
+ "C said Abby",
+ "C said accidents",
+ "C said apology",
+ "C said Diablo",
+ "C said diskette",
+ "C said ditch",
+ "C said fire",
+ "C said gold",
+ "C said gumbo",
+ "C said haunted",
+ "C said Louis",
+ "C said scraper",
+ "C said screen",
+ "C said seance",
+ "C said secret",
+ "C said thump",
+ "C said upset",
+ "C said Valdez",
+ "C upset",
+ "chain1 off",
+ "chain2 off",
+ "Charlie available",
+ "diskette in laptop",
+ "E said attic",
+ "E said bandit",
+ "E said directory",
+ "E said gumbo",
+ "E said Hanzi",
+ "E said ladies",
+ "E said Lizzie",
+ "E said Louis",
+ "E said Mexico",
+ "E said recluse",
+ "E said Valdez",
+ "E said Victoria",
+ "E said Yerba",
+ "event01",
+ "event02",
+ "event03",
+ "event04",
+ "event05",
+ "event06",
+ "event07",
+ "event08",
+ "event09",
+ "event10",
+ "H said Abby",
+ "H said attic",
+ "H said Charlie",
+ "H said confession",
+ "H said fire",
+ "H said gumbo",
+ "H said haunted",
+ "H said Louis",
+ "H said owner",
+ "H said policy",
+ "H said projector",
+ "H said seance",
+ "H said secret",
+ "H said spindle",
+ "H said steal",
+ "H said Valdez",
+ "heard argument",
+ "heard crying",
+ "heard door shut",
+ "L said antique",
+ "L said busy",
+ "L said Charlie",
+ "L said christmas",
+ "L said fire",
+ "L said gumbo",
+ "L said hotel",
+ "L said insulate",
+ "L said ladies",
+ "L said Lizzie",
+ "L said papers",
+ "L said Phoenix",
+ "L said poem",
+ "L said scraper",
+ "L said screen",
+ "L said sellout",
+ "L said thump"
+ "L said Valdez",
+ "Louis available",
+ "met Abby",
+ "met BG"
+ "met Charlie",
+ "met Emily",
+ "met Louis",
+ "met Ned",
+ "met Rose",
+ "N said haunt",
+ "N said treasure",
+ "opened attic",
+ "R said Abby",
+ "R said ashes",
+ "R said Charlie",
+ "R said dumbwaiter",
+ "R said fire",
+ "R said Hx",
+ "R said inlay",
+ "R said Lizzie",
+ "R said Louis",
+ "R said papers",
+ "R said policy",
+ "R said rainbow",
+ "R said seance",
+ "R said sellout",
+ "R said tiles",
+ "R said tonight",
+ "R said winter",
+ "Rose available",
+ "said stunt",
+ "saw ashes",
+ "saw bandits",
+ "saw blink",
+ "saw desk lock",
+ "saw directory",
+ "saw E note",
+ "saw gardenia",
+ "saw gumbo",
+ "saw Hanzi",
+ "saw Kehne letter",
+ "saw Lizzie book",
+ "saw locked Armoire",
+ "saw Louis steal",
+ "saw mirror",
+ "saw music",
+ "saw papers",
+ "saw passage",
+ "saw poem",
+ "saw policy",
+ "saw projector",
+ "saw pyramid",
+ "saw rainbow",
+ "saw recorder",
+ "saw report",
+ "saw roses",
+ "saw safe",
+ "saw seance",
+ "saw secret room",
+ "saw shadow",
+ "saw speaker",
+ "saw threat",
+ "saw treasure map",
+ "saw Valdez",
+ "saw zodiac",
+ "screw01 off",
+ "screw02 off",
+ "screw03 off",
+ "screw04 off",
+ "solved attic",
+ "solved brief",
+ "solved brief left",
+ "solved brief right",
+ "solved charm",
+ "solved desk",
+ "solved dumbwaiter",
+ "solved fire",
+ "solved fiver",
+ "solved inlay",
+ "solved mantle",
+ "solved piano",
+ "solved safe",
+ "solved slider",
+ "solved spindle",
+ "solved template",
+ "solved zodiac",
+ "stop spooky01",
+ "stop spooky02",
+ "stop spooky 03",
+ "stop spooky04",
+ "stop spooky05",
+ "stop spooky06",
+ "stop spooky07",
+ "stop spooky08",
+ "stop spooky09",
+ "stop spooky10",
+ "tape in deck",
+ "tile01 off",
+ "tile02 off",
+ "tile03 off",
+ "tile04 off",
+ "tile05 off",
+ "tile06 off",
+ "tile07 off",
+ "tile08 off",
+ "tile09 off",
+ "tile1 - pos1",
+ "tile1 pos2",
+ "tile1 pos3",
+ "tile10 off",
+ "tile11 off",
+ "tile12 off",
+ "tile13 off",
+ "tile14 off",
+ "tile15 off",
+ "tile2 pos1",
+ "tile2 pos2",
+ "tile2 pos3",
+ "tile3 pos1",
+ "tile3 pos2",
+ "tile3 pos3",
+ "saw gardenia letter",
+ "saw robbery book",
+ "A said men",
+ "sound 0",
+ "sound 1",
+ "sound 2",
+ "sound 3",
+ "sound 4",
+ "A said scraper",
+ "BG said Louis Steal",
+ "empty",
+ "saw bookcase",
+ "solved tiles",
+ "R said Iowa",
+ "C said Knox",
+ "C said last ",
+ "C said trap",
+ "C said poem",
+ "saw dumbwaiter",
+ "C said dumb",
+ "Louis says Lizzie",
+ "saw Yerba",
+ "R said trust",
+ "R said PA",
+ "R said roses",
+ "saw laptop",
+ "R said laptop",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+ "empty",
+};
+
+#endif // NANCY3DATA_H
diff --git a/devtools/create_nancy/types.h b/devtools/create_nancy/types.h
index f6191ef4250..ac46452098e 100644
--- a/devtools/create_nancy/types.h
+++ b/devtools/create_nancy/types.h
@@ -42,7 +42,7 @@ struct GameConstants {
struct EventFlagDescription {
int16 label;
- NancyFlag flag;
+ byte flag; // NancyFlag up to nancy2, bool from nancy3 up
};
struct SceneChangeDescription {
More information about the Scummvm-git-logs
mailing list