[Scummvm-git-logs] scummvm master -> 8e0d4dfa7a31ad3b5093c92268803a49276da037

sev- noreply at scummvm.org
Thu Mar 2 13:28:20 UTC 2023


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

Summary:
2c798c6e43 DEVTOOLS: Add create_nancy project
62553f2b9f DEVTOOLS: Add create_nancy description to README
3680c8ec57 DISTS: Add nancy.dat to engine data
ec1ce07669 DEVTOOLS: create_nancy code cleanup
8e0d4dfa7a DEVTOOLS:  Fix compile errors


Commit: 2c798c6e43bf74370155019861a28a6d78dc21c2
    https://github.com/scummvm/scummvm/commit/2c798c6e43bf74370155019861a28a6d78dc21c2
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-02T14:28:10+01:00

Commit Message:
DEVTOOLS: Add create_nancy project

Add initial version of create_nancy, which generates a datafile(nancy.dat) containing various data for games using the Nancy Drew engine.

Changed paths:
  A devtools/create_nancy/create_nancy.cpp
  A devtools/create_nancy/file.cpp
  A devtools/create_nancy/file.h
  A devtools/create_nancy/module.mk
  A devtools/create_nancy/nancy1_data.h
  A devtools/create_nancy/tvd_data.h
  A devtools/create_nancy/types.h


