From 27ef37b4004e10e9052115372d99a1af16897654 Mon Sep 17 00:00:00 2001
From: Paul Gilbert
Date: Thu, 22 Mar 2018 20:22:52 -0400
Subject: XEEN: Add original copy protection dialog

---
 devtools/create_xeen/constants.cpp               |  11 ++-
 dists/engine-data/xeen.ccs                       | Bin 43490 -> 43729 bytes
 engines/xeen/dialogs/dialogs_copy_protection.cpp | 100 +++++++++++++++++++++++
 engines/xeen/dialogs/dialogs_copy_protection.h   |  64 +++++++++++++++
 engines/xeen/module.mk                           |   1 +
 engines/xeen/resources.cpp                       |   1 +
 engines/xeen/resources.h                         |   1 +
 engines/xeen/scripts.cpp                         |   5 +-
 8 files changed, 180 insertions(+), 3 deletions(-)
 create mode 100644 engines/xeen/dialogs/dialogs_copy_protection.cpp
 create mode 100644 engines/xeen/dialogs/dialogs_copy_protection.h

diff --git a/devtools/create_xeen/constants.cpp b/devtools/create_xeen/constants.cpp
index 9075ed568c..db1c73d063 100644
--- a/devtools/create_xeen/constants.cpp
+++ b/devtools/create_xeen/constants.cpp
@@ -176,7 +176,15 @@ const char *const WHO_WILL = "\x03""c\x0B""000\x09""000%s\x0A\x0A"
 
 const char *const HOW_MUCH = "\x3""cHow Much\n\n";
 
-const char *const WHATS_THE_PASSWORD = "What's the Password?";
+const char *const WHATS_THE_PASSWORD = "\x3""cWhat's the Password?\n"
+	"\n"
+	"Please turn to page %u, go to\n"
+	"line %u, and type in word %u.\v067\t000Spaces are not counted as words or lines.  "
+	"Hyphenated words are treated as one word.  Any line that has any text is considered a line."
+	"\x3""c\v040\t000\n";
+
+const char *const PASSWORD_INCORRECT = "\x3""c\v040\n"
+	"\f32Incorrect!\fd";
 
 const char *const IN_NO_CONDITION = "\x0B""007%s is not in any condition to perform actions!";
 