diff --git a/devtools/create_nancy/create_nancy.cpp b/devtools/create_nancy/create_nancy.cpp
new file mode 100644
index 00000000000..9623c83201a
--- /dev/null
+++ b/devtools/create_nancy/create_nancy.cpp
@@ -0,0 +1,212 @@
+/* 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/>.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "file.h"
+#include "tvd_data.h"
+#include "nancy1_data.h"
+
+#define NANCYDAT_MAJOR_VERSION 0
+#define NANCYDAT_MINOR_VERSION 1
+
+#define NANCYDAT_NUM_GAMES 2
+
+/**
+ * Format specifications for nancy.dat:
+ * 4 bytes              Magic string 'NNCY'
+ * 1 byte               Major version number
+ * 1 byte               Minor version number
+ * 2 bytes              Number of games (ignoring multiple languages)
+ * 4 bytes per game     File offsets for every game's data
+ * 
+ * Game data order:
+ *      Game constants structure
+ *      Array with the order of game languages
+ *      Conditional dialogue (logic)
+ *      Goodbyes (logic)
+ *      Hints (logic)
+ *      Conditional dialogue (text)
+ *      Goodbyes (text)
+ *      Hints (text)  
+ *      Telephone ringing text
+ *      Item names
+ *      Event flag names
+ * 
+ * Arrays in the game data are variable-size.
+ * All arrays are preceded by a 2-byte size property.
+ * 2D arrays with strings (e.g conditional dialogue) are also preceded
+ * by a list of 4-byte offsets (one per language).
+ * Nonexistent data isn't skipped, but has size 0.
+ * All offsets are absolute (relative to start of file)
+ * 
+ * Game order:
+ *      The Vampire Diaries
+ *      Nancy Drew: Secrets Can Kill
+*/
+
+void NORETURN_PRE error(const char *s, ...) {
+	printf("%s\n", s);
+	exit(1);
+}
+
+void writeGameData( File &output,
+                    const GameConstants &gameConstants,
+                    const Common::Array<Common::Language> &languages,
+                    const Common::Array<Common::Array<ConditionalDialogue>> *conditionalDialogue,
+                    const Common::Array<Goodbye> *goodbyes,
+                    const Common::Array<Common::Array<Hint>> *hints,
+                    const Common::Array<Common::Array<const char *>> *dialogueTexts,
+                    const Common::Array<Common::Array<const char *>> *goodbyeTexts,
+                    const Common::Array<Common::Array<const char *>> *hintTexts,
+                    const Common::Array<const char *> *ringingTexts,
+                    const Common::Array<const char *> &itemNames,
+                    const Common::Array<const char *> &eventFlagNames) {
+    
+    // Write game constants
+    output.writeUint16(gameConstants.numItems);
+    output.writeUint16(gameConstants.numEventFlags);
+    writeToFile(output, gameConstants.mapAccessSceneIDs);
+    writeToFile(output, gameConstants.genericEventFlags);
+    output.writeUint16(gameConstants.numNonItemCursors);
+    output.writeUint16(gameConstants.numCurtainAnimationFrames);
+    output.writeUint32(gameConstants.logoEndAfter);
+
+    // Write languages
+    writeToFile(output, languages);
+
+    // Write conditional dialogue logic
+    if (conditionalDialogue) {
+        writeToFile(output, *conditionalDialogue);
+    } else {
+        output.writeUint16(0);
+    }
+
+    // Write Goodbyes logic
+    if (goodbyes) {
+        writeToFile(output, *goodbyes);
+    } else {
+        output.writeUint16(0);
+    }
+
+    // Write hints logic
+    if (hints) {
+        writeToFile(output, *hints);
+    } else {
+        output.writeUint16(0);
+    }
+
+    // Write conditional dialogue text
+    if (dialogueTexts) {
+        output.writeMultilangArray(*dialogueTexts);
+    } else {
+        output.writeUint16(0);
+    }
+
+    // Write goodbyes text
+    if (goodbyeTexts) {
+        output.writeMultilangArray(*goodbyeTexts);
+    } else {
+        output.writeUint16(0);
+    }
+
+    // Write hints text
+    if (hintTexts) {
+        output.writeMultilangArray(*hintTexts);
+    } else {
+        output.writeUint16(0);
+    }
+
+    // Write hints text
+    if (ringingTexts) {
+        writeToFile(output, *ringingTexts);
+    } else {
+        output.writeUint16(0);
+    }
+
+    // Write item names
+    writeToFile(output, itemNames);
+
+    // Write event flag names
+    writeToFile(output, eventFlagNames);
+}
+
+int main(int argc, char *argv[]) {
+    File output;
+	if (!output.open("nancy.dat", kFileWriteMode)) {
+		error("Unable to open nancy.dat");
+	}
+
+    Common::Array<uint32> gameOffsets;
+
+    // Write header
+    output.writeByte('N');
+    output.writeByte('N');
+    output.writeByte('C');
+    output.writeByte('Y');
+    output.writeByte(NANCYDAT_MAJOR_VERSION);
+    output.writeByte(NANCYDAT_MINOR_VERSION);
+    output.writeUint16(NANCYDAT_NUM_GAMES);
+
+    // Skip game offsets, they'll be written at the end
+    uint32 offsetsOffset = output.pos();
+    output.skip(NANCYDAT_NUM_GAMES * 4);
+
+    // The Vampire Diaries data
+    gameOffsets.push_back(output.pos());
+    writeGameData(  output,
+                    _tvdConstants,
+                    _tvdLanguagesOrder,
+                    &_tvdConditionalDialogue,
+                    &_tvdGoodbyes,
+                    nullptr,
+                    &_tvdConditionalDialogueTexts,
+                    &_tvdGoodbyeTexts,
+                    nullptr,
+                    nullptr,
+                    _tvdItemNames,
+                    _tvdEventFlagNames);
+    
+    // Nancy Drew: Secrets Can Kill data
+    gameOffsets.push_back(output.pos());
+    writeGameData(  output,
+                    _nancy1Constants,
+                    _nancy1LanguagesOrder,
+                    &_nancy1ConditionalDialogue,
+                    &_nancy1Goodbyes,
+                    &_nancy1Hints,
+                    &_nancy1ConditionalDialogueTexts,
+                    &_nancy1GoodbyeTexts,
+                    &_nancy1HintTexts,
+                    &_nancy1TelephoneRinging,
+                    _nancy1ItemNames,
+                    _nancy1EventFlagNames);
+
+    // Write the offsets for each game in the header
+    output.seek(offsetsOffset);
+    for (uint i = 0; i < gameOffsets.size(); ++i) {
+        output.writeUint32(gameOffsets[i]);
+    }
+
+    output.close();
+
+    return 0;
+}
diff --git a/devtools/create_nancy/file.cpp b/devtools/create_nancy/file.cpp
new file mode 100644
index 00000000000..db58599062b
--- /dev/null
+++ b/devtools/create_nancy/file.cpp
@@ -0,0 +1,234 @@
+/* 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/>.
+ *
+ */
+
+#include "file.h"
+
+#include "common/endian.h"
+
+bool File::open(const char *filename, AccessMode mode) {
+    _memPtr = nullptr;
+    _f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb+");
+    return (_f != NULL);
+}
+
+bool File::open(const byte *data, uint size) {
+    close();
+    _f = nullptr;
+    _memPtr = data;
+    _size = size;
+    return true;
+}
+
+void File::close() {
+    if (_f)
+        fclose(_f);
+    _f = nullptr;
+    delete[] _memPtr;
+    _memPtr = nullptr;
+}
+
+uint File::pos() const {
+    if (_f)
+        return ftell(_f);
+    else
+        return _offset;
+}
+
+uint File::size() const {
+    if (_f) {
+        uint currentPos = pos();
+        fseek(_f, 0, SEEK_END);
+        uint result = pos();
+        fseek(_f, currentPos, SEEK_SET);
+        return result;
+    } else if (_memPtr) {
+        return _size;
+    } else {
+        return 0;
+    }
+}
+
+bool File::eof() const {
+    if (_f)
+        return feof(_f) != 0;
+    else if (_memPtr)
+        return _offset >= _size;
+    return false;
+}
+
+int File::seek(int offset, int whence) {
+    if (_f)
+        return fseek(_f, offset, whence);
+
+    switch (whence) {
+        case SEEK_SET:
+            _offset = offset;
+            break;
+        case SEEK_CUR:
+            _offset += offset;
+            break;
+        case SEEK_END:
+            _offset = _size + offset;
+            break;
+        default:
+            break;
+    }
+
+    return _offset;
+}
+
+void File::skip(int offset) {
+    if (_f)
+        fseek(_f, offset, SEEK_CUR);
+    else
+        _offset += offset;
+}
+
+long File::read(void *buffer, size_t len) {
+    if (_f)
+        return fread(buffer, 1, len, _f);
+
+    uint bytesToRead = CLIP(len, (size_t)0, _size - _offset);
+    memcpy(buffer, &_memPtr[_offset], bytesToRead);
+    _offset += bytesToRead;
+    return bytesToRead;
+}
+
+byte File::readByte() {
+    byte v;
+    read(&v, sizeof(byte));
+    return v;
+}
+
+void File::write(const void *buffer, size_t len) {
+    assert(_f);
+    fwrite(buffer, 1, len, _f);
+}
+
+void File::writeByte(byte v) {
+    write(&v, sizeof(byte));
+}
+
+void File::writeByte(byte v, int len) {
+    byte *b = new byte[len];
+    memset(b, v, len);
+    write(b, len);
+    delete[] b;
+}
+
+void File::writeUint16(uint16 v) {
+    uint16 vTemp = TO_LE_16(v);
+    write(&vTemp, sizeof(uint16));
+}
+
+void File::writeUint32(uint v) {
+    uint vTemp = TO_LE_32(v);
+    write(&vTemp, sizeof(uint));
+}
+
+void File::writeString(const char *msg) {
+    if (!msg) {
+        writeByte(0);
+    } else {
+        do {
+            writeByte(*msg);
+        } while (*msg++);
+    }
+}
+
+void File::writeMultilangArray(const Common::Array<Common::Array<const char *>> &array) {
+    writeUint16(array.size());
+    Common::Array<uint32> offsets;
+    uint32 offsetsOffset = pos();
+
+    skip(array.size() * 4);
+
+    for (uint i = 0; i < array.size(); ++i) {
+        offsets.push_back(pos());
+        writeToFile(*this, array[i]);
+    }
+
+    uint end = pos();
+    seek(offsetsOffset);
+
+    for (uint i = 0; i < array.size(); ++i) {
+        writeUint32(offsets[i]);
+    }
+
+    seek(end);
+}
+
+template<>
+void writeToFile(File &file, const Common::Array<const char *> &obj) {
+    file.writeUint16(obj.size());
+    for (uint i = 0; i < obj.size(); ++i) {
+        file.writeString(obj[i]);
+    }
+}
+
+template<>
+void writeToFile(File &file, const EventFlagDescription &obj) {
+    file.writeUint16((uint)obj.label);
+    file.writeByte(obj.flag);
+}
+
+template<>
+void writeToFile(File &file, const SceneChangeDescription &obj) {
+    file.writeUint16(obj.sceneID);
+    file.writeUint16(obj.frameID);
+    file.writeUint16(obj.verticalOffset);
+    file.writeUint16(obj.doNotStartSound);
+}
+
+template<>
+void writeToFile(File &file, const ConditionalDialogue &obj) {
+    file.writeByte(obj.textID);
+    file.writeUint16(obj.sceneID);
+    file.writeString(obj.soundID);
+    writeToFile(file, obj.flagConditions);
+    writeToFile(file, obj.inventoryConditions);
+}
+
+template<>
+void writeToFile(File &file, const GoodbyeSceneChange &obj) {
+    writeToFile(file, obj.sceneIDs);
+    writeToFile(file, obj.flagConditions);
+    writeToFile(file, obj.flagToSet);
+}
+
+template<>
+void writeToFile(File &file, const Goodbye &obj) {
+    file.writeString(obj.soundID);
+    writeToFile(file, obj.sceneChanges);
+}
+
+template<>
+void writeToFile(File &file, const Hint &obj) {
+    file.writeByte(obj.textID);
+    file.writeUint16((uint16)obj.hintWeight);
+    writeToFile(file, obj.sceneChange);
+    // always three
+    file.writeString(obj.soundIDs[0]);
+    file.writeString(obj.soundIDs[1]);
+    file.writeString(obj.soundIDs[2]);
+    writeToFile(file, obj.flagConditions);
+    writeToFile(file, obj.inventoryConditions);
+}
diff --git a/devtools/create_nancy/file.h b/devtools/create_nancy/file.h
new file mode 100644
index 00000000000..df532a00811
--- /dev/null
+++ b/devtools/create_nancy/file.h
@@ -0,0 +1,98 @@
+/* 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 CREATE_NANCY_FILE_H
+#define CREATE_NANCY_FILE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "types.h"
+
+enum AccessMode {
+	kFileReadMode = 1,
+	kFileWriteMode = 2
+};
+
+class File {
+private:
+	FILE *_f;
+	const byte *_memPtr;
+	size_t _offset, _size;
+
+public:
+	File() : _f(nullptr), _memPtr(nullptr), _offset(0), _size(0) {}
+
+	bool open(const char *filename, AccessMode mode = kFileReadMode);
+	bool open(const byte *data, uint size);
+
+	void close();
+
+    uint pos() const;
+    uint size() const;
+    bool eof() const;
+
+	int seek(int offset, int whence = SEEK_SET);
+	void skip(int offset);
+	long read(void *buffer, size_t len);
+	byte readByte();
+
+	void write(const void *buffer, size_t len);
+	void writeByte(byte v);
+	void writeByte(byte v, int len);
+	void writeUint16(uint16 v);
+	void writeUint32(uint v);
+	void writeString(const char *msg);
+
+	void writeMultilangArray(const Common::Array<Common::Array<const char *>> &array);
+};
+
+template <class T>
+void writeToFile(File &file, T &obj) {
+    file.write(&obj, sizeof(obj));
+}
+
+template<class T>
+void writeToFile(File &file, const Common::Array<T> &obj) {
+    file.writeUint16(obj.size());
+    for (uint i = 0; i < obj.size(); ++i) {
+        writeToFile(file, obj[i]);
+    }
+}
+
+template<>
+void writeToFile(File &file, const Common::Array<const char *> &obj);
+template<>
+void writeToFile(File &file, const EventFlagDescription &obj);
+template<>
+void writeToFile(File &file, const SceneChangeDescription &obj);
+template<>
+void writeToFile(File &file, const ConditionalDialogue &obj);
+template<>
+void writeToFile(File &file, const GoodbyeSceneChange &obj);
+template<>
+void writeToFile(File &file, const Goodbye &obj);
+template<>
+void writeToFile(File &file, const Hint &obj);
+
+#endif // CREATE_NANCY_FILE_H
diff --git a/devtools/create_nancy/module.mk b/devtools/create_nancy/module.mk
new file mode 100644
index 00000000000..0db0310ae3c
--- /dev/null
+++ b/devtools/create_nancy/module.mk
@@ -0,0 +1,12 @@
+
+MODULE := devtools/create_nancy
+
+MODULE_OBJS := \
+	create_nancy.o \
+	file.o
+
+# Set the name of the executable
+TOOL_EXECUTABLE := create_nancy
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/devtools/create_nancy/nancy1_data.h b/devtools/create_nancy/nancy1_data.h
new file mode 100644
index 00000000000..9056bb5c2cf
--- /dev/null
+++ b/devtools/create_nancy/nancy1_data.h
@@ -0,0 +1,836 @@
+/* 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 NANCY1DATA_H
+#define NANCY1DATA_H
+
+#include "types.h"
+
+const GameConstants _nancy1Constants = {
+    11,
+    168,
+    { 9, 10, 11, 666, 888, 1200, 1250, 1666 },
+    {	44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+        63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+        75, 76, 77, 78, 79, 80, 81, 82, 83, 84 },
+    12,
+    7,
+    7000
+};
+
+const Common::Array<Common::Language> _nancy1LanguagesOrder = {
+    Common::Language::EN_ANY,
+    Common::Language::RU_RUS
+};
+
+const Common::Array<Common::Array<ConditionalDialogue>> _nancy1ConditionalDialogue = {
+{   // Daryl, 18 responses
+    {   17, 124, "DIC1",
+        { { 0x1D, kTrue }, { 0x39, kFalse } },
+        { } },
+    {   16, 127, "DIC2",
+        { { 0x13, kTrue }, { 0x37, kFalse } },
+        { } },
+    {   15, 129, "DIC3",
+        { { 0xB, kTrue }, { 0x38, kFalse } },
+        { } },
+    {   14, 131, "DIC4",
+        { { 0, kTrue }, { 1, kFalse }, { 0x6B, kFalse } },
+        { } },
+    {   13, 132, "DIC5",
+        { { 0x64, kTrue }, { 0x1E, kFalse }, { 0x14, kFalse }, { 0xC, kFalse }, { 0x6C, kFalse } },
+        { } },
+    {   12, 134, "DIC6",
+        { { 0x6D, kFalse }, { 0x6, kTrue }, { 0x8, kTrue }, { 0x5E, kTrue }, { 0x17, kTrue }, { 0x24, kTrue }, { 0x9, kTrue } },
+        { } },
+    {   11, 139, "DIC7",
+        { { 0x6E, kFalse }, { 0x24, kTrue }, { 0x9, kTrue }, { 0x5E, kFalse }, { 0x8, kFalse } },
+        { } },
+    {   10, 141, "DIC8",
+        { { 0x6F, kFalse }, { 0x5E, kTrue }, { 0x24, kTrue }, { 0x9, kTrue }, { 0x8, kFalse } },
+        { } },
+    {   9, 143, "DIC9",
+        { { 0x70, kFalse }, { 0x24, kTrue }, { 0x9, kTrue }, { 0x6, kTrue }, { 0x8, kTrue }, { 0x5E, kFalse } },
+        { } },
+    {   8, 144, "DIC10",
+        { { 0x71, kFalse }, { 0x5E, kTrue }, { 0x24, kFalse }, { 0x8, kFalse } },
+        { } },
+    {   7, 145, "DIC10",
+        { { 0x72, kFalse }, { 0x5E, kTrue }, { 0x8, kTrue }, { 0x6, kTrue }, { 0x24, kFalse } },
+        { } },
+    {   6, 146, "DIC12",
+        { { 0x73, kFalse }, { 0x8, kTrue }, { 0x6, kTrue }, { 0x5E, kFalse }, { 0x24, kFalse } },
+        { } },
+    {   5, 150, "DIC13",
+        { { 0x74, kFalse }, { 0x1D, kTrue }, { 0x13, kTrue }, { 0xB, kTrue }, { 0x5E, kFalse }, { 0x24, kFalse }, { 0x8, kFalse } },
+        { } },
+    {   4, 151, "DIC14",
+        { { 0x27, kFalse }, { 0x5, kTrue } },
+        { } },
+    {   3, 156, "DIC15",
+        { { 0x28, kTrue }, { 0x75, kFalse } },
+        { } },
+    {   2, 147, "DIC16",
+        { { 0xC, kFalse }, { 0x6, kTrue }, { 0x76, kFalse } },
+        { } },
+    {   1, 148, "DIC17",
+        { { 0x14, kFalse }, { 0x4, kTrue }, { 0x77, kFalse } },
+        { } },
+    {   0, 149, "DIC18",
+        { { 0x1E, kFalse }, { 0x63, kTrue }, { 0x78, kFalse } },
+        { } }
+},
+{   // Connie, 10 responses
+    {   26, 233, "CIC1", 
+        { { 0x1D, kTrue }, { 0x18, kFalse } },
+        { } },
+    {   25, 234, "CIC2",
+        { { 0x1F, kTrue }, { 0x19, kFalse } },
+        { } },
+    {   24, 235, "CIC3",
+        { { 0xB, kTrue }, { 0x1A, kFalse } },
+        { } },
+    {   23, 236, "CIC4",
+        { { 0x26, kTrue }, { 0x1C, kFalse } },
+        { } },
+    {   22, 237, "CIC5",
+        { { 0, kTrue }, { 1, kFalse }, { 0x79, kFalse } },
+        { } },
+    {   21, 238, "CIC6",
+        { { 2, kTrue }, { 3, kTrue }, { 0x17, kFalse } },
+        { } },
+    {   13, 239, "DIC5",
+        { { 0x64, kTrue }, { 0x16, kFalse } },
+        { } },        
+    {   20, 240, "CIC8",
+        { { 0x5, kTrue }, { 0x14, kFalse } },
+        { } },
+    {   19, 245, "CIC9",
+        { { 0x28, kTrue } },
+        { } },
+    {   18, 231, "CIC10",
+        { { 0xD, kTrue }, { 0x5E, kFalse } },
+        { } }
+},
+{   // Hal, 9 responses
+    {   33, 435, "hic1",
+        { { 0x1D, kTrue }, { 0x11, kFalse } },
+        { } },
+    {   16, 437, "DIC2",
+        { { 0x13, kTrue }, { 0xE, kFalse } },
+        { } },
+    {   32, 438, "hic3",
+        { { 0x1B, kTrue }, { 0xF, kFalse } },
+        { } },
+    {   31, 439, "hic4",
+        { { 0x26, kTrue }, { 0x10, kFalse } },
+        { } },
+    {   30, 441, "hic5",
+        { { 0, kTrue }, { 1, kFalse }, { 0x68, kFalse } },
+        { } },
+    {   29, 442, "hic6",
+        { { 0, kTrue }, { 1, kFalse }, { 0x20, kTrue }, { 0x69, kFalse } },
+        { } },
+    {   13, 443, "DIC5",
+        { { 0x6A, kFalse }, { 0x64, kTrue }, { 0x5, kFalse } },
+        { } },
+    {   28, 444, "hic8",
+        { { 0x8, kTrue }, { 0x6, kTrue }, { 0xC, kFalse } },
+        { } },
+    {   27, 446, "hic9",
+        { { 0x28, kTrue } },
+        { } },
+},
+{   // Hulk, 9 responses
+    {   39, 333, "hdic1",
+        { { 0x13, kTrue }, { 0x3A, kFalse } },
+        { } },
+    {   24, 336, "CIC3",
+        { { 0xB, kTrue }, { 0x25, kFalse } },
+        { } },
+    {   38, 339, "hdic3",
+        { { 0x12, kTrue }, { 0x21, kFalse } },
+        { } },
+    {   31, 340, "hic4",
+        { { 0x26, kTrue }, { 0x22, kFalse } },
+        { } },
+    {   37, 341, "hdic5",
+        { { 0, kTrue }, { 1, kFalse }, { 0x66, kFalse } },
+        { } },
+    {   13, 342, "DIC5",
+        { { 0x67, kFalse }, { 0x64, kTrue } },
+        { } },
+    {   36, 343, "hdic7",
+        { { 0x63, kTrue }, { 0x24, kFalse } },
+        { } },
+    {   35, 344, "hdic8",
+        { { 0x5, kTrue }, { 0x1E, kFalse } },
+        { } },
+    {   34, 345, "hdic9",
+        { { 0x28, kTrue } },
+        { } },
+}
+};
+
+const Common::Array<Goodbye> _nancy1Goodbyes = {
+    { "nd0d", { { { 3220, 3221, 3222, 3223 }, {}, NOFLAG } } }, // Daryl
+    { "nd0c", { { { 252, 2520, 2521, 2523 }, {}, NOFLAG } } },  // Connie
+    { "nd0hl", { { { 451, 452, 453, 454 }, {}, NOFLAG } } },    // Hal
+    { "nd0h", { { { 3298, 3296 }, {}, NOFLAG } } }              // Hulk, only two answers
+};
+
+const Common::Array<Common::Array<Hint>> _nancy1Hints = {
+{   // Ned, 8 hints
+    {   1, -1, { 501, 0, 0, true },
+        { "hn01", "hn02", "hn03" },
+        { { 0, kFalse } },
+        { } },
+    {   2, -1, { 501, 0, 0, true },
+        { "hn04", "hn05", "hn06" },
+        { { 0, kTrue }, { 1, kFalse } },
+        { } },
+    {   3, -1, { 501, 0, 0, true },
+        { "hn07", "hn08", "hn09" },
+        { { 1, kFalse } },
+        { { 3, kFalse } } },
+    {   4, -1, { 501, 0, 0, true },
+        { "hn10", "hn11", "hn09" },
+        { { 0x55, kFalse } },
+        { { 3, kTrue } } },
+    {   5, -1, { 501, 0, 0, true },
+        { "hn13", "hn14", "hn15" },
+        { { 0x55, kTrue }, { 0x56, kFalse } },
+        { } },
+    {   6, -1, { 501, 0, 0, true },
+        { "hn16", "hn17", "hn18" },
+        { { 0x57, kFalse }, { 0x56, kTrue } },
+        { } },
+    {   7, -1, { 501, 0, 0, true },
+        { "hn21", "hn21", "hn20" },
+        { { 0xA, kTrue }, { 0x3B, kTrue } },
+        { { 7, kFalse } } },
+    {   0, 0, { 501, 0, 0, true }, // Out of hints
+        { "hn19", "hn19", "hn19" },
+        { },
+        { } }
+},
+{   // Bess, 9 hints
+    {   9, -1, { 501, 0, 0, true },
+        { "hb01", "hb02", "hb03" },
+        { { 0x57, kFalse } },
+        { } },
+    {   10, -1, { 501, 0, 0, true },
+        { "hb04", "hb05", "hb06" },
+        { { 0x57, kTrue }, { 0x3C, kFalse } },
+        { } },
+    {   11, -1, { 501, 0, 0, true },
+        { "hb07", "hb08", "hb09" },
+        { { 0x5A, kFalse }, { 0x3C, kTrue }, { 0x56, kFalse } },
+        { } },
+    {   12, -1, { 501, 0, 0, true },
+        { "hb11", "hb10", "hb12" },
+        { { 0x5A, kTrue }, { 0x56, kFalse } },
+        { } },
+    {   13, -1, { 501, 0, 0, true },
+        { "hb14", "hb15", "hb16" },
+        { { 0x5A, kFalse }, { 0x3C, kTrue }, { 0x56, kTrue } },
+        { } },
+    {   14, -1, { 501, 0, 0, true },
+        { "hb17", "hb18", "hb19" },
+        { { 0x59, kTrue }, { 0xA, kFalse }, { 0x56, kTrue } },
+        { { 0, kFalse } } },
+    {   15, -1, { 501, 0, 0, true },
+        { "hb20", "hb21", "hb22" },
+        { { 0xA, kTrue }, { 0x3B, kTrue } },
+        { { 0, kTrue }, { 7, kFalse } } },
+    {   16, -1, { 501, 0, 0, true },
+        { "hb24", "hb23", "hb25" },
+        { { 0x59, kFalse }, { 0xA, kTrue }, { 0x3B, kTrue } },
+        { { 7, kFalse } } },
+    {   8, 0, { 501, 0, 0, true }, // Out of hints
+        { "hb26", "hb26", "hb26" },
+        { },
+        { } }
+},
+{   // George, 9 hints
+    {   25, -1, { 501, 0, 0, true }, // Easter egg
+        { "GeorBark", "GeorBark", "GeorBark" },
+        { { 0x4A, kTrue } },
+        { } },
+    {   18, -1, { 501, 0, 0, true },
+        { "hg01", "hg02", "hg03" },
+        { { 0x5B, kFalse } },
+        { } },
+    {   19, -1, { 501, 0, 0, true },
+        { "hg16", "hg15", "hg17" },
+        { { 0x5B, kTrue } },
+        { { 9, kFalse } } },
+    {   20, -1, { 501, 0, 0, true },
+        { "hg18", "hg19", "hg20" },
+        { { 0x5B, kTrue }, { 0x5C, kFalse }, { 0x5D, kFalse } },
+        { { 9, kTrue } } },
+    {   21, -1, { 501, 0, 0, true },
+        { "hg08", "hg09", "hg10" },
+        { { 0x5B, kTrue }, { 0x5C, kTrue }, { 0x5D, kFalse } },
+        { { 9, kFalse } } },
+    {   22, -1, { 501, 0, 0, true },
+        { "hg04", "hg05", "hg06" },
+        { { 0x5B, kTrue }, { 0x5C, kTrue }, { 0x5D, kTrue }, { 0x3B, kFalse } },
+        { { 9, kTrue } } },
+    {   23, -1, { 501, 0, 0, true },
+        { "hg22", "hg21", "hg13" },
+        { { 0xA, kFalse }, { 0x3B, kTrue } },
+        { { 9, kTrue } } },
+    {   24, -1, { 501, 0, 0, true },
+        { "hg11", "hg12", "hg13" },
+        { { 0x3B, kTrue }, { 0xA, kTrue } },
+        { { 7, kFalse } } },
+    {   17, 0, { 501, 0, 0, true }, // Out of hints
+        { "hg14", "hg14", "hg14" },
+        { },
+        { } }
+}
+};
+
+const Common::Array<Common::Array<const char *>> _nancy1ConditionalDialogueTexts = {
+{   // English
+    // 00
+    "<c1>W<c0>hat do you know about the break-in at the pharmacy?<h><n>",
+    "<c1>W<c0>as Jake interested in Judo?<h><n>",
+    "<c1>W<c0>hy would Jake have an old English book in his locker?<h><n>",
+    "<c1>D<c0>aryl, we're going to find the person who killed Jake.  If you help out now, the case will move a lot quicker.<h><n>",
+    "<c1>I<c0> saw Jake's tape, Daryl.  I know he was blackmailing you.<h><n>",
+    // 05
+    "<c1>H<c0>al, Connie, and Hulk didn't seem to like Jake very much.  I think they all know something about Jake's death, I just don't know what.<h><n>",
+    "<c1>H<c0>al had a reason to hate Jake, but it's hard to picture him as a murderer.<h><n>",
+    "<c1>J<c0>ake had some kind of hold on Connie and Hal.  Is it possible that one of them could have resorted to murder?<h><n>",
+    "<c1>C<c0>onnie lied about her dating Jake.  Could something have happened between them that would push her to murder?<h><n>",
+    "<c1>J<c0>ake was pressuring both Hal and Hulk.  It could have been either of them.  This is really complicated.<h><n>",
+    // 10
+    "<c1>L<c0>ooks like Jake had a hold on both Hulk and Connie.  What now?<h><n>",
+    "<c1>I<c0> think Jake had some sensitive information on Hulk Sanchez.  Do you think Hulk could have killed Jake?<h><n>",
+    "<c1>H<c0>al, Hulk and Connie were all involved with Jake.  He had information that could jeopardize Hal's career.  Connie once dated Jake and Hulk seems awfully touchy about that break-in at the Drug Depot.<h><n>",
+    "<c1>D<c0>o you know why Jake had a video camera in his locker?<h><n>",
+    "<c1>D<c0>aryl, do you know where I could get Jake Roger's locker combination?<h><n>",
+    // 15
+    "<c1>W<c0>hat can you tell me about Hal Tanaka?<h><n>",
+    "<c1>D<c0>o you know Connie Watson?<h><n>",
+    "<c1>H<c0>ow well do you know Hulk Sanchez?<h><n>",
+    "<c1>D<c0>idn't I hear you were dating Jake?<h><n>",
+    "<c1>C<c0>onnie, we're going to find the person who killed Jake.  If you help out now, the case will move a lot quicker.<h><n>",
+    // 20
+    "<c1>I<c0> know you're the unknown winner of that judo competition.  Jake Rogers had it all on videotape.<h><n>",
+    "<c1>Y<c0>ou're wearing a Japanese medallion with a symbol that means crane, and Crane is the name of the judo school on the poster in the gym.<h><n>",
+    "<c1>D<c0>o you know the combination to Jake Roger's locker?<h><n>", // Misspelled in the original game
+    "<c1>H<c0>ow well do you know Daryl Gray?<h><n>",
+    "<c1>D<c0>o you know Hal Tanaka?<h><n>",
+    // 25
+    "<c1>H<c0>ulk told me money's been tight for you these days.<h><n>",
+    "<c1>W<c0>hat do you know about Hulk Sanchez?<h><n>",
+    "<c1>H<c0>al, we're going to find the person who killed Jake.  If you help out now, this case will move a lot quicker.<h><n>",
+    "<c1>J<c0>ake knew you copied your essay from that book of English essays, didn't he?<h><n>",
+    "<c1>H<c0>ulk said your locker was right next to Jake's.  Are you sure you don't know the combination?<h><n>",
+    // 30
+    "<c1>D<c0>o you know the combination to Jake Rogers' locker?<h><n>",
+    "<c1>W<c0>hat can you tell me about Daryl Gray?<h><n>",
+    "<c1>C<c0>onnie told me you study too hard.  Is that true?<h><n>",
+    "<c1>H<c0>ave you heard of Hulk Sanchez?<h><n>",
+    "<c1>H<c0>ulk, we're going to find the person who killed Jake.  If you help out now, this case will move a lot quicker.<h><n>",
+    // 35
+    "<c1>J<c0>ake knew you broke into the Drug Depot.  He was blackmailing you, wasn't he?<h><n>",
+    "<c1>T<c0>ell me about the robbery at the Drug Depot pharmacy.<h><n>",
+    "<c1>H<c0>ow could I get into Jake's locker?<h><n>",
+    "<c1>I<c0>'m really sorry you got injured.  Does that affect your chances of playing college ball?<h><n>",
+    "<c1>W<c0>hat can you tell me about Connie Watson?<h><n>",
+},
+{   // Russian
+    // 00
+    "<c1>Wto t= znaew% o krage v apteke?<c0><h><n>",
+    "<c1>Dgek zanimals* dzydo?<c0><h><n>",
+    "<c1>Poqemu Dgek xranil v svoem wkafqike staruy knihu?<c0><h><n>",
+    "<c1>D&ril, m= sobiraems* pojmat% ubijcu. I nam oqen% nugna tvo* pomoQ%.<c0><h><n>",
+    "<c1>D&ril, * videla videokassetu Dgeka. Y znay, qto on teb* wantagiroval.<c0><h><n>",
+    // 05
+    "<c1>Xolu, Konni i Xalku Dgek ne osobo nravils*. Dumay, im qto-to izvestno o eho smerti, no oni ne xot*t hovorit%.<c0><h><n>",
+    "<c1>U Xola b=li priqin= nenavidet% Dgeka. No predstavit% eho ubijcej slogno.<c0><h><n>",
+    "<c1>Dgek wantagiroval Konni i Xola. Moh kto-to iz nix pojti na ubijstvo?<c0><h><n>",
+    "<c1>Konni ne skazala, qto <n>vstreqalas% s Dgekom. <n>Ona mohla pojti na <n>ubijstvo, potomu qto <n>oni possorilis%?<c0><h><n>",
+    "<c1>Dgek wantagiroval i Xola, i Xalka. U oboix b=l motiv.<c0><h><n>",
+    // 10
+    "<c1>Poxoge, Dgek wantagiroval i Xola, i Konni. Wto teper%?<c0><h><n>",
+    "<c1>Dgeku b=lo qto-to izvestno o Xalke Sanqese. Dumaew%, Xalk moh ubit% eho?<c0><h><n>",
+    "<c1>Xol, Xalk i Konni b=li kak-to sv*zan= s Dgekom. U neho b=li svedeni*, kotor=e mohli navredit% kar%ere Xola. <n>Konni odin raz xodila s Dgekom na svidanie, a Xalka zadel moj vopros o krage v apteke.<c0><h><n>",
+    "<c1>T= znaew%, zaqem Dgek xranil v svoem wkafqike videokameru?<c0><h><n>",
+    "<c1>D&ril, kak mne uznat% kod k wkafqiku Dgeka?<c0><h><n>",
+    // 15
+    "<c1>Wto t= znaew% o Xole Tanake?<c0><h><n>",
+    "<c1>T= znaew% Konni Vatson?<c0><h><n>",
+    "<c1>T= xorowo znaew% Xalka Sanqesa?<c0><h><n>",
+    "<c1>Y sl=wala, qto t= vstreqalas% s Dgekom.<c0><h><n>",
+    "<c1>Konni, m= sobiraems* najti ubijcu Dgeka. Nam oqen% nugna tvo* pomoQ%.<c0><h><n>",
+    // 20
+    "<c1>Y znay, qto t= pobedila v sorevnovani*x po dzydo. Dgek Rodgers zapisal vse na video.<c0><h><n>",
+    "<c1>U teb* na medal%one narisovan ierohlif 'guravl%'. Toqno tak ge naz=vaets* wkola dzydo. <n>Y videla plakat vozle sportzala.<c0><h><n>",
+    "<c1>T= znaew% kod k wkafqiku Dgeka Rodgersa?<c0><h><n>",
+    "<c1>T= xorowo znaew% D&rila Hre*?<c0><h><n>",
+    "<c1>T= znaew% Xola Tanaku?<c0><h><n>",
+    // 25
+    "<c1>Xalk skazal, qto u teb* sejqas trudn=e vremena. Cto pravda?<c0><h><n>",
+    "<c1>Wto t= znaew% o Xalke Sanqese?<c0><h><n>",
+    "<c1>Xol, m= sobiraems* pojmat% <n>ubijcu Dgeka. Nam oqen% nugna <n>tvo* pomoQ%.<c0><h><n>",
+    "<c1>Dgek znal, qto t= spisal <n>soqinenie iz knihi. Y prava?<c0><h><n>",
+    "<c1>Xalk skazal, qto tvoj wkafqik <n>naxodits* r*dom so wkafqikom <n>Dgeka. T= toqno ne znaew% <n>kod ot eho zamka?<c0><h><n>",
+    // 30
+    "<c1>T= znaew% kod k wkafqiku <n>Dgeka Rodgersa?<c0><h><n>",
+    "<c1>Wto t= znaew% o <n>D&rile Hree?<c0><h><n>",
+    "<c1>Konni skazala, qto t= <n>sliwkom mnoho zanimaew%s*.<c0><h><n>",
+    "<c1>Wto t= znaew% o <n>Xalke Sanqese?<c0><h><n>",
+    "<c1>Xalk, m= sobiraems* pojmat% ubijcu Dgeka. Nam oqen% nugna tvo* pomoQ%.<c0><h><n>",
+    // 35
+    "<c1>Dgek znal, qto t= soverwil kragu v apteke. On wantagiroval teb*?<c0><h><n>",
+    "<c1>Rasskagi o krage v apteke.<c0><h><n>",
+    "<c1>T= znaew%, kak otkr=t% wkafqik Dgeka?<c0><h><n>",
+    "<c1>Mne gal%, qto t= poluqil travmu. Teper% u teb* budet men%we wansov postupit% v prestign=j kolledg?<c0><h><n>",
+    "<c1>Wto t= mogew% skazat% o <n>Konni Vatson?<c0><h><n>"
+}
+};
+
+const Common::Array<Common::Array<const char *>> _nancy1GoodbyeTexts = {
+{   // English
+    "<c1>S<c0>ee ya' later.<h>",        // Daryl
+    "<c1>G<c0>ood Bye.<h>",             // Connie
+    "<c1>T<c0>alk to ya' later.<h>",    // Hal
+    "<c1>B<c0>ye.<h>"                   // Hulk
+},
+{   // Russian
+    "<c1>Udaqi.<c0><h>",                // Daryl
+    "<c1>Poka.<c0><h>",                 // Connie
+    "<c1>Pohovorim pozge.<c0><h>",      // Hal
+    "<c1>Poka.<c0><h>"                  // Hulk
+}
+};
+
+const Common::Array<Common::Array<const char *>> _nancy1HintTexts = {
+{   // English
+    // 00
+    "Nancy, I don't know how else to help.<n>Just be careful, OK?<n><e>",
+    "Nancy, I don't know how else to help.<n>Just be careful, OK?<n><e>",
+    "Nancy, I don't know how else to help.<n>Just be careful, OK?<n><e>",
+    // 01
+    "Try to find the victim's locker,<n>it may hold some clues.<n><e>",
+    "I'd definitely search the crime<n>scene for clues.<n><e>",
+    "Nancy, put on your detective's cap<n>and begin at the beginning!<n><e>",
+    // 02
+    "Nancy, to open the victim's<n>locker, I'd think of a way to make<n>the owner's name into<n>numbers, like maybe on a phone.<n><e>",
+    "On my locker, my combination<n>is related to my name.<n><e>",
+    "To open the victim's locker,<n>I'd think of how letters and<n>numbers could be related.<n><e>",
+    // 03
+    "Are you sure nothing fell out<n>of Jake's locker and onto the floor?<n><e>",
+    "Search that locker, there's<n>bound to be something useful<n>there.<n><e>",
+    "Nancy, be careful. I was<n>afraid that Jake's locker was<n>booby trapped.<n><e>",
+    // 04
+    "Use the glasscutter you found<n>by the locker to open up<n>a window, like outside<n>the school.<n><e>",
+    "That Jake Rogers was sneaky,<n>he probably used that glasscutter<n>in his locker to break into<n>the school.<n><e>",
+    "Nancy, be careful. I was<n>afraid that Jake's locker was<n>booby trapped.<n><e>",
+    // 05
+    "There must be a computer in<n>the teacher's lounge.<n>Can you access it?<n><e>",
+    "There must be clues in the<n>teacher's lounge somewhere.<n>Search around the desk!<n><e>",
+    "I can't believe you broke into<n>the teacher's lounge!<n>I'm sure you'll find some very<n>important information there!<n><e>",
+    // 06
+    "Nancy perhaps you can use your<n>Aunt Eloise's login and<n>password to access<n>the school computer.  Doesn't<n>she keep the password in her safe<n>at home?<n><e>",
+    "Nancy perhaps you can use your<n>Aunt Eloise's login and<n>password to access<n>the school computer.  She's<n>probably hidden it somewhere at<n>home in a safe place.<n><e>",
+    "Try your Aunt Eloise's name to<n>log onto the school computer.<n>She must keep her password<n>and login at home somewhere.<n><e>",
+    // 07
+    "I bet the first boiler lever<n>controls whether the second<n>and third lever can move.<n><e>",
+    "I bet the first boiler lever<n>controls whether the second<n>and third lever can move.<n><e>",
+    "I think the level of each<n>lever may have something to do<n>with reducing the boiler<n>pressure and temperature.<n><e>",
+    // 08
+    "Nancy, I've run out of ideas.<n>Please be careful, okay?<n><e>",
+    "Nancy, I've run out of ideas.<n>Please be careful, okay?<n><e>",
+    "Nancy, I've run out of ideas.<n>Please be careful, okay?<n><e>",
+    // 09
+    "Oh, I'm sure your Aunt Eloise<n>will be helpful.  She<n>just LOVES to hide things!<n><e>",
+    "Oh, I'm sure your Aunt Eloise<n>will be helpful.<n><e>",
+    "How is your Aunt Eloise?<n>Her house is so beautiful!<n><e>",
+    // 10
+    "Those letters on your Aunt's safe<n>are definitely Greek letters.<n>I bet the combination is related<n>to the Greek letters on that note<n>from her college sorority!<n><e>",
+    "Those letters on your Aunt's safe<n>are definitely Greek letters.<n>I bet there's a note somewhere<n>in the house that also has<n>Greek letters.<n><e>",
+    "Those letters on your Aunt's safe<n>are definitely Greek letters.<n><e>",
+    // 11
+    "That box in Aunt Eloise's safe<n>must hold an important clue!<n><e>",
+    "Aunt Eloise must have some important<n>items in the safe.<n><e>",
+    "This is such a puzzling situation!<n><e>",
+    // 12
+    "Can you use Aunt Eloise's login<n>and password to access the <n>school administration computers?<n>I bet they're in the teacher's<n>lounge.<n><e>",
+    "Can you use Aunt Eloise's login<n>and password to access the <n>school administration computer?<n><e>",
+    "Oh Nancy, are you sure your Aunt<n>wouldn't mind you poking around<n>with her school stuff?<n><e>",
+    // 13
+    "I bet that box in Aunt Eloise's<n>safe hides her login ID<n>and password.<n><e>",
+    "Aunt Eloise probably hid her<n>login ID and password in<n>the safe at home.<n><e>",
+    "Aunt Eloise just loves to hide things!<n>Why not go to her house and take<n>a look around?<n><e>",
+    // 14
+    "This sounds dangerous, Nancy!<n>You'll need to find something in the<n>kitchen that will prop up the<n>gas line so you can take<n>the bolt cutters!<n><e>",
+    "Could something take the place<n>of the bolt cutters and hold<n>up that gas line?<n><e>",
+    "Nancy, this sounds too dangerous!<n>There must be another way to prop<n>up that gas line instead<n>of the bolt cutter!<n><e>",
+    // 15
+    "Well, the bolt cutters cut the chain.<n>Can you move the levers on the<n>boiler to change the<n>dials so they match<n>the poster with the gauges?<n><e>",
+    "There must be a poster down there<n>that shows the right position<n>of the levers so the pressure<n>goes down!<n><e>",
+    "Can you find the right level<n>for the levers so the pressure<n>will lower?<n><e>",
+    // 16
+    "Nancy!  Could that correct combination<n>be in the boiler room?<n>Maybe written on a wall<n>or something.<n><e>",
+    "Nancy!  Could that correct combination<n>be in the boiler room?<n><e>",
+    "Nancy!  Have you searched the boiler<n>room for a clue?<n><e>",
+    // 17
+    "I'm stumped, Nancy.<n>I'm afraid I'm not very much help.<n><e>",
+    "I'm stumped, Nancy.<n>I'm afraid I'm not very much help.<n><e>",
+    "I'm stumped, Nancy.<n>I'm afraid I'm not very much help.<n><e>",
+    // 18
+    "Why not go to the school library<n>and look around.  There's<n>always so much to learn there.<n><e>",
+    "Why don't you head for the library?<n>You might find some interesting<n>information there.<n><e>",
+    "There must be some place to go where<n>you can find out lots of information.<n><e>",
+    // 19
+    "I bet an extra key to the library<n>is hidden in Aunt Eloise's house.<n>Go check the walls.  Maybe there's<n>a secret compartment!<n><e>",
+    "I bet an extra key to the library<n>is hidden in Aunt Eloise's house.<n><e>",
+    "Your Aunt Eloise is head librarian.<n>Have her open up the school library.<n><e>",
+    // 20
+    "Have you checked the school basement?<n>You should find the maintenance door<n>and take a look down there!<n><e>",
+    "There must be other places to<n>investigate around the school.<n>Have you checked the basement?<n><e>",
+    "There must be other places<n>around the school to investigate<n>Have you checked all over?<n><e>",
+    // 21
+    "That maintenance door lock is definitely<n>in Braille.<n>I'd look in the school computer<n>for a password.<n><e>",
+    "The maintenance door lock uses Braille;<n>you can probably find a password<n>on the school computer.<n><e>",
+    "That maintenance door lock is definitely<n>in Braille, but I bet the password isn't!<n><e>",
+    // 22
+    "You found the password!<n>The encyclopedias in the school<n>library can help you to translate<n>the maintenance door's password<n>into Braille.<n><e>",
+    "You found the password!<n>Now you have to translate it into Braille<n>at the library.<n><e>",
+    "You found the password!<n>Now you'll have to translate it<n>into Braille.<n><e>",
+    // 23
+    "I bet the school basement is full<n>of clues.  Be careful, Nancy,<n>I have a bad feeling about<n>that old boiler.<n><e>",
+    "I bet the school basement is full of clues.<n><e>",
+    "If I were the boiler room room supervisor,<n>I would keep the combination on<n>something close by.<n><e>",
+    // 24
+    "I would check out the numbers<n>on that stone that tells us<n>when the school was built.<n><e>",
+    "I would look around the boiler room<n>for the combination.<n>It's a smart place to start.<n><e>",
+    "If I were the boiler room room supervisor,<n>I would keep the combination on<n>something close by.<n><e>",
+    // 25
+    "Get down on your knees and bark<n>like a dog!<n><e>",
+    "Get down on your knees and bark<n>like a dog!<n><e>",
+    "Get down on your knees and bark<n>like a dog!<n><e>"
+},
+{   // Russian
+    // 00
+    "N&nsi, * ne znay, qem pomoq%. <n>Bud% ostorogna.<n><e>",
+    "N&nsi, * ne znay, qem pomoq%. <n>Bud% ostorogna.<n><e>",
+    "N&nsi, * ne znay, qem pomoq%. <n>Bud% ostorogna.<n><e>",
+    // 01
+    "Najdi wkafqik ubitoho. <n>Tam mohut b=t% uliki.<n><e>",
+    "Y b= na tvoem meste ob=skal <n>mesto prestupleni*.<n><e>",
+    "N&nsi, poprobuj naqat% s <n>samoho naqala!<n><e>",
+    // 02
+    "N&nsi, poprobuj otkr=t% <n>wkafqik Dgeka. Navernoe, u neho <n>ne oqen% slogn=j kod. <n>Moget b=t%, u teb* vse <n>poluqits*, esli zamenit% <n>bukv= v eho imeni na <n>cifr=. Kak na telefone.<n><e>",
+    "Kod k moemu wkafqiku sv*zan <n>s moim imenem.<n><e>",
+    "Wtob= uznat% kod k wkafqiku <n>Dgeka, nugno zamenit% bukv= v <n>eho imeni na cifr=.<n><e>",
+    // 03
+    "T= xorowo osmotrela wkafqik <n>Dgeka? Moget, iz neho qto-to <n>v=palo?<n><e>",
+    "Osmotri wkafqik. Tam dolgno <n>b=t% qto-to interesnoe.<n><e>",
+    "N&nsi, bud% ostorogna. <n>)kafqik Dgeka opeqatan <n>policiej.<n><e>",
+    // 04
+    "Ispol%zuj steklorez, qtob= <n>otkr=t% okno s bokovoj <n>storon= wkol=.<n><e>",
+    "Navernoe, Dgek Rodgers <n>ispol%zoval steklorez ili <n>nog, qtob= popast% v <n>wkolu.<n><e>",
+    "N&nsi, bud% ostorogna. <n>)kafqik Dgeka opeqatan <n>policiej.<n><e>",
+    // 05
+    "V uqitel%skoj dolgen b=t% <n>komp%yter. T= mogew% tuda <n>popast%?<n><e>",
+    "V uqitel%skoj dolgn= b=t% <n>kakie-to uliki. Osmotri stol <n>s komp%yterom.<n><e>",
+    "Ne mohu poverit%, qto t= <n>popala v uqitel%skuy! <n>Dumay, t= najdew% tam <n>qto-to vagnoe.<n><e>",
+    // 06
+    "Tebe nugno vvesti v komp%yter <n>parol% i lohin teti Cloiz=. <n>Po-moemu, ona xranit &ti dann=e <n>v sejfe u seb* doma.<n><e>",
+    "Tebe nugno vvesti v komp%yter <n>parol% i lohin teti Cloiz=. <n>Navernoe, ona xranit &ti dann=e <n>u seb* doma.<n><e>",
+    "Wtob= vojti v komp%yter, tebe <n>nugno znat% parol% i lohin <n>teti Cloiz=. Vozmogno, ona <n>xranit &ti dann=e u seb* doma.<n><e>",
+    // 07
+    "Skoree vseho, perv=j <n>r=qah kotla upravl*et vtor=m <n>i tret%im.<n><e>",
+    "Skoree vseho, perv=j <n>r=qah kotla upravl*et vtor=m <n>i tret%im.<n><e>",
+    "Dumay, s pomoQ%y r=qahov <n>mogno ponigat% v kotle <n>davlenie i temperaturu vod=.<n><e>",
+    // 08
+    "N&nsi, u men* net nikakix idej. <n>Bud% ostorogna, ladno?<n><e>",
+    "N&nsi, u men* net nikakix idej. <n>Bud% ostorogna, ladno?<n><e>",
+    "N&nsi, u men* net nikakix idej. <n>Bud% ostorogna, ladno?<n><e>",
+    // 09
+    "Dumay, tebe pomoget tet* <n>Cloiza. Ona OBOGAET <n>pr*tat% veQi!<n><e>",
+    "Dumay, tebe pomoget tet* Cloiza.<n><e>",
+    "Kak pogivaet tet* Cloiza? <n>U nee takoj krasiv=j dom!<n><e>",
+    // 10
+    "Na zamke sejfa bukv= hreqeskoho <n>alfavita, a v sekretere teti <n>Cloiz= est% zapiska s hreqeskimi <n>bukvami. <n>Navern*ka, oni kak-to sv*zan=!<n><e>",
+    "Na zamke sejfa bukv= hreqeskoho <n>alfavita. Navern*ka, hde-to v dome teti <n>Cloiz= est% zapiska s hreqeskimi <n>bukvami.<n><e>",
+    "Na zamke sejfa bukv= hreqeskoho <n>alfavita.<n><e>",
+    // 11
+    "Kagets*, v wkatulke sejfa est% <n>qto-to vagnoe!<n><e>",
+    "Dumay, tet* Cloiza xranit v <n>sejfe qto-to vagnoe.<n><e>",
+    "Vot tak zadaqka!<n><e>",
+    // 12
+    "T= mogew% ispol%zovat% lohin i <n>parol% teti Cloiz=, qtob= vojti <n>v hlavn=j wkol%n=j komp%yter. <n>Navern*ka, on naxodits* v <n>uqitel%skoj.<n><e>",
+    "T= mogew% ispol%zovat% lohin i <n>parol% teti Cloiz=, qtob= vojti <n>v hlavn=j komp%yter wkol=.<n><e>",
+    "N&nsi, a t= uverena, qto tet* <n>Cloiza razrewila tebe vse <n>osmotret%?<n><e>",
+    // 13
+    "Tet* Cloiza xranit svoj lohin <n>i parol% v wkatulke, kotora* <n>stoit v sejfe.<n><e>",
+    "Skoree vseho, tet* Cloiza <n>pr*qet svoj lohin i parol% <n>v sejfe.<n><e>",
+    "Tet* Cloiza obogaet pr*tat% <n>veQi! Tebe nugno kak sleduet <n>osmotret% ee dom.<n><e>",
+    // 14
+    "N&nsi, &to oqen% opasno! <n>Tebe nugno najti to, qto budet <n>dergat% hazovuy trubu. <n>Tohda t= smogew% vz*t% <n>boltorez!<n><e>",
+    "PoiQi to, qem mogno zamenit% <n>boltorez pod hazovoj truboj.<n><e>",
+    "N&nsi, &to oqen% opasno!<n>PoiQi to, qto budet dergat%<n>hazovuy trubu vmesto<n>boltoreza.<n><e>",
+    // 15
+    "(ep% pererezana. Teper% tebe <n>nugno dvihat% r=qahi kotla, <n>qtob= pokazani* datqikov <n>sootvetstvovali sxeme.<n><e>",
+    "V kotel%noj dolgna b=t% <n>sxema s pravil%n=mi <n>pokazani*mi priborov.<n><e>",
+    "Tebe nugno dvihat% r=qahi, <n>qtob= snizit% davlenie.<n><e>",
+    // 16
+    "N&nsi! Moget b=t%, kod hde-to <n>v kotel%noj? Vnimatel%no <n>osmotri sten=.<n><e>",
+    "N&nsi! Moget b=t%, kod hde-to <n>v kotel%noj?<n><e>",
+    "T= xorowo osmotrela kotel%nuy?<n><e>",
+    // 17
+    "Izvini, N&nsi. U men* net <n>nikakix idej.<n><e>",
+    "Izvini, N&nsi. U men* net <n>nikakix idej.<n><e>",
+    "Izvini, N&nsi. U men* net <n>nikakix idej.<n><e>",
+    // 18
+    "Pojdi v biblioteku i vse tam <n>osmotri. Dumay, t= uznaew% <n>mnoho interesnoho.<n><e>",
+    "Poqemu b= tebe ne sxodit% v <n>biblioteku? T= najdew% tam <n>mnoho interesnoho.<n><e>",
+    "Tebe nugno pojti tuda, hde <n>mogno poqitat% interesn=e <n>knihi.<n><e>",
+    // 19
+    "Y dumay, zapasnoj klyq ot <n>biblioteki spr*tan v dome <n>teti Cloiz=. Prover% sten=. <n>Tam dolgen b=t% sejf.<n><e>",
+    "PoiQi zapasnoj klyq <n>ot biblioteki v <n>dome teti Cloiz=.<n><e>",
+    "Tet* Cloiza - bibliotekar%. U nee <n>navern*ka est% klyq ot <n>biblioteki.<n><e>",
+    // 20
+    "Vnimatel%no osmotri <n>kotel%nuy.<n><e>",
+    "V wkole mnoho razn=x <n>pomeQenij. T= uge <n>osmotrela podval?<n><e>",
+    "V wkole est% mnoho razn=x <n>pomeQenij. T= uge vse <n>osmotrela?<n><e>",
+    // 21
+    "Na zamke kotel%noj bukv= <n>napisan= wriftom Brajl*. <n>PoiQi parol% v <n>komp%ytere.<n><e>",
+    "Na zamke kotel%noj bukv= <n>napisan= wriftom Brajl*. <n>PoiQi parol% v <n>komp%ytere.<n><e>",
+    "Bukv= na zamke kotel%noj - <n>wrift Brajl*. Takim ge nugno <n>sdelat% i parol%.<n><e>",
+    // 22
+    "T= znaew% parol% v kotel%nuy! <n>V biblioteke est% &nciklopedi*, <n>kotora* pomoget perevesti eho <n>v wrift Brajl*.<n><e>",
+    "T= znaew% parol%! Teper% <n>nugno perevesti eho v wrift <n>Brajl*.<n><e>",
+    "T= znaew% parol%! Teper% nugno <n>perevesti eho v wrift Brajl*.<n><e>",
+    // 23
+    "Dumay, v podvale est% mnoho <n>ulik. N&nsi, bud% ostorogna <n>so star=m kotlom.<n><e>",
+    "Dumay, v podvale est% mnoho <n>ulik.<n><e>",
+    "Esli b= * rabotala v kotel%noj, <n>* zapisala b= kod na samom <n>vidnom meste.<n><e>",
+    // 24
+    "Vnimatel%no posmotri na <n>datu osnovani* wkol=.<n><e>",
+    "Vnimatel%no osmotri kotel%nuy. <n>Kod dolgen b=t% hde-to tam.<n><e>",
+    "Esli b= * rabotala v kotel%noj, <n>* zapisala b= kod na samom <n>vidnom meste.<n><e>",
+    // 25
+    "Opustis% na koleni i laj, kak sobaka!<n><e>",
+    "Opustis% na koleni i laj, kak sobaka!<n><e>",
+    "Opustis% na koleni i laj, kak sobaka!<n><e>",
+}
+};
+
+const Common::Array<const char *> _nancy1TelephoneRinging = {
+    "ringing...<n><e>", // English
+    "Hudki...  <n><e>"  // Russian
+};
+
+const Common::Array<const char *> _nancy1ItemNames = {
+    "Bolt Cutter",
+    "Calling Card",
+    "Coins",
+    "Glass Cutter",
+    "Gun",
+    "Keys",
+    "Soup Ladle",
+    "Video Tape",
+    "Work Gloves",
+    "Silver Library Key",
+    "TV VCR Remote Control"
+};
+
+const Common::Array<const char *> _nancy1EventFlagNames = {
+    "Tried the locker",
+    "Locker open",
+    "Read Kanji",
+    "Seen the poster",
+    "Has magazine",
+    "Viewed the tape",
+    "Read Literature book",
+    "Gone To Teachers Lounge (Found Backpack)",
+    "Seen Paper",
+    "Researched drug",
+    "Has Letter",
+    "Met Hal",
+    "Hal confessed",
+    "Hal said date",
+    "Hal told Connie",
+    "Hal said lie",
+    "Hal told Daryl",
+    "Hal told Hulk",
+    "Hal said injury",
+    "Met Connie",
+    "Connie confessed",
+    "Connie suspicious",
+    "Connie worried",
+    "Connie scared",
+    "Connie told Hulk",
+    "Connie said lie",
+    "Connie told Hal",
+    "Connie said load",
+    "Connie told Daryl",
+    "Met Hulk",
+    "Hulk confessed",
+    "Hulk said money",
+    "Hulk said locker",
+    "Hulk said lie",
+    "Hulk told Daryl",
+    "Hulk worried",
+    "Hulk angry",
+    "Hulk told Hal",
+    "Met Daryl",
+    "Daryl confessed",
+    "Set up sting",
+    "Time for end game",
+    "Player won game",
+    "Stop player scrolling",
+    "Generic 0",
+    "Generic 1",
+    "Generic 2",
+    "Generic 3",
+    "Generic 4",
+    "Generic 5",
+    "Generic 6",
+    "Generic 7",
+    "Generic 8",
+    "Generic 9",
+    "Jukebox Is Playing",
+    "Daryl talked about Connie",
+    "Daryl talked about Hal",
+    "Daryl talked about Hulk",
+    "Hulk told Connie",
+    "Solved Boiler Door Puzzle",
+    "Solved Aunt Safe Puzzle",
+    "Boiler Has Chains on it",
+    "Solved Boiler Lever Puzzle",
+    "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",
+    "Lounge Window Open",
+    "Tried Computer",
+    "Seen Aunt Safe",
+    "Boiler Die",
+    "Kitchen Die",
+    "Solved Slider Puzzle",
+    "Tried Library Door",
+    "Seen Boiler Door",
+    "Player Has Boiler Pwd",
+    "Connie Said Date",
+    "Connie Chickens",
+    "Hal Chickens",
+    "Hulk Chickens",
+    "Solved Boiler Lock",
+    "Seen the drug depot robbery article",
+    "Seen video camera in Jake's locker",
+    "Has soup ladle",
+    "HDIC 5 Loop",
+    "HDIC 6 Loop",
+    "HIC 5 Loop",
+    "HIC 6 Loop",
+    "HIC 7 Loop",
+    "DIC 4 Loop",
+    "DIC 5 Loop",
+    "DIC 6 Loop",
+    "DIC 7 Loop",
+    "DIC 8 Loop",
+    "DIC 9 Loop",
+    "DIC 10 Loop",
+    "DIC 11 Loop",
+    "DIC 12 Loop",
+    "DIC 13 Loop",
+    "DIC 15 Loop",
+    "DIC 16 Loop",
+    "DIC 17 Loop",
+    "DIC 18 Loop",
+    "CIC 5 Loop",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty",
+    "empty"
+};
+
+#endif // NANCY1DATA_H
diff --git a/devtools/create_nancy/tvd_data.h b/devtools/create_nancy/tvd_data.h
new file mode 100644
index 00000000000..cb931d88f04
--- /dev/null
+++ b/devtools/create_nancy/tvd_data.h
@@ -0,0 +1,615 @@
+/* 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 TVDDATA_H
+#define TVDDATA_H
+
+#include "types.h"
+
+const GameConstants _tvdConstants = {
+    24,
+    120,
+    { 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 125, 219, 220 },
+    { 110, 111, 112, 113, 114 },
+    8,
+    10,
+    167000
+};
+
+const Common::Array<Common::Language> _tvdLanguagesOrder = {
+    Common::Language::EN_ANY
+};
+
+const Common::Array<Common::Array<ConditionalDialogue>> _tvdConditionalDialogue = {
+{   // Damon?, empty
+},
+{   // Security guard, empty
+},
+{   // Mrs. Flowers, 20 responses
+    {   19, 759, "FIC_01",
+        { { 0x4, kFalse }, { 0x9, kTrue } },
+        { { 0x7, kFalse } } },
+    {   18, 758, "FIC_02",
+        { { 0x7, kFalse }, { 0x4F, kTrue } },
+        { { 0x3, kFalse } } },
+    {   17, 757, "FIC_03",
+        { { 0x10, kFalse }, { 0x18, kTrue }, { 0x1E, kFalse }, { 0x22, kTrue } },
+        { } },
+    {   16, 756, "FIC_04",
+        { { 0x10, kFalse }, { 0x18, kTrue }, { 0x1E, kFalse }, { 0x22, kFalse } },
+        { } },
+    {   15, 755, "FIC_05",
+        { { 0xD, kFalse }, { 0x1C, kTrue } },
+        { { 0x14, kFalse } } },
+    {   14, 754, "FIC_06",
+        { { 0x4A, kTrue }, { 0x52, kFalse }, { 0x2, kFalse } },
+        { { 0x10, kFalse } } },
+    {   13, 753, "FIC_07",
+        { { 0x4A, kTrue }, { 0x52, kFalse }, { 0x9, kFalse } },
+        { { 0x7, kFalse } } },
+    {   12, 753, "FIC_08",
+        { { 0x4A, kTrue }, { 0x52, kFalse }, { 0x8, kFalse } },
+        { { 0x2, kFalse } } },
+    {   11, 751, "FIC_09",
+        { { 0x4A, kTrue }, { 0x52, kFalse }, { 0x11, kFalse } },
+        { { 0x3, kFalse } } },
+    {   10, 750, "FIC_10",
+        { { 0x21, kTrue }, { 0xE, kTrue } },
+        { { 0x9, kTrue } } },
+    {   9, 749, "FIC_11",
+        { { 0x21, kTrue }, { 0x5D, kFalse } },
+        { { 0xD, kTrue } } },
+    {   8, 748, "FIC_12",
+        { { 0x21, kTrue }, { 0x5A, kFalse } },
+        { { 0x10, kTrue } } },
+    {   7, 747, "FIC_13",
+        { { 0x21, kTrue }, { 0x5B, kFalse } },
+        { { 0x7, kTrue } } },
+    {   6, 746, "FIC_14",
+        { { 0x21, kTrue }, { 0x5C, kFalse } },
+        { { 0x2, kTrue } } },
+    {   5, 745, "FIC_15",
+        { { 0x21, kTrue }, { 0x5E, kFalse } },
+        { { 0x5, kTrue } } },
+    {   4, 744, "FIC_16",
+        { { 0x21, kTrue }, { 0x60, kFalse } },
+        { { 0x8, kTrue } } },
+    {   3, 743, "FIC_17",
+        { { 0x21, kTrue }, { 0x5F, kFalse } },
+        { { 0xB, kTrue } } },
+    {   2, 742, "FIC_18",
+        { { 0x21, kTrue }, { 0x61, kFalse } },
+        { { 0x14, kTrue } } },
+    {   1, 741, "FIC_19",
+        { { 0xC, kFalse }, { 0x46, kTrue }, { 0x1D, kFalse } },
+        { } },
+    {   0, 740, "FIC_20",
+        { { 0xF, kFalse }, { 0x1D, kTrue } },
+        { } }
+},
+{   // Bonnie, 9 responses + 2 repeats
+    {   29, 928, "BIC_01",
+        { { 0x7, kFalse }, { 0x4F, kTrue }, { 0x4A, kFalse } },
+        { } },
+    {   28, 927, "BIC_02",
+        { { 0x10, kFalse }, { 0x22, kTrue }, { 0x1E, kFalse } },
+        { } },
+    {   28, 927, "BIC_02",
+        { { 0x10, kFalse }, { 0x22, kFalse }, { 0x18, kTrue }, { 0x1E, kFalse } },
+        { } },
+    {   27, 926, "BIC_03",
+        { { 0xC, kFalse }, { 0x46, kTrue } },
+        { { 0xB, kFalse } } },
+    {   27, 926, "BIC_03",
+        { { 0xC, kFalse }, { 0x46, kTrue } },
+        { { 0xB, kTrue }, { 0x8, kFalse } } },
+    {   26, 925, "BIC_04",
+        { { 0xD, kFalse }, { 0x1C, kTrue } },
+        { } },
+    {   25, 924, "BIC_05",
+        { { 0xA, kFalse }, { 0x47, kTrue }, { 0x3c, kTrue } },
+        { { 0xD, kFalse } } },
+    {   24, 923, "BIC_06",
+        { { 0x4A, kTrue }, { 0x2, kFalse } },
+        { { 0x10, kFalse } } },
+    {   23, 922, "BIC_07",
+        { { 0x4A, kTrue }, { 0x4, kFalse } },
+        { { 0x7, kFalse } } },
+    {   22, 921, "BIC_08",
+        { { 0x4A, kTrue }, { 0x8, kFalse } },
+        { { 0x2, kFalse } } },
+    {   21, 920, "BIC_09",
+        { { 0x4A, kTrue }, { 0x11, kFalse } },
+        { { 0x3, kFalse } } },
+    {   20, 919, "BIC_10",
+        { { 0x4A, kTrue }, { 0xF, kFalse }, { 0x1D, kTrue } },
+        { } }
+},
+{   // Caroline, 4 responses
+    {   33, 846, "CIC_01",
+        { { 0x4, kFalse }, { 0x49, kTrue } },
+        { { 0x7, kFalse } } },
+    {   32, 845, "CIC_02",
+        { { 0x5, kFalse } },
+        { } },
+    {   31, 844, "CIC_03",
+        { { 0x6, kFalse }, { 0x56, kTrue } },
+        { { 0x16, kFalse } } },
+    {   30, 843, "CIC_04",
+        { { 0x10, kFalse }, { 0x18, kTrue } },
+        { { 0x14, kFalse } } }
+},
+{   // Stefan, 10 responses
+    {   43, 342, "SIC_10",
+        { { 0x52, kTrue } },
+        { } },
+    {   42, 351, "SIC_01",
+        { { 0x52, kFalse }, { 0x4, kFalse }, { 0x49, kTrue } },
+        { { 0x7, kTrue } } },
+    {   41, 350, "SIC_02",
+        { { 0x52, kFalse }, { 0x10, kFalse }, { 0x18, kTrue } },
+        { { 0x14, kFalse } } },
+    {   40, 349, "SIC_03",
+        { { 0x52, kFalse }, { 0xD, kFalse }, { 0x1C, kTrue } },
+        { { 0xD, kFalse } } },
+    {   39, 348, "SIC_04",
+        { { 0x52, kFalse }, { 0xA, kFalse }, { 0x47, kTrue }, { 0x3C, kTrue } },
+        { { 0xD, kFalse } } },
+    {   38, 347, "SIC_05",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x1, kFalse } },
+        { { 0x10, kFalse } } },
+    {   37, 346, "SIC_06",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x8, kFalse } },
+        { { 0x2, kFalse } } },
+    {   36, 345, "SIC_07",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x11, kFalse } },
+        { { 0x3, kFalse } } },
+    {   35, 344, "SIC_08",
+        { { 0x52, kFalse }, { 0xC, kFalse }, { 0x46, kTrue }, { 0x1D, kFalse } },
+        { } },
+    {   34, 343, "SIC_09",
+        { { 0x52, kFalse }, { 0xF, kFalse }, { 0x1D, kTrue } },
+        { { 0x12, kFalse } } }
+},
+{   // Mrs. Grimesby, 20 responses + 2 repeats
+    {   63, 714, "EGS_02A",
+        { { 0x17, kTrue }, { 0x28, kFalse } },
+        { } },
+    {   63, 714, "EGS_02A",
+        { { 0x17, kFalse }, { 0x4F, kTrue }, { 0x28, kFalse } },
+        { } },
+    {   62, 713, "EGS_02B",
+        { { 0x17, kTrue }, { 0x28, kTrue } },
+        { } },
+    {   62, 713, "EGS_02B",
+        { { 0x17, kFalse }, { 0x4F, kTrue }, { 0x28, kTrue } },
+        { } },
+    {   61, 712, "EGS_02C",
+        { { 0x50, kTrue }, { 0x1D, kFalse }, { 0x2C, kFalse } },
+        { } },
+    {   60, 711, "EGS_02D",
+        { { 0x50, kTrue }, { 0x1D, kFalse }, { 0x2C, kTrue } },
+        { } },
+    {   59, 719, "EGS_02E",
+        { { 0x47, kTrue }, { 0x13, kTrue }, { 0x27, kFalse } },
+        { } },
+    {   58, 709, "EGS_02F",
+        { { 0x47, kTrue }, { 0x13, kTrue }, { 0x27, kTrue } },
+        { } },
+    {   57, 708, "EGS_02G",
+        { { 0x1E, kFalse }, { 0x18, kTrue }, { 0x2D, kFalse } },
+        { } },
+    {   56, 707, "EGS_02H",
+        { { 0x1E, kFalse }, { 0x18, kTrue }, { 0x2D, kTrue } },
+        { } },
+    {   55, 706, "EGS_02I",
+        { { 0x1E, kFalse }, { 0x1C, kTrue }, { 0x2A, kFalse } },
+        { { 0x14, kFalse } } },
+    {   54, 705, "EGS_02J",
+        { { 0x1E, kFalse }, { 0x1C, kTrue }, { 0x2A, kTrue } },
+        { { 0x14, kFalse } } },
+    {   53, 704, "EGS_02K",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x25, kFalse } },
+        { { 0x10, kFalse } } },
+    {   52, 703, "EGS_02L",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x25, kTrue } },
+        { { 0x10, kFalse } } },
+    {   51, 702, "EGS_02M",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x29, kFalse } },
+        { { 0x2, kFalse } } },
+    {   50, 701, "EGS_02N",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x29, kTrue } },
+        { { 0x2, kFalse } } },
+    {   49, 700, "EGS_02O",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x2E, kFalse } },
+        { { 0x3, kFalse } } },
+    {   48, 699, "EGS_02P",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x2E, kTrue } },
+        { { 0x3, kFalse } } },
+    {   47, 698, "EGS_02Q",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x26, kFalse } },
+        { { 0x7, kFalse } } },
+    {   46, 697, "EGS_02R",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x26, kTrue } },
+        { { 0x7, kFalse } } },
+    {   45, 696, "EGS_02S",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x1D, kTrue }, { 0x2B, kFalse } },
+        { } },
+    {   44, 695, "EGS_02T",
+        { { 0x52, kFalse }, { 0x4A, kTrue }, { 0x1D, kTrue }, { 0x2B, kTrue } },
+        { } }
+},
+{   // Aunt Judith, 11 responses
+    {   74, 493, "JIC_01",
+        { { 0x4, kFalse }, { 0x49, kTrue } },
+        { { 0x7, kFalse } } },
+    {   73, 492, "JIC_02",
+        { { 0x10, kFalse }, { 0x18, kTrue } },
+        { { 0xD, kFalse } } },
+    {   72, 491, "JIC_03",
+        { { 0xD, kFalse }, { 0x1C, kTrue } },
+        { { 0xD, kFalse } } },
+    {   71, 490, "JIC_04",
+        { { 0xA, kFalse }, { 0x47, kTrue } },
+        { { 0xD, kFalse } } },
+    {   70, 489, "JIC_05",
+        { { 0x4A, kTrue }, { 0x1, kFalse } },
+        { { 0x10, kFalse } } },
+    {   69, 488, "JIC_06",
+        { { 0x4A, kTrue }, { 0x9, kFalse } },
+        { { 0x7, kFalse } } },
+    {   68, 487, "JIC_07",
+        { { 0x4A, kTrue }, { 0x8, kFalse } },
+        { { 0x2, kFalse } } },
+    {   67, 486, "JIC_08",
+        { { 0x4A, kTrue }, { 0x11, kFalse } },
+        { { 0x3, kFalse } } },
+    {   66, 485, "JIC_09",
+        { { 0xC, kFalse }, { 0x46, kTrue }, { 0x1D, kFalse } },
+        { } },
+    {   65, 484, "JIC_10",
+        { { 0xF, kFalse }, { 0x1D, kTrue } },
+        { { 0x12, kFalse } } },
+    {   64, 483, "JIC_11",
+        { { 0xB, kFalse }, { 0x48, kTrue } },
+        { { 0x5, kFalse } } },
+},
+{   // Mr. Richards, empty
+},
+{   // Mikhail, 6 responses
+    {   80, 452, "MIC_01",
+        { { 0x10, kFalse }, { 0x49, kTrue } },
+        { { 0xD, kTrue }, { 0x14, kFalse } } },
+    {   79, 451, "MIC_02",
+        { { 0x4A, kTrue }, { 0x1, kFalse } },
+        { { 0x10, kFalse } } },
+    {   78, 450, "MIC_03",
+        { { 0x4A, kTrue }, { 0x4, kFalse } },
+        { { 0x7, kFalse } } },
+    {   77, 449, "MIC_04",
+        { { 0x4A, kTrue }, { 0x8, kFalse } },
+        { { 0x2, kFalse } } },
+    {   76, 448, "MIC_05",
+        { { 0x4A, kTrue }, { 0x11, kFalse } },
+        { { 0x3, kFalse } } },
+    {   75, 448, "MIC_06",
+        { { 0xF, kFalse }, { 0x1D, kTrue } },
+        { { 0x12, kFalse } } }
+}
+};
+
+static Common::Array<Goodbye> _tvdGoodbyes = {
+    // Damon
+    { "DAMBYE", {   { { 809 }, {}, NOFLAG } } },
+    // Security guard
+    { "EGBYE", {    { { 1108 }, {}, NOFLAG } } },
+    // Mrs. Flowers
+    { "FLOWBYE", {  { { 1112, 1113, 1114 }, { { 0x3E, kFalse } }, NOFLAG },
+                    { { 1109, 1110, 1111 }, {}, NOFLAG  } } },
+    // Bonnie
+    { "BONBYE", {   { { 1103, 1104, 1105 }, { { 0x3E, kTrue } }, NOFLAG },
+                    { { 997 }, { { 0x3E, kFalse }, { 0x15, kTrue }, { 0x1B, kTrue }, { 0x20, kTrue }, { 0x3F, kTrue } }, { 0x41, kTrue } },
+                    { { 1100, 1101, 1102 }, {}, NOFLAG  } } },
+    // Caroline; S1142.IFF appears to be missing
+    { "CAROLBYE", { { { 1140, 1141/*, 1142,*/ }, { { 0x3E, kFalse }, { 0x42, kTrue } }, NOFLAG },
+                    { { 1115, 1116, 1117 }, { { 0x3E, kFalse }, { 0x42, kFalse } }, NOFLAG },
+                    { { 1119 }, {}, NOFLAG  } } },
+    // Stefan
+    { "STEFBYE", {  { { 1121, 1122, 1123 }, { { 0x23, kTrue }, { 0x42, kTrue } }, NOFLAG },
+                    { { 1150 }, {}, NOFLAG } } },
+    // Mrs. Grimesby
+    { "GRMBYE", {   { { 1124 }, {}, NOFLAG } } },
+    // Aunt Judith
+    { "JUDYBYE", {  { { 1125 }, { { 0x3E, kFalse }, { 0x42, kFalse } }, NOFLAG },
+                    { { 1126 }, { { 0x3E, kFalse }, { 0x42, kTrue } }, NOFLAG },
+                    { { 1127 }, {}, NOFLAG } } },
+    // Mr. Richards
+    { "RICHBYE", {  { { 1128 }, { { 0x59, kTrue } }, NOFLAG },
+                    { { 1129 }, {}, NOFLAG } } },
+    // Mikhail
+    { "EGBYE", {    { { 1130 }, {}, NOFLAG } } }
+};
+
+const Common::Array<Common::Array<const char *>> _tvdConditionalDialogueTexts = { {
+    // 00
+    "<c1>D<c0>id you find a ring in the cemetery the other night? It was made of silver and Lapis.<h><n>",
+    "<c1>I<c0>'m looking for silver and Lapis for a project I'm doing. Do you know where I could find some?<h><n>",
+    "<c1>W<c0>ill you trade the vervain for this rune?<h><n>",
+    "<c1>W<c0>ill you trade the vervain for some Lapis?<h><n>",
+    "<c1>W<c0>ill you trade the vervain for my class ring?<h><n>",
+    // 05
+    "<c1>W<c0>ill you trade the vervain for this key?<h><n>",
+    "<c1>W<c0>ill you trade the vervain for an owl feather?<h><n>",
+    "<c1>W<c0>ill you trade the vervain for the dagger?<h><n>",
+    "<c1>W<c0>ill you trade the vervain for this black candle?<h><n>",
+    "<c1>I<c0>'ve got some gold to trade for the vervain, Mrs. Flowers. Would you take that?<h><n>",
+    // 10
+    "<c1>I<c0>'ve got something to trade for the vervain, Mrs. Flowers.It's a beautiful antique mortar and pestle I found in my attic. It belonged to my mother.<h><n>",
+    "<c1>Y<c0>ou wouldn't happen to know what vervain is, would you, Mrs. Flowers?<h><n>",
+    "<c1>I<c0>'m looking for an owls feather. Do you have any idea where I could find one?<h><n>",
+    "<c1>T<c0>his sounds strange, I know, but I'm looking for a dagger.<h><n>",
+    "<c1>Y<c0>ou wouldn't happen to have any black candles, would you, Mrs. Flowers?<h><n>",
+    // 15
+    "<c1>M<c0>rs. Flowers, how can someone my age get a loan? There's something at the gallery I have to have.<h><n>",
+    "<c1>H<c0>ave you ever heard of runes, Mrs. Flowers? Bonnie swears they're for real, but I'm not so sure I should believe her.<h><n>",
+    "<c1>W<c0>hat was that you told me about runes, Mrs. Flowers? I'm sorry, I forgot.<h><n>",
+    "<c1>Y<c0>ou seem to know a lot of strange stuff, Mrs. Flowers. Do you know anything about Druids, by any chance?<h><n>",
+    "<c1>H<c0>ave you seen the newspaper article on Mr. Richards' collection? Now he's got some weird dagger. Pretty creepy, huh?<h><n>",
+    // 20
+    "<c1>I<c0> went to the graveyard, at night, just like your grandmother said in her diary. And I did the Ring Ceremony. But I don't have the Ring and I can't find the silver or Lapis either. What do I do?<h><n>",
+    "<c1>I<c0>n the spell book, it said I need vervain to power the binding spell. Do you have any vervain, Bonnie? What about Mr. Richards?<h><n>",
+    "<c1>A<c0>ccording to the spell book, I need an owl feather -- of all things -- in the binding spell. If anybody has seen an owl around, I figured it would be you.<h><n>",
+    "<c1>T<c0>he spell book said I need a dagger to complete the binding spell. There's only one dagger I can think of. Can you help me?<h><n>",
+    "<c1>B<c0>onnie, the spell book said I need a black candle for the binding spell. But I don't know where to find one, do you?<h><n>",
+    // 25
+    "<c1>I<c0> read that ghost story about Adelaide Chambers, you remember it.  I think there really is gold buried in her grave. But I can't get past the ghost that's guarding it.  Do you have any ideas?<h><n>",
+    "<c1>I<c0> think I found a rune to replace the one you're missing, Bonnie. It's in Mikhail's art gallery. But Caroline said it will cost loads of money? Do you have any idea what I can do?<h><n>",
+    "<c1>I<c0> read your grandmother's diary, Bonnie. She says you need silver and Lapis to make a Ring of Power. Do you have any idea where I could find some?<h><n>",
+    "<c1>I<c0> know you know something about Runes, Bonnie. What can you tell me about them?<h><n>",
+    "<c1>H<c0>ave you ever heard of Druids, Bonnie? I heard they believed in magic, so I thought you might know something about them.<h><n>",
+    // 30
+    "<c1>T<c0>hat's a rune over there, isn't it? Bonnie would sure like that for her birthday. How much is it?<h><n>",
+    "<c1>D<c0>o you know anything about the display Mr. Smith is doing for the high school?<h><n>",
+    "<c1>M<c0>r. Smith gave you a ride home from the hospital, right? What do you know about him?<h><n>",
+    "<c1>H<c0>ave you heard anything about that new dagger Gary Richards has added to his collection? Has Mikhail said mentioned it?<h><n>",
+    "<c1>W<c0>hat am I going to do, Stefan? I did the ceremony to summon the Ring Maker, but nothing happened. And now I don't have the silver, or the Lapis, or the Ring of Power!<h><n>",
+    // 35
+    "<c1>A<c0>ccording to the diary of Bonnie's grandmother, I need silver and Lapis for a Ring of Power. But I don't have any silver or Lapis. And I need to summon the ring maker once I have the ingredients..<h><n>",
+    "<c1>T<c0>here's one more thing that I need for the binding spell, Stefan. Some vervain. But I have no idea where to find any. Do you have any ideas?<h><n>",
+    "<c1>O<c0>kay, I've got the binding spell, but I need an owl feather. You wouldn't happen to be an owl in your other form, would you?<h><n>",
+    "<c1>N<c0>ow that I've found the binding spell, I need a black candle. But why does it have to be a black candle, and not a red or white candle?<h><n>",
+    "<c1>D<c0>o you have any idea how I could get rid of Adelaide Chambers' ghost, Stefan?  I need to find out if there's gold buried there.  But every time I try to get near, she drives me off.<h><n>",
+    // 40
+    "<c1>I<c0> think I found a rune to replace the one that Bonnie is missing. The only snag is that it's for sale in Mikhail's art gallery. Which means that a need a whole lot of money to buy it. You wouldn'thappen to have any money you could lend me, do you?<h><n>",
+    "<c1>B<c0>onnie told me that she's missing one of her grandmother's runes, Stefan. You wouldn't know where I could find it, do you?<h><n>",
+    "<c1>I<c0> read about the Brasov Dagger in the paper, Stefan. They said it had something to do with immortality. But that doesn't sound right. What can you tell me about it?<h><n>",
+    "<c1>I<c0>'ve got everything. Stefan. And -- it's the weirdest thing -- Bonnie and Mrs. Flowers just came to tell me it's time, that he's drawing in his power. Will you come with me, please?<h><n>",
+    "<c1>H<c0>as anyone mentioned finding a silver and lapis ring yet, Mrs. Grimesby?<h><n>",
+    // 45
+    "<c1>I<c0>'m looking for a ring, made of silver and lapis. Have you seen it?<h><n>",
+    "<c1>I<c0>'m still trying to find out about that weird dagger. Can you tell me anything more?<h><n>",
+    "<c1>H<c0>ave you ever heard of a magical dagger that has something to do with ULTIMATE POWER?<h><n>",
+    "<c1>W<c0>hat else can you tell me about vervain?<h><n>",
+    "<c1>W<c0>hat's vervain?<h><n>",
+    // 50
+    "<c1>I<c0>'m still looking for an owl feather. What can I do?<h><n>",
+    "<c1>D<c0>o you have any idea where I can find an owl feather?<h><n>",
+    "<c1>I<c0>'m still looking for a black candle, Mrs. Grimesby. Can you help me?<h><n>",
+    "<c1>I<c0>'m looking for a black candle. Do you know where I can find one?<h><n>",
+    "<c1>I<c0>'m still trying to find enough money to buy something from the art gallery. Do you have any idea what I can do?<h><n>",
+    // 55
+    "<c1>M<c0>rs. Grimesby, do you have any idea where I can get enough money to buy something from the art gallery?<h><n>",
+    "<c1>W<c0>here was that information about Runes again, please?<h><n>",
+    "<c1>W<c0>here can I find something about Runes? You know, those Viking fortune-telling things.<h><n>",
+    "<c1>W<c0>here did you say I could find something from that Civil War ghost story, Mrs. Grimesby?<h><n>",
+    "<c1>I<c0> read a ghost story about the daughter of a Union general who was in love with a Confederate soldier. Do you know if it's true?<h><n>",
+    // 60
+    "<c1>W<c0>hat was it you said about a Ring of Power?<h><n>",
+    "<c1>H<c0>ave you ever heard of something called a Ring of Power?<h><n>",
+    "<c1>C<c0>an you tell about Druids again, please?<h><n>",
+    "<c1>W<c0>hat can you tell me about Druids?<h><n>",
+    "<c1>A<c0>unt Judith, do you know what Margaret did with the key to my jewelry box?<h><n>",
+    // 65
+    "<c1>I<c0> was looking for a silver ring. Have you seen one, Aunt Judith?<h><n>",
+    "<c1>D<c0>o you have any idea where I could find any silver or Lapis jewelry, Aunt Judith?<h><n>",
+    "<c1>A<c0>unt Judith, do you know where I could find some vervain?<h><n>",
+    "<c1>W<c0>ould you know how I could get an owl feather?<h><n>",
+    "<c1>H<c0>ow could I get Mr. Richards to lend me his new dagger?<h><n>",
+    // 70
+    "<c1>D<c0>o you know where I could find a black candle, Aunt Judith?<h><n>"
+    "<c1>D<c0>o you remember the old ghost story about Adelaide Chambers, Aunt Judith? A book in the library says she was buried with gold. Do you think it's true?<h><n>",
+    "<c1>I<c0> want to buy something from the art gallery, Aunt Judith. Can you help me?<h><n>",
+    "<c1>D<c0>o you know anything about runes, Aunt Judith? Bonnie said one of her's is missing and I'd like to get her another one.<h><n>",
+    "<c1>D<c0>o you know anything about that dagger Mr. Richards just added to his collection, Aunt Judith?<h><n>",
+    // 75
+    "<c1>I<c0> lost a ring, it was made of silver and Lapis. You haven't seen it, have you?<h><n>",
+    "<c1>I<c0>'m trying to find some vervain. Do you know where I could find some?<h><n>",
+    "<c1>H<c0>ave you by any chance seen any owl feathers anywhere around?<h><n>",
+    "<c1>I<c0>'m looking for a special dagger, it's supposed to have something to do with Ultimate Power or something. Can you help me?<h><n>",
+    "<c1>C<c0>ould you tell me where I could find a black candle, please?<h><n>",
+    // 80
+    "<c1>I<c0>'m interested in buying a rune you have for sale.<h><n>"
+} };
+
+const Common::Array<Common::Array<const char *>> _tvdGoodbyeTexts = { {
+    "<c1>I<c0> think I'd better go.<h>", // DAMBYE
+    "<c1>b<c0>ye.<h>", // EGBYE
+    "<c1>I<c0> should go now, Mrs. Flowers. I'll see you later, okay?.<h>", // FLOWBYE
+    "<c1>S<c0>ee you later, Bonnie..<h>", // BONBYE
+    "<c1>F<c0>ine. I am out of here..<h>", // CAROLBYE
+    "<c1>I<c0>'ll be back soon, Stefan. I promise..<h>", // STEFBYE
+    "<c1>b<c0>ye.<h>", // GRMBYE
+    "<c1>S<c0>ee you later, Aunt Judith..<h>", // JUDYBYE
+    "<c1>I<c0> guess it's time for me to go..<h>", // RICHBYE
+    "<c1>b<c0>ye.<h>", // EGBYE, again
+} };
+
+const Common::Array<const char *> _tvdItemNames = {
+    "Maker Note",
+    "Magic Book",
+    "Feather",
+    "Vervain",
+    "Crypt Key",
+    "Jewelry Box",
+    "House Key",
+    "Dagger",
+    "Class Ring",
+    "Mortar And Pestle",
+    "Mask",
+    "Lapis Jewel",
+    "Case Key",
+    "Gold Coin",
+    "Matches",
+    "White Candle",
+    "Black Candle",
+    "Fence Piece",
+    "Ring Of Power",
+    "Shovel",
+    "Perth Rune",
+    "Rune Bag",
+    "Confederate Hat",
+    "Clock Key"
+};
+
+const Common::Array<const char *> _tvdEventFlagNames = {
+    "Aristocrat Bonnie told about mikhails bgnd",
+    "AskedCandle asked about a black candle",
+    "AskedCaroline  asked Mikhail about caroline (in EG)",
+    "AskedChildren ask Mik about children EG",
+    "AskedDagger asked about the dagger",
+    "AskedDamon asked about Damon",
+    "AskedDisplay ask about display at school",
+    "AskedDruids asked about druids",
+    "AskedFeather asked about owl feathers",
+    "AskedGetDagger ask about getting dagger",
+    "AskedGold ask how to get gold from ghost",
+    "AskedKey ask about key to her jewelry box",
+    "AskedLapis asked about Lapis",
+    "AskedMoney asked to borrow money",
+    "AskedMortar asked to trade the Mortar",
+    "AskedRing asked if whoever has seen the ring",
+    "AskedRunes asked about runes",
+    "AskedVervain asked about Vervain",
+    "AskedWhy asked Mikhail why he is doing this",
+    "BeenToGrave ",
+    "BeenToHospitalOnce ",
+    "BonieIntro met Bonnie",
+    "BonnieMad  Bonnie mad during convo at party",
+    "BonnieSaidDruid Bonnie mentioned her druid relatives",
+    "BonnieToldRunes Bonnie said  missing rune",
+    "BonnieToldJob Bonnie told about her job",
+    "CarolineAngry made Caroline angry",
+    "CarolineIntro met Caroline",
+    "CarolineSaidMoney Caroline told rune costs",
+    "DoneRingCeremony ",
+    "DoneRuneReading",
+    "DumbGuySaveGame Not really used",
+    "FlowersIntro met Mrs Flowers",
+    "FlowersSaidTrade Flowers told about trade",
+    "FlowersToldRunes Flowers talked about runes",
+    "GoneToLounge",
+    "GrimesbyTalked talked to Grimesby",
+    "GToldCandle Grimesby has mentioned candles",
+    "GToldDagger Grimesby has mentioned dagger",
+    "GToldDisplay Grimesby mentioned display",
+    "GToldDruid",
+    "GToldFeather Grimesby talked about feathers",
+    "GToldGold Grimesby talked about gold",
+    "GToldLapisRing mentioned ring to Grimesby",
+    "GToldRingOfPower asked Grimesby ring of power",
+    "GToldRunes Grimesby told where to find runes info",
+    "GToldVervain Grimesby player about vervain ",
+    "GuardCaught",
+    "GuardMad player makes the guard mad",
+    "GuardToldKey guard tells the player about the key",
+    "School door chain is broken",
+    "IntoThePit",
+    "Elena Gone To Bed",
+    "Damon At Desk",
+    "Caroline Hospital Done",
+    "Mikhail Working",
+    "End Game Puzzle",
+    "Judith Talked Once",
+    "Stefan Talked Once",
+    "Player Won Game",
+    "Seen Ghost Attack",
+    "Ghost Kiss Done",
+    "IntroDone",
+    "JudithIntro met Aunt Judy",
+    "JudithToldCandle Judy told where the candle is",
+    "LastToTalk ",
+    "MargaretAttacked ",
+    "MikhailMet player has met Mikhail",
+    "MikhailTrapped ",
+    "Dream Done",
+    "ReadDiary ",
+    "ReadGhostStory ",
+    "ReadMargaretNote ",
+    "ReadPaper ",
+    "ReadSpellBook ",
+    "RichardsIntro  met Gary Richards",
+    "RingCeremonyStarted ",
+    "StefanIntro player has met Stefan",
+    "StefanSaidBrother Stefan has mentioned his brother",
+    "StefanSaidDruid Stefan mentioned druids",
+    "StefanSaidRingOfPower Stefan mentioned ring of power",
+    "TalkedToMikhail  talked to Mikhail",
+    "TimeForEndgame",
+    "ToldAboutMary player mentioned Bonnies sister to Gary",
+    "ToldBite ",
+    "ToldDangerous ",
+    "ToldDisplay player been told about school display",
+    "ToldInnocent player been told about innocent blood?",
+    "ToldVampire player been told Stefan is a vampire",
+    "ToldVampireDagger player been told relation between dagger and vampires?",
+    "TradeCandle player has offered the candle to Flowers",
+    "TradeDagger player offered dagger to Flowers",
+    "TradeFeather player offered the feather to flowers",
+    "TradeGold player has offered gold to flowers",
+    "TradeKey player has offered the key to flowers",
+    "TradeLapis player has offered the lapis to flowers",
+    "TradeClassRing offered class ring to flowers",
+    "TradeRune player offered the rune to flowers",
+    "TriedToOpenDoor tried door at Gary's house during day",
+    "TriggerScream ",
+    "WhereIsMikhail ",
+    "Stop player scrolling ",
+    "GaryRichardsMezzDragonSlider ",
+    "GaryRichardsSpiralStaircase ",
+    "SirenSoundEffect",
+    "Stormy",
+    "Dagger Puzzle",
+    "Owl Puzzle",
+    "Magic Book Movie",
+    "Mask Used On Door",
+    "Generic 0, single scene only - clear, set, clear",
+    "Generic 1, single scene only - clear, set, clear",
+    "Generic 2, single scene only - clear, set, clear",
+    "Generic 3, single scene only - clear, set, clear",
+    "Generic 4, single scene only - clear, set, clear",
+    " ",
+	" ",
+	" ",
+	" ",
+	" "
+};
+
+#endif // TVDDATA_H
diff --git a/devtools/create_nancy/types.h b/devtools/create_nancy/types.h
new file mode 100644
index 00000000000..5406e8e3f67
--- /dev/null
+++ b/devtools/create_nancy/types.h
@@ -0,0 +1,83 @@
+/* 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 CREATE_NANCY_TYPES_H
+#define CREATE_NANCY_TYPES_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/language.h"
+
+#define NOFLAG { -1, kFalse }
+
+enum NancyFlag : byte { kFalse = 1, kTrue = 2 };
+
+struct GameConstants {
+	uint16 numItems;
+	uint16 numEventFlags;
+	Common::Array<uint16> mapAccessSceneIDs;
+	Common::Array<uint16> genericEventFlags;
+	uint16 numNonItemCursors;
+	uint16 numCurtainAnimationFrames;
+	uint32 logoEndAfter;
+};
+
+struct EventFlagDescription {
+	int16 label;
+	NancyFlag flag;
+};
+
+struct SceneChangeDescription {
+	uint16 sceneID;
+	uint16 frameID;
+	uint16 verticalOffset;
+	bool doNotStartSound;
+};
+
+struct ConditionalDialogue {
+    byte textID;
+    uint16 sceneID;
+    const char soundID[9];
+	Common::Array<EventFlagDescription> flagConditions;
+	Common::Array<EventFlagDescription> inventoryConditions;
+};
+
+struct GoodbyeSceneChange {
+	Common::Array<int16> sceneIDs;
+	Common::Array<EventFlagDescription> flagConditions;
+	EventFlagDescription flagToSet;
+};
+
+struct Goodbye {
+	const char soundID[9];
+	Common::Array<GoodbyeSceneChange> sceneChanges;
+};
+
+struct Hint {
+    byte textID;
+    int16 hintWeight;
+    SceneChangeDescription sceneChange;
+    const char *soundIDs[3];
+    Common::Array<EventFlagDescription> flagConditions;
+	Common::Array<EventFlagDescription> inventoryConditions;
+};
+
+#endif // CREATE_NANCY_TYPES_H


Commit: 62553f2b9f54457dae3d95ee3958ae629c7e8411
    https://github.com/scummvm/scummvm/commit/62553f2b9f54457dae3d95ee3958ae629c7e8411
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-02T14:28:10+01:00

Commit Message:
DEVTOOLS: Add create_nancy description to README

Changed paths:
    devtools/README


diff --git a/devtools/README b/devtools/README
index 7e6195923ec..fc505ba6dfd 100644
--- a/devtools/README
+++ b/devtools/README
@@ -90,6 +90,11 @@ create_mort (Strangerke)
     - Font data
     - French, German and fan-made English translation
 
+create_nancy (fracturehill)
+-----------
+    Creates nancy.dat file containing various constants, game logic
+    and strings originally embedded in the games' executables.
+
 
 create_project (LordHoto, Littleboy)
 --------------


Commit: 3680c8ec5703f16e194d1df24992b807e6d9ea3b
    https://github.com/scummvm/scummvm/commit/3680c8ec5703f16e194d1df24992b807e6d9ea3b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-02T14:28:10+01:00

Commit Message:
DISTS: Add nancy.dat to engine data

Added an initial version of nancy.dat to dists/game-data

Changed paths:
  A dists/engine-data/nancy.dat
    dists/engine-data/README


diff --git a/dists/engine-data/README b/dists/engine-data/README
index d5c02a1bf7b..26dbe5686a2 100644
--- a/dists/engine-data/README
+++ b/dists/engine-data/README
@@ -49,6 +49,10 @@ File created partially by extracting font data from the French executable. It
 also contains the French and German translation, as well as a custom-made
 English translation.
 
+nancy.dat:
+File containing various constants, game logic and strings originally embedded
+in the games' executables.
+
 neverhood.dat:
 This file contains hardcoded game data used by The Neverhood game.
 
diff --git a/dists/engine-data/nancy.dat b/dists/engine-data/nancy.dat
new file mode 100644
index 00000000000..59684a3f665
Binary files /dev/null and b/dists/engine-data/nancy.dat differ


Commit: ec1ce0766907ec5ef25534a75e6dc80188343be5
    https://github.com/scummvm/scummvm/commit/ec1ce0766907ec5ef25534a75e6dc80188343be5
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-02T14:28:10+01:00

Commit Message:
DEVTOOLS: create_nancy code cleanup

Changed paths:
    devtools/create_nancy/create_nancy.cpp
    devtools/create_nancy/file.cpp
    devtools/create_nancy/file.h


diff --git a/devtools/create_nancy/create_nancy.cpp b/devtools/create_nancy/create_nancy.cpp
index 9623c83201a..64998c67188 100644
--- a/devtools/create_nancy/create_nancy.cpp
+++ b/devtools/create_nancy/create_nancy.cpp
@@ -19,8 +19,6 @@
  *
  */
 
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
 #include "file.h"
 #include "tvd_data.h"
 #include "nancy1_data.h"
@@ -116,21 +114,21 @@ void writeGameData( File &output,
 
     // Write conditional dialogue text
     if (dialogueTexts) {
-        output.writeMultilangArray(*dialogueTexts);
+        writeMultilangArray(output, *dialogueTexts);
     } else {
         output.writeUint16(0);
     }
 
     // Write goodbyes text
     if (goodbyeTexts) {
-        output.writeMultilangArray(*goodbyeTexts);
+        writeMultilangArray(output, *goodbyeTexts);
     } else {
         output.writeUint16(0);
     }
 
     // Write hints text
     if (hintTexts) {
-        output.writeMultilangArray(*hintTexts);
+        writeMultilangArray(output, *hintTexts);
     } else {
         output.writeUint16(0);
     }
diff --git a/devtools/create_nancy/file.cpp b/devtools/create_nancy/file.cpp
index db58599062b..7b5a8f06a1a 100644
--- a/devtools/create_nancy/file.cpp
+++ b/devtools/create_nancy/file.cpp
@@ -38,18 +38,21 @@ bool File::open(const byte *data, uint size) {
 }
 
 void File::close() {
-    if (_f)
+    if (_f) {
         fclose(_f);
+    }
+
     _f = nullptr;
     delete[] _memPtr;
     _memPtr = nullptr;
 }
 
 uint File::pos() const {
-    if (_f)
+    if (_f) {
         return ftell(_f);
-    else
+    } else {
         return _offset;
+    }
 }
 
 uint File::size() const {
@@ -67,16 +70,19 @@ uint File::size() const {
 }
 
 bool File::eof() const {
-    if (_f)
+    if (_f) {
         return feof(_f) != 0;
-    else if (_memPtr)
+    } else if (_memPtr) {
         return _offset >= _size;
+    }
+
     return false;
 }
 
 int File::seek(int offset, int whence) {
-    if (_f)
+    if (_f) {
         return fseek(_f, offset, whence);
+    }
 
     switch (whence) {
         case SEEK_SET:
@@ -96,15 +102,17 @@ int File::seek(int offset, int whence) {
 }
 
 void File::skip(int offset) {
-    if (_f)
+    if (_f) {
         fseek(_f, offset, SEEK_CUR);
-    else
+    } else {
         _offset += offset;
+    }
 }
 
 long File::read(void *buffer, size_t len) {
-    if (_f)
+    if (_f) {
         return fread(buffer, 1, len, _f);
+    }
 
     uint bytesToRead = CLIP(len, (size_t)0, _size - _offset);
     memcpy(buffer, &_memPtr[_offset], bytesToRead);
@@ -154,28 +162,6 @@ void File::writeString(const char *msg) {
     }
 }
 
-void File::writeMultilangArray(const Common::Array<Common::Array<const char *>> &array) {
-    writeUint16(array.size());
-    Common::Array<uint32> offsets;
-    uint32 offsetsOffset = pos();
-
-    skip(array.size() * 4);
-
-    for (uint i = 0; i < array.size(); ++i) {
-        offsets.push_back(pos());
-        writeToFile(*this, array[i]);
-    }
-
-    uint end = pos();
-    seek(offsetsOffset);
-
-    for (uint i = 0; i < array.size(); ++i) {
-        writeUint32(offsets[i]);
-    }
-
-    seek(end);
-}
-
 template<>
 void writeToFile(File &file, const Common::Array<const char *> &obj) {
     file.writeUint16(obj.size());
@@ -232,3 +218,25 @@ void writeToFile(File &file, const Hint &obj) {
     writeToFile(file, obj.flagConditions);
     writeToFile(file, obj.inventoryConditions);
 }
+
+void writeMultilangArray(File &file, const Common::Array<Common::Array<const char *>> &array) {
+    file.writeUint16(array.size());
+    Common::Array<uint32> offsets;
+    uint32 offsetsOffset = file.pos();
+
+    file.skip(array.size() * 4);
+
+    for (uint i = 0; i < array.size(); ++i) {
+        offsets.push_back(file.pos());
+        writeToFile(file, array[i]);
+    }
+
+    uint end = file.pos();
+    file.seek(offsetsOffset);
+
+    for (uint i = 0; i < array.size(); ++i) {
+        file.writeUint32(offsets[i]);
+    }
+
+    file.seek(end);
+}
diff --git a/devtools/create_nancy/file.h b/devtools/create_nancy/file.h
index df532a00811..28a4dbe5b4b 100644
--- a/devtools/create_nancy/file.h
+++ b/devtools/create_nancy/file.h
@@ -63,8 +63,6 @@ public:
 	void writeUint16(uint16 v);
 	void writeUint32(uint v);
 	void writeString(const char *msg);
-
-	void writeMultilangArray(const Common::Array<Common::Array<const char *>> &array);
 };
 
 template <class T>
@@ -95,4 +93,6 @@ void writeToFile(File &file, const Goodbye &obj);
 template<>
 void writeToFile(File &file, const Hint &obj);
 
+void writeMultilangArray(File &file, const Common::Array<Common::Array<const char *>> &array);
+
 #endif // CREATE_NANCY_FILE_H


Commit: 8e0d4dfa7a31ad3b5093c92268803a49276da037
    https://github.com/scummvm/scummvm/commit/8e0d4dfa7a31ad3b5093c92268803a49276da037
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-02T14:28:10+01:00

Commit Message:
DEVTOOLS:  Fix compile errors

Changed a couple of type definition to (hopefully) fix the buildbot
compiler errors

Changed paths:
    devtools/create_nancy/types.h


diff --git a/devtools/create_nancy/types.h b/devtools/create_nancy/types.h
index 5406e8e3f67..cf5c6677d1d 100644
--- a/devtools/create_nancy/types.h
+++ b/devtools/create_nancy/types.h
@@ -55,7 +55,7 @@ struct SceneChangeDescription {
 struct ConditionalDialogue {
     byte textID;
     uint16 sceneID;
-    const char soundID[9];
+    const char *soundID;
 	Common::Array<EventFlagDescription> flagConditions;
 	Common::Array<EventFlagDescription> inventoryConditions;
 };
@@ -67,7 +67,7 @@ struct GoodbyeSceneChange {
 };
 
 struct Goodbye {
-	const char soundID[9];
+	const char *soundID;
 	Common::Array<GoodbyeSceneChange> sceneChanges;
 };
 




More information about the Scummvm-git-logs mailing list