@@ -1892,6 +1900,7 @@ void writeConstants(CCArchive &cc) {
 	file.syncString(WHO_WILL);
 	file.syncString(HOW_MUCH);
 	file.syncString(WHATS_THE_PASSWORD);
+	file.syncString(PASSWORD_INCORRECT);
 	file.syncString(IN_NO_CONDITION);
 	file.syncString(NOTHING_HERE);
 	file.syncStrings(TERRAIN_TYPES, 6);
diff --git a/dists/engine-data/xeen.ccs b/dists/engine-data/xeen.ccs
index 3c7bcbc2cf..801168a2ee 100644
Binary files a/dists/engine-data/xeen.ccs and b/dists/engine-data/xeen.ccs differ
diff --git a/engines/xeen/dialogs/dialogs_copy_protection.cpp b/engines/xeen/dialogs/dialogs_copy_protection.cpp
new file mode 100644
index 0000000000..7788cb5a22
--- /dev/null
+++ b/engines/xeen/dialogs/dialogs_copy_protection.cpp
@@ -0,0 +1,100 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "xeen/dialogs/dialogs_copy_protection.h"
+#include "xeen/dialogs/dialogs_input.h"
+#include "xeen/resources.h"
+#include "xeen/xeen.h"
+
+namespace Xeen {
+
+bool CopyProtection::show(XeenEngine *vm) {
+	CopyProtection *dlg = new CopyProtection(vm);
+	int result = dlg->execute();
+	delete dlg;
+
+	return result;
+}
+
+CopyProtection::CopyProtection(XeenEngine *vm) : Input(vm, &(*vm->_windows)[11]) {
+	loadEntries();
+}
+
+bool CopyProtection::execute() {
+	EventsManager &events = *_vm->_events;
+	Sound &sound = *_vm->_sound;
+	Window &w = *_window;
+	bool result = false;
+	Common::String line;
+
+	// Choose a random entry
+	ProtectionEntry &protEntry = _entries[_vm->getRandomNumber(_entries.size() - 1)];
+	Common::String msg = Common::String::format(Res.WHATS_THE_PASSWORD,
+		protEntry._pageNum, protEntry._lineNum, protEntry._wordNum);
+
+	w.open();
+	w.writeString(msg);
+	w.update();
+
+	for (int tryNum = 0; tryNum < 3 && !_vm->shouldExit(); ++tryNum) {
+		line.clear();
+		if (getString(line, 20, 200, false) && !line.compareToIgnoreCase(protEntry._text)) {
+			sound.playFX(20);
+			result = true;
+			break;
+		}
+
+		sound.playFX(21);
+		w.writeString("\x3l\v040\n\x4""200");
+		w.writeString(Res.PASSWORD_INCORRECT);
+		w.update();
+
+		events.updateGameCounter();
+		events.wait(50, false);
+	}
+
+	w.close();
+	return result;
+}
+
+void CopyProtection::loadEntries() {
+	FileManager &files = *g_vm->_files;
+	File f(files._ccNum ? "timer.drv" : "cpstruct");
+	ProtectionEntry pe;
+	byte seed = 0;
+	char text[13];
+
+	while (f.pos() < f.size()) {
+		pe._pageNum = f.readByte() ^ seed++;
+		pe._lineNum = f.readByte() ^ seed++;
+		pe._wordNum = f.readByte() ^ seed++;
+
+		for (int idx = 0; idx < 13; ++idx)
+			text[idx] = f.readByte() ^ seed++;
+		text[12] = '\0';
+		pe._text = Common::String(text);
+
+		_entries.push_back(pe);
+	}
+}
+
+} // End of namespace Xeen
diff --git a/engines/xeen/dialogs/dialogs_copy_protection.h b/engines/xeen/dialogs/dialogs_copy_protection.h
new file mode 100644
index 0000000000..97c8a6a53e
--- /dev/null
+++ b/engines/xeen/dialogs/dialogs_copy_protection.h
@@ -0,0 +1,64 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef XEEN_DIALOGS_COPY_PROTECTION_H
+#define XEEN_DIALOGS_COPY_PROTECTION_H
+
+#include "xeen/dialogs/dialogs_input.h"
+#include "common/array.h"
+
+namespace Xeen {
+
+class CopyProtection : public Input {
+	struct ProtectionEntry {
+		uint8 _pageNum;
+		uint8 _lineNum;
+		uint8 _wordNum;
+		Common::String _text;
+	};
+private:
+	Common::Array<ProtectionEntry> _entries;
+private:
+	/**
+	 * Constructor
+	 */
+	CopyProtection(XeenEngine *vm);
+
+	/**
+	 * Execute the dialog
+	 */
+	bool execute();
+
+	/**
+	 * Load the copy protection entries
+	 */
+	void loadEntries();
+public:
+	/**
+	 * Show the dialog
+	 */
+	static bool show(XeenEngine *vm);
+};
+
+} // End of namespace Xeen
+
+#endif /* XEEN_DIALOGS_COPY_PROTECTION_H */
diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk
index 0154b8533b..9f6075b5f6 100644
--- a/engines/xeen/module.mk
+++ b/engines/xeen/module.mk
@@ -14,6 +14,7 @@ MODULE_OBJS := \
 	dialogs/dialogs_awards.o \
 	dialogs/dialogs_char_info.o \
 	dialogs/dialogs_control_panel.o \
+	dialogs/dialogs_copy_protection.o \
 	dialogs/dialogs_create_char.o \
 	dialogs/dialogs_difficulty.o \
 	dialogs/dialogs_dismiss.o \
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 45e0989644..7c804b18f0 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -72,6 +72,7 @@ void Resources::loadData() {
 	file.syncString(WHO_WILL);
 	file.syncString(HOW_MUCH);
 	file.syncString(WHATS_THE_PASSWORD);
+	file.syncString(PASSWORD_INCORRECT);
 	file.syncString(IN_NO_CONDITION);
 	file.syncString(NOTHING_HERE);
 	file.syncStrings(TERRAIN_TYPES, 6);
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 08aa90e665..3e70987627 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -126,6 +126,7 @@ public:
 	const char *WHO_WILL;
 	const char *HOW_MUCH;
 	const char *WHATS_THE_PASSWORD;
+	const char *PASSWORD_INCORRECT;
 	const char *IN_NO_CONDITION;
 	const char *NOTHING_HERE;
 	const char *TERRAIN_TYPES[6];
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 3b989ab46a..2df48d5e84 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -22,6 +22,7 @@
 
 #include "common/config-manager.h"
 #include "xeen/scripts.h"
+#include "xeen/dialogs/dialogs_copy_protection.h"
 #include "xeen/dialogs/dialogs_input.h"
 #include "xeen/dialogs/dialogs_whowill.h"
 #include "xeen/dialogs/dialogs_query.h"
@@ -1841,8 +1842,8 @@ bool Scripts::copyProtectionCheck() {
 	if (!ConfMan.getBool("copy_protection"))
 		return true;
 
-	// Currently not implemented
-	return true;
+	// Show the copy protection dialog
+	return CopyProtection::show(_vm);
 }
 
 void Scripts::display(bool justifyFlag, int var46) {
-- 
cgit v1.2.3