[Scummvm-git-logs] scummvm master -> 6b4d3f70dd8f6b13dcf379c239363559e2a82278
dreammaster
dreammaster at scummvm.org
Fri Feb 23 21:24:23 CET 2018
This automated email contains information about 13 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
900ef91aca XEEN: Creation of create_xeen tool
ad7b947da3 XEEN: Change Resource String fields to const char *
5e0782c8da XEEN: Fix loading maps with no monsters
81b9f9b0fc XEEN: Add _filename field to SpriteResource
a8961fc145 XEEN: Fix saving maps with no objects and/or monsters
eca55e500c XEEN: Make mirror text entry matching case insensitive
2f6ca8f45e XEEN: Fix exiting ScummVM when 'Nothing here' dialog is active
bb19a6c771 XEEN: Add custom maze to the create_xeen tool
6614d8df17 XEEN: Remove un-needed initialization of monsters list in code
7dde659bf6 XEEN: Fix some incorrect string arrays in create_xeen
6b523a1d04 XEEN: Properly erase items dialog when exited
d132d66c28 XEEN: Add Clouds of Xeen MAE and Spells to xeen.ccs
6b4d3f70dd XEEN: Add data to create_xeen for Clouds of Xeen on it's own
Commit: 900ef91aca039dc23e4cf300070f7fa5f6f3a335
https://github.com/scummvm/scummvm/commit/900ef91aca039dc23e4cf300070f7fa5f6f3a335
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Creation of create_xeen tool
Changed paths:
A devtools/create_xeen/cc.cpp
A devtools/create_xeen/cc.h
A devtools/create_xeen/constants.cpp
A devtools/create_xeen/constants.h
A devtools/create_xeen/create_xeen.cpp
A devtools/create_xeen/file.h
A devtools/create_xeen/hash-str.h
A devtools/create_xeen/hashmap.cpp
A devtools/create_xeen/hashmap.h
A devtools/create_xeen/memorypool.cpp
A devtools/create_xeen/memorypool.h
A devtools/create_xeen/module.mk
A devtools/create_xeen/str.cpp
A devtools/create_xeen/str.h
Makefile.common
devtools/create_project/xcode.cpp
dists/scummvm.rc
dists/scummvm.rc.in
engines/xeen/character.cpp
engines/xeen/character.h
engines/xeen/dialogs_char_info.cpp
engines/xeen/dialogs_create_char.cpp
engines/xeen/dialogs_items.cpp
engines/xeen/dialogs_quests.cpp
engines/xeen/dialogs_spells.cpp
engines/xeen/files.cpp
engines/xeen/files.h
engines/xeen/locations.cpp
engines/xeen/map.cpp
engines/xeen/party.cpp
engines/xeen/resources.cpp
engines/xeen/resources.h
engines/xeen/scripts.cpp
engines/xeen/worldofxeen/darkside_cutscenes.cpp
engines/xeen/worldofxeen/darkside_cutscenes.h
engines/xeen/xeen.cpp
engines/xeen/xeen.h
diff --git a/Makefile.common b/Makefile.common
index 161f50f..b296446 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -308,6 +308,9 @@ endif
ifdef ENABLE_MACVENTURE
DIST_FILES_ENGINEDATA+=macventure.dat
endif
+ifdef ENABLE_XEEN
+DIST_FILES_ENGINEDATA+=xeen.ccs
+endif
DIST_FILES_ENGINEDATA:=$(addprefix $(srcdir)/dists/engine-data/,$(DIST_FILES_ENGINEDATA))
# pred.dic is currently only used for the AGI engine
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index fb4dc5e..fb459da 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -764,6 +764,7 @@ XcodeProvider::ValueList& XcodeProvider::getResourceFiles() const {
files.push_back("dists/engine-data/toon.dat");
files.push_back("dists/engine-data/wintermute.zip");
files.push_back("dists/engine-data/macventure.dat");
+ files.push_back("dists/engine-data/xeen.ccs");
files.push_back("dists/pred.dic");
files.push_back("icons/scummvm.icns");
}
diff --git a/devtools/create_xeen/cc.cpp b/devtools/create_xeen/cc.cpp
new file mode 100644
index 0000000..4020301
--- /dev/null
+++ b/devtools/create_xeen/cc.cpp
@@ -0,0 +1,116 @@
+/* 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.
+ *
+ */
+
+ // Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include "cc.h"
+#include "common/endian.h"
+
+uint16 CCArchive::convertNameToId(const Common::String &resourceName) {
+ if (resourceName.empty())
+ return 0xffff;
+
+ Common::String name = resourceName;
+ name.toUppercase();
+
+ // Check if a resource number is being directly specified
+ if (name.size() == 4) {
+ char *endPtr;
+ uint16 num = (uint16)strtol(name.c_str(), &endPtr, 16);
+ if (!*endPtr)
+ return num;
+ }
+
+ const byte *msgP = (const byte *)name.c_str();
+ int total = *msgP++;
+ for (; *msgP; total += *msgP++) {
+ // Rotate the bits in 'total' right 7 places
+ total = (total & 0x007F) << 9 | (total & 0xFF80) >> 7;
+ }
+
+ return total;
+}
+
+void CCArchive::saveIndex() {
+ // Fill up the data for the index entries into a raw data block
+ byte *rawIndex = new byte[_index.size() * 8];
+ byte b;
+
+ byte *entryP = rawIndex;
+ uint entryOffset = 8 * _index.size() + 2;
+ for (uint i = 0; i < _index.size(); ++i, entryP += 8) {
+ CCEntry &entry = _index[i];
+ entry._offset = entryOffset;
+ entryOffset += entry._size;
+
+ WRITE_LE_UINT16(&entryP[0], entry._id);
+ WRITE_LE_UINT32(&entryP[2], entry._offset);
+ WRITE_LE_UINT16(&entryP[5], entry._size);
+ entryP[7] = 0;
+ }
+
+ // Encrypt the index
+ int seed = 0xac;
+ for (uint i = 0; i < _index.size() * 8; ++i, seed += 0x67) {
+ b = (rawIndex[i] - seed) & 0xff;
+ b = (byte)((b >> 2) | (b << 6));
+
+ assert(rawIndex[i] == (byte)((((b << 2) | (b >> 6)) + seed) & 0xff));
+ rawIndex[i] = b;
+ }
+
+ // Write out the number of entries and the encrypted index data
+ _file.writeWord(_index.size());
+ _file.write(rawIndex, _index.size() * 8);
+
+ delete[] rawIndex;
+}
+
+void CCArchive::saveEntries() {
+ for (uint idx = 0; idx < _index.size(); ++idx) {
+ CCEntry &ccEntry = _index[idx];
+
+ // Encrypt the entry
+ for (int i = 0; i < ccEntry._size; ++i)
+ ccEntry._data[i] ^= 0x35;
+
+ // Write out the entry
+ _file.seek(ccEntry._offset);
+ _file.write(ccEntry._data, ccEntry._size);
+ }
+}
+
+void CCArchive::close() {
+ saveIndex();
+ saveEntries();
+}
+
+void CCArchive::add(const Common::String &name, Common::MemFile &f) {
+ _index.push_back(CCEntry(convertNameToId(name), f.getData(), f.size()));
+}
diff --git a/devtools/create_xeen/cc.h b/devtools/create_xeen/cc.h
new file mode 100644
index 0000000..192a7d5
--- /dev/null
+++ b/devtools/create_xeen/cc.h
@@ -0,0 +1,84 @@
+/* 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 CC_H
+#define CC_H
+
+#include "file.h"
+#include "str.h"
+#include "common/array.h"
+
+/**
+ * Details of a single entry in a CC file index
+ */
+struct CCEntry {
+ uint16 _id;
+ int _offset;
+ uint16 _size;
+ byte _data[MAX_MEM_SIZE];
+
+ CCEntry() : _id(0), _offset(0), _size(0) {
+ memset(_data, 0, MAX_MEM_SIZE);
+ }
+ CCEntry(uint16 id, const byte *data, uint32 size) :
+ _id(id), _offset(0), _size(size) {
+ memcpy(_data, data, size);
+ }
+};
+
+class CCArchive {
+private:
+ Common::Array<CCEntry> _index;
+ Common::File &_file;
+private:
+ /**
+ * Convert a resource name to it's equivalent hash key
+ */
+ uint16 convertNameToId(const Common::String &resourceName);
+
+ /**
+ * Saves the index to the file
+ */
+ void saveIndex();
+
+ /**
+ * Saves the individual entries to the file
+ */
+ void saveEntries();
+public:
+ /**
+ * Constructor
+ */
+ CCArchive(Common::File &file) : _file(file) {}
+
+ /**
+ * Finishes the CC file, writing out the resulting content
+ */
+ void close();
+
+ /**
+ * Adds an entry to the CC
+ */
+ void add(const Common::String &name, Common::MemFile &f);
+};
+
+#endif
diff --git a/devtools/create_xeen/constants.cpp b/devtools/create_xeen/constants.cpp
new file mode 100644
index 0000000..a744558
--- /dev/null
+++ b/devtools/create_xeen/constants.cpp
@@ -0,0 +1,2098 @@
+/* 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.
+ *
+ */
+
+ // Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include "file.h"
+#include "constants.h"
+
+enum MagicSpell {
+ MS_AcidSpray = 0, MS_Awaken = 1, MS_BeastMaster = 2, MS_Bless = 3,
+ MS_Clairvoyance = 4, MS_ColdRay = 5, MS_CreateFood = 6,
+ MS_CureDisease = 7, MS_CureParalysis = 8, MS_CurePoison = 9,
+ MS_CureWounds = 10, MS_DancingSword = 11, MS_DayOfProtection = 12,
+ MS_DayOfSorcery = 13, MS_DeadlySwarm = 14, MS_DetectMonster = 15,
+ MS_DivineIntervention = 16, MS_DragonSleep = 17, MS_ElementalStorm = 18,
+ MS_EnchantItem = 19, MS_EnergyBlast = 20, MS_Etheralize = 21,
+ MS_FantasticFreeze = 22, MS_FieryFlail = 23, MS_FingerOfDeath = 24,
+ MS_Fireball = 25, MS_FirstAid = 26, MS_FlyingFist = 27,
+ MS_FrostBite = 28, MS_GolemStopper = 29, MS_Heroism = 30,
+ MS_HolyBonus = 31, MS_HolyWord = 32, MS_Hynotize = 33,
+ MS_IdentifyMonster = 34, MS_Implosion = 35, MS_Incinerate = 36,
+ MS_Inferno = 37, MS_InsectSpray = 38, MS_ItemToGold = 39,
+ MS_Jump = 40, MS_Levitate = 41, MS_Light = 42, MS_LightningBolt = 43,
+ MS_LloydsBeacon = 44, MS_MagicArrow = 45, MS_MassDistortion = 46,
+ MS_MegaVolts = 47, MS_MoonRay = 48, MS_NaturesCure = 49, MS_Pain = 50,
+ MS_PoisonVolley = 51, MS_PowerCure = 52, MS_PowerShield = 53,
+ MS_PrismaticLight = 54, MS_ProtFromElements = 55, MS_RaiseDead = 56,
+ MS_RechargeItem = 57, MS_Resurrection = 58, MS_Revitalize = 59,
+ MS_Shrapmetal = 60, MS_Sleep = 61, MS_Sparks = 62, MS_StarBurst = 63,
+ MS_StoneToFlesh = 64, MS_SunRay = 65, MS_SuperShelter = 66,
+ MS_SuppressDisease = 67, MS_SuppressPoison = 68, MS_Teleport = 69,
+ MS_TimeDistortion = 70, MS_TownPortal = 71, MS_ToxicCloud = 72,
+ MS_TurnUndead = 73, MS_WalkOnWater = 74, MS_WizardEye = 75,
+ NO_SPELL = 76
+};
+
+const char *const CREDITS =
+ "\013""012\010""000\003""c\014""35Designed and Directed By:\n"
+ "\014""17Jon Van Caneghem\003""l\n"
+ "\n"
+ "\t025\014""35Programming:\n"
+ "\t035\014""17Mark Caldwell\n"
+ "\t035Dave Hathaway\n"
+ "\n"
+ "\t025\014""35Sound System & FX:\n"
+ "\t035\014""17Mike Heilemann\n"
+ "\n"
+ "\t025\014""35Music & Speech:\n"
+ "\t035\014""17Tim Tully\n"
+ "\n"
+ "\t025\014""35Writing:\n"
+ "\t035\014""17Paul Rattner\n"
+ "\t035Debbie Van Caneghem\n"
+ "\t035Jon Van Caneghem\013""012\n"
+ "\n"
+ "\n"
+ "\t180\014""35Graphics:\n"
+ "\t190\014""17Jonathan P. Gwyn\n"
+ "\t190Bonita Long-Hemsath\n"
+ "\t190Julia Ulano\n"
+ "\t190Ricardo Barrera\n"
+ "\n"
+ "\t180\014""35Testing:\n"
+ "\t190\014""17Benjamin Bent\n"
+ "\t190Christian Dailey\n"
+ "\t190Mario Escamilla\n"
+ "\t190Marco Hunter\n"
+ "\t190Robert J. Lupo\n"
+ "\t190Clayton Retzer\n"
+ "\t190David Vela\003""c";
+
+const char *const OPTIONS_TITLE =
+ "\x0D\x01\003""c\014""dMight and Magic Options\n"
+ "World of Xeen\x02\n"
+ "\v117Copyright (c) 1993 NWC, Inc.\n"
+ "All Rights Reserved\x01";
+
+const char *const THE_PARTY_NEEDS_REST = "\x0B""012The Party needs rest!";
+
+const char *const WHO_WILL = "\x03""c\x0B""000\x09""000%s\x0A\x0A"
+ "Who will\x0A%s?\x0A\x0B""055F1 - F%d";
+
+const char *const HOW_MUCH = "\x3""cHow Much\n\n";
+
+const char *const WHATS_THE_PASSWORD = "What's the Password?";
+
+const char *const IN_NO_CONDITION = "\x0B""007%s is not in any condition to perform actions!";
+
+const char *const NOTHING_HERE = "\x03""c\x0B""010Nothing here.";
+
+const char *const TERRAIN_TYPES[6] = {
+ "town", "cave", "towr", "cstl", "dung", "scfi"
+};
+
+const char *const OUTDOORS_WALL_TYPES[16] = {
+ nullptr, "mount", "ltree", "dtree", "grass", "snotree", "dsnotree",
+ "snomnt", "dedltree", "mount", "lavamnt", "palm", "dmount", "dedltree",
+ "dedltree", "dedltree"
+};
+
+const char *const SURFACE_NAMES[16] = {
+ "water.srf", "dirt.srf", "grass.srf", "snow.srf", "swamp.srf",
+ "lava.srf", "desert.srf", "road.srf", "dwater.srf", "tflr.srf",
+ "sky.srf", "croad.srf", "sewer.srf", "cloud.srf", "scortch.srf",
+ "space.srf"
+};
+
+const char *const WHO_ACTIONS[32] = {
+ "search", "open", "drink", "mine", "touch", "read", "learn", "take",
+ "bang", "steal", "bribe", "pay", "sit", "try", "turn", "bathe",
+ "destroy", "pull", "descend", "toss a coin", "pray", "join", "act",
+ "play", "push", "rub", "pick", "eat", "sign", "close", "look", "try"
+};
+
+const char *const WHO_WILL_ACTIONS[4] = {
+ "Open Grate", "Open Door", "Open Scroll", "Select Char"
+};
+
+const byte SYMBOLS[20][64] = {
+ { // 0
+ 0x00, 0x00, 0xA8, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x00, 0xA8, 0x9E, 0x9C, 0x9C, 0x9E, 0x9E, 0x9E,
+ 0xAC, 0x9C, 0xA4, 0xAC, 0xAC, 0x9A, 0x9A, 0x9A, 0xAC, 0x9E, 0xAC, 0xA8, 0xA8, 0xA6, 0x97, 0x98,
+ 0xAC, 0xA0, 0xAC, 0xAC, 0xA4, 0xA6, 0x98, 0x99, 0x00, 0xAC, 0xA0, 0xA0, 0xA8, 0xAC, 0x9A, 0x9A,
+ 0x00, 0x00, 0xAC, 0xAC, 0xAC, 0xA4, 0x9B, 0x9A, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xA0, 0x9B, 0x9B,
+ },
+ { // 1
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
+ 0x99, 0x9A, 0x9A, 0x99, 0x99, 0x99, 0x9A, 0x99, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97,
+ 0x99, 0x98, 0x98, 0x99, 0x98, 0x98, 0x99, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
+ 0x9A, 0x9B, 0x9B, 0x9C, 0x9B, 0x9A, 0x9C, 0x9A, 0x9B, 0x9A, 0x99, 0x99, 0x99, 0x9A, 0x9A, 0x9B,
+ },
+ { // 2
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
+ 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x99, 0x98, 0x98, 0x99, 0x98, 0x98, 0x97, 0x98, 0x98,
+ 0x99, 0x98, 0x98, 0x98, 0x99, 0x99, 0x98, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
+ 0x9B, 0x9B, 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0x9B, 0x99, 0x9A, 0x9B, 0x9B, 0x9A, 0x9A, 0x99, 0x9A,
+ },
+ { // 3
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
+ 0x99, 0x9A, 0x9A, 0x9A, 0x99, 0x99, 0x99, 0x9A, 0x98, 0x98, 0x97, 0x97, 0x98, 0x98, 0x98, 0x98,
+ 0x99, 0x99, 0x98, 0x99, 0x98, 0x98, 0x99, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
+ 0x9B, 0x9C, 0x9B, 0x9B, 0x9C, 0x9C, 0x9C, 0x9C, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x99, 0x99, 0x9A,
+ },
+ { // 4
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
+ 0x9A, 0x9A, 0x9A, 0x99, 0x99, 0x99, 0x99, 0x9A, 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
+ 0x99, 0x99, 0x98, 0x99, 0x99, 0x98, 0x98, 0x98, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
+ 0x9A, 0x9C, 0x9B, 0x9B, 0x9C, 0x9B, 0x9B, 0x9B, 0x9A, 0x99, 0x9B, 0x9B, 0x9A, 0x99, 0x9A, 0x9A,
+ },
+ { // 5
+ 0xA4, 0xA4, 0xA8, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x9E, 0x9E, 0xA0, 0xA8, 0xAC, 0x00, 0x00,
+ 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9E, 0xAC, 0x00, 0x97, 0x97, 0x97, 0x98, 0x9C, 0x9C, 0xA0, 0xAC,
+ 0x99, 0x98, 0x99, 0x99, 0x99, 0x9B, 0xA0, 0xAC, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9B, 0xA0, 0xAC,
+ 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x9A, 0x9A, 0x9B, 0x9B, 0xA4, 0xAC, 0x00,
+ },
+ { // 6
+ 0x00, 0x00, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x00, 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x9B, 0x99,
+ 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x98, 0x99, 0x99,
+ 0x00, 0xAC, 0xA0, 0x9C, 0x9C, 0xA0, 0x9C, 0x9A, 0x00, 0x00, 0xAC, 0xA4, 0xA0, 0x99, 0x99, 0x99,
+ 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99,
+ },
+ { // 7
+ 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
+ 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0xAC, 0xA4, 0x9C, 0x9C, 0x99, 0x99,
+ 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99,
+ 0x00, 0x00, 0xAC, 0xA0, 0x9B, 0xA0, 0x9E, 0x9C, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x9C, 0x99, 0x99,
+ },
+ { // 8
+ 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x9B, 0x99, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
+ 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
+ 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
+ 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x9C, 0x99, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x9E, 0x9C, 0x99,
+ },
+ { // 9
+ 0x00, 0x00, 0xAC, 0xA4, 0xA0, 0x9C, 0x99, 0x99, 0x00, 0xAC, 0xA0, 0x9C, 0x9C, 0xA0, 0x9C, 0x9A,
+ 0xAC, 0xA4, 0x9C, 0x9A, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
+ 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99,
+ 0x00, 0xAC, 0xA4, 0x9C, 0x9A, 0x9C, 0x99, 0x99, 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x9A, 0x99, 0x99,
+ },
+ { // 10
+ 0x99, 0x99, 0x99, 0x9A, 0xA0, 0xAC, 0x00, 0x00, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x00,
+ 0x99, 0x99, 0x9C, 0x9E, 0xA4, 0xAC, 0x00, 0x00, 0x99, 0x99, 0x9C, 0x99, 0x9C, 0xA4, 0xAC, 0x00,
+ 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x00,
+ 0x99, 0x99, 0x99, 0xA0, 0xA4, 0xAC, 0x00, 0x00, 0x9A, 0x9B, 0x9E, 0x9C, 0x9C, 0xA4, 0xAC, 0x00,
+ },
+ { // 11
+ 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0x9E, 0xAC,
+ 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00,
+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
+ 0x9C, 0x99, 0x99, 0x99, 0x9C, 0x9C, 0xA4, 0xAC, 0x99, 0x9E, 0x9E, 0x9C, 0x9C, 0xA0, 0xAC, 0x00,
+ },
+ { // 12
+ 0x99, 0x99, 0x9C, 0xA0, 0xA4, 0xAC, 0x00, 0x00, 0x9B, 0x9C, 0x9E, 0x9C, 0x9C, 0xA4, 0xAC, 0x00,
+ 0x99, 0x99, 0x99, 0x99, 0x99, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
+ 0x99, 0x99, 0x99, 0x99, 0x9C, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xA4, 0xAC, 0x00,
+ 0x99, 0x99, 0x9C, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
+ },
+ { // 13
+ 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x00,
+ 0x99, 0x9B, 0x9C, 0xA0, 0xA4, 0xAC, 0x00, 0x00, 0x99, 0x99, 0x9A, 0x99, 0x9C, 0xA0, 0xAC, 0x00,
+ 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
+ 0x99, 0x99, 0x99, 0x99, 0x9A, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x9A, 0x9C, 0xA4, 0xAC, 0x00,
+ },
+ { // 14
+ 0x00, 0x00, 0xAC, 0x9E, 0x9C, 0x9C, 0x9C, 0x9B, 0x00, 0xAC, 0x9C, 0xA0, 0x9E, 0xA4, 0xA4, 0xA4,
+ 0xAC, 0x9C, 0xA4, 0xAC, 0xAC, 0xAC, 0x9C, 0x9E, 0xAC, 0xA0, 0xAC, 0xA8, 0x9E, 0xA8, 0xAC, 0x99,
+ 0xAC, 0x9E, 0xAC, 0xA8, 0xAC, 0x9E, 0xA4, 0xAC, 0xAC, 0xA4, 0xA0, 0xAC, 0xAC, 0xA0, 0xA4, 0xAC,
+ 0x00, 0xAC, 0xA4, 0xA0, 0xA0, 0xA4, 0xAC, 0xA4, 0x00, 0x00, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
+ },
+ { // 15
+ 0x9C, 0x9C, 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0x9B, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
+ 0x9E, 0x9E, 0x9E, 0x9C, 0x9E, 0x9E, 0x9E, 0x9E, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x99, 0x98,
+ 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0x9C, 0x9C, 0x9C, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0x9E, 0x9E, 0xA0,
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
+ },
+ { // 16
+ 0x9B, 0x9B, 0x9B, 0x9B, 0x9C, 0x9B, 0x9C, 0x9C, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
+ 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9E, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99,
+ 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0xA0, 0xA0, 0xA0, 0x9E, 0xA0, 0x9E, 0x9E, 0xA0,
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
+ },
+ { // 17
+ 0x9C, 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0x9C, 0x9B, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
+ 0x9E, 0x9E, 0x9E, 0x9C, 0x9C, 0x9C, 0x9E, 0x9E, 0x98, 0x98, 0x98, 0x99, 0x9A, 0x9A, 0x99, 0x98,
+ 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0x9B, 0x9B, 0x9C, 0xA0, 0x9E, 0x9E, 0xA0, 0xA0, 0xA0, 0xA0, 0x9E,
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
+ },
+ { // 18
+ 0x9B, 0x9B, 0x9C, 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
+ 0x9E, 0x9E, 0x9E, 0x9E, 0x9C, 0x9C, 0x9C, 0x9E, 0x98, 0x98, 0x98, 0x98, 0x9A, 0x9A, 0x98, 0x99,
+ 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9B, 0x9C, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0xA0, 0xA0, 0xA0,
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
+ },
+ { // 19
+ 0x9C, 0x9B, 0x9C, 0x9C, 0xA0, 0xA4, 0xAC, 0x00, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0x00, 0x00,
+ 0x9E, 0x9E, 0x9C, 0x9C, 0x9E, 0xA0, 0xAC, 0x00, 0x99, 0x98, 0x98, 0x99, 0x9A, 0x9A, 0xA0, 0xAC,
+ 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0xA0, 0xAC, 0xA0, 0xA0, 0x9E, 0xA0, 0xA0, 0xA0, 0xA0, 0xAC,
+ 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0x00, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0x00, 0x00,
+ }
+};
+
+const byte TEXT_COLORS[40][4] = {
+ { 0x00, 0x19, 0x19, 0x19 },
+ { 0x00, 0x08, 0x08, 0x08 },
+ { 0x00, 0x0F, 0x0F, 0x0F },
+ { 0x00, 0x15, 0x15, 0x15 },
+ { 0x00, 0x01, 0x01, 0x01 },
+ { 0x00, 0x21, 0x21, 0x21 },
+ { 0x00, 0x26, 0x26, 0x26 },
+ { 0x00, 0x2B, 0x2B, 0x2B },
+ { 0x00, 0x31, 0x31, 0x31 },
+ { 0x00, 0x36, 0x36, 0x36 },
+ { 0x00, 0x3D, 0x3D, 0x3D },
+ { 0x00, 0x41, 0x41, 0x41 },
+ { 0x00, 0x46, 0x46, 0x46 },
+ { 0x00, 0x4C, 0x4C, 0x4C },
+ { 0x00, 0x50, 0x50, 0x50 },
+ { 0x00, 0x55, 0x55, 0x55 },
+ { 0x00, 0x5D, 0x5D, 0x5D },
+ { 0x00, 0x60, 0x60, 0x60 },
+ { 0x00, 0x65, 0x65, 0x65 },
+ { 0x00, 0x6C, 0x6C, 0x6C },
+ { 0x00, 0x70, 0x70, 0x70 },
+ { 0x00, 0x75, 0x75, 0x75 },
+ { 0x00, 0x7B, 0x7B, 0x7B },
+ { 0x00, 0x80, 0x80, 0x80 },
+ { 0x00, 0x85, 0x85, 0x85 },
+ { 0x00, 0x8D, 0x8D, 0x8D },
+ { 0x00, 0x90, 0x90, 0x90 },
+ { 0x00, 0x97, 0x97, 0x97 },
+ { 0x00, 0x9D, 0x9D, 0x9D },
+ { 0x00, 0xA4, 0xA4, 0xA4 },
+ { 0x00, 0xAB, 0xAB, 0xAB },
+ { 0x00, 0xB0, 0xB0, 0xB0 },
+ { 0x00, 0xB6, 0xB6, 0xB6 },
+ { 0x00, 0xBD, 0xBD, 0xBD },
+ { 0x00, 0xC0, 0xC0, 0xC0 },
+ { 0x00, 0xC6, 0xC6, 0xC6 },
+ { 0x00, 0xCD, 0xCD, 0xCD },
+ { 0x00, 0xD0, 0xD0, 0xD0 },
+ { 0x00, 0xD6, 0xD6, 0xD6 },
+ { 0x00, 0xDB, 0xDB, 0xDB },
+};
+
+const char *const DIRECTION_TEXT_UPPER[4] = { "NORTH", "EAST", "SOUTH", "WEST" };
+
+const char *const DIRECTION_TEXT[4] = { "North", "East", "South", "West" };
+
+const char *const RACE_NAMES[5] = { "Human", "Elf", "Dwarf", "Gnome", "H-Orc" };
+
+const int RACE_HP_BONUSES[5] = { 0, -2, 1, -1, 2 };
+
+const int RACE_SP_BONUSES[5][2] = {
+ { 0, 0 }, { 2, 0 }, { -1, -1 }, { 1, 1 }, { -2, -2 }
+};
+
+const char *const ALIGNMENT_NAMES[3] = { "Good", "Neutral", "Evil" };
+
+const char *const SEX_NAMES[2] = { "Male", "Female" };
+
+const char *const SKILL_NAMES[18] = {
+ "Thievery\t100", "Arms Master", "Astrologer", "Body Builder", "Cartographer",
+ "Crusader", "Direction Sense", "Linguist", "Merchant", "Mountaineer",
+ "Navigator", "Path Finder", "Prayer Master", "Prestidigitator",
+ "Swimmer", "Tracker", "Spot Secret Door", "Danger Sense"
+};
+
+const char *const CLASS_NAMES[11] = {
+ "Knight", "Paladin", "Archer", "Cleric", "Sorcerer", "Robber",
+ "Ninja", "Barbarian", "Druid", "Ranger", nullptr
+};
+
+const int CLASS_EXP_LEVELS[10] = {
+ 1500, 2000, 2000, 1500, 2000, 1000, 1500, 1500, 1500, 2000
+};
+
+const char *const CONDITION_NAMES[17] = {
+ "Cursed", "Heart Broken", "Weak", "Poisoned", "Diseased",
+ "Insane", "In Love", "Drunk", "Asleep", "Depressed", "Confused",
+ "Paralyzed", "Unconscious", "Dead", "Stone", "Eradicated", "Good"
+};
+
+const int CONDITION_COLORS[17] = {
+ 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32, 32, 6, 6, 6, 6, 15
+};
+
+const char *const GOOD = "Good";
+
+const char *const BLESSED = "\n\t020Blessed\t095%+d";
+
+const char *const POWER_SHIELD = "\n\t020Power Shield\t095%+d";
+
+const char *const HOLY_BONUS = "\n\t020Holy Bonus\t095%+d";
+
+const char *const HEROISM = "\n\t020Heroism\t095%+d";
+
+const char *const IN_PARTY = "\014""15In Party\014""d";
+
+const char *const PARTY_DETAILS = "\015\003l\002\014""00"
+ "\013""001""\011""035%s"
+ "\013""009""\011""035%s"
+ "\013""017""\011""035%s"
+ "\013""025""\011""035%s"
+ "\013""001""\011""136%s"
+ "\013""009""\011""136%s"
+ "\013""017""\011""136%s"
+ "\013""025""\011""136%s"
+ "\013""044""\011""035%s"
+ "\013""052""\011""035%s"
+ "\013""060""\011""035%s"
+ "\013""068""\011""035%s"
+ "\013""044""\011""136%s"
+ "\013""052""\011""136%s"
+ "\013""060""\011""136%s"
+ "\013""068""\011""136%s";
+const char *const PARTY_DIALOG_TEXT =
+ "%s\x2\x3""c\v106\t013Up\t048Down\t083\f37D\fdel\t118\f37R\fdem"
+ "\t153\f37C\fdreate\t188E\f37x\fdit\x1";
+
+const int FACE_CONDITION_FRAMES[17] = {
+ 2, 2, 2, 1, 1, 4, 4, 4, 3, 2, 4, 3, 3, 5, 6, 7, 0
+};
+
+const int CHAR_FACES_X[6] = { 10, 45, 81, 117, 153, 189 };
+
+const int HP_BARS_X[6] = { 13, 50, 86, 122, 158, 194 };
+
+const char *const NO_ONE_TO_ADVENTURE_WITH = "You have no one to adventure with";
+
+const char *const YOUR_ROSTER_IS_FULL = "Your Roster is full!";
+
+const byte DARKNESS_XLAT[3][256] = {
+ {
+ 0, 25, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 44, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 60, 61, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 108, 109, 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 124, 125, 126, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 140, 141, 142, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 168, 169, 170, 171, 172, 173, 174, 175, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 188, 189, 190, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 204, 205, 206, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 220, 221, 222, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 236, 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 252, 253, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, {
+ 0, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0,
+ 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0,
+ 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0,
+ 104, 105, 106, 107, 108, 109, 110, 111, 0, 0, 0, 0, 0, 0, 0, 0,
+ 120, 121, 122, 123, 124, 125, 126, 127, 0, 0, 0, 0, 0, 0, 0, 0,
+ 136, 137, 138, 139, 140, 141, 142, 143, 0, 0, 0, 0, 0, 0, 0, 0,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 184, 185, 186, 187, 188, 189, 190, 191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 200, 201, 202, 203, 204, 205, 206, 207, 0, 0, 0, 0, 0, 0, 0, 0,
+ 216, 217, 218, 219, 220, 221, 222, 223, 0, 0, 0, 0, 0, 0, 0, 0,
+ 232, 233, 234, 235, 236, 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, 0,
+ 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0
+ }, {
+ 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0,
+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0,
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 0, 0, 0, 0,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 0, 0, 0, 0,
+ 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 0, 0, 0, 0,
+ 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175, 0, 0, 0, 0, 0, 0, 0, 0,
+ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 0, 0, 0, 0,
+ 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, 0, 0, 0,
+ 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 0, 0, 0, 0,
+ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 0, 0, 0, 0,
+ 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, 0, 0
+ }
+};
+
+const char *const PLEASE_WAIT = "\014""d\003""c\011""000"
+ "\013""002Please Wait...";
+
+const char *const OOPS = "\003""c\011""000\013""002Oops...";
+
+const int SCREEN_POSITIONING_X[4][48] = {
+ {
+ -1, 0, 0, 0, 1, -1, 0, 0, 0, 1, -2, -1,
+ -1, 0, 0, 0, 1, 1, 2, -4, -3, -3, -2, -2,
+ -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4,
+ -3, -2, -1, 0, 0, 1, 2, 3, -4, 4, 0, 0
+ }, {
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 1
+ }, {
+ 1, 0, 0, 0, -1, 1, 0, 0, 0, -1, 2, 1,
+ 1, 0, 0, 0, -1, -1, -2, 4, 3, 3, 2, 2,
+ 1, 1, 0, 0, 0, -1, -1, -2, -2, -3, -3, -4,
+ 3, 2, 1, 0, 0, -1, -2, -3, 4, -4, 0, 0
+ }, {
+ 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3,
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
+ -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 0, -1
+ }
+};
+
+const int SCREEN_POSITIONING_Y[4][48] = {
+ {
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 1
+ }, {
+ 1, 0, 0, 0, -1, 1, 0, 0, 0, -1, 2, 1,
+ 1, 0, 0, 0, -1, -1, -2, 4, 3, 3, 2, 2,
+ 1, 1, 0, 0, 0, -1, -1, -2, -2, -3, -3, -4,
+ 3, 2, 1, 0, 0, -1, -2, -3, 4, -4, 0, 0
+ }, {
+ 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3,
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
+ -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 0, -1
+ }, {
+ -1, 0, 0, 0, 1, -1, 0, 0, 0, 1, -2, -1,
+ -1, 0, 0, 0, 1, 1, 2, -4, -3, -3, -2, -2,
+ -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4,
+ -3, -2, -1, 0, 0, 1, 2, 3, -4, 4, 0, 0
+ }
+};
+
+const int MONSTER_GRID_BITMASK[12] = {
+ 0xC, 8, 4, 0, 0xF, 0xF000, 0xF00, 0xF0, 0xF00, 0xF0, 0x0F, 0xF000
+};
+
+const int INDOOR_OBJECT_X[2][12] = {
+ { 5, -7, -112, 98, -8, -65, 49, -9, -34, 16, -58, 40 },
+ { -35, -35, -142, 68, -35, -95, 19, -35, -62, -14, -98, 16 }
+};
+
+const int MAP_OBJECT_Y[2][12] = {
+ { 2, 25, 25, 25, 50, 50, 50, 58, 58, 58, 58, 58 },
+ { -65, -6, -6, -6, 36, 36, 36, 54, 54, 54, 54, 54 }
+};
+
+const int INDOOR_MONSTERS_Y[4] = { 2, 34, 53, 59 };
+
+const int OUTDOOR_OBJECT_X[2][12] = {
+ { -5, -7, -112, 98, -8, -77, 61, -9, -43, 25, -74, 56 },
+ { -35, -35, -142, 68, -35, -95, 19, -35, -62, -24, -98, 16 }
+};
+
+const int OUTDOOR_MONSTER_INDEXES[26] = {
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 69, 70,
+ 71, 72, 73, 74, 75, 90, 91, 92, 93, 94, 112, 115, 118
+};
+
+const int OUTDOOR_MONSTERS_Y[26] = {
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 53, 53,
+ 53, 53, 53, 53, 53, 34, 34, 34, 34, 34, 2, 2, 2
+};
+
+const int DIRECTION_ANIM_POSITIONS[4][4] = {
+ { 0, 1, 2, 3 }, { 3, 0, 1, 2 }, { 2, 3, 0, 1 }, { 1, 2, 3, 0 }
+};
+
+const byte WALL_SHIFTS[4][48] = {
+ {
+ 12, 0, 12, 8, 12, 12, 0, 12, 8, 12, 12, 0,
+ 12, 0, 12, 8, 12, 8, 12, 12, 0, 12, 0, 12,
+ 0, 12, 0, 12, 8, 12, 8, 12, 8, 12, 8, 12,
+ 0, 0, 0, 0, 8, 8, 8, 8, 0, 0, 4, 4
+ }, {
+ 8, 12, 8, 4, 8, 8, 12, 8, 4, 8, 8, 12,
+ 8, 12, 8, 4, 8, 4, 8, 8, 12, 8, 12, 8,
+ 12, 8, 12, 8, 4, 8, 4, 8, 4, 8, 4, 8,
+ 12, 12, 12, 12, 4, 4, 4, 4, 0, 0, 0, 0
+ }, {
+ 4, 8, 4, 0, 4, 4, 8, 4, 0, 4, 4, 8,
+ 4, 8, 4, 0, 4, 0, 4, 4, 8, 4, 8, 4,
+ 8, 4, 8, 4, 0, 4, 0, 4, 0, 4, 0, 4,
+ 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 12, 12
+ }, {
+ 0, 4, 0, 12, 0, 0, 4, 0, 12, 0, 0, 4,
+ 0, 4, 0, 12, 0, 12, 0, 0, 4, 0, 4, 0,
+ 4, 0, 4, 0, 12, 0, 12, 0, 12, 0, 12, 0,
+ 4, 4, 4, 4, 12, 12, 12, 12, 0, 0, 8, 8
+ }
+};
+
+const int DRAW_NUMBERS[25] = {
+ 36, 37, 38, 43, 42, 41,
+ 39, 20, 22, 24, 33, 31,
+ 29, 26, 10, 11, 18, 16,
+ 13, 5, 9, 6, 0, 4, 1
+};
+
+const int DRAW_FRAMES[25][2] = {
+ { 18, 24 }, { 19, 23 }, { 20, 22 }, { 24, 18 }, { 23, 19 }, { 22, 20 },
+ { 21, 21 }, { 11, 17 }, { 12, 16 }, { 13, 15 }, { 17, 11 }, { 16, 12 },
+ { 15, 13 }, { 14, 14 }, { 6, 10 }, { 7, 9 }, { 10, 6 }, { 9, 7 },
+ { 8, 8 }, { 3, 5 }, { 5, 3 }, { 4, 4 }, { 0, 2 }, { 2, 0 },
+ { 1, 1 }
+};
+
+const int COMBAT_FLOAT_X[8] = { -2, -1, 0, 1, 2, 1, 0, -1 };
+
+const int COMBAT_FLOAT_Y[8] = { -2, 0, 2, 0, -1, 0, 2, 0 };
+
+const int MONSTER_EFFECT_FLAGS[15][8] = {
+ { 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10A, 0x10B },
+ { 0x10C, 0x10D, 0x10E, 0x10F, 0x0, 0x0, 0x0, 0x0 },
+ { 0x110, 0x111, 0x112, 0x113, 0x0, 0x0, 0x0, 0x0 },
+ { 0x114, 0x115, 0x116, 0x117, 0x0, 0x0, 0x0, 0x0 },
+ { 0x200, 0x201, 0x202, 0x203, 0x0, 0x0, 0x0, 0x0 },
+ { 0x300, 0x301, 0x302, 0x303, 0x400, 0x401, 0x402, 0x403 },
+ { 0x500, 0x501, 0x502, 0x503, 0x0, 0x0, 0x0, 0x0 },
+ { 0x600, 0x601, 0x602, 0x603, 0x0, 0x0, 0x0, 0x0 },
+ { 0x604, 0x605, 0x606, 0x607, 0x608, 0x609, 0x60A, 0x60B },
+ { 0x60C, 0x60D, 0x60E, 0x60F, 0x0, 0x0, 0x0, 0x0 },
+ { 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100 },
+ { 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101 },
+ { 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102 },
+ { 0x103, 0x103, 0x103, 0x103, 0x103, 0x103, 0x103, 0x103 },
+ { 0x108, 0x108, 0x108, 0x108, 0x108, 0x108, 0x108, 0x108 }
+};
+
+const int SPELLS_ALLOWED[3][40] = {
+ {
+ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10,
+ 12, 14, 16, 23, 26, 27, 28, 30, 31, 32,
+ 33, 42, 46, 48, 49, 50, 52, 55, 56, 58,
+ 59, 62, 64, 65, 67, 68, 71, 73, 74, 76
+ }, {
+ 1, 4, 11, 13, 15, 17, 18, 19, 20, 21,
+ 22, 24, 25, 29, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 47, 51, 53, 54,
+ 57, 60, 61, 63, 66, 69, 70, 72, 75, 76
+ }, {
+ 0, 1, 2, 3, 4, 5, 7, 9, 10, 20,
+ 25, 26, 27, 28, 30, 31, 34, 38, 40, 41,
+ 42, 43, 44, 45, 49, 50, 52, 53, 55, 59,
+ 60, 61, 62, 67, 68, 72, 73, 74, 75, 76
+ }
+};
+
+const int BASE_HP_BY_CLASS[10] = { 10, 8, 7, 5, 4, 8, 7, 12, 6, 9 };
+
+const int AGE_RANGES[10] = { 1, 6, 11, 18, 36, 51, 76, 101, 201, 0xffff };
+
+const int AGE_RANGES_ADJUST[2][10] = {
+ { -250, -50, -20, -10, 0, -2, -5, -10, -20, -50 },
+ { -250, -50, -20, -10, 0, 2, 5, 10, 20, 50 }
+};
+
+const int STAT_VALUES[24] = {
+ 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 25, 30, 35, 40,
+ 50, 75, 100, 125, 150, 175, 200, 225, 250,
+};
+
+const int STAT_BONUSES[24] = {
+ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20
+};
+
+const int ELEMENTAL_CATEGORIES[6] = { 8, 15, 20, 25, 33, 36 };
+
+const int ATTRIBUTE_CATEGORIES[10] = {
+ 9, 17, 25, 33, 39, 45, 50, 56, 61, 72 };
+
+const int ATTRIBUTE_BONUSES[72] = {
+ 2, 3, 5, 8, 12, 17, 23, 30, 38, 47, // Might bonus
+ 2, 3, 5, 8, 12, 17, 23, 30, // INT bonus
+ 2, 3, 5, 8, 12, 17, 23, 30, // PER bonus
+ 2, 3, 5, 8, 12, 17, 23, 30, // SPD bonus
+ 3, 5, 10, 15, 20, 30, // ACC bonus
+ 5, 10, 15, 20, 25, 30, // LUC bonus
+ 4, 6, 10, 20, 50, // HP bonus
+ 4, 8, 12, 16, 20, 25, // SP bonus
+ 2, 4, 6, 10, 16, // AC bonus
+ 4, 6, 8, 10, 12, 14, 16, 18, 20, 25 // Thievery bonus
+};
+
+const int ELEMENTAL_RESISTENCES[37] = {
+ 0, 5, 7, 9, 12, 15, 20, 25, 30, 5, 7, 9, 12, 15, 20, 25,
+ 5, 10, 15, 20, 25, 10, 15, 20, 25, 40, 5, 7, 9, 11, 13, 15, 20, 25,
+ 5, 10, 20
+};
+
+const int ELEMENTAL_DAMAGE[37] = {
+ 0, 2, 3, 4, 5, 10, 15, 20, 30, 2, 3, 4, 5, 10, 15, 20, 2, 4, 5, 10, 20,
+ 2, 4, 8, 16, 32, 2, 3, 4, 5, 10, 15, 20, 30, 5, 10, 25
+};
+
+const int WEAPON_DAMAGE_BASE[35] = {
+ 0, 3, 2, 3, 2, 2, 4, 1, 2, 4, 2, 3,
+ 2, 2, 1, 1, 1, 1, 4, 4, 3, 2, 4, 2,
+ 2, 2, 5, 3, 3, 3, 3, 5, 4, 2, 6
+};
+
+const int WEAPON_DAMAGE_MULTIPLIER[35] = {
+ 0, 3, 3, 4, 5, 4, 2, 3, 3, 3, 3, 3,
+ 2, 4, 10, 6, 8, 9, 4, 3, 6, 8, 5, 6,
+ 4, 5, 3, 5, 6, 7, 2, 2, 2, 2, 4
+};
+
+const int METAL_DAMAGE[22] = {
+ -3, -6, -4, -2, 2, 4, 6, 8, 10, 0, 1,
+ 1, 2, 2, 3, 4, 5, 12, 15, 20, 30, 50
+};
+
+const int METAL_DAMAGE_PERCENT[22] = {
+ 253, 252, 3, 2, 1, 2, 3, 4, 6, 0, 1,
+ 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10
+};
+
+const int METAL_LAC[9] = { -3, 0, -2, -1, 1, 2, 4, 6, 8 };
+
+const int ARMOR_STRENGTHS[14] = { 0, 2, 4, 5, 6, 7, 8, 10, 4, 2, 1, 1, 1, 1 };
+
+const int MAKE_ITEM_ARR1[6] = { 0, 8, 15, 20, 25, 33 };
+
+const int MAKE_ITEM_ARR2[6][7][2] = {
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 7 }, { 7, 7 } },
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, { 5, 5 } },
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
+ { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 1, 2 }, { 2, 2 }, { 2, 3 }, { 3, 3 } }
+};
+
+const int MAKE_ITEM_ARR3[10][7][2] = {
+ { { 0, 0 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 10 }, { 10, 10 } },
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } },
+ { { 0, 0 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, { 5, 6 }, { 6, 6 } },
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } },
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
+ { { 0, 0 }, { 1, 2 }, { 1, 4 }, { 3, 6 }, { 5, 8 }, { 7, 10 }, { 10, 10 } }
+};
+
+const int MAKE_ITEM_ARR4[2][7][2] = {
+ { { 0, 0 }, { 1, 4 }, { 3, 7 }, { 4, 8 }, { 5, 9 }, { 8, 9 }, { 9, 9 } },
+ { { 0, 0 }, { 1, 4 }, { 2, 6 }, { 4, 7 }, { 6, 10 }, { 9, 13 }, { 13, 13 } }
+};
+
+
+const int MAKE_ITEM_ARR5[8][2] = {
+ { 0, 0 }, { 1, 15 }, { 16, 30 }, { 31, 40 }, { 41, 50 },
+ { 51, 60 }, { 61, 73 }, { 61, 73 }
+};
+
+const int OUTDOOR_DRAWSTRUCT_INDEXES[44] = {
+ 37, 38, 39, 40, 41, 44, 42, 43, 47, 45, 46,
+ 48, 49, 52, 50, 51, 66, 67, 68, 69, 70, 71,
+ 72, 75, 73, 74, 87, 88, 89, 90, 91, 94, 92,
+ 93, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120
+};
+
+const int TOWN_MAXES[2][11] = {
+ { 23, 13, 32, 16, 26, 16, 16, 16, 16, 16, 16 },
+ { 26, 19, 48, 27, 26, 37, 16, 16, 16, 16, 16 }
+};
+
+const char *const TOWN_ACTION_MUSIC[2][7] = {
+ { "bank.m", "smith.m", "guild.m", "tavern.m",
+ "temple.m", "grounds.m", "endgame.m" },
+ { "bank.m", "sf09.m", "guild.m", "tavern.m",
+ "temple.m", "smith.m", "endgame.m" }
+};
+
+const char *const TOWN_ACTION_SHAPES[7] = {
+ "bnkr", "blck", "gild", "tvrn", "tmpl", "trng", "eface08"
+};
+
+const int TOWN_ACTION_FILES[2][7] = {
+ { 3, 2, 4, 2, 4, 2, 1 }, { 5, 3, 7, 5, 4, 6, 1 }
+};
+
+const char *const BANK_TEXT = "\xD\x2\x3""c\xB""122\t013"
+ "\xC""37D\xC""dep\t040\xC""37W\xC""dith\t067ESC"
+ "\x1\t000\xB""000Bank of Xeen\xB""015\n"
+ "Bank\x3l\n"
+ "Gold\x3r\t000%s\x3l\n"
+ "Gems\x3r\t000%s\x3""c\n"
+ "\n"
+ "Party\x3l\n"
+ "Gold\x3r\t000%s\x3l\n"
+ "Gems\x3r\t000%s";
+
+const char *const BLACKSMITH_TEXT = "\x01\x0D\x03""c\x0B""000\x09""000"
+ "Store Options for\x09""039\x0B""027%s\x03""l\x0B""046\n"
+ "\x09""011\x0C""37B\x0C""drowse\n"
+ "\x09""000\x0B""090Gold\x03r\x09""000%s"
+ "\x02\x03""c\x0B""122\x09""040ESC\x01";
+
+const char *const GUILD_NOT_MEMBER_TEXT =
+ "\n\nYou have to be a member to shop here.";
+
+const char *const GUILD_TEXT = "\x03""c\x0B""027\x09""039%s"
+ "\x03l\x0B""046\n"
+ "\x09""012\x0C""37B\x0C""duy Spells\n"
+ "\x09""012\x0C""37S\x0C""dpell Info";
+
+const char *const TAVERN_TEXT =
+ "\x0D\x03""c\x0B""000\x09""000Tavern Options for\x09""039"
+ "\x0B""027%s%s\x03l\x09""000"
+ "\x0B""090Gold\x03r\x09""000%s\x02\x03""c\x0B""122"
+ "\x09""021\x0C""37S\x0C""dign in\x09""060ESC\x01";
+
+const char *const FOOD_AND_DRINK =
+ "\x03l\x09""017\x0B""046\x0C""37D\x0C""drink\n"
+ "\x09""017\x0C""37F\x0C""dood\n"
+ "\x09""017\x0C""37T\x0C""dip\n"
+ "\x09""017\x0C""37R\x0C""dumors";
+
+const char *const GOOD_STUFF = "\n"
+ "\n"
+ "Good Stuff\n"
+ "\n"
+ "Hit a key!";
+
+const char *const HAVE_A_DRINK = "\n\nHave a Drink\n\nHit a key!";
+
+const char *const YOURE_DRUNK = "\n\nYou're Drunk\n\nHit a key!";
+
+const int TAVERN_EXIT_LIST[2][6][5][2] = {
+ {
+ { { 21, 17 }, { 0, 0 }, { 20, 3 }, { 0, 0 }, { 0, 0 } },
+ { { 13, 4 }, { 0, 0 }, { 19, 9 }, { 0, 0 }, { 0, 0 } },
+ { { 20, 10 }, { 12, 8 }, { 5, 26 }, { 3, 4 }, { 7, 5 } },
+ { { 18, 4 }, { 0, 0 }, { 19, 16 }, { 0, 0 }, { 11, 12 } },
+ { { 15, 21 }, { 0, 0 }, { 13, 21 }, { 0, 0 }, { 0, 0 } },
+ { { 10, 8 }, { 0, 0 }, { 15, 12 }, { 0, 0 }, { 0, 0 } },
+ }, {
+ { { 21, 17 }, { 0, 0 }, { 20, 3 }, { 0, 0 }, { 0, 0 } },
+ { { 13, 4 }, { 0, 0 }, { 19, 9 }, { 0, 0 }, { 0, 0 } },
+ { { 20, 10 }, { 12, 8 }, { 5, 26 }, { 3, 4 }, { 7, 5 } },
+ { { 17, 24 }, { 14, 13 }, { 0, 0 }, { 0, 0 }, { 9, 4 } },
+ { { 15, 21 }, { 0, 0 }, { 13, 21 }, { 0, 0 }, { 0, 0 } },
+ { { 10, 8 }, { 0, 0 }, { 15, 12 }, { 0, 0 }, { 0, 0 } }
+ }
+};
+
+const char *const TEMPLE_TEXT =
+ "\x0D\x03""c\x0B""000\x09""000Temple Options for"
+ "\x09""039\x0B""027%s\x03l\x09""000\x0B""046"
+ "\x0C""37H\x0C""deal\x03r\x09""000%lu\x03l\n"
+ "\x0C""37D\x0C""donation\x03r\x09""000%lu\x03l\n"
+ "\x0C""37U\x0C""dnCurse\x03r\x09""000%s"
+ "\x03l\x09""000\x0B""090Gold\x03r\x09""000%s"
+ "\x02\x03""c\x0B""122\x09""040ESC\x01";
+
+const char *const EXPERIENCE_FOR_LEVEL =
+ "%s needs %lu experience for level %u.";
+
+const char *const LEARNED_ALL = "%s has learned all we can teach!";
+
+const char *const ELIGIBLE_FOR_LEVEL = "%s is eligible for level %d.";
+
+const char *const TRAINING_TEXT =
+ "\x0D\x03""cTraining Options\n"
+ "\n"
+ "%s\x03l\x0B""090\x09""000Gold\x03r\x09"
+ "000%s\x02\x03""c\x0B""122\x09""021"
+ "\x0C""37T\x0C""drain\x09""060ESC\x01";
+
+const char *const GOLD_GEMS =
+ "\x03""c\x0B""000\x09""000%s\x03l\n"
+ "\n"
+ "Gold\x03r\x09""000%s\x03l\n"
+ "Gems\x03r\x09""000%s\x02\x03""c\x0B""096\x09""013G"
+ "\x0C""37o\x0C""dld\x09""040G\x0C\x03""7e"
+ "\x0C""dms\x09""067ESC\x01";
+
+const char *const GOLD_GEMS_2 =
+ "\x09""000\x0B""000\x03""c%s\x03l\n"
+ "\n"
+ "\x04""077Gold\x03r\x09""000%s\x03l\n"
+ "\x04""077Gems\x03r\x09""000%s\x03l\x09""000\x0B""051\x04""077\n"
+ "\x04""077";
+
+const char *const DEPOSIT_WITHDRAWL[2] = { "Deposit", "Withdrawl" };
+
+const char *const NOT_ENOUGH_X_IN_THE_Y =
+ "\x03""c\x0B""012Not enough %s in the %s!\x03l";
+
+const char *const NO_X_IN_THE_Y = "\x03""c\x0B""012No %s in the %s!\x03l";
+
+const char *const STAT_NAMES[16] = {
+ "Might", "Intellect", "Personality", "Endurance", "Speed",
+ "Accuracy", "Luck", "Age", "Level", "Armor Class", "Hit Points",
+ "Spell Points", "Resistances", "Skills", "Awards", "Experience"
+};
+
+const char *const CONSUMABLE_NAMES[4] = { "Gold", "Gems", "Food", "Condition" };
+
+const char *const WHERE_NAMES[2] = { "Party", "Bank" };
+
+const char *const AMOUNT = "\x03""c\x09""000\x0B""051Amount\x03l\n";
+
+const char *const FOOD_PACKS_FULL = "\v007Your food packs are already full!";
+
+const char *const BUY_SPELLS =
+ "\x03""c\x0B""027\x09""039%s\x03l\x0B""046\n"
+ "\x09""012\x0C""37B\x0C""duy Spells\n"
+ "\x09""012\x0C""37S\x0C""dpell Info";
+
+const char *const GUILD_OPTIONS =
+ "\x0D\x0C""00\x03""c\x0B""000\x09""000Guild Options for%s"
+ "\x03l\x09""000\x0B""090Gold"
+ "\x03r\x09""000%s\x02\x03""c\x0B""122\x09""040ESC\x01";
+
+const int MISC_SPELL_INDEX[74] = {
+ NO_SPELL, MS_Light, MS_Awaken, MS_MagicArrow,
+ MS_FirstAid, MS_FlyingFist, MS_EnergyBlast, MS_Sleep,
+ MS_Revitalize, MS_CureWounds, MS_Sparks, MS_Shrapmetal,
+ MS_InsectSpray, MS_ToxicCloud, MS_ProtFromElements, MS_Pain,
+ MS_Jump, MS_BeastMaster, MS_Clairvoyance, MS_TurnUndead,
+ MS_Levitate, MS_WizardEye, MS_Bless, MS_IdentifyMonster,
+ MS_LightningBolt, MS_HolyBonus, MS_PowerCure, MS_NaturesCure,
+ MS_LloydsBeacon, MS_PowerShield, MS_Heroism, MS_Hynotize,
+ MS_WalkOnWater, MS_FrostBite, MS_DetectMonster, MS_Fireball,
+ MS_ColdRay, MS_CurePoison, MS_AcidSpray, MS_TimeDistortion,
+ MS_DragonSleep, MS_CureDisease, MS_Teleport, MS_FingerOfDeath,
+ MS_CureParalysis, MS_GolemStopper, MS_PoisonVolley, MS_DeadlySwarm,
+ MS_SuperShelter, MS_DayOfProtection, MS_DayOfSorcery, MS_CreateFood,
+ MS_FieryFlail, MS_RechargeItem, MS_FantasticFreeze, MS_TownPortal,
+ MS_StoneToFlesh, MS_RaiseDead, MS_Etheralize, MS_DancingSword,
+ MS_MoonRay, MS_MassDistortion, MS_PrismaticLight, MS_EnchantItem,
+ MS_Incinerate, MS_HolyWord, MS_Resurrection, MS_ElementalStorm,
+ MS_MegaVolts, MS_Inferno, MS_SunRay, MS_Implosion,
+ MS_StarBurst, MS_DivineIntervention
+};
+
+const int SPELL_COSTS[77] = {
+ 8, 1, 5, -2, 5, -2, 20, 10, 12, 8, 3,
+ - 3, 75, 40, 12, 6, 200, 10, 100, 30, -1, 30,
+ 15, 25, 10, -2, 1, 2, 7, 20, -2, -2, 100,
+ 15, 5, 100, 35, 75, 5, 20, 4, 5, 1, -2,
+ 6, 2, 75, 40, 60, 6, 4, 25, -2, -2, 60,
+ - 1, 50, 15, 125, 2, -1, 3, -1, 200, 35, 150,
+ 15, 5, 4, 10, 8, 30, 4, 5, 7, 5, 0
+};
+
+const int DARK_SPELL_RANGES[12][2] = {
+ { 0, 20 }, { 16, 35 }, { 27, 37 }, { 29, 39 },
+ { 0, 17 }, { 14, 34 }, { 26, 37 }, { 29, 39 },
+ { 0, 20 }, { 16, 35 }, { 27, 37 }, { 29, 39 }
+};
+
+const int CLOUDS_SPELL_OFFSETS[5][20] = {
+ {
+ 1, 10, 20, 26, 27, 38, 40, 42, 45, 50,
+ 55, 59, 60, 61, 62, 68, 72, 75, 77, 77
+ }, {
+ 3, 4, 5, 14, 15, 25, 30, 31, 34, 41,
+ 49, 51, 53, 67, 73, 75, -1, -1, -1, -1
+ }, {
+ 4, 8, 9, 12, 13, 22, 23, 24, 28, 34,
+ 41, 44, 52, 70, 73, 74, -1, -1, -1, -1
+ }, {
+ 6, 7, 9, 11, 12, 13, 17, 21, 22, 24,
+ 29, 36, 56, 58, 64, 71, -1, -1, -1, -1
+ }, {
+ 6, 7, 9, 11, 12, 13, 18, 21, 29, 32,
+ 36, 37, 46, 51, 56, 58, 69, -1, -1, -1
+ }
+};
+
+const int DARK_SPELL_OFFSETS[3][39] = {
+ {
+ 42, 1, 26, 59, 27, 10, 50, 68, 55, 62, 67, 73, 2,
+ 5, 3, 31, 30, 52, 49, 28, 74, 0, 9, 7, 14, 8,
+ 33, 6, 23, 71, 64, 56, 48, 46, 12, 32, 58, 65, 16
+ }, {
+ 42, 1, 45, 61, 72, 40, 20, 60, 38, 41, 75, 34, 4,
+ 43, 25, 53, 44, 15, 70, 17, 24, 69, 22, 66, 57, 11,
+ 29, 39, 51, 21, 19, 36, 47, 13, 54, 37, 18, 35, 63
+ }, {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
+ }
+};
+
+const int SPELL_GEM_COST[77] = {
+ 0, 0, 2, 1, 2, 4, 5, 0, 0, 0, 0, 10, 10, 10, 0, 0, 20, 4, 10, 20, 1, 10,
+ 5, 5, 4, 2, 0, 0, 0, 10, 3, 1, 20, 4, 0, 20, 10, 10, 1, 10, 0, 0, 0, 2,
+ 2, 0, 10, 10, 10, 0, 0, 10, 3, 2, 10, 1, 10, 10, 20, 0, 0, 1, 1, 20, 5, 20,
+ 5, 0, 0, 0, 0, 5, 1, 2, 0, 2, 0
+};
+
+const char *const NOT_A_SPELL_CASTER = "Not a spell caster...";
+
+const char *const SPELLS_FOR = "\xD\xC""d%s\x2\x3""c\x9""000\xB""002Spells for %s";
+
+const char *const SPELL_LINES_0_TO_9 =
+ "\x2\x3l\xB""015\x9""0011\n2\n3\n4\n5\n6\n7\n8\n9\n0";
+
+const char *const SPELLS_DIALOG_SPELLS = "\x3l\xB""015"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l\n"
+ "\x9""010\xC""%2u%s\xC""d\x3l"
+ "\x9""004\xB""110%s - %lu\x1";
+
+const char *const SPELL_PTS = "Spell Pts";
+
+const char *const GOLD = "Gold";
+
+const char *const SPELLS_PRESS_A_KEY =
+ "\x3""c\xC""09%s\xC""d\x3l\n"
+ "\n"
+ "%s\x3""c\x9""000\xB""100Press a Key!";
+
+const char *const SPELLS_PURCHASE =
+ "\x3l\xB""000\x9""000\xC""d%s Do you wish to purchase "
+ "\xC""09%s\xC""d for %u?";
+
+const char *const MAP_TEXT =
+ "\x3""c\xB""000\x9""000%s\x3l\xB""139"
+ "\x9""000X = %d\x3r\x9""000Y = %d\x3""c\x9""000%s";
+
+const char *const LIGHT_COUNT_TEXT = "\x3l\n\n\t024Light\x3r\t124%d";
+
+const char *const FIRE_RESISTENCE_TEXT = "%c%sFire%s%u";
+
+const char *const ELECRICITY_RESISTENCE_TEXT = "%c%sElectricity%s%u";
+
+const char *const COLD_RESISTENCE_TEXT = "c%sCold%s%u";
+
+const char *const POISON_RESISTENCE_TEXT = "%c%sPoison/Acid%s%u";
+
+const char *const CLAIRVOYANCE_TEXT = "%c%sClairvoyance%s";
+
+const char *const LEVITATE_TEXT = "%c%sLevitate%s";
+
+const char *const WALK_ON_WATER_TEXT = "%c%sWalk on Water";
+
+const char *const GAME_INFORMATION =
+ "\xD\x3""c\x9""000\xB""001\xC""37%s of Xeen\xC""d\n"
+ "Game Information\n"
+ "\n"
+ "Today is \xC""37%ssday\xC""d\n"
+ "\n"
+ "\x9""032Time\x9""072Day\x9""112Year\n"
+ "\x9""032\xC""37%d:%02d%c\x9""072%u\x9""112%u\xC""d%s";
+
+const char *const WORLD_GAME_TEXT = "World";
+const char *const DARKSIDE_GAME_TEXT = "Darkside";
+const char *const CLOUDS_GAME_TEXT = "Clouds";
+const char *const SWORDS_GAME_TEXT = "Swords";
+
+const char *const WEEK_DAY_STRINGS[10] = {
+ "Ten", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"
+};
+
+const char *const CHARACTER_DETAILS =
+ "\x3l\xB""041\x9""196%s\x9""000\xB""002%s : %s %s %s"
+ "\x3r\x9""053\xB""028\xC%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""%02u%d\xC""d\x9""196\xC""15%lu\xC""d\x3r"
+ "\x9""053\xB""051\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""%02u%u\xC""d\x9""196\xC""15%lu\xC""d"
+ "\x3r\x9""053\xB""074\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""15%lu\xC""d"
+ "\x3r\x9""053\xB""097\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""15%u day%c\xC""d"
+ "\x3r\x9""053\xB""120\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""%02u%s\xC""d"
+ "\x9""230%s%s%s%s\xC""d";
+
+const char *const PARTY_GOLD = "Party Gold";
+
+const char *const PLUS_14 = "14+";
+
+const char *const CHARACTER_TEMPLATE =
+ "\x1\xC""00\xD\x3l\x9""029\xB""018Mgt\x9""080Acy\x9""131H.P.\x9""196Experience"
+ "\x9""029\xB""041Int\x9""080Lck\x9""131S.P.\x9""029\xB""064Per\x9""080Age"
+ "\x9""131Resis\x9""196Party Gems\x9""029\xB""087End\x9""080Lvl\x9""131Skills"
+ "\x9""196Party Food\x9""029\xB""110Spd\x9""080AC\x9""131Awrds\x9""196Condition\x3""c"
+ "\x9""290\xB""025\xC""37I\xC""dtem\x9""290\xB""057\xC""37Q"
+ "\xC""duick\x9""290\xB""089\xC""37E\xC""dxch\x9""290\xB""121Exit\x3l%s";
+
+const char *const EXCHANGING_IN_COMBAT = "\x3""c\xB""007\x9""000Exchanging in combat is not allowed!";
+
+const char *const CURRENT_MAXIMUM_RATING_TEXT = "\x2\x3""c%s\n"
+ "Current / Maximum\n"
+ "\x3r\x9""054%lu\x3l\x9""058/ %lu\n"
+ "\x3""cRating: %s";
+
+const char *const CURRENT_MAXIMUM_TEXT = "\x2\x3""c%s\n"
+ "Current / Maximum\n"
+ "\x3r\x9""054%u\x3l\x9""058/ %u";
+
+const char *const RATING_TEXT[24] = {
+ "Nonexistant", "Very Poor", "Poor", "Very Low", "Low", "Averarage", "Good",
+ "Very Good", "High", "Very High", "Great", "Super", "Amazing", "Incredible",
+ "Gigantic", "Fantastic", "Astoundig", "Astonishing", "Monumental", "Tremendous",
+ "Collosal", "Awesome", "AweInspiring", "aUltimate"
+};
+
+const char *const AGE_TEXT = "\x2\x3""c%s\n"
+ "Current / Natural\n"
+ "\x3r\x9""057%u\x3l\x9""061/ %u\n"
+ "\x3""cBorn: %u / %u\x1";
+
+const char *const LEVEL_TEXT =
+ "\x2\x3""c%s\n"
+ "Current / Maximum\n"
+ "\x3r\x9""054%u\x3l\x9""058/ %u\n"
+ "\x3""c%u Attack%s/Round\x1";
+
+const char *const RESISTENCES_TEXT =
+ "\x2\x3""c%s\x3l\n"
+ "\x9""020Fire\x9""100%u\n"
+ "\x9""020Cold\x9""100%u\n"
+ "\x9""020Electricity\x9""100%u\n"
+ "\x9""020Poison\x9""100%u\n"
+ "\x9""020Energy\x9""100%u\n"
+ "\x9""020Magic\x9""100%u";
+
+const char *const NONE = "\n\x9""020";
+
+const char *const EXPERIENCE_TEXT = "\x2\x3""c%s\x3l\n"
+ "\x9""010Current:\x9""070%lu\n"
+ "\x9""010Next Level:\x9""070%s\x1";
+
+const char *const ELIGIBLE = "\xC""12Eligible\xC""d";
+
+const char *const IN_PARTY_IN_BANK =
+ "\x2\x3""cParty %s\n"
+ "%lu on hand\n"
+ "%lu in bank\x1\x3l";
+
+const char *const FOOD_TEXT =
+ "\x2\x3""cParty %s\n"
+ "%u on hand\n"
+ "Enough for %u day%s\x3l";
+
+const char *const EXCHANGE_WITH_WHOM = "\t010\v005Exchange with whom?";
+
+const char *const QUICK_REF_LINE =
+ "\xB%3d\x9""007%u)\x9""027%s\x9""110%c%c%c\x3r\x9""160\xC%02u%u\xC""d"
+ "\x3l\x9""170\xC%02u%d\xC""d\x9""208\xC%02u%u\xC""d\x9""247\xC"
+ "%02u%u\xC""d\x9""270\xC%02u%c%c%c%c\xC""d";
+
+const char *const QUICK_REFERENCE =
+ "\xD\x3""cQuick Reference Chart\xB""012\x3l"
+ "\x9""007#\x9""027Name\x9""110Cls\x9""140Lvl\x9""176H.P."
+ "\x9""212S.P.\x9""241A.C.\x9""270Cond"
+ "%s%s%s%s%s%s%s%s"
+ "\xB""110\x9""064\x3""cGold\x9""144Gems\x9""224Food\xB""119"
+ "\x9""064\xC""15%lu\x9""144%lu\x9""224%u day%s\xC""d";
+
+const int BLACKSMITH_MAP_IDS[2][4] = { { 28, 30, 73, 49 }, { 29, 31, 37, 43 } };
+
+const char *const ITEMS_DIALOG_TEXT1 =
+ "\r\x2\x3""c\v021\t017\f37W\fdeap\t051\f37A\fdrmor\t085A"
+ "\f37c\fdces\t119\f37M\fdisc\t153%s\t187%s\t221%s"
+ "\t255%s\t289Exit";
+const char *const ITEMS_DIALOG_TEXT2 =
+ "\r\x2\x3""c\v021\t017\f37W\fdeap\t051\f37A\fdrmor\t085A"
+ "\f37c\fdces\t119\f37M\fdisc\t153\f37%s\t289Exit";
+const char *const ITEMS_DIALOG_LINE1 = "\x3r\f%02u\f023%2d)\x3l\t028%s\n";
+const char *const ITEMS_DIALOG_LINE2 = "\x3r\f%02u\t023%2d)\x3l\t028%s\x3r\t000%lu\n";
+
+const char *const BTN_BUY = "\f37B\fduy";
+const char *const BTN_SELL = "\f37S\fdell";
+const char *const BTN_IDENTIFY = "\f37I\fddentify";
+const char *const BTN_FIX = "\f37F\fdix";
+const char *const BTN_USE = "\f37U\fdse";
+const char *const BTN_EQUIP = "\f37E\fdquip";
+const char *const BTN_REMOVE = "\f37R\fdem";
+const char *const BTN_DISCARD = "\f37D\fdisc";
+const char *const BTN_QUEST = "\f37Q\fduest";
+const char *const BTN_ENCHANT = "E\fdnchant";
+const char *const BTN_RECHARGE = "R\fdechrg";
+const char *const BTN_GOLD = "G\fdold";
+
+const char *const ITEM_BROKEN = "\f32broken ";
+const char *const ITEM_CURSED = "\f09cursed ";
+const char *const BONUS_NAMES[7] = {
+ "", "Dragon Slayer", "Undead Eater", "Golem Smasher",
+ "Bug Zapper", "Monster Masher", "Beast Bopper"
+};
+
+const char *const WEAPON_NAMES[35] = {
+ nullptr, "long sword ", "short sword ", "broad sword ", "scimitar ",
+ "cutlass ", "sabre ", "club ", "hand axe ", "katana ", "nunchakas ",
+ "wakazashi ", "dagger ", "mace ", "flail ", "cudgel ", "maul ", "spear ",
+ "bardiche ", "glaive ", "halberd ", "pike ", "flamberge ", "trident ",
+ "staff ", "hammer ", "naginata ", "battle axe ", "grand axe ", "great axe ",
+ "short bow ", "long bow ", "crossbow ", "sling ", "Xeen Slayer Sword"
+};
+
+const char *const ARMOR_NAMES[14] = {
+ nullptr, "robes ", "sale armor ", "ring mail ", "chain mail ",
+ "splint mail ", "plate mail ", "plate armor ", "shield ",
+ "helm ", "boots ", "cloak ", "cape ", "gauntlets "
+};
+
+const char *const ACCESSORY_NAMES[11] = {
+ nullptr, "ring ", "belt ", "broach ", "medal ", "charm ", "cameo ",
+ "scarab ", "pendant ", "necklace ", "amulet "
+};
+
+const char *const MISC_NAMES[22] = {
+ nullptr, "rod ", "jewel ", "gem ", "box ", "orb ", "horn ", "coin ",
+ "wand ", "whistle ", "potion ", "scroll ", "RogueVM",
+ "bogusg", "bogus", "bogus", "bogus", "bogus",
+ "bogus", "bogus", "bogus", "bogus"
+};
+
+const char *const ELEMENTAL_NAMES[6] = {
+ "Fire", "Elec", "Cold", "Acid/Poison", "Energy", "Magic"
+};
+
+const char *const ATTRIBUTE_NAMES[10] = {
+ "might", "Intellect", "Personality", "Speed", "accuracy", "Luck",
+ "Hit Points", "Spell Points", "Armor Class", "Thievery"
+};
+
+const char *const EFFECTIVENESS_NAMES[7] = {
+ nullptr, "Dragons", "Undead", "Golems", "Bugs", "Monsters", "Beasts"
+};
+
+const char *const QUEST_ITEM_NAMES[85] = {
+ "Deed to New Castle",
+ "Crystal Key to Witch Tower",
+ "Skeleton Key to Darzog's Tower",
+ "Enchanted Key to Tower of High Magic",
+ "Jeweled Amulet of the Northern Sphinx",
+ "Stone of a Thousand Terrors",
+ "Golem Stone of Admittance",
+ "Yak Stone of Opening",
+ "Xeen's Scepter of Temporal Distortion",
+ "Alacorn of Falista",
+ "Elixir of Restoration",
+ "Wand of Faery Magic",
+ "Princess Roxanne's Tiara",
+ "Holy Book of Elvenkind",
+ "Scarab of Imaging",
+ "Crystals of Piezoelectricity",
+ "Scroll of Insight",
+ "Phirna Root",
+ "Orothin's Bone Whistle",
+ "Barok's Magic Pendant",
+ "Ligono's Missing Skull",
+ "Last Flower of Summer",
+ "Last Raindrop of Spring",
+ "Last Snowflake of Winter",
+ "Last Leaf of Autumn",
+ "Ever Hot Lava Rock",
+ "King's Mega Credit",
+ "Excavation Permit",
+ "Cupie Doll",
+ "Might Doll",
+ "Speed Doll",
+ "Endurance Doll",
+ "Accuracy Doll",
+ "Luck Doll",
+ "Widget",
+ "Pass to Castleview",
+ "Pass to Sandcaster",
+ "Pass to Lakeside",
+ "Pass to Necropolis",
+ "Pass to Olympus",
+ "Key to Great Western Tower",
+ "Key to Great Southern Tower",
+ "Key to Great Eastern Tower",
+ "Key to Great Northern Tower",
+ "Key to Ellinger's Tower",
+ "Key to Dragon Tower",
+ "Key to Darkstone Tower",
+ "Key to Temple of Bark",
+ "Key to Dungeon of Lost Souls",
+ "Key to Ancient Pyramid",
+ "Key to Dungeon of Death",
+ "Amulet of the Southern Sphinx",
+ "Dragon Pharoah's Orb",
+ "Cube of Power",
+ "Chime of Opening",
+ "Gold ID Card",
+ "Silver ID Card",
+ "Vulture Repellant",
+ "Bridle",
+ "Enchanted Bridle",
+ "Treasure Map (Goto E1 x1, y11)",
+ "",
+ "Fake Map",
+ "Onyx Necklace",
+ "Dragon Egg",
+ "Tribble",
+ "Golden Pegasus Statuette",
+ "Golden Dragon Statuette",
+ "Golden Griffin Statuette",
+ "Chalice of Protection",
+ "Jewel of Ages",
+ "Songbird of Serenity",
+ "Sandro's Heart",
+ "Ector's Ring",
+ "Vespar's Emerald Handle",
+ "Queen Kalindra's Crown",
+ "Caleb's Magnifying Glass",
+ "Soul Box",
+ "Soul Box with Corak inside",
+ "Ruby Rock",
+ "Emerald Rock",
+ "Sapphire Rock",
+ "Diamond Rock",
+ "Monga Melon",
+ "Energy Disk"
+};
+
+const int WEAPON_BASE_COSTS[35] = {
+ 0, 50, 15, 100, 80, 40, 60, 1, 10, 150, 30, 60, 8, 50,
+ 100, 15, 30, 15, 200, 80, 250, 150, 400, 100, 40, 120,
+ 300, 100, 200, 300, 25, 100, 50, 15, 0
+};
+const int ARMOR_BASE_COSTS[14] = {
+ 0, 20, 100, 200, 400, 600, 1000, 2000, 100, 60, 40, 250, 200, 100
+};
+const int ACCESSORY_BASE_COSTS[11] = {
+ 0, 100, 100, 250, 100, 50, 300, 200, 500, 1000, 2000
+};
+const int MISC_MATERIAL_COSTS[22] = {
+ 0, 50, 1000, 500, 10, 100, 20, 10, 50, 10, 10, 100,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+const int MISC_BASE_COSTS[76] = {
+ 0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 300, 300, 300, 300, 300,
+ 300, 300, 300, 300, 300, 400, 400, 400, 400, 400, 400, 400,
+ 400, 400, 400, 500, 500, 500, 500, 500, 500, 500, 500, 500,
+ 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600
+};
+const int METAL_BASE_MULTIPLIERS[22] = {
+ 10, 25, 5, 75, 2, 5, 10, 20, 50, 2, 3, 5, 10, 20, 30, 40,
+ 50, 60, 70, 80, 90, 100
+};
+const int ITEM_SKILL_DIVISORS[4] = { 1, 2, 100, 10 };
+
+const int RESTRICTION_OFFSETS[4] = { 0, 35, 49, 60 };
+
+const int ITEM_RESTRICTIONS[86] = {
+ 0, 86, 86, 86, 86, 86, 86, 0, 6, 239, 239, 239, 2, 4, 4, 4, 4,
+ 6, 70, 70, 70, 70, 94, 70, 0, 4, 239, 86, 86, 86, 70, 70, 70, 70,
+ 0, 0, 0, 68, 100, 116, 125, 255, 255, 85, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+const char *const NOT_PROFICIENT =
+ "\t000\v007\x3""c%ss are not proficient with a %s!";
+
+const char *const NO_ITEMS_AVAILABLE = "\x3""c\n"
+ "\t000No items available.";
+
+const char *const CATEGORY_NAMES[4] = { "Weapons", "Armor", "Accessories", "Miscellaneous" };
+
+const char *const X_FOR_THE_Y =
+ "\x1\fd\r%s\v000\t000%s for %s the %s%s\v011\x2%s%s%s%s%s%s%s%s%s\x1\fd";
+
+const char *const X_FOR_Y =
+ "\x1\xC""d\r\x3l\v000\t000%s for %s\x3r\t000%s\x3l\v011\x2%s%s%s%s%s%s%s%s%s\x1\xC""d";
+
+const char *const X_FOR_Y_GOLD =
+ "\x1\fd\r\x3l\v000\t000%s for %s\t150Gold - %lu%s\x3l\v011"
+ "\x2%s%s%s%s%s%s%s%s%s\x1\fd";
+
+const char *const FMT_CHARGES = "\x3rr\t000Charges\x3l";
+
+const char *const AVAILABLE_GOLD_COST =
+ "\x1\fd\r\x3l\v000\t000Available %s\t150Gold - %lu\x3r\t000Cost"
+ "\x3l\v011\x2%s%s%s%s%s%s%s%s%s\x1\xC""d";
+
+const char *const CHARGES = "Charges";
+
+const char *const COST = "Cost";
+
+const char *const ITEM_ACTIONS[7] = {
+ "Equip", "Remove", "Use", "Discard", "Enchant", "Recharge", "Gold"
+};
+const char *const WHICH_ITEM = "\t010\v005%s which item?";
+
+const char *const WHATS_YOUR_HURRY = "\v007What's your hurry?\n"
+ "Wait till you get out of here!";
+
+const char *const USE_ITEM_IN_COMBAT =
+ "\v007To use an item in Combat, invoke the Use command on your turn!";
+
+const char *const NO_SPECIAL_ABILITIES = "\v005\x3""c%s\fdhas no special abilities!";
+
+const char *const CANT_CAST_WHILE_ENGAGED = "\x3""c\v007Can't cast %s while engaged!";
+
+const char *const EQUIPPED_ALL_YOU_CAN = "\x3""c\v007You have equipped all the %ss you can!";
+const char *const REMOVE_X_TO_EQUIP_Y = "\x3""c\v007You must remove %sto equip %s\x8!";
+const char *const RING = "ring";
+const char *const MEDAL = "medal";
+
+const char *const CANNOT_REMOVE_CURSED_ITEM = "\x3""You cannot remove a cursed item!";
+
+const char *const CANNOT_DISCARD_CURSED_ITEM = "\3x""cYou cannot discard a cursed item!";
+
+const char *const PERMANENTLY_DISCARD = "\v000\t000\x03lPermanently discard %s\fd?";
+
+const char *const BACKPACK_IS_FULL = "\v005\x3""c\fd%s's backpack is full.";
+
+const char *const CATEGORY_BACKPACK_IS_FULL[4] = {
+ "\v010\t000\x3""c%s's weapons backpack is full.",
+ "\v010\t000\x3""c%s's armor backpack is full.",
+ "\v010\t000\x3""c%s's accessories backpack is full.",
+ "\v010\t000\x3""c%s's miscellaneous backpack is full."
+};
+
+const char *const BUY_X_FOR_Y_GOLD = "\x3l\v000\t000\fdBuy %s\fd for %lu gold?";
+
+const char *const SELL_X_FOR_Y_GOLD = "\x3l\v000\t000\fdSell %s\fd for %lu gold?";
+
+const char *const NO_NEED_OF_THIS = "\v005\x3""c\fdWe have no need of this %s\f!";
+
+const char *const NOT_RECHARGABLE = "\v012\x3""c\fdNot Rechargeable. %s";
+
+const char *const NOT_ENCHANTABLE = "\v012\t000\x3""cNot Enchantable. %s";
+
+const char *const SPELL_FAILED = "Spell Failed!";
+
+const char *const ITEM_NOT_BROKEN = "\fdThat item is not broken!";
+
+const char *const FIX_IDENTIFY[2] = { "Fix", "Identify" };
+
+const char *const FIX_IDENTIFY_GOLD = "\x3l\v000\t000%s %s\fd for %lu gold?";
+
+const char *const IDENTIFY_ITEM_MSG = "\fd\v000\t000\x3""cIdentify Item\x3l\n"
+ "\n"
+ "\v012%s\fd\n"
+ "\n"
+ "%s";
+
+const char *const ITEM_DETAILS =
+ "Proficient Classes\t132:\t140%s\n"
+ "to Hit Modifier\t132:\t140%s\n"
+ "Physical Damage\t132:\t140%s\n"
+ "Elemental Damage\t132:\t140%s\n"
+ "Elemental Resistance\t132:\t140%s\n"
+ "Armor Class Bonus\t132:\t140%s\n"
+ "Attribute Bonus\t132:\t140%s\n"
+ "Special Power\t132:\t140%s";
+
+const char *const ALL = "All";
+const char *const FIELD_NONE = "None";
+const char *const DAMAGE_X_TO_Y = "%d to %d";
+const char *const ELEMENTAL_XY_DAMAGE = "%+d %s Damage";
+const char *const ATTR_XY_BONUS = "%+d %s";
+const char *const EFFECTIVE_AGAINST = "x3 vs %s";
+
+const char *const QUESTS_DIALOG_TEXT =
+ "\r\x2\x3""c\v021\t017\f37I\fdtems\t085\f37Q\fduests\t153"
+ "\f37A\fduto Notes 221\f37U\fdp\t255\f37D\fdown"
+ "\t289Exit";
+const char *const CLOUDS_OF_XEEN_LINE = "\b \b*-- \f04Clouds of Xeen\fd --";
+const char *const DARKSIDE_OF_XEEN_LINE = "\b \b*-- \f04Darkside of Xeen\fd --";
+
+const char *const NO_QUEST_ITEMS =
+ "\r\x3""c\v000 000Quest Items\x3l\x2\n"
+ "\n"
+ "\x3""cNo Quest Items";
+const char *const NO_CURRENT_QUESTS =
+ "\x3""c\v000\t000\n"
+ "\n"
+ "No Current Quests";
+const char *const NO_AUTO_NOTES = "\x3""cNo Auto Notes";
+
+const char *const QUEST_ITEMS_DATA =
+ "\r\x1\fd\x3""c\v000\t000Quest Items\x3l\x2\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s";
+const char *const CURRENT_QUESTS_DATA =
+ "\r\x1\fd\x3""c\t000\v000Current Quests\x3l\x2\n"
+ "%s\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "%s";
+const char *const AUTO_NOTES_DATA =
+ "\r\x1\fd\x3""c\t000\v000Auto Notes\x3l\x2\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l";
+
+const char *const REST_COMPLETE =
+ "\v000\t0008 hours pass. Rest complete.\n"
+ "%s\n"
+ "%d food consumed.";
+const char *const PARTY_IS_STARVING = "\f07The Party is Starving!\fd";
+const char *const HIT_SPELL_POINTS_RESTORED = "Hit Pts and Spell Pts restored.";
+const char *const TOO_DANGEROUS_TO_REST = "Too dangerous to rest here!";
+const char *const SOME_CHARS_MAY_DIE = "Some Chars may die. Rest anyway?";
+
+const char *const CANT_DISMISS_LAST_CHAR = "You cannot dismiss your last character!";
+
+const char *const REMOVE_DELETE[2] = { "Remove", "Delete" };
+
+const char *const REMOVE_OR_DELETE_WHICH = "\x3l\t010\v005%s which character?";
+
+const char *const YOUR_PARTY_IS_FULL = "\v007Your party is full!";
+
+const char *const HAS_SLAYER_SWORD =
+ "\v000\t000This character has the Xeen Slayer Sword and cannot be deleted!";
+const char *const SURE_TO_DELETE_CHAR =
+ "Are you sure you want to delete %s the %s?";
+
+const char *const CREATE_CHAR_DETAILS =
+ "\f04\x3""c\x2\t144\v119\f37R\f04oll\t144\v149\f37C\f04reate"
+ "\t144\v179\f37ESC\f04\x3l\x1\t195\v021\f37M\f04gt"
+ "\t195\v045\f37I\f04nt\t195\v069\f37P\f04er\t195\v093\f37E\f04nd"
+ "\t195\v116\f37S\f04pd\t195\v140\f37A\f04cy\t195\v164\f37L\f04ck%s";
+
+const char *const NEW_CHAR_STATS =
+ "\f04\x3l\t022\v148Race\t055: %s\n"
+ "\t022Sex\t055: %s\n"
+ "\t022Class\t055:\n"
+ "\x3r\t215\v031%d\t215\v055%d\t215\v079%d\t215\v103%d\t215\v127%d"
+ "\t215\v151%d\t215\v175%d\x3l\t242\v020\f%.2dKnight\t242\v031\f%.2d"
+ "Paladin\t242\v042\f%.2dArcher\t242\v053\f%.2dCleric\t242\v064\f%.2d"
+ "Sorcerer\t242\v075\f%.2dRobber\t242\v086\f%.2dNinja\t242\v097\f%.2d"
+ "Barbarian\t242\v108\f%.2dDruid\t242\v119\f%.2dRanger\f04\x3""c"
+ "\t265\v142Skills\x3l\t223\v155%s\t223\v170%s%s";
+
+const char *const NAME_FOR_NEW_CHARACTER =
+ "\x3""cEnter a Name for this Character\n\n";
+const char *const SELECT_CLASS_BEFORE_SAVING =
+ "\v006\x3""cSelect a Class before saving.\x3l";
+const char *const EXCHANGE_ATTR_WITH = "Exchange %s with...";
+
+const int NEW_CHAR_SKILLS[10] = { 1, 5, -1, -1, 4, 0, 0, -1, 6, 11 };
+const int NEW_CHAR_SKILLS_LEN[10] = { 11, 8, 0, 0, 12, 8, 8, 0, 9, 11 };
+const int NEW_CHAR_RACE_SKILLS[10] = { 14, -1, 17, 16, -1, 0, 0, 0, 0, 0 };
+
+const int RACE_MAGIC_RESISTENCES[5] = { 7, 5, 20, 0, 0 };
+const int RACE_FIRE_RESISTENCES[5] = { 7, 0, 2, 5, 10 };
+const int RACE_ELECTRIC_RESISTENCES[5] = { 7, 0, 2, 5, 10 };
+const int RACE_COLD_RESISTENCES[5] = { 7, 0, 2, 5, 10 };
+const int RACE_ENERGY_RESISTENCES[5] = { 7, 5, 2, 5, 0 };
+const int RACE_POISON_RESISTENCES[5] = { 7, 0, 2, 20, 0 };
+const int NEW_CHARACTER_SPELLS[10][4] = {
+ { -1, -1, -1, -1 },
+ { 21, -1, -1, -1 },
+ { 22, -1, -1, -1 },
+ { 21, 1, 14, -1 },
+ { 22, 0, 25, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { -1, -1, -1, -1 },
+ { 20, 1, 11, 23 },
+ { 20, 1, -1, -1 }
+};
+
+const char *const COMBAT_DETAILS = "\r\f00\x3""c\v000\t000\x2""Combat%s%s%s\x1";
+
+const char *NOT_ENOUGH_TO_CAST = "\x3""c\v010Not enough %s to Cast %s";
+const char *SPELL_CAST_COMPONENTS[2] = { "Spell Points", "Gems" };
+
+const char *const CAST_SPELL_DETAILS =
+ "\r\x2\x3""c\v122\t013\f37C\fdast\t040\f37N\fdew"
+ "\t067ESC\x1\t000\v000\x3""cCast Spell\n"
+ "\n"
+ "%s\x3l\n"
+ "\n"
+ "Spell Ready:\x3""c\n"
+ "\n"
+ "\f09%s\fd\x2\x3l\n"
+ "\v082Cost\x3r\t000%u/%u\x3l\n"
+ "Cur SP\x3r\t000%u\x1";
+
+const char *const PARTY_FOUND =
+ "\x3""cThe Party Found:\n"
+ "\n"
+ "\x3r\t000%lu Gold\n"
+ "%lu Gems";
+
+const char *const BACKPACKS_FULL_PRESS_KEY =
+ "\v007\f12Warning! BackPacks Full!\fd\n"
+ "Press a Key";
+
+const char *const HIT_A_KEY = "\x3l\v120\t000\x4""077\x3""c\f37Hit a key\xC""d";
+
+const char *const GIVE_TREASURE_FORMATTING =
+ "\x3l\v060\t000\x4""077\n"
+ "\x4""077\n"
+ "\x4""077\n"
+ "\x4""077\n"
+ "\x4""077\n"
+ "\x4""077";
+
+const char *const X_FOUND_Y = "\v060\t000\x3""c%s found: %s";
+
+const char *const ON_WHO = "\x3""c\v009On Who?";
+
+const char *const WHICH_ELEMENT1 =
+ "\r\x3""c\x1Which Element?\x2\v034\t014\f15F\fdire\t044"
+ "\f15E\fdlec\t074\f15C\fdold\t104\f15A\fdcid\x1";
+
+const char *const WHICH_ELEMENT2 =
+ "\r\x3""cWhich Element?', 2, 0Bh, '034\t014\f15F\fdire\t044"
+ "\f15E\fdlec\t074\f15C\fdold\t104\f15A\fdcid\x1";
+
+const char *const DETECT_MONSTERS = "\x3""cDetect Monsters";
+
+const char *const LLOYDS_BEACON =
+ "\r\x3""c\v000\t000\x1Lloyd's Beacon\n"
+ "\n"
+ "Last Location\n"
+ "\n"
+ "%s\x3l\n"
+ "x = %d\x3r\t000y = %d\x3""c\x2\v122\t021\f15S\fdet\t060\f15R\fdeturn\x1";
+
+const char *const HOW_MANY_SQUARES = "\x3""cTeleport\nHow many squares %s (1-9)";
+
+const char *const TOWN_PORTAL =
+ "\x3""cTown Portal\x3l\n"
+ "\n"
+ "\t0101. %s\n"
+ "\t0102. %s\n"
+ "\t0103. %s\n"
+ "\t0104. %s\n"
+ "\t0105. %s\x3""c\n"
+ "\n"
+ "To which Town (1-5)\n"
+ "\n";
+
+const int TOWN_MAP_NUMBERS[2][5] = {
+ { 28, 29, 30, 31, 32 }, { 29, 31, 33, 35, 37 }
+};
+
+const char *const MONSTER_DETAILS =
+ "\x3l\n"
+ "%s\x3""c\t100%s\t140%u\t180%u\x3r\t000%s";
+
+const char *const MONSTER_SPECIAL_ATTACKS[23] = {
+ "None", "Magic", "Fire", "Elec", "Cold", "Poison", "Energy", "Disease",
+ "Insane", "Asleep", "CurseItm", "InLove", "DrnSPts", "Curse", "Paralys",
+ "Uncons", "Confuse", "BrkWpn", "Weak", "Erad", "Age+5", "Dead", "Stone"
+};
+
+const char *const IDENTIFY_MONSTERS =
+ "Name\x3""c\t100HP\t140AC\t177#Atks\x3r\t000Special%s%s%s";
+
+const char *const EVENT_SAMPLES[6] = {
+ "ahh.voc", "whereto.voc", "gulp.voc", "null.voc", "scream.voc", "laff1.voc"
+};
+
+const char *const MOONS_NOT_ALIGNED =
+"\x3""c\xB""012\t000The moons are not aligned. Passage to the %s is unavailable";
+
+const char *const AWARDS_FOR =
+ "\r\x1\fd\x3""c\v000\t000Awards for %s the %s\x3""l\x2\n"
+ "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\x1";
+
+const char *const AWARDS_TEXT =
+ "\r\x2\x3""c\xB""021\t221\xC""37U\xC""dp\t255\xC""37D\xC""down\t289Exit";
+
+const char *const NO_AWARDS = "\x3""cNo Awards";
+
+const char *const WARZONE_BATTLE_MASTER = "The Warzone\n\t125Battle Master";
+
+const char *const WARZONE_MAXED = "What! You again? Go pick on someone your own size!";
+
+const char *const WARZONE_LEVEL = "What level of monsters? (1-10)\n";
+
+const char *const WARZONE_HOW_MANY = "How many monsters? (1-20)\n";
+
+const char *const PICKS_THE_LOCK = "\x3""c\xB""010%s picks the lock!\nPress any key.";
+
+const char *const UNABLE_TO_PICK_LOCK = "\x3""c\v010%s was unable to pick the lock!\nPress any key.";
+
+const char *const CONTROL_PANEL_TEXT =
+ "\x1\xC""00\x3""c\xB""000\t000Control Panel\x3r"
+ "\xB""022\t045\xC""06L\xC""doad:\t124\xC""06E\xC""dfx:"
+ "\xB""041\t045\xC""06S\xC""dave:\t124\xC""06M\xC""dusic:"
+ "\xB""060\t045\xC""06Q\xC""duit:"
+ "\xB""080\t084Mr \xC""06W\xC""dizard:%s\t000\x1";
+const char *const CONTROL_PANEL_BUTTONS =
+ "\x3""c\f11"
+ "\xB""022\t062load\t141%s"
+ "\xB""041\t062save\t141%s"
+ "\xB""060\t062exit"
+ "\xB""079\t102Help\xC""d";
+const char *const ON = "\f15on\f11";
+const char *const OFF = "\f32off\f11";
+const char *const CONFIRM_QUIT = "Are you sure you want to quit?";
+const char *const MR_WIZARD =
+ "Are you sure you want Mr.Wizard's Help ?";
+const char *const NO_LOADING_IN_COMBAT =
+ "No Loading Allowed in Combat!";
+const char *const NO_SAVING_IN_COMBAT =
+ "No Saving Allowed in Combat!";
+const char *const QUICK_FIGHT_TEXT = "\r\fd\x3""c\v000\t000QuickFight Options\n\n"
+ "%s\x3l\n\n"
+ "Current\x3r\n"
+ "\t000%s\x2\x3""c\v122\t021\f37N\f04ext\t060Exit\x1";
+const char *const QUICK_FIGHT_OPTIONS[4] = { "Attack", "Cast", "Block", "Run" };
+
+const char *const WORLD_END_TEXT[9] = {
+ "\n\n\n\n\n\n\n"
+ "Congratulations Adventurers!\n\n"
+ "Let the unification ceremony begin!",
+ "And so the call went out to the people throughout the lands of Xeen"
+ " that the prophecy was nearing completion.",
+ "They came in great numbers to witness the momentous occasion.",
+ "\xB""026The Dragon Pharoah presided over the ceremony.",
+ "\xB""026Queen Kalindra presented the Cube of Power.",
+ "\xB""026Prince Roland presented the Xeen Sceptre.",
+ "\xB""026Together, they placed the Cube of Power...",
+ "\xB""026and the Sceptre, onto the Altar of Joining.",
+ "With the prophecy complete, the two sides of Xeen were united as one",
+};
+
+const char *const WORLD_CONGRATULATIONS =
+ "\x3""cCongratulations\n\n"
+ "Your Final Score is:\n\n"
+ "%010lu\n"
+ "\x3l\n"
+ "Please send this score to the Ancient's Headquarters where "
+ "you'll be added to the Hall of Legends!\n\n"
+ "Ancient's Headquarters\n"
+ "New World Computing, Inc.\n"
+ "P.O. Box 4302\n"
+ "Hollywood, CA 90078";
+const char *const WORLD_CONGRATULATIONS2 =
+ "\n\n\n\n\n\n"
+ "But wait... there's more!\n"
+ "\n\n"
+ "Include the message\n"
+ "\"%s\"\n"
+ "with your final score and receive a special bonus.";
+const char *const CLOUDS_CONGRATULATIONS1 =
+ "\xC""23\x3l"
+ "\xB""000\t000Please send this score to the Ancient's Headquarters "
+ "where you'll be added to the Hall of Legends!\xC""33\x3""c"
+ "\xB""070\t000Press a Key";
+const char *const CLOUDS_CONGRATULATIONS2 =
+ "\xC""23\x3l"
+ "\xB""000\t000Ancient's Headquarters\n"
+ "New World Computing, Inc.\n"
+ "P.O. Box 4302\n"
+ "Hollywood, CA 90078-4302\xC""33\x3""c"
+ "\xB""070\t000Press a Key";
+const char *const GOOBER[3] = {
+ "", "I am a Goober!", "I am a Super Goober!"
+};
+
+const char *const MUSIC_FILES1[5] = {
+ "outdoors.m", "town.m", "cavern.m", "dungeon.m", "castle.m"
+};
+
+const char *const MUSIC_FILES2[6][7] = {
+ { "outday1.m", "outday2.m", "outday4.m", "outnght1.m",
+ "outnght2.m", "outnght4.m", "daydesrt.m" },
+ { "townday1.m", "twnwlk.m", "newbrigh.m", "twnnitea.m",
+ "twnniteb.m", "twnwlk.m", "townday1.m" },
+ { "cavern1.m", "cavern2.m", "cavern3a.m", "cavern1.m",
+ "cavern2.m", "cavern3a.m", "cavern1.m" },
+ { "dngon1.m", "dngon2.m", "dngon3.m", "dngon1.m",
+ "dngon2.m", "dngon3.m", "dngon1.m" },
+ { "cstl1rev.m", "cstl2rev.m", "cstl3rev.m", "cstl1rev.m",
+ "cstl2rev.m", "cstl3rev.m", "cstl1rev.m" },
+ { "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m" }
+};
+
+void writeConstants(CCArchive &cc) {
+ Common::MemFile file;
+ file.syncString(CREDITS);
+ file.syncString(OPTIONS_TITLE);
+ file.syncString(THE_PARTY_NEEDS_REST);
+ file.syncString(WHO_WILL);
+ file.syncString(HOW_MUCH);
+ file.syncString(WHATS_THE_PASSWORD);
+ file.syncString(IN_NO_CONDITION);
+ file.syncString(NOTHING_HERE);
+ file.syncStrings(TERRAIN_TYPES, 6);
+ file.syncStrings(OUTDOORS_WALL_TYPES, 16);
+ file.syncStrings(SURFACE_NAMES, 16);
+ file.syncStrings(WHO_ACTIONS, 32);
+ file.syncStrings(WHO_WILL_ACTIONS, 4);
+ file.syncBytes2D((const byte *)SYMBOLS, 20, 64);
+ file.syncBytes2D((const byte *)TEXT_COLORS, 40, 4);
+ file.syncStrings(DIRECTION_TEXT_UPPER, 4);
+ file.syncStrings(DIRECTION_TEXT, 4);
+ file.syncStrings(RACE_NAMES, 5);
+ file.syncNumbers(RACE_HP_BONUSES, 5);
+ file.syncNumbers2D((const int *)RACE_SP_BONUSES, 5, 2);
+ file.syncStrings(CLASS_NAMES, 11);
+ file.syncNumbers(CLASS_EXP_LEVELS, 10);
+ file.syncStrings(ALIGNMENT_NAMES, 3);
+ file.syncStrings(SEX_NAMES, 2);
+ file.syncStrings(SKILL_NAMES, 18);
+ file.syncStrings(CONDITION_NAMES, 17);
+ file.syncNumbers(CONDITION_COLORS, 17);
+ file.syncString(GOOD);
+ file.syncString(BLESSED);
+ file.syncString(POWER_SHIELD);
+ file.syncString(HOLY_BONUS);
+ file.syncString(HEROISM);
+ file.syncString(IN_PARTY);
+ file.syncString(PARTY_DETAILS);
+ file.syncString(PARTY_DIALOG_TEXT);
+ file.syncNumbers(FACE_CONDITION_FRAMES, 17);
+ file.syncNumbers(CHAR_FACES_X, 6);
+ file.syncNumbers(HP_BARS_X, 6);
+ file.syncString(NO_ONE_TO_ADVENTURE_WITH);
+ file.syncBytes2D((const byte *)DARKNESS_XLAT, 3, 256);
+ file.syncString(YOUR_ROSTER_IS_FULL);
+ file.syncString(PLEASE_WAIT);
+ file.syncString(OOPS);
+ file.syncNumbers2D((const int *)SCREEN_POSITIONING_X, 4, 48);
+ file.syncNumbers2D((const int *)SCREEN_POSITIONING_Y, 4, 48);
+ file.syncNumbers(MONSTER_GRID_BITMASK, 12);
+ file.syncNumbers2D((const int *)INDOOR_OBJECT_X, 2, 12);
+ file.syncNumbers2D((const int *)MAP_OBJECT_Y, 2, 12);
+ file.syncNumbers(INDOOR_MONSTERS_Y, 4);
+ file.syncNumbers2D((const int *)OUTDOOR_OBJECT_X, 2, 12);
+ file.syncNumbers(OUTDOOR_MONSTER_INDEXES, 26);
+ file.syncNumbers(OUTDOOR_MONSTERS_Y, 26);
+ file.syncNumbers2D((const int *)DIRECTION_ANIM_POSITIONS, 4, 4);
+ file.syncBytes2D((const byte *)WALL_SHIFTS, 4, 48);
+ file.syncNumbers(DRAW_NUMBERS, 25);
+ file.syncNumbers2D((const int *)DRAW_FRAMES, 25, 2);
+ file.syncNumbers(COMBAT_FLOAT_X, 8);
+ file.syncNumbers(COMBAT_FLOAT_Y, 8);
+ file.syncNumbers2D((const int *)MONSTER_EFFECT_FLAGS, 15, 8);
+ file.syncNumbers2D((const int *)SPELLS_ALLOWED, 3, 40);
+ file.syncNumbers(BASE_HP_BY_CLASS, 10);
+ file.syncNumbers(AGE_RANGES, 10);
+ file.syncNumbers2D((const int *)AGE_RANGES_ADJUST, 2, 10);
+ file.syncNumbers(STAT_VALUES, 24);
+ file.syncNumbers(STAT_BONUSES, 24);
+ file.syncNumbers(ELEMENTAL_CATEGORIES, 6);
+ file.syncNumbers(ATTRIBUTE_CATEGORIES, 10);
+ file.syncNumbers(ATTRIBUTE_BONUSES, 72);
+ file.syncNumbers(ELEMENTAL_RESISTENCES, 37);
+ file.syncNumbers(ELEMENTAL_DAMAGE, 37);
+ file.syncNumbers(WEAPON_DAMAGE_BASE, 35);
+ file.syncNumbers(WEAPON_DAMAGE_MULTIPLIER, 35);
+ file.syncNumbers(METAL_DAMAGE, 22);
+ file.syncNumbers(METAL_DAMAGE_PERCENT, 22);
+ file.syncNumbers(METAL_LAC, 9);
+ file.syncNumbers(ARMOR_STRENGTHS, 14);
+ file.syncNumbers(MAKE_ITEM_ARR1, 6);
+ file.syncNumbers3D((const int *)MAKE_ITEM_ARR2, 6, 7, 2);
+ file.syncNumbers3D((const int *)MAKE_ITEM_ARR3, 10, 7, 2);
+ file.syncNumbers3D((const int *)MAKE_ITEM_ARR4, 2, 7, 2);
+ file.syncNumbers2D((const int *)MAKE_ITEM_ARR5, 8, 2);
+ file.syncNumbers(OUTDOOR_DRAWSTRUCT_INDEXES, 44);
+ file.syncNumbers2D((const int *)TOWN_MAXES, 2, 11);
+ file.syncStrings2D((const char *const *)TOWN_ACTION_MUSIC, 2, 7);
+ file.syncStrings(TOWN_ACTION_SHAPES, 7);
+ file.syncNumbers2D((const int *)TOWN_ACTION_FILES, 2, 7);
+ file.syncString(BANK_TEXT);
+ file.syncString(BLACKSMITH_TEXT);
+ file.syncString(GUILD_NOT_MEMBER_TEXT);
+ file.syncString(GUILD_TEXT);
+ file.syncString(TAVERN_TEXT);
+ file.syncString(GOOD_STUFF);
+ file.syncString(HAVE_A_DRINK);
+ file.syncString(YOURE_DRUNK);
+ file.syncNumbers4D((const int *)TAVERN_EXIT_LIST, 2, 6, 5, 2);
+ file.syncString(FOOD_AND_DRINK);
+ file.syncString(TEMPLE_TEXT);
+ file.syncString(EXPERIENCE_FOR_LEVEL);
+ file.syncString(LEARNED_ALL);
+ file.syncString(ELIGIBLE_FOR_LEVEL);
+ file.syncString(TRAINING_TEXT);
+ file.syncString(GOLD_GEMS);
+ file.syncString(GOLD_GEMS_2);
+ file.syncString(DEPOSIT_WITHDRAWL[2]);
+ file.syncString(NOT_ENOUGH_X_IN_THE_Y);
+ file.syncString(NO_X_IN_THE_Y);
+ file.syncString(STAT_NAMES[16]);
+ file.syncString(CONSUMABLE_NAMES[4]);
+ file.syncString(WHERE_NAMES[2]);
+ file.syncString(AMOUNT);
+ file.syncString(FOOD_PACKS_FULL);
+ file.syncString(BUY_SPELLS);
+ file.syncString(GUILD_OPTIONS);
+ file.syncNumbers((const int *)MISC_SPELL_INDEX, 74);
+ file.syncNumbers((const int *)SPELL_COSTS, 77);
+ file.syncNumbers2D((const int *)CLOUDS_SPELL_OFFSETS, 5, 20);
+ file.syncNumbers2D((const int *)DARK_SPELL_OFFSETS, 3, 39);
+ file.syncNumbers2D((const int *)DARK_SPELL_RANGES, 12, 2);
+ file.syncNumbers((const int *)SPELL_GEM_COST, 77);
+ file.syncString(NOT_A_SPELL_CASTER);
+ file.syncString(SPELLS_FOR);
+ file.syncString(SPELL_LINES_0_TO_9);
+ file.syncString(SPELLS_DIALOG_SPELLS);
+ file.syncString(SPELL_PTS);
+ file.syncString(GOLD);
+ file.syncString(SPELLS_PRESS_A_KEY);
+ file.syncString(SPELLS_PURCHASE);
+ file.syncString(MAP_TEXT);
+ file.syncString(LIGHT_COUNT_TEXT);
+ file.syncString(FIRE_RESISTENCE_TEXT);
+ file.syncString(ELECRICITY_RESISTENCE_TEXT);
+ file.syncString(COLD_RESISTENCE_TEXT);
+ file.syncString(POISON_RESISTENCE_TEXT);
+ file.syncString(CLAIRVOYANCE_TEXT);
+ file.syncString(LEVITATE_TEXT);
+ file.syncString(WALK_ON_WATER_TEXT);
+ file.syncString(GAME_INFORMATION);
+ file.syncString(WORLD_GAME_TEXT);
+ file.syncString(DARKSIDE_GAME_TEXT);
+ file.syncString(CLOUDS_GAME_TEXT);
+ file.syncString(SWORDS_GAME_TEXT);
+ file.syncStrings(WEEK_DAY_STRINGS, 10);
+ file.syncString(CHARACTER_DETAILS);
+ file.syncString(PARTY_GOLD);
+ file.syncString(PLUS_14);
+ file.syncString(CHARACTER_TEMPLATE);
+ file.syncString(EXCHANGING_IN_COMBAT);
+ file.syncString(CURRENT_MAXIMUM_RATING_TEXT);
+ file.syncString(CURRENT_MAXIMUM_TEXT);
+ file.syncStrings(RATING_TEXT, 24);
+ file.syncString(AGE_TEXT);
+ file.syncString(LEVEL_TEXT);
+ file.syncString(RESISTENCES_TEXT);
+ file.syncString(NONE);
+ file.syncString(EXPERIENCE_TEXT);
+ file.syncString(ELIGIBLE);
+ file.syncString(IN_PARTY_IN_BANK);
+ file.syncString(FOOD_TEXT);
+ file.syncString(EXCHANGE_WITH_WHOM);
+ file.syncString(QUICK_REF_LINE);
+ file.syncString(QUICK_REFERENCE);
+ file.syncNumbers2D((const int *)BLACKSMITH_MAP_IDS, 2, 4);
+ file.syncString(ITEMS_DIALOG_TEXT1);
+ file.syncString(ITEMS_DIALOG_TEXT2);
+ file.syncString(ITEMS_DIALOG_LINE1);
+ file.syncString(ITEMS_DIALOG_LINE2);
+ file.syncString(BTN_BUY);
+ file.syncString(BTN_SELL);
+ file.syncString(BTN_IDENTIFY);
+ file.syncString(BTN_FIX);
+ file.syncString(BTN_USE);
+ file.syncString(BTN_EQUIP);
+ file.syncString(BTN_REMOVE);
+ file.syncString(BTN_DISCARD);
+ file.syncString(BTN_QUEST);
+ file.syncString(BTN_ENCHANT);
+ file.syncString(BTN_RECHARGE);
+ file.syncString(BTN_GOLD);
+ file.syncString(ITEM_BROKEN);
+ file.syncString(ITEM_CURSED);
+ file.syncStrings(BONUS_NAMES, 7);
+ file.syncStrings(WEAPON_NAMES, 35);
+ file.syncStrings(ARMOR_NAMES, 14);
+ file.syncStrings(ACCESSORY_NAMES, 11);
+ file.syncStrings(MISC_NAMES, 22);
+ file.syncStrings(ELEMENTAL_NAMES, 6);
+ file.syncStrings(ATTRIBUTE_NAMES, 10);
+ file.syncStrings(EFFECTIVENESS_NAMES, 7);
+ file.syncStrings(QUEST_ITEM_NAMES, 85);
+ file.syncNumbers((const int *)WEAPON_BASE_COSTS, 35);
+ file.syncNumbers((const int *)ARMOR_BASE_COSTS, 14);
+ file.syncNumbers((const int *)ACCESSORY_BASE_COSTS, 11);
+ file.syncNumbers((const int *)MISC_MATERIAL_COSTS, 22);
+ file.syncNumbers((const int *)MISC_BASE_COSTS, 76);
+ file.syncNumbers((const int *)METAL_BASE_MULTIPLIERS, 22);
+ file.syncNumbers((const int *)ITEM_SKILL_DIVISORS, 4);
+ file.syncNumbers((const int *)RESTRICTION_OFFSETS, 4);
+ file.syncNumbers((const int *)ITEM_RESTRICTIONS, 86);
+ file.syncString(NOT_PROFICIENT);
+ file.syncString(NO_ITEMS_AVAILABLE);
+ file.syncStrings(CATEGORY_NAMES, 4);
+ file.syncString(X_FOR_THE_Y);
+ file.syncString(X_FOR_Y);
+ file.syncString(X_FOR_Y_GOLD);
+ file.syncString(FMT_CHARGES);
+ file.syncString(AVAILABLE_GOLD_COST);
+ file.syncString(CHARGES);
+ file.syncString(COST);
+ file.syncStrings(ITEM_ACTIONS, 7);
+ file.syncString(WHICH_ITEM);
+ file.syncString(WHATS_YOUR_HURRY);
+ file.syncString(USE_ITEM_IN_COMBAT);
+ file.syncString(NO_SPECIAL_ABILITIES);
+ file.syncString(CANT_CAST_WHILE_ENGAGED);
+ file.syncString(EQUIPPED_ALL_YOU_CAN);
+ file.syncString(REMOVE_X_TO_EQUIP_Y);
+ file.syncString(RING);
+ file.syncString(MEDAL);
+ file.syncString(CANNOT_REMOVE_CURSED_ITEM);
+ file.syncString(CANNOT_DISCARD_CURSED_ITEM);
+ file.syncString(PERMANENTLY_DISCARD);
+ file.syncString(BACKPACK_IS_FULL);
+ file.syncStrings(CATEGORY_BACKPACK_IS_FULL, 4);
+ file.syncString(BUY_X_FOR_Y_GOLD);
+ file.syncString(SELL_X_FOR_Y_GOLD);
+ file.syncString(NO_NEED_OF_THIS);
+ file.syncString(NOT_RECHARGABLE);
+ file.syncString(SPELL_FAILED);
+ file.syncString(NOT_ENCHANTABLE);
+ file.syncString(ITEM_NOT_BROKEN);
+ file.syncStrings(FIX_IDENTIFY, 2);
+ file.syncString(FIX_IDENTIFY_GOLD);
+ file.syncString(IDENTIFY_ITEM_MSG);
+ file.syncString(ITEM_DETAILS);
+ file.syncString(ALL);
+ file.syncString(FIELD_NONE);
+ file.syncString(DAMAGE_X_TO_Y);
+ file.syncString(ELEMENTAL_XY_DAMAGE);
+ file.syncString(ATTR_XY_BONUS);
+ file.syncString(EFFECTIVE_AGAINST);
+ file.syncString(QUESTS_DIALOG_TEXT);
+ file.syncString(CLOUDS_OF_XEEN_LINE);
+ file.syncString(DARKSIDE_OF_XEEN_LINE);
+ file.syncString(NO_QUEST_ITEMS);
+ file.syncString(NO_CURRENT_QUESTS);
+ file.syncString(NO_AUTO_NOTES);
+ file.syncString(QUEST_ITEMS_DATA);
+ file.syncString(CURRENT_QUESTS_DATA);
+ file.syncString(AUTO_NOTES_DATA);
+ file.syncString(REST_COMPLETE);
+ file.syncString(PARTY_IS_STARVING);
+ file.syncString(HIT_SPELL_POINTS_RESTORED);
+ file.syncString(TOO_DANGEROUS_TO_REST);
+ file.syncString(SOME_CHARS_MAY_DIE);
+ file.syncString(CANT_DISMISS_LAST_CHAR);
+ file.syncStrings(REMOVE_DELETE, 2);
+ file.syncString(REMOVE_OR_DELETE_WHICH);
+ file.syncString(YOUR_PARTY_IS_FULL);
+ file.syncString(HAS_SLAYER_SWORD);
+ file.syncString(SURE_TO_DELETE_CHAR);
+ file.syncString(CREATE_CHAR_DETAILS);
+ file.syncString(NEW_CHAR_STATS);
+ file.syncString(NAME_FOR_NEW_CHARACTER);
+ file.syncString(SELECT_CLASS_BEFORE_SAVING);
+ file.syncString(EXCHANGE_ATTR_WITH);
+ file.syncNumbers((const int *)NEW_CHAR_SKILLS, 10);
+ file.syncNumbers((const int *)NEW_CHAR_SKILLS_LEN, 10);
+ file.syncNumbers((const int *)NEW_CHAR_RACE_SKILLS, 10);
+ file.syncNumbers((const int *)RACE_MAGIC_RESISTENCES, 5);
+ file.syncNumbers((const int *)RACE_FIRE_RESISTENCES, 5);
+ file.syncNumbers((const int *)RACE_ELECTRIC_RESISTENCES, 5);
+ file.syncNumbers((const int *)RACE_COLD_RESISTENCES, 5);
+ file.syncNumbers((const int *)RACE_ENERGY_RESISTENCES, 5);
+ file.syncNumbers((const int *)RACE_POISON_RESISTENCES, 5);
+ file.syncNumbers2D((const int *)NEW_CHARACTER_SPELLS, 10, 4);
+ file.syncString(COMBAT_DETAILS);
+ file.syncString(NOT_ENOUGH_TO_CAST);
+ file.syncStrings(SPELL_CAST_COMPONENTS, 2);
+ file.syncString(CAST_SPELL_DETAILS);
+ file.syncString(PARTY_FOUND);
+ file.syncString(BACKPACKS_FULL_PRESS_KEY);
+ file.syncString(HIT_A_KEY);
+ file.syncString(GIVE_TREASURE_FORMATTING);
+ file.syncString(X_FOUND_Y);
+ file.syncString(ON_WHO);
+ file.syncString(WHICH_ELEMENT1);
+ file.syncString(WHICH_ELEMENT2);
+ file.syncString(DETECT_MONSTERS);
+ file.syncString(LLOYDS_BEACON);
+ file.syncString(HOW_MANY_SQUARES);
+ file.syncString(TOWN_PORTAL);
+ file.syncNumbers2D((const int *)TOWN_MAP_NUMBERS, 2, 5);
+ file.syncString(MONSTER_DETAILS);
+ file.syncStrings(MONSTER_SPECIAL_ATTACKS, 23);
+ file.syncString(IDENTIFY_MONSTERS);
+ file.syncStrings(EVENT_SAMPLES, 6);
+ file.syncString(MOONS_NOT_ALIGNED);
+ file.syncString(AWARDS_FOR);
+ file.syncString(AWARDS_TEXT);
+ file.syncString(NO_AWARDS);
+ file.syncString(WARZONE_BATTLE_MASTER);
+ file.syncString(WARZONE_MAXED);
+ file.syncString(WARZONE_LEVEL);
+ file.syncString(WARZONE_HOW_MANY);
+ file.syncString(PICKS_THE_LOCK);
+ file.syncString(UNABLE_TO_PICK_LOCK);
+ file.syncString(CONTROL_PANEL_TEXT);
+ file.syncString(CONTROL_PANEL_BUTTONS);
+ file.syncString(ON);
+ file.syncString(OFF);
+ file.syncString(CONFIRM_QUIT);
+ file.syncString(MR_WIZARD);
+ file.syncString(NO_LOADING_IN_COMBAT);
+ file.syncString(NO_SAVING_IN_COMBAT);
+ file.syncString(QUICK_FIGHT_TEXT);
+ file.syncStrings(QUICK_FIGHT_OPTIONS, 4);
+ file.syncStrings(WORLD_END_TEXT, 9);
+ file.syncString(WORLD_CONGRATULATIONS);
+ file.syncString(WORLD_CONGRATULATIONS2);
+ file.syncString(CLOUDS_CONGRATULATIONS1);
+ file.syncString(CLOUDS_CONGRATULATIONS2);
+ file.syncStrings(GOOBER, 3);
+ file.syncStrings(MUSIC_FILES1, 5);
+ file.syncStrings2D((const char *const *)MUSIC_FILES2, 6, 7);
+
+ cc.add("CONSTANTS", file);
+}
diff --git a/devtools/create_xeen/constants.h b/devtools/create_xeen/constants.h
new file mode 100644
index 0000000..32177e8
--- /dev/null
+++ b/devtools/create_xeen/constants.h
@@ -0,0 +1,31 @@
+/* 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 CONSTANTS_H
+#define CONSTANTS_H
+
+#include "common/scummsys.h"
+#include "cc.h"
+
+extern void writeConstants(CCArchive &cc);
+
+#endif
diff --git a/devtools/create_xeen/create_xeen.cpp b/devtools/create_xeen/create_xeen.cpp
new file mode 100644
index 0000000..94af74f
--- /dev/null
+++ b/devtools/create_xeen/create_xeen.cpp
@@ -0,0 +1,65 @@
+/* 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.
+ *
+ */
+
+ // Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cc.h"
+#include "file.h"
+#include "constants.h"
+
+#define VERSION_NUMBER 1
+
+Common::File outputFile;
+
+void NORETURN_PRE error(const char *s, ...) {
+ printf("%s\n", s);
+ exit(1);
+}
+
+void writeVersion(CCArchive &cc) {
+ Common::MemFile f;
+ f.writeLong(VERSION_NUMBER);
+ cc.add("VERSION", f);
+}
+
+int main(int argc, char *argv[]) {
+ if (!outputFile.open(argc == 1 ? "xeen.ccs" : argv[1], Common::kFileWriteMode)) {
+ error("Could not open input file");
+ }
+
+ CCArchive cc(outputFile);
+ writeVersion(cc);
+ writeConstants(cc);
+
+ cc.close();
+ return 0;
+}
diff --git a/devtools/create_xeen/file.h b/devtools/create_xeen/file.h
new file mode 100644
index 0000000..8fdb9b4
--- /dev/null
+++ b/devtools/create_xeen/file.h
@@ -0,0 +1,264 @@
+/* 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 __FILE_H__
+#define __FILE_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+
+namespace Common {
+
+enum AccessMode {
+ kFileReadMode = 1,
+ kFileWriteMode = 2
+};
+
+class Stream {
+public:
+ Stream() {}
+ virtual ~Stream() {}
+
+ virtual int seek(int offset, int whence = SEEK_SET) = 0;
+ virtual long read(void *buffer, size_t len) = 0;
+ virtual void write(const void *buffer, size_t len) = 0;
+ virtual uint pos() const = 0;
+ virtual uint size() const = 0;
+ virtual bool eof() const = 0;
+
+ void skip(int offset) {
+ seek(offset, SEEK_CUR);
+ }
+ void write(Stream &src, size_t len) {
+ for (size_t idx = 0; idx < len; ++idx)
+ writeByte(src.readByte());
+ }
+ byte readByte() {
+ byte v;
+ read(&v, sizeof(byte));
+ return v;
+ }
+ uint16 readWord() {
+ uint16 v;
+ read(&v, sizeof(uint16));
+ return FROM_LE_16(v);
+ }
+ uint readLong() {
+ uint v;
+ read(&v, sizeof(uint));
+ return FROM_LE_32(v);
+ }
+
+ uint readUint16BE() {
+ uint16 v;
+ read(&v, sizeof(uint16));
+ return FROM_BE_16(v);
+ }
+ uint readUint16LE() {
+ uint16 v;
+ read(&v, sizeof(uint16));
+ return FROM_LE_16(v);
+ }
+ uint readUint32BE() {
+ uint32 v;
+ read(&v, sizeof(uint32));
+ return FROM_BE_32(v);
+ }
+ uint readUint32LE() {
+ uint32 v;
+ read(&v, sizeof(uint32));
+ return FROM_LE_32(v);
+ }
+
+ void writeByte(byte v) {
+ write(&v, sizeof(byte));
+ }
+ void writeByte(byte v, int len) {
+ byte *b = new byte[len];
+ memset(b, v, len);
+ write(b, len);
+ delete[] b;
+ }
+ void writeWord(uint16 v) {
+ uint16 vTemp = TO_LE_16(v);
+ write(&vTemp, sizeof(uint16));
+ }
+ void writeLong(uint v) {
+ uint vTemp = TO_LE_32(v);
+ write(&vTemp, sizeof(uint));
+ }
+ void writeString(const char *msg) {
+ if (!msg) {
+ writeByte(0);
+ }
+ else {
+ do {
+ writeByte(*msg);
+ } while (*msg++);
+ }
+ }
+};
+
+class File : public Stream {
+private:
+ ::FILE *_f;
+public:
+ File() : _f(nullptr) {}
+ virtual ~File() { close(); }
+
+ bool open(const char *filename, AccessMode mode = kFileReadMode) {
+ _f = fopen(filename, (mode == kFileReadMode) ? "rb" : "wb+");
+ return (_f != NULL);
+ }
+ void close() {
+ if (_f)
+ fclose(_f);
+ _f = nullptr;
+ }
+
+ virtual int seek(int offset, int whence = SEEK_SET) {
+ return fseek(_f, offset, whence);
+ }
+ virtual long read(void *buffer, size_t len) {
+ return fread(buffer, 1, len, _f);
+ }
+ virtual void write(const void *buffer, size_t len) {
+ assert(_f);
+ fwrite(buffer, 1, len, _f);
+ }
+ virtual uint pos() const {
+ return ftell(_f);
+ }
+ virtual uint size() const {
+ uint currentPos = pos();
+ fseek(_f, 0, SEEK_END);
+ uint result = pos();
+ fseek(_f, currentPos, SEEK_SET);
+ return result;
+ }
+ virtual bool eof() const {
+ return feof(_f) != 0;
+ }
+};
+
+#define MAX_MEM_SIZE 65536
+
+class MemFile : public Stream {
+private:
+ byte _data[MAX_MEM_SIZE];
+ size_t _size, _offset;
+public:
+ MemFile() : _size(0), _offset(0) {
+ memset(_data, 0, MAX_MEM_SIZE);
+ }
+ virtual ~MemFile() {}
+
+ bool open() {
+ memset(_data, 0, MAX_MEM_SIZE);
+ _size = _offset = 0;
+ }
+ void close() {
+ }
+
+ virtual int seek(int offset, int whence = SEEK_SET) {
+ switch (whence) {
+ case SEEK_SET: _offset = whence; break;
+ case SEEK_CUR: _offset += whence; break;
+ case SEEK_END: _offset = _size + whence; break;
+ }
+
+ return _offset;
+ }
+ virtual long read(void *buffer, size_t len) {
+ len = MAX(len, _size - _offset);
+ memcpy(buffer, &_data[_offset], len);
+ return len;
+ }
+ virtual void write(const void *buffer, size_t len) {
+ assert(len <= (MAX_MEM_SIZE - _offset));
+ memcpy(&_data[_offset], buffer, len);
+ _offset += len;
+ _size = MAX(_offset, _size);
+ }
+ virtual uint pos() const {
+ return _offset;
+ }
+ virtual uint size() const {
+ return _size;
+ }
+ virtual bool eof() const {
+ return _offset >= _size;
+ }
+
+ const byte *getData() const { return _data; }
+
+ void syncString(const char *str) {
+ write(str, strlen(str) + 1);
+ }
+ void syncStrings(const char *const *str, int count) {
+ writeLong(MKTAG(count, 0, 0, 0));
+ for (int idx = 0; idx < count; ++idx, ++str)
+ writeString(*str);
+ }
+ void syncStrings2D(const char *const *str, int count1, int count2) {
+ writeLong(MKTAG(count1, count2, 0, 0));
+ for (int idx = 0; idx < count1 * count2; ++idx, ++str)
+ writeString(*str);
+ }
+ void syncNumber(const int val) {
+ writeLong(val);
+ }
+ void syncNumbers(const int *vals, int count) {
+ writeLong(MKTAG(count, 0, 0, 0));
+ for (int idx = 0; idx < count; ++idx, ++vals)
+ writeLong(*vals);
+ }
+ void syncNumbers2D(const int *vals, int count1, int count2) {
+ writeLong(MKTAG(count1, count2, 0, 0));
+ for (int idx = 0; idx < count1 * count2; ++idx, ++vals)
+ writeLong(*vals);
+ }
+ void syncNumbers3D(const int *vals, int count1, int count2, int count3) {
+ writeLong(MKTAG(count1, count2, count3, 0));
+ for (int idx = 0; idx < count1 * count2 * count3; ++idx, ++vals)
+ writeLong(*vals);
+ }
+ void syncNumbers4D(const int *vals, int count1, int count2, int count3, int count4) {
+ writeLong(MKTAG(count1, count2, count3, count4));
+ for (int idx = 0; idx < count1 * count2 * count3 * count4; ++idx, ++vals)
+ writeLong(*vals);
+ }
+ void syncBytes2D(const byte *vals, int count1, int count2) {
+ writeLong(MKTAG(count1, count2, 0, 0));
+ write(vals, count1 * count2);
+ }
+};
+
+} // End of namespace Common
+
+#endif
diff --git a/devtools/create_xeen/hash-str.h b/devtools/create_xeen/hash-str.h
new file mode 100644
index 0000000..b9f6d50
--- /dev/null
+++ b/devtools/create_xeen/hash-str.h
@@ -0,0 +1,86 @@
+/* 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 COMMON_HASH_STR_H
+#define COMMON_HASH_STR_H
+
+#include "hashmap.h"
+#include "str.h"
+
+namespace Common {
+
+uint hashit(const char *str);
+uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string
+inline uint hashit(const String &str) { return hashit(str.c_str()); }
+inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); }
+
+
+// FIXME: The following functors obviously are not consistently named
+
+struct CaseSensitiveString_EqualTo {
+ bool operator()(const String& x, const String& y) const { return x.equals(y); }
+};
+
+struct CaseSensitiveString_Hash {
+ uint operator()(const String& x) const { return hashit(x.c_str()); }
+};
+
+
+struct IgnoreCase_EqualTo {
+ bool operator()(const String& x, const String& y) const { return x.equalsIgnoreCase(y); }
+};
+
+struct IgnoreCase_Hash {
+ uint operator()(const String& x) const { return hashit_lower(x.c_str()); }
+};
+
+
+
+// Specalization of the Hash functor for String objects.
+// We do case sensitve hashing here, because that is what
+// the default EqualTo is compatible with. If one wants to use
+// case insensitve hashing, then only because one wants to use
+// IgnoreCase_EqualTo, and then one has to specify a custom
+// hash anyway.
+template<>
+struct Hash<String> {
+ uint operator()(const String& s) const {
+ return hashit(s.c_str());
+ }
+};
+
+template<>
+struct Hash<const char *> {
+ uint operator()(const char *s) const {
+ return hashit(s);
+ }
+};
+
+// String map -- by default case insensitive
+typedef HashMap<String, String, IgnoreCase_Hash, IgnoreCase_EqualTo> StringMap;
+
+
+
+} // End of namespace Common
+
+
+#endif
diff --git a/devtools/create_xeen/hashmap.cpp b/devtools/create_xeen/hashmap.cpp
new file mode 100644
index 0000000..9984099
--- /dev/null
+++ b/devtools/create_xeen/hashmap.cpp
@@ -0,0 +1,109 @@
+/* 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.
+ *
+ */
+
+// The hash map (associative array) implementation in this file is
+// based on the PyDict implementation of CPython. The erase() method
+// is based on example code in the Wikipedia article on Hash tables.
+
+#include "common/hashmap.h"
+
+namespace Common {
+
+// Hash function for strings, taken from CPython.
+uint hashit(const char *p) {
+ uint hash = *p << 7;
+ byte c;
+ int size = 0;
+ while ((c = *p++)) {
+ hash = (1000003 * hash) ^ c;
+ size++;
+ }
+ return hash ^ size;
+}
+
+// Like hashit, but converts every char to lowercase before hashing.
+uint hashit_lower(const char *p) {
+ uint hash = tolower(*p) << 7;
+ byte c;
+ int size = 0;
+ while ((c = *p++)) {
+ hash = (1000003 * hash) ^ tolower(c);
+ size++;
+ }
+ return hash ^ size;
+}
+
+#ifdef DEBUG_HASH_COLLISIONS
+static double
+ g_collisions = 0,
+ g_dummyHits = 0,
+ g_lookups = 0,
+ g_collPerLook = 0,
+ g_capacity = 0,
+ g_size = 0;
+static int g_max_capacity = 0, g_max_size = 0;
+static int g_totalHashmaps = 0;
+static int g_stats[4] = {0,0,0,0};
+
+void updateHashCollisionStats(int collisions, int dummyHits, int lookups, int arrsize, int nele) {
+ g_collisions += collisions;
+ g_lookups += lookups;
+ g_dummyHits += dummyHits;
+ if (lookups)
+ g_collPerLook += (double)collisions / (double)lookups;
+ g_capacity += arrsize;
+ g_size += nele;
+ g_totalHashmaps++;
+
+ if (3*nele <= 2*8)
+ g_stats[0]++;
+ if (3*nele <= 2*16)
+ g_stats[1]++;
+ if (3*nele <= 2*32)
+ g_stats[2]++;
+ if (3*nele <= 2*64)
+ g_stats[3]++;
+
+ g_max_capacity = MAX(g_max_capacity, arrsize);
+ g_max_size = MAX(g_max_size, nele);
+
+ debug("%d hashmaps: colls %.1f; dummies hit %.1f, lookups %.1f; ratio %.3f%%; size %f (max: %d); capacity %f (max: %d)",
+ g_totalHashmaps,
+ g_collisions / g_totalHashmaps,
+ g_dummyHits / g_totalHashmaps,
+ g_lookups / g_totalHashmaps,
+ 100 * g_collPerLook / g_totalHashmaps,
+ g_size / g_totalHashmaps, g_max_size,
+ g_capacity / g_totalHashmaps, g_max_capacity);
+ debug(" %d less than %d; %d less than %d; %d less than %d; %d less than %d",
+ g_stats[0], 2*8/3,
+ g_stats[1],2*16/3,
+ g_stats[2],2*32/3,
+ g_stats[3],2*64/3);
+
+ // TODO:
+ // * Should record the maximal size of the map during its lifetime, not that at its death
+ // * Should do some statistics: how many maps are less than 2/3*8, 2/3*16, 2/3*32, ...
+}
+#endif
+
+} // End of namespace Common
diff --git a/devtools/create_xeen/hashmap.h b/devtools/create_xeen/hashmap.h
new file mode 100644
index 0000000..c8691ae
--- /dev/null
+++ b/devtools/create_xeen/hashmap.h
@@ -0,0 +1,637 @@
+/* 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.
+ *
+ */
+
+// The hash map (associative array) implementation in this file is
+// based on the PyDict implementation of CPython.
+
+#ifndef COMMON_HASHMAP_H
+#define COMMON_HASHMAP_H
+
+/**
+ * @def DEBUG_HASH_COLLISIONS
+ * Enable the following #define if you want to check how many collisions the
+ * code produces (many collisions indicate either a bad hash function, or a
+ * hash table that is too small).
+ */
+//#define DEBUG_HASH_COLLISIONS
+
+/**
+ * @def USE_HASHMAP_MEMORY_POOL
+ * Enable the following define to let HashMaps use a memory pool for the
+ nodes they contain. * This increases memory usage, but also can improve
+ speed quite a bit.
+ */
+#define USE_HASHMAP_MEMORY_POOL
+
+
+#include "common/func.h"
+
+#ifdef DEBUG_HASH_COLLISIONS
+#include "common/debug.h"
+#endif
+
+#ifdef USE_HASHMAP_MEMORY_POOL
+#include "memorypool.h"
+#endif
+
+
+
+namespace Common {
+
+// The sgi IRIX MIPSpro Compiler has difficulties with nested templates.
+// This and the other __sgi conditionals below work around these problems.
+// The Intel C++ Compiler suffers from the same problems.
+#if (defined(__sgi) && !defined(__GNUC__)) || defined(__INTEL_COMPILER)
+template<class T> class IteratorImpl;
+#endif
+
+
+/**
+ * HashMap<Key,Val> maps objects of type Key to objects of type Val.
+ * For each used Key type, we need an "size_type hashit(Key,size_type)" function
+ * that computes a hash for the given Key object and returns it as an
+ * an integer from 0 to hashsize-1, and also an "equality functor".
+ * that returns true if if its two arguments are to be considered
+ * equal. Also, we assume that "=" works on Val objects for assignment.
+ *
+ * If aa is an HashMap<Key,Val>, then space is allocated each time aa[key] is
+ * referenced, for a new key. If the object is const, then an assertion is
+ * triggered instead. Hence if you are not sure whether a key is contained in
+ * the map, use contains() first to check for its presence.
+ */
+template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> >
+class HashMap {
+public:
+ typedef uint size_type;
+
+private:
+
+ typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t;
+
+ struct Node {
+ const Key _key;
+ Val _value;
+ explicit Node(const Key &key) : _key(key), _value() {}
+ Node() : _key(), _value() {}
+ };
+
+ enum {
+ HASHMAP_PERTURB_SHIFT = 5,
+ HASHMAP_MIN_CAPACITY = 16,
+
+ // The quotient of the next two constants controls how much the
+ // internal storage of the hashmap may fill up before being
+ // increased automatically.
+ // Note: the quotient of these two must be between and different
+ // from 0 and 1.
+ HASHMAP_LOADFACTOR_NUMERATOR = 2,
+ HASHMAP_LOADFACTOR_DENOMINATOR = 3,
+
+ HASHMAP_MEMORYPOOL_SIZE = HASHMAP_MIN_CAPACITY * HASHMAP_LOADFACTOR_NUMERATOR / HASHMAP_LOADFACTOR_DENOMINATOR
+ };
+
+#ifdef USE_HASHMAP_MEMORY_POOL
+ ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool;
+#endif
+
+ Node **_storage; ///< hashtable of size arrsize.
+ size_type _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
+ size_type _size;
+ size_type _deleted; ///< Number of deleted elements (_dummyNodes)
+
+ HashFunc _hash;
+ EqualFunc _equal;
+
+ /** Default value, returned by the const getVal. */
+ const Val _defaultVal;
+
+ /** Dummy node, used as marker for erased objects. */
+ #define HASHMAP_DUMMY_NODE ((Node *)1)
+
+#ifdef DEBUG_HASH_COLLISIONS
+ mutable int _collisions, _lookups, _dummyHits;
+#endif
+
+ Node *allocNode(const Key &key) {
+#ifdef USE_HASHMAP_MEMORY_POOL
+ return new (_nodePool) Node(key);
+#else
+ return new Node(key);
+#endif
+ }
+
+ void freeNode(Node *node) {
+ if (node && node != HASHMAP_DUMMY_NODE)
+#ifdef USE_HASHMAP_MEMORY_POOL
+ _nodePool.deleteChunk(node);
+#else
+ delete node;
+#endif
+ }
+
+ void assign(const HM_t &map);
+ size_type lookup(const Key &key) const;
+ size_type lookupAndCreateIfMissing(const Key &key);
+ void expandStorage(size_type newCapacity);
+
+#if !defined(__sgi) || defined(__GNUC__)
+ template<class T> friend class IteratorImpl;
+#endif
+
+ /**
+ * Simple HashMap iterator implementation.
+ */
+ template<class NodeType>
+ class IteratorImpl {
+ friend class HashMap;
+#if (defined(__sgi) && !defined(__GNUC__)) || defined(__INTEL_COMPILER)
+ template<class T> friend class Common::IteratorImpl;
+#else
+ template<class T> friend class IteratorImpl;
+#endif
+ protected:
+ typedef const HashMap hashmap_t;
+
+ size_type _idx;
+ hashmap_t *_hashmap;
+
+ protected:
+ IteratorImpl(size_type idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
+
+ NodeType *deref() const {
+ assert(_hashmap != 0);
+ assert(_idx <= _hashmap->_mask);
+ Node *node = _hashmap->_storage[_idx];
+ assert(node != 0);
+ assert(node != HASHMAP_DUMMY_NODE);
+ return node;
+ }
+
+ public:
+ IteratorImpl() : _idx(0), _hashmap(0) {}
+ template<class T>
+ IteratorImpl(const IteratorImpl<T> &c) : _idx(c._idx), _hashmap(c._hashmap) {}
+
+ NodeType &operator*() const { return *deref(); }
+ NodeType *operator->() const { return deref(); }
+
+ bool operator==(const IteratorImpl &iter) const { return _idx == iter._idx && _hashmap == iter._hashmap; }
+ bool operator!=(const IteratorImpl &iter) const { return !(*this == iter); }
+
+ IteratorImpl &operator++() {
+ assert(_hashmap);
+ do {
+ _idx++;
+ } while (_idx <= _hashmap->_mask && (_hashmap->_storage[_idx] == 0 || _hashmap->_storage[_idx] == HASHMAP_DUMMY_NODE));
+ if (_idx > _hashmap->_mask)
+ _idx = (size_type)-1;
+
+ return *this;
+ }
+
+ IteratorImpl operator++(int) {
+ IteratorImpl old = *this;
+ operator ++();
+ return old;
+ }
+ };
+
+public:
+ typedef IteratorImpl<Node> iterator;
+ typedef IteratorImpl<const Node> const_iterator;
+
+ HashMap();
+ HashMap(const HM_t &map);
+ ~HashMap();
+
+ HM_t &operator=(const HM_t &map) {
+ if (this == &map)
+ return *this;
+
+ // Remove the previous content and ...
+ clear();
+ delete[] _storage;
+ // ... copy the new stuff.
+ assign(map);
+ return *this;
+ }
+
+ bool contains(const Key &key) const;
+
+ Val &operator[](const Key &key);
+ const Val &operator[](const Key &key) const;
+
+ Val &getVal(const Key &key);
+ const Val &getVal(const Key &key) const;
+ const Val &getVal(const Key &key, const Val &defaultVal) const;
+ void setVal(const Key &key, const Val &val);
+
+ void clear(bool shrinkArray = 0);
+
+ void erase(iterator entry);
+ void erase(const Key &key);
+
+ size_type size() const { return _size; }
+
+ iterator begin() {
+ // Find and return the first non-empty entry
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
+ if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
+ return iterator(ctr, this);
+ }
+ return end();
+ }
+ iterator end() {
+ return iterator((size_type)-1, this);
+ }
+
+ const_iterator begin() const {
+ // Find and return the first non-empty entry
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
+ if (_storage[ctr] && _storage[ctr] != HASHMAP_DUMMY_NODE)
+ return const_iterator(ctr, this);
+ }
+ return end();
+ }
+ const_iterator end() const {
+ return const_iterator((size_type)-1, this);
+ }
+
+ iterator find(const Key &key) {
+ size_type ctr = lookup(key);
+ if (_storage[ctr])
+ return iterator(ctr, this);
+ return end();
+ }
+
+ const_iterator find(const Key &key) const {
+ size_type ctr = lookup(key);
+ if (_storage[ctr])
+ return const_iterator(ctr, this);
+ return end();
+ }
+
+ // TODO: insert() method?
+
+ bool empty() const {
+ return (_size == 0);
+ }
+};
+
+//-------------------------------------------------------
+// HashMap functions
+
+/**
+ * Base constructor, creates an empty hashmap.
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+HashMap<Key, Val, HashFunc, EqualFunc>::HashMap()
+//
+// We have to skip _defaultVal() on PS2 to avoid gcc 3.2.2 ICE
+//
+#ifdef __PLAYSTATION2__
+ {
+#else
+ : _defaultVal() {
+#endif
+ _mask = HASHMAP_MIN_CAPACITY - 1;
+ _storage = new Node *[HASHMAP_MIN_CAPACITY];
+ assert(_storage != NULL);
+ memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *));
+
+ _size = 0;
+ _deleted = 0;
+
+#ifdef DEBUG_HASH_COLLISIONS
+ _collisions = 0;
+ _lookups = 0;
+ _dummyHits = 0;
+#endif
+}
+
+/**
+ * Copy constructor, creates a full copy of the given hashmap.
+ * We must provide a custom copy constructor as we use pointers
+ * to heap buffers for the internal storage.
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+HashMap<Key, Val, HashFunc, EqualFunc>::HashMap(const HM_t &map) :
+ _defaultVal() {
+#ifdef DEBUG_HASH_COLLISIONS
+ _collisions = 0;
+ _lookups = 0;
+ _dummyHits = 0;
+#endif
+ assign(map);
+}
+
+/**
+ * Destructor, frees all used memory.
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr)
+ freeNode(_storage[ctr]);
+
+ delete[] _storage;
+#ifdef DEBUG_HASH_COLLISIONS
+ extern void updateHashCollisionStats(int, int, int, int, int);
+ updateHashCollisionStats(_collisions, _dummyHits, _lookups, _mask+1, _size);
+#endif
+}
+
+/**
+ * Internal method for assigning the content of another HashMap
+ * to this one.
+ *
+ * @note We do *not* deallocate the previous storage here -- the caller is
+ * responsible for doing that!
+ */
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
+ _mask = map._mask;
+ _storage = new Node *[_mask+1];
+ assert(_storage != NULL);
+ memset(_storage, 0, (_mask+1) * sizeof(Node *));
+
+ // Simply clone the map given to us, one by one.
+ _size = 0;
+ _deleted = 0;
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
+ if (map._storage[ctr] == HASHMAP_DUMMY_NODE) {
+ _storage[ctr] = HASHMAP_DUMMY_NODE;
+ _deleted++;
+ } else if (map._storage[ctr] != NULL) {
+ _storage[ctr] = allocNode(map._storage[ctr]->_key);
+ _storage[ctr]->_value = map._storage[ctr]->_value;
+ _size++;
+ }
+ }
+ // Perform a sanity check (to help track down hashmap corruption)
+ assert(_size == map._size);
+ assert(_deleted == map._deleted);
+}
+
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
+ for (size_type ctr = 0; ctr <= _mask; ++ctr) {
+ freeNode(_storage[ctr]);
+ _storage[ctr] = NULL;
+ }
+
+#ifdef USE_HASHMAP_MEMORY_POOL
+ _nodePool.freeUnusedPages();
+#endif
+
+ if (shrinkArray && _mask >= HASHMAP_MIN_CAPACITY) {
+ delete[] _storage;
+
+ _mask = HASHMAP_MIN_CAPACITY;
+ _storage = new Node *[HASHMAP_MIN_CAPACITY];
+ assert(_storage != NULL);
+ memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *));
+ }
+
+ _size = 0;
+ _deleted = 0;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(size_type newCapacity) {
+ assert(newCapacity > _mask+1);
+
+#ifndef NDEBUG
+ const size_type old_size = _size;
+#endif
+ const size_type old_mask = _mask;
+ Node **old_storage = _storage;
+
+ // allocate a new array
+ _size = 0;
+ _deleted = 0;
+ _mask = newCapacity - 1;
+ _storage = new Node *[newCapacity];
+ assert(_storage != NULL);
+ memset(_storage, 0, newCapacity * sizeof(Node *));
+
+ // rehash all the old elements
+ for (size_type ctr = 0; ctr <= old_mask; ++ctr) {
+ if (old_storage[ctr] == NULL || old_storage[ctr] == HASHMAP_DUMMY_NODE)
+ continue;
+
+ // Insert the element from the old table into the new table.
+ // Since we know that no key exists twice in the old table, we
+ // can do this slightly better than by calling lookup, since we
+ // don't have to call _equal().
+ const size_type hash = _hash(old_storage[ctr]->_key);
+ size_type idx = hash & _mask;
+ for (size_type perturb = hash; _storage[idx] != NULL && _storage[idx] != HASHMAP_DUMMY_NODE; perturb >>= HASHMAP_PERTURB_SHIFT) {
+ idx = (5 * idx + perturb + 1) & _mask;
+ }
+
+ _storage[idx] = old_storage[ctr];
+ _size++;
+ }
+
+ // Perform a sanity check: Old number of elements should match the new one!
+ // This check will fail if some previous operation corrupted this hashmap.
+ assert(_size == old_size);
+
+ delete[] old_storage;
+
+ return;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
+ const size_type hash = _hash(key);
+ size_type ctr = hash & _mask;
+ for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+ if (_storage[ctr] == NULL)
+ break;
+ if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
+#ifdef DEBUG_HASH_COLLISIONS
+ _dummyHits++;
+#endif
+ } else if (_equal(_storage[ctr]->_key, key))
+ break;
+
+ ctr = (5 * ctr + perturb + 1) & _mask;
+
+#ifdef DEBUG_HASH_COLLISIONS
+ _collisions++;
+#endif
+ }
+
+#ifdef DEBUG_HASH_COLLISIONS
+ _lookups++;
+ debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d",
+ _collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
+ (const void *)this, _mask+1, _size);
+#endif
+
+ return ctr;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
+ const size_type hash = _hash(key);
+ size_type ctr = hash & _mask;
+ const size_type NONE_FOUND = _mask + 1;
+ size_type first_free = NONE_FOUND;
+ bool found = false;
+ for (size_type perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) {
+ if (_storage[ctr] == NULL)
+ break;
+ if (_storage[ctr] == HASHMAP_DUMMY_NODE) {
+#ifdef DEBUG_HASH_COLLISIONS
+ _dummyHits++;
+#endif
+ if (first_free != _mask + 1)
+ first_free = ctr;
+ } else if (_equal(_storage[ctr]->_key, key)) {
+ found = true;
+ break;
+ }
+
+ ctr = (5 * ctr + perturb + 1) & _mask;
+
+#ifdef DEBUG_HASH_COLLISIONS
+ _collisions++;
+#endif
+ }
+
+#ifdef DEBUG_HASH_COLLISIONS
+ _lookups++;
+ debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d",
+ _collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
+ (const void *)this, _mask+1, _size);
+#endif
+
+ if (!found && first_free != _mask + 1)
+ ctr = first_free;
+
+ if (!found) {
+ if (_storage[ctr])
+ _deleted--;
+ _storage[ctr] = allocNode(key);
+ assert(_storage[ctr] != NULL);
+ _size++;
+
+ // Keep the load factor below a certain threshold.
+ // Deleted nodes are also counted
+ size_type capacity = _mask + 1;
+ if ((_size + _deleted) * HASHMAP_LOADFACTOR_DENOMINATOR >
+ capacity * HASHMAP_LOADFACTOR_NUMERATOR) {
+ capacity = capacity < 500 ? (capacity * 4) : (capacity * 2);
+ expandStorage(capacity);
+ ctr = lookup(key);
+ assert(_storage[ctr] != NULL);
+ }
+ }
+
+ return ctr;
+}
+
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+bool HashMap<Key, Val, HashFunc, EqualFunc>::contains(const Key &key) const {
+ size_type ctr = lookup(key);
+ return (_storage[ctr] != NULL);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) {
+ return getVal(key);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+const Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) const {
+ return getVal(key);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) {
+ size_type ctr = lookupAndCreateIfMissing(key);
+ assert(_storage[ctr] != NULL);
+ return _storage[ctr]->_value;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) const {
+ return getVal(key, _defaultVal);
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key, const Val &defaultVal) const {
+ size_type ctr = lookup(key);
+ if (_storage[ctr] != NULL)
+ return _storage[ctr]->_value;
+ else
+ return defaultVal;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::setVal(const Key &key, const Val &val) {
+ size_type ctr = lookupAndCreateIfMissing(key);
+ assert(_storage[ctr] != NULL);
+ _storage[ctr]->_value = val;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::erase(iterator entry) {
+ // Check whether we have a valid iterator
+ assert(entry._hashmap == this);
+ const size_type ctr = entry._idx;
+ assert(ctr <= _mask);
+ Node * const node = _storage[ctr];
+ assert(node != NULL);
+ assert(node != HASHMAP_DUMMY_NODE);
+
+ // If we remove a key, we replace it with a dummy node.
+ freeNode(node);
+ _storage[ctr] = HASHMAP_DUMMY_NODE;
+ _size--;
+ _deleted++;
+}
+
+template<class Key, class Val, class HashFunc, class EqualFunc>
+void HashMap<Key, Val, HashFunc, EqualFunc>::erase(const Key &key) {
+
+ size_type ctr = lookup(key);
+ if (_storage[ctr] == NULL)
+ return;
+
+ // If we remove a key, we replace it with a dummy node.
+ freeNode(_storage[ctr]);
+ _storage[ctr] = HASHMAP_DUMMY_NODE;
+ _size--;
+ _deleted++;
+ return;
+}
+
+#undef HASHMAP_DUMMY_NODE
+
+} // End of namespace Common
+
+#endif
diff --git a/devtools/create_xeen/memorypool.cpp b/devtools/create_xeen/memorypool.cpp
new file mode 100644
index 0000000..13c640b
--- /dev/null
+++ b/devtools/create_xeen/memorypool.cpp
@@ -0,0 +1,182 @@
+/* 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 "memorypool.h"
+#include "common/util.h"
+
+namespace Common {
+
+enum {
+ INITIAL_CHUNKS_PER_PAGE = 8
+};
+
+static size_t adjustChunkSize(size_t chunkSize) {
+ // You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
+ chunkSize = MAX(chunkSize, sizeof(void *));
+ // There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary
+ // so we round to the next sizeof(void *)
+ chunkSize = (chunkSize + sizeof(void *) - 1) & (~(sizeof(void *) - 1));
+
+ return chunkSize;
+}
+
+
+MemoryPool::MemoryPool(size_t chunkSize)
+ : _chunkSize(adjustChunkSize(chunkSize)) {
+
+ _next = NULL;
+
+ _chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
+}
+
+MemoryPool::~MemoryPool() {
+#if 0
+ freeUnusedPages();
+ if (!_pages.empty())
+ warning("Memory leak found in pool");
+#endif
+
+ for (size_t i = 0; i < _pages.size(); ++i)
+ ::free(_pages[i].start);
+}
+
+void MemoryPool::allocPage() {
+ Page page;
+
+ // Allocate a new page
+ page.numChunks = _chunksPerPage;
+ assert(page.numChunks * _chunkSize < 16*1024*1024); // Refuse to allocate pages bigger than 16 MB
+
+ page.start = ::malloc(page.numChunks * _chunkSize);
+ assert(page.start);
+ _pages.push_back(page);
+
+
+ // Next time, we'll allocate a page twice as big as this one.
+ _chunksPerPage *= 2;
+
+ // Add the page to the pool of free chunk
+ addPageToPool(page);
+}
+
+void MemoryPool::addPageToPool(const Page &page) {
+ // Add all chunks of the new page to the linked list (pool) of free chunks
+ void *current = page.start;
+ for (size_t i = 1; i < page.numChunks; ++i) {
+ void *next = (byte *)current + _chunkSize;
+ *(void **)current = next;
+
+ current = next;
+ }
+
+ // Last chunk points to the old _next
+ *(void **)current = _next;
+
+ // From now on, the first free chunk is the first chunk of the new page
+ _next = page.start;
+}
+
+void *MemoryPool::allocChunk() {
+ // No free chunks left? Allocate a new page
+ if (!_next)
+ allocPage();
+
+ assert(_next);
+ void *result = _next;
+ _next = *(void **)result;
+ return result;
+}
+
+void MemoryPool::freeChunk(void *ptr) {
+ // Add the chunk back to (the start of) the list of free chunks
+ *(void **)ptr = _next;
+ _next = ptr;
+}
+
+// Technically not compliant C++ to compare unrelated pointers. In practice...
+bool MemoryPool::isPointerInPage(void *ptr, const Page &page) {
+ return (ptr >= page.start) && (ptr < (char *)page.start + page.numChunks * _chunkSize);
+}
+
+void MemoryPool::freeUnusedPages() {
+ //std::sort(_pages.begin(), _pages.end());
+ Array<size_t> numberOfFreeChunksPerPage;
+ numberOfFreeChunksPerPage.resize(_pages.size());
+ for (size_t i = 0; i < numberOfFreeChunksPerPage.size(); ++i) {
+ numberOfFreeChunksPerPage[i] = 0;
+ }
+
+ // Compute for each page how many chunks in it are still in use.
+ void *iterator = _next;
+ while (iterator) {
+ // TODO: This should be a binary search (requiring us to keep _pages sorted)
+ for (size_t i = 0; i < _pages.size(); ++i) {
+ if (isPointerInPage(iterator, _pages[i])) {
+ ++numberOfFreeChunksPerPage[i];
+ break;
+ }
+ }
+
+ iterator = *(void **)iterator;
+ }
+
+ // Free all pages which are not in use.
+ size_t freedPagesCount = 0;
+ for (size_t i = 0; i < _pages.size(); ++i) {
+ if (numberOfFreeChunksPerPage[i] == _pages[i].numChunks) {
+ // Remove all chunks of this page from the list of free chunks
+ void **iter2 = &_next;
+ while (*iter2) {
+ if (isPointerInPage(*iter2, _pages[i]))
+ *iter2 = **(void ***)iter2;
+ else
+ iter2 = *(void ***)iter2;
+ }
+
+ ::free(_pages[i].start);
+ ++freedPagesCount;
+ _pages[i].start = NULL;
+ }
+ }
+
+// debug("freed %d pages out of %d", (int)freedPagesCount, (int)_pages.size());
+
+ // Remove all now unused pages
+ size_t newSize = 0;
+ for (size_t i = 0; i < _pages.size(); ++i) {
+ if (_pages[i].start != NULL) {
+ if (newSize != i)
+ _pages[newSize] = _pages[i];
+ ++newSize;
+ }
+ }
+ _pages.resize(newSize);
+
+ // Reset _chunksPerPage
+ _chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
+ for (size_t i = 0; i < _pages.size(); ++i) {
+ if (_chunksPerPage < _pages[i].numChunks)
+ _chunksPerPage = _pages[i].numChunks;
+ }
+}
+
+} // End of namespace Common
diff --git a/devtools/create_xeen/memorypool.h b/devtools/create_xeen/memorypool.h
new file mode 100644
index 0000000..c8a8fc7
--- /dev/null
+++ b/devtools/create_xeen/memorypool.h
@@ -0,0 +1,162 @@
+/* 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 COMMON_MEMORYPOOL_H
+#define COMMON_MEMORYPOOL_H
+
+#include "common/array.h"
+
+
+namespace Common {
+
+/**
+ * This class provides a pool of memory 'chunks' of identical size.
+ * The size of a chunk is determined when creating the memory pool.
+ *
+ * Using a memory pool may yield better performance and memory usage
+ * when allocating and deallocating many memory blocks of equal size.
+ * E.g. the Common::String class uses a memory pool for the refCount
+ * variables (each the size of an int) it allocates for each string
+ * instance.
+ */
+class MemoryPool {
+protected:
+ MemoryPool(const MemoryPool&);
+ MemoryPool& operator=(const MemoryPool&);
+
+ struct Page {
+ void *start;
+ size_t numChunks;
+ };
+
+ const size_t _chunkSize;
+ Array<Page> _pages;
+ void *_next;
+ size_t _chunksPerPage;
+
+ void allocPage();
+ void addPageToPool(const Page &page);
+ bool isPointerInPage(void *ptr, const Page &page);
+
+public:
+ /**
+ * Constructor for a memory pool with the given chunk size.
+ * @param chunkSize the chunk size of this memory pool
+ */
+ explicit MemoryPool(size_t chunkSize);
+ ~MemoryPool();
+
+ /**
+ * Allocate a new chunk from the memory pool.
+ */
+ void *allocChunk();
+ /**
+ * Return a chunk to the memory pool. The given pointer must have
+ * been obtained from calling the allocChunk() method of the very
+ * same MemoryPool instance. Passing any other pointer (e.g. to
+ * a chunk from another MemoryPool, or a malloc'ed memory block)
+ * will lead to undefined behavior and may result in a crash (if
+ * you are lucky) or in silent data corruption.
+ */
+ void freeChunk(void *ptr);
+
+ /**
+ * Perform garbage collection. The memory pool stores all the
+ * chunks it manages in memory 'pages' obtained via the classic
+ * memory allocation APIs (i.e. malloc/free). Ordinarily, once
+ * a page has been allocated, it won't be released again during
+ * the life time of the memory pool. The exception is when this
+ * method is called.
+ */
+ void freeUnusedPages();
+
+ /**
+ * Return the chunk size used by this memory pool.
+ */
+ size_t getChunkSize() const { return _chunkSize; }
+};
+
+/**
+ * This is a memory pool which already contains in itself some storage
+ * space for a fixed number of chunks. Thus if the memory pool is only
+ * lightly used, no malloc() calls have to be made at all.
+ */
+template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32>
+class FixedSizeMemoryPool : public MemoryPool {
+private:
+ enum {
+ REAL_CHUNK_SIZE = (CHUNK_SIZE + sizeof(void *) - 1) & (~(sizeof(void *) - 1))
+ };
+
+ byte _storage[NUM_INTERNAL_CHUNKS * REAL_CHUNK_SIZE];
+public:
+ FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {
+ assert(REAL_CHUNK_SIZE == _chunkSize);
+ // Insert some static storage
+ Page internalPage = { _storage, NUM_INTERNAL_CHUNKS };
+ addPageToPool(internalPage);
+ }
+};
+
+// Ensure NUM_INTERNAL_CHUNKS == 0 results in a compile error
+template<size_t CHUNK_SIZE>
+class FixedSizeMemoryPool<CHUNK_SIZE,0> : public MemoryPool {
+public:
+ FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {}
+};
+
+/**
+ * A memory pool for C++ objects.
+ */
+template<class T, size_t NUM_INTERNAL_CHUNKS = 32>
+class ObjectPool : public FixedSizeMemoryPool<sizeof(T), NUM_INTERNAL_CHUNKS> {
+public:
+ /**
+ * Return the memory chunk used as storage for the given object back
+ * to the pool, after calling its destructor.
+ */
+ void deleteChunk(T *ptr) {
+ ptr->~T();
+ this->freeChunk(ptr);
+ }
+};
+
+} // End of namespace Common
+
+/**
+ * A custom placement new operator, using an arbitrary MemoryPool.
+ *
+ * This *should* work with all C++ implementations, but may not.
+ *
+ * For details on using placement new for custom allocators, see e.g.
+ * <http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14>
+ */
+inline void *operator new(size_t nbytes, Common::MemoryPool &pool) {
+ assert(nbytes <= pool.getChunkSize());
+ return pool.allocChunk();
+}
+
+inline void operator delete(void *p, Common::MemoryPool &pool) {
+ pool.freeChunk(p);
+}
+
+#endif
diff --git a/devtools/create_xeen/module.mk b/devtools/create_xeen/module.mk
new file mode 100644
index 0000000..d382fc6
--- /dev/null
+++ b/devtools/create_xeen/module.mk
@@ -0,0 +1,15 @@
+MODULE := devtools/create_xeen
+
+MODULE_OBJS := \
+ create_xeen.o \
+ cc.o \
+ constants.o \
+ hashmap.o \
+ memorypool.o \
+ str.o
+
+# Set the name of the executable
+TOOL_EXECUTABLE := create_xeen
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/devtools/create_xeen/str.cpp b/devtools/create_xeen/str.cpp
new file mode 100644
index 0000000..6aa66d0
--- /dev/null
+++ b/devtools/create_xeen/str.cpp
@@ -0,0 +1,786 @@
+/* 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 "common/hash-str.h"
+#include "common/list.h"
+#include "memorypool.h"
+#include "common/str.h"
+#include "common/util.h"
+
+namespace Common {
+
+MemoryPool *g_refCountPool = 0; // FIXME: This is never freed right now
+
+static uint32 computeCapacity(uint32 len) {
+ // By default, for the capacity we use the next multiple of 32
+ return ((len + 32 - 1) & ~0x1F);
+}
+
+String::String(const char *str) : _size(0), _str(_storage) {
+ if (str == 0) {
+ _storage[0] = 0;
+ _size = 0;
+ } else
+ initWithCStr(str, strlen(str));
+}
+
+String::String(const char *str, uint32 len) : _size(0), _str(_storage) {
+ initWithCStr(str, len);
+}
+
+String::String(const char *beginP, const char *endP) : _size(0), _str(_storage) {
+ assert(endP >= beginP);
+ initWithCStr(beginP, endP - beginP);
+}
+
+void String::initWithCStr(const char *str, uint32 len) {
+ assert(str);
+
+ // Init _storage member explicitly (ie. without calling its constructor)
+ // for GCC 2.95.x compatibility (see also tracker item #1602879).
+ _storage[0] = 0;
+
+ _size = len;
+
+ if (len >= _builtinCapacity) {
+ // Not enough internal storage, so allocate more
+ _extern._capacity = computeCapacity(len+1);
+ _extern._refCount = 0;
+ _str = new char[_extern._capacity];
+ assert(_str != 0);
+ }
+
+ // Copy the string into the storage area
+ memmove(_str, str, len);
+ _str[len] = 0;
+}
+
+String::String(const String &str)
+ : _size(str._size) {
+ if (str.isStorageIntern()) {
+ // String in internal storage: just copy it
+ memcpy(_storage, str._storage, _builtinCapacity);
+ _str = _storage;
+ } else {
+ // String in external storage: use refcount mechanism
+ str.incRefCount();
+ _extern._refCount = str._extern._refCount;
+ _extern._capacity = str._extern._capacity;
+ _str = str._str;
+ }
+ assert(_str != 0);
+}
+
+String::String(char c)
+ : _size(0), _str(_storage) {
+
+ _storage[0] = c;
+ _storage[1] = 0;
+
+ _size = (c == 0) ? 0 : 1;
+}
+
+String::~String() {
+ decRefCount(_extern._refCount);
+}
+
+void String::makeUnique() {
+ ensureCapacity(_size, true);
+}
+
+/**
+ * Ensure that enough storage is available to store at least new_size
+ * characters plus a null byte. In addition, if we currently share
+ * the storage with another string, unshare it, so that we can safely
+ * write to the storage.
+ */
+void String::ensureCapacity(uint32 new_size, bool keep_old) {
+ bool isShared;
+ uint32 curCapacity, newCapacity;
+ char *newStorage;
+ int *oldRefCount = _extern._refCount;
+
+ if (isStorageIntern()) {
+ isShared = false;
+ curCapacity = _builtinCapacity;
+ } else {
+ isShared = (oldRefCount && *oldRefCount > 1);
+ curCapacity = _extern._capacity;
+ }
+
+ // Special case: If there is enough space, and we do not share
+ // the storage, then there is nothing to do.
+ if (!isShared && new_size < curCapacity)
+ return;
+
+ if (isShared && new_size < _builtinCapacity) {
+ // We share the storage, but there is enough internal storage: Use that.
+ newStorage = _storage;
+ newCapacity = _builtinCapacity;
+ } else {
+ // We need to allocate storage on the heap!
+
+ // Compute a suitable new capacity limit
+ // If the current capacity is sufficient we use the same capacity
+ if (new_size < curCapacity)
+ newCapacity = curCapacity;
+ else
+ newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
+
+ // Allocate new storage
+ newStorage = new char[newCapacity];
+ assert(newStorage);
+ }
+
+ // Copy old data if needed, elsewise reset the new storage.
+ if (keep_old) {
+ assert(_size < newCapacity);
+ memcpy(newStorage, _str, _size + 1);
+ } else {
+ _size = 0;
+ newStorage[0] = 0;
+ }
+
+ // Release hold on the old storage ...
+ decRefCount(oldRefCount);
+
+ // ... in favor of the new storage
+ _str = newStorage;
+
+ if (!isStorageIntern()) {
+ // Set the ref count & capacity if we use an external storage.
+ // It is important to do this *after* copying any old content,
+ // else we would override data that has not yet been copied!
+ _extern._refCount = 0;
+ _extern._capacity = newCapacity;
+ }
+}
+
+void String::incRefCount() const {
+ assert(!isStorageIntern());
+ if (_extern._refCount == 0) {
+ if (g_refCountPool == 0) {
+ g_refCountPool = new MemoryPool(sizeof(int));
+ assert(g_refCountPool);
+ }
+
+ _extern._refCount = (int *)g_refCountPool->allocChunk();
+ *_extern._refCount = 2;
+ } else {
+ ++(*_extern._refCount);
+ }
+}
+
+void String::decRefCount(int *oldRefCount) {
+ if (isStorageIntern())
+ return;
+
+ if (oldRefCount) {
+ --(*oldRefCount);
+ }
+ if (!oldRefCount || *oldRefCount <= 0) {
+ // The ref count reached zero, so we free the string storage
+ // and the ref count storage.
+ if (oldRefCount) {
+ assert(g_refCountPool);
+ g_refCountPool->freeChunk(oldRefCount);
+ }
+ delete[] _str;
+
+ // Even though _str points to a freed memory block now,
+ // we do not change its value, because any code that calls
+ // decRefCount will have to do this afterwards anyway.
+ }
+}
+
+String &String::operator=(const char *str) {
+ uint32 len = strlen(str);
+ ensureCapacity(len, false);
+ _size = len;
+ memmove(_str, str, len + 1);
+ return *this;
+}
+
+String &String::operator=(const String &str) {
+ if (&str == this)
+ return *this;
+
+ if (str.isStorageIntern()) {
+ decRefCount(_extern._refCount);
+ _size = str._size;
+ _str = _storage;
+ memcpy(_str, str._str, _size + 1);
+ } else {
+ str.incRefCount();
+ decRefCount(_extern._refCount);
+
+ _extern._refCount = str._extern._refCount;
+ _extern._capacity = str._extern._capacity;
+ _size = str._size;
+ _str = str._str;
+ }
+
+ return *this;
+}
+
+String &String::operator=(char c) {
+ decRefCount(_extern._refCount);
+ _str = _storage;
+
+ _str[0] = c;
+ _str[1] = 0;
+
+ _size = (c == 0) ? 0 : 1;
+ return *this;
+}
+
+String &String::operator+=(const char *str) {
+ if (_str <= str && str <= _str + _size)
+ return operator+=(String(str));
+
+ int len = strlen(str);
+ if (len > 0) {
+ ensureCapacity(_size + len, true);
+
+ memcpy(_str + _size, str, len + 1);
+ _size += len;
+ }
+ return *this;
+}
+
+String &String::operator+=(const String &str) {
+ if (&str == this)
+ return operator+=(String(str));
+
+ int len = str._size;
+ if (len > 0) {
+ ensureCapacity(_size + len, true);
+
+ memcpy(_str + _size, str._str, len + 1);
+ _size += len;
+ }
+ return *this;
+}
+
+String &String::operator+=(char c) {
+ ensureCapacity(_size + 1, true);
+
+ _str[_size++] = c;
+ _str[_size] = 0;
+
+ return *this;
+}
+
+bool String::hasPrefix(const String &x) const {
+ return hasPrefix(x.c_str());
+}
+
+bool String::hasPrefix(const char *x) const {
+ assert(x != 0);
+ // Compare x with the start of _str.
+ const char *y = c_str();
+ while (*x && *x == *y) {
+ ++x;
+ ++y;
+ }
+ // It's a prefix, if and only if all letters in x are 'used up' before
+ // _str ends.
+ return *x == 0;
+}
+
+bool String::hasSuffix(const String &x) const {
+ return hasSuffix(x.c_str());
+}
+
+bool String::hasSuffix(const char *x) const {
+ assert(x != 0);
+ // Compare x with the end of _str.
+ const uint32 x_size = strlen(x);
+ if (x_size > _size)
+ return false;
+ const char *y = c_str() + _size - x_size;
+ while (*x && *x == *y) {
+ ++x;
+ ++y;
+ }
+ // It's a suffix, if and only if all letters in x are 'used up' before
+ // _str ends.
+ return *x == 0;
+}
+
+bool String::contains(const String &x) const {
+ return strstr(c_str(), x.c_str()) != NULL;
+}
+
+bool String::contains(const char *x) const {
+ assert(x != 0);
+ return strstr(c_str(), x) != NULL;
+}
+
+bool String::contains(char x) const {
+ return strchr(c_str(), x) != NULL;
+}
+
+void String::deleteLastChar() {
+ if (_size > 0)
+ deleteChar(_size - 1);
+}
+
+void String::deleteChar(uint32 p) {
+ assert(p < _size);
+
+ makeUnique();
+ while (p++ < _size)
+ _str[p - 1] = _str[p];
+ _size--;
+}
+
+void String::erase(uint32 p, uint32 len) {
+ assert(p < _size);
+
+ makeUnique();
+ // If len == npos or p + len is over the end, remove all the way to the end
+ if (len == npos || p + len >= _size) {
+ // Delete char at p as well. So _size = (p - 1) + 1
+ _size = p;
+ // Null terminate
+ _str[_size] = 0;
+ return;
+ }
+
+ for ( ; p + len <= _size; p++) {
+ _str[p] = _str[p + len];
+ }
+ _size -= len;
+}
+
+void String::clear() {
+ decRefCount(_extern._refCount);
+
+ _size = 0;
+ _str = _storage;
+ _storage[0] = 0;
+}
+
+void String::setChar(char c, uint32 p) {
+ assert(p < _size);
+
+ makeUnique();
+ _str[p] = c;
+}
+
+void String::insertChar(char c, uint32 p) {
+ assert(p <= _size);
+
+ ensureCapacity(_size + 1, true);
+ _size++;
+ for (uint32 i = _size; i > p; --i)
+ _str[i] = _str[i - 1];
+ _str[p] = c;
+}
+
+void String::toLowercase() {
+ makeUnique();
+ for (uint32 i = 0; i < _size; ++i)
+ _str[i] = tolower(_str[i]);
+}
+
+void String::toUppercase() {
+ makeUnique();
+ for (uint32 i = 0; i < _size; ++i)
+ _str[i] = toupper(_str[i]);
+}
+
+uint String::hash() const {
+ return hashit(c_str());
+}
+
+// static
+String String::format(const char *fmt, ...) {
+ String output;
+
+ va_list va;
+ va_start(va, fmt);
+ output = String::vformat(fmt, va);
+ va_end(va);
+
+ return output;
+}
+
+// static
+String String::vformat(const char *fmt, va_list args) {
+ String output;
+ assert(output.isStorageIntern());
+
+ va_list va;
+ scumm_va_copy(va, args);
+ int len = vsnprintf(output._str, _builtinCapacity, fmt, va);
+ va_end(va);
+
+ if (len == -1 || len == _builtinCapacity - 1) {
+ // MSVC and IRIX don't return the size the full string would take up.
+ // MSVC returns -1, IRIX returns the number of characters actually written,
+ // which is at the most the size of the buffer minus one, as the string is
+ // truncated to fit.
+
+ // We assume MSVC failed to output the correct, null-terminated string
+ // if the return value is either -1 or size.
+ // For IRIX, because we lack a better mechanism, we assume failure
+ // if the return value equals size - 1.
+ // The downside to this is that whenever we try to format a string where the
+ // size is 1 below the built-in capacity, the size is needlessly increased.
+
+ // Try increasing the size of the string until it fits.
+ int size = _builtinCapacity;
+ do {
+ size *= 2;
+ output.ensureCapacity(size - 1, false);
+ assert(!output.isStorageIntern());
+ size = output._extern._capacity;
+
+ scumm_va_copy(va, args);
+ len = vsnprintf(output._str, size, fmt, va);
+ va_end(va);
+ } while (len == -1 || len >= size - 1);
+ output._size = len;
+ } else if (len < (int)_builtinCapacity) {
+ // vsnprintf succeeded
+ output._size = len;
+ } else {
+ // vsnprintf didn't have enough space, so grow buffer
+ output.ensureCapacity(len, false);
+ scumm_va_copy(va, args);
+ int len2 = vsnprintf(output._str, len+1, fmt, va);
+ va_end(va);
+ assert(len == len2);
+ output._size = len2;
+ }
+
+ return output;
+}
+
+
+#pragma mark -
+
+bool String::operator==(const String &x) const {
+ return equals(x);
+}
+
+bool String::operator==(const char *x) const {
+ assert(x != 0);
+ return equals(x);
+}
+
+bool String::operator!=(const String &x) const {
+ return !equals(x);
+}
+
+bool String::operator !=(const char *x) const {
+ assert(x != 0);
+ return !equals(x);
+}
+
+bool String::operator<(const String &x) const {
+ return compareTo(x) < 0;
+}
+
+bool String::operator<=(const String &x) const {
+ return compareTo(x) <= 0;
+}
+
+bool String::operator>(const String &x) const {
+ return compareTo(x) > 0;
+}
+
+bool String::operator>=(const String &x) const {
+ return compareTo(x) >= 0;
+}
+
+#pragma mark -
+
+bool operator==(const char* y, const String &x) {
+ return (x == y);
+}
+
+bool operator!=(const char* y, const String &x) {
+ return x != y;
+}
+
+#pragma mark -
+
+bool String::equals(const String &x) const {
+ return (0 == compareTo(x));
+}
+
+bool String::equals(const char *x) const {
+ assert(x != 0);
+ return (0 == compareTo(x));
+}
+
+bool String::equalsIgnoreCase(const String &x) const {
+ return (0 == compareToIgnoreCase(x));
+}
+
+bool String::equalsIgnoreCase(const char *x) const {
+ assert(x != 0);
+ return (0 == compareToIgnoreCase(x));
+}
+
+int String::compareTo(const String &x) const {
+ return compareTo(x.c_str());
+}
+
+int String::compareTo(const char *x) const {
+ assert(x != 0);
+ return strcmp(c_str(), x);
+}
+
+int String::compareToIgnoreCase(const String &x) const {
+ return compareToIgnoreCase(x.c_str());
+}
+
+int String::compareToIgnoreCase(const char *x) const {
+ assert(x != 0);
+ return scumm_stricmp(c_str(), x);
+}
+
+#pragma mark -
+
+String operator+(const String &x, const String &y) {
+ String temp(x);
+ temp += y;
+ return temp;
+}
+
+String operator+(const char *x, const String &y) {
+ String temp(x);
+ temp += y;
+ return temp;
+}
+
+String operator+(const String &x, const char *y) {
+ String temp(x);
+ temp += y;
+ return temp;
+}
+
+String operator+(char x, const String &y) {
+ String temp(x);
+ temp += y;
+ return temp;
+}
+
+String operator+(const String &x, char y) {
+ String temp(x);
+ temp += y;
+ return temp;
+}
+
+String lastPathComponent(const String &path, const char sep) {
+ const char *str = path.c_str();
+ const char *last = str + path.size();
+
+ // Skip over trailing slashes
+ while (last > str && *(last-1) == sep)
+ --last;
+
+ // Path consisted of only slashes -> return empty string
+ if (last == str)
+ return String();
+
+ // Now scan the whole component
+ const char *first = last - 1;
+ while (first > str && *first != sep)
+ --first;
+
+ if (*first == sep)
+ first++;
+
+ return String(first, last);
+}
+
+String normalizePath(const String &path, const char sep) {
+ if (path.empty())
+ return path;
+
+ const char *cur = path.c_str();
+ String result;
+
+ // If there is a leading slash, preserve that:
+ if (*cur == sep) {
+ result += sep;
+ // Skip over multiple leading slashes, so "//" equals "/"
+ while (*cur == sep)
+ ++cur;
+ }
+
+ // Scan for path components till the end of the String
+ List<String> comps;
+ while (*cur != 0) {
+ const char *start = cur;
+
+ // Scan till the next path separator resp. the end of the string
+ while (*cur != sep && *cur != 0)
+ cur++;
+
+ const String component(start, cur);
+
+ if (component.empty() || component == ".") {
+ // Skip empty components and dot components
+ } else if (!comps.empty() && component == ".." && comps.back() != "..") {
+ // If stack is non-empty and top is not "..", remove top
+ comps.pop_back();
+ } else {
+ // Add the component to the stack
+ comps.push_back(component);
+ }
+
+ // Skip over separator chars
+ while (*cur == sep)
+ cur++;
+ }
+
+ // Finally, assemble all components back into a path
+ while (!comps.empty()) {
+ result += comps.front();
+ comps.pop_front();
+ if (!comps.empty())
+ result += sep;
+ }
+
+ return result;
+}
+
+size_t strlcpy(char *dst, const char *src, size_t size) {
+ // Our backup of the source's start, we need this
+ // to calculate the source's length.
+ const char * const srcStart = src;
+
+ // In case a non-empty size was specified we
+ // copy over (size - 1) bytes at max.
+ if (size != 0) {
+ // Copy over (size - 1) bytes at max.
+ while (--size != 0) {
+ if ((*dst++ = *src) == 0)
+ break;
+ ++src;
+ }
+
+ // In case the source string was longer than the
+ // destination, we need to add a terminating
+ // zero.
+ if (size == 0)
+ *dst = 0;
+ }
+
+ // Move to the terminating zero of the source
+ // string, we need this to determine the length
+ // of the source string.
+ while (*src)
+ ++src;
+
+ // Return the source string's length.
+ return src - srcStart;
+}
+
+size_t strlcat(char *dst, const char *src, size_t size) {
+ // In case the destination buffer does not contain
+ // space for at least 1 character, we will just
+ // return the source string's length.
+ if (size == 0)
+ return strlen(src);
+
+ // Our backup of the source's start, we need this
+ // to calculate the source's length.
+ const char * const srcStart = src;
+
+ // Our backup of the destination's start, we need
+ // this to calculate the destination's length.
+ const char * const dstStart = dst;
+
+ // Search the end of the destination, but do not
+ // move past the terminating zero.
+ while (size-- != 0 && *dst != 0)
+ ++dst;
+
+ // Calculate the destination's length;
+ const size_t dstLength = dst - dstStart;
+
+ // In case we reached the end of the destination
+ // buffer before we had a chance to append any
+ // characters we will just return the destination
+ // length plus the source string's length.
+ if (size == 0)
+ return dstLength + strlen(srcStart);
+
+ // Copy over all of the source that fits
+ // the destination buffer. We also need
+ // to take the terminating zero we will
+ // add into consideration.
+ while (size-- != 0 && *src != 0)
+ *dst++ = *src++;
+ *dst = 0;
+
+ // Move to the terminating zero of the source
+ // string, we need this to determine the length
+ // of the source string.
+ while (*src)
+ ++src;
+
+ // Return the total length of the result string
+ return dstLength + (src - srcStart);
+}
+
+} // End of namespace Common
+
+// Portable implementation of stricmp / strcasecmp / strcmpi.
+// TODO: Rename this to Common::strcasecmp
+int scumm_stricmp(const char *s1, const char *s2) {
+ byte l1, l2;
+ do {
+ // Don't use ++ inside tolower, in case the macro uses its
+ // arguments more than once.
+ l1 = (byte)*s1++;
+ l1 = tolower(l1);
+ l2 = (byte)*s2++;
+ l2 = tolower(l2);
+ } while (l1 == l2 && l1 != 0);
+ return l1 - l2;
+}
+
+// Portable implementation of strnicmp / strncasecmp / strncmpi.
+// TODO: Rename this to Common::strncasecmp
+int scumm_strnicmp(const char *s1, const char *s2, uint n) {
+ byte l1, l2;
+ do {
+ if (n-- == 0)
+ return 0; // no difference found so far -> signal equality
+
+ // Don't use ++ inside tolower, in case the macro uses its
+ // arguments more than once.
+ l1 = (byte)*s1++;
+ l1 = tolower(l1);
+ l2 = (byte)*s2++;
+ l2 = tolower(l2);
+ } while (l1 == l2 && l1 != 0);
+ return l1 - l2;
+}
diff --git a/devtools/create_xeen/str.h b/devtools/create_xeen/str.h
new file mode 100644
index 0000000..2f954dc
--- /dev/null
+++ b/devtools/create_xeen/str.h
@@ -0,0 +1,386 @@
+/* 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 COMMON_STRING_H
+#define COMMON_STRING_H
+
+#include "common/scummsys.h"
+
+#include <stdarg.h>
+
+namespace Common {
+
+/**
+ * Simple string class for ScummVM. Provides automatic storage managment,
+ * and overloads several operators in a 'natural' fashion, mimicking
+ * the std::string class. Even provides simple iterators.
+ *
+ * This class tries to avoid allocating lots of small blocks on the heap,
+ * since that is inefficient on several platforms supported by ScummVM.
+ * Instead, small strings are stored 'inside' the string object (i.e. on
+ * the stack, for stack allocated objects), and only for strings exceeding
+ * a certain length do we allocate a buffer on the heap.
+ *
+ * The presence of \0 characters in the string will cause undefined
+ * behavior in some operations.
+ */
+class String {
+public:
+ static const uint32 npos = 0xFFFFFFFF;
+protected:
+ /**
+ * The size of the internal storage. Increasing this means less heap
+ * allocations are needed, at the cost of more stack memory usage,
+ * and of course lots of wasted memory. Empirically, 90% or more of
+ * all String instances are less than 32 chars long. If a platform
+ * is very short on stack space, it would be possible to lower this.
+ * A value of 24 still seems acceptable, though considerably worse,
+ * while 16 seems to be the lowest you want to go... Anything lower
+ * than 8 makes no sense, since that's the size of member _extern
+ * (on 32 bit machines; 12 bytes on systems with 64bit pointers).
+ */
+ static const uint32 _builtinCapacity = 32 - sizeof(uint32) - sizeof(char *);
+
+ /**
+ * Length of the string. Stored to avoid having to call strlen
+ * a lot. Yes, we limit ourselves to strings shorter than 4GB --
+ * on purpose :-).
+ */
+ uint32 _size;
+
+ /**
+ * Pointer to the actual string storage. Either points to _storage,
+ * or to a block allocated on the heap via malloc.
+ */
+ char *_str;
+
+
+ union {
+ /**
+ * Internal string storage.
+ */
+ char _storage[_builtinCapacity];
+ /**
+ * External string storage data -- the refcounter, and the
+ * capacity of the string _str points to.
+ */
+ struct {
+ mutable int *_refCount;
+ uint32 _capacity;
+ } _extern;
+ };
+
+ inline bool isStorageIntern() const {
+ return _str == _storage;
+ }
+
+public:
+ /** Construct a new empty string. */
+ String() : _size(0), _str(_storage) { _storage[0] = 0; }
+
+ /** Construct a new string from the given NULL-terminated C string. */
+ String(const char *str);
+
+ /** Construct a new string containing exactly len characters read from address str. */
+ String(const char *str, uint32 len);
+
+ /** Construct a new string containing the characters between beginP (including) and endP (excluding). */
+ String(const char *beginP, const char *endP);
+
+ /** Construct a copy of the given string. */
+ String(const String &str);
+
+ /** Construct a string consisting of the given character. */
+ explicit String(char c);
+
+ ~String();
+
+ String &operator=(const char *str);
+ String &operator=(const String &str);
+ String &operator=(char c);
+ String &operator+=(const char *str);
+ String &operator+=(const String &str);
+ String &operator+=(char c);
+
+ bool operator==(const String &x) const;
+ bool operator==(const char *x) const;
+ bool operator!=(const String &x) const;
+ bool operator!=(const char *x) const;
+
+ bool operator<(const String &x) const;
+ bool operator<=(const String &x) const;
+ bool operator>(const String &x) const;
+ bool operator>=(const String &x) const;
+
+ bool equals(const String &x) const;
+ bool equalsIgnoreCase(const String &x) const;
+ int compareTo(const String &x) const; // strcmp clone
+ int compareToIgnoreCase(const String &x) const; // stricmp clone
+
+ bool equals(const char *x) const;
+ bool equalsIgnoreCase(const char *x) const;
+ int compareTo(const char *x) const; // strcmp clone
+ int compareToIgnoreCase(const char *x) const; // stricmp clone
+
+ bool hasSuffix(const String &x) const;
+ bool hasSuffix(const char *x) const;
+
+ bool hasPrefix(const String &x) const;
+ bool hasPrefix(const char *x) const;
+
+ bool contains(const String &x) const;
+ bool contains(const char *x) const;
+ bool contains(char x) const;
+
+ inline const char *c_str() const { return _str; }
+ inline uint size() const { return _size; }
+
+ inline bool empty() const { return (_size == 0); }
+ char firstChar() const { return (_size > 0) ? _str[0] : 0; }
+ char lastChar() const { return (_size > 0) ? _str[_size - 1] : 0; }
+
+ char operator[](int idx) const {
+ assert(_str && idx >= 0 && idx < (int)_size);
+ return _str[idx];
+ }
+
+ /** Remove the last character from the string. */
+ void deleteLastChar();
+
+ /** Remove the character at position p from the string. */
+ void deleteChar(uint32 p);
+
+ /** Remove all characters from position p to the p + len. If len = String::npos, removes all characters to the end */
+ void erase(uint32 p, uint32 len = npos);
+
+ /** Set character c at position p, replacing the previous character there. */
+ void setChar(char c, uint32 p);
+
+ /** Insert character c before position p. */
+ void insertChar(char c, uint32 p);
+
+ /** Clears the string, making it empty. */
+ void clear();
+
+ /** Convert all characters in the string to lowercase. */
+ void toLowercase();
+
+ /** Convert all characters in the string to uppercase. */
+ void toUppercase();
+
+ /**
+ * Removes trailing and leading whitespaces. Uses isspace() to decide
+ * what is whitespace and what not.
+ */
+ void trim();
+
+ uint hash() const;
+
+ /**
+ * Print formatted data into a String object. Similar to sprintf,
+ * except that it stores the result in (variably sized) String
+ * instead of a fixed size buffer.
+ */
+ static String format(const char *fmt, ...) GCC_PRINTF(1,2);
+
+ /**
+ * Print formatted data into a String object. Similar to vsprintf,
+ * except that it stores the result in (variably sized) String
+ * instead of a fixed size buffer.
+ */
+ static String vformat(const char *fmt, va_list args);
+
+public:
+ typedef char value_type;
+ /**
+ * Unsigned version of the underlying type. This can be used to cast
+ * individual string characters to bigger integer types without sign
+ * extension happening.
+ */
+ typedef unsigned char unsigned_type;
+ typedef char * iterator;
+ typedef const char * const_iterator;
+
+ iterator begin() {
+ // Since the user could potentially
+ // change the string via the returned
+ // iterator we have to assure we are
+ // pointing to a unique storage.
+ makeUnique();
+
+ return _str;
+ }
+
+ iterator end() {
+ return begin() + size();
+ }
+
+ const_iterator begin() const {
+ return _str;
+ }
+
+ const_iterator end() const {
+ return begin() + size();
+ }
+
+protected:
+ void makeUnique();
+ void ensureCapacity(uint32 new_size, bool keep_old);
+ void incRefCount() const;
+ void decRefCount(int *oldRefCount);
+ void initWithCStr(const char *str, uint32 len);
+};
+
+// Append two strings to form a new (temp) string
+String operator+(const String &x, const String &y);
+
+String operator+(const char *x, const String &y);
+String operator+(const String &x, const char *y);
+
+String operator+(const String &x, char y);
+String operator+(char x, const String &y);
+
+// Some useful additional comparison operators for Strings
+bool operator==(const char *x, const String &y);
+bool operator!=(const char *x, const String &y);
+
+// Utility functions to remove leading and trailing whitespaces
+extern char *ltrim(char *t);
+extern char *rtrim(char *t);
+extern char *trim(char *t);
+
+
+/**
+ * Returns the last component of a given path.
+ *
+ * Examples:
+ * /foo/bar.txt would return 'bar.txt'
+ * /foo/bar/ would return 'bar'
+ * /foo/./bar// would return 'bar'
+ *
+ * @param path the path of which we want to know the last component
+ * @param sep character used to separate path components
+ * @return The last component of the path.
+ */
+String lastPathComponent(const String &path, const char sep);
+
+/**
+ * Normalize a given path to a canonical form. In particular:
+ * - trailing separators are removed: /foo/bar/ -> /foo/bar
+ * - double separators (= empty components) are removed: /foo//bar -> /foo/bar
+ * - dot components are removed: /foo/./bar -> /foo/bar
+ *
+ * @todo remove double dot components: /foo/baz/../bar -> /foo/bar
+ *
+ * @param path the path to normalize
+ * @param sep the separator token (usually '/' on Unix-style systems, or '\\' on Windows based stuff)
+ * @return the normalized path
+ */
+String normalizePath(const String &path, const char sep);
+
+
+/**
+ * Simple DOS-style pattern matching function (understands * and ? like used in DOS).
+ * Taken from exult/files/listfiles.cc
+ *
+ * Token meaning:
+ * "*": any character, any amount of times.
+ * "?": any character, only once.
+ * "#": any decimal digit, only once.
+ *
+ * Example strings/patterns:
+ * String: monkey.s01 Pattern: monkey.s?? => true
+ * String: monkey.s101 Pattern: monkey.s?? => false
+ * String: monkey.s99 Pattern: monkey.s?1 => false
+ * String: monkey.s101 Pattern: monkey.s* => true
+ * String: monkey.s99 Pattern: monkey.s*1 => false
+ * String: monkey.s01 Pattern: monkey.s## => true
+ * String: monkey.s01 Pattern: monkey.### => false
+ *
+ * @param str Text to be matched against the given pattern.
+ * @param pat Glob pattern.
+ * @param ignoreCase Whether to ignore the case when doing pattern match
+ * @param pathMode Whether to use path mode, i.e., whether slashes must be matched explicitly.
+ *
+ * @return true if str matches the pattern, false otherwise.
+ */
+bool matchString(const char *str, const char *pat, bool ignoreCase = false, bool pathMode = false);
+
+
+/**
+ * Take a 32 bit value and turn it into a four character string, where each of
+ * the four bytes is turned into one character. Most significant byte is printed
+ * first.
+ */
+String tag2string(uint32 tag);
+
+/**
+ * Copy up to size - 1 characters from src to dst and also zero terminate the
+ * result. Note that src must be a zero terminated string.
+ *
+ * In case size is zero this function just returns the length of the source
+ * string.
+ *
+ * @note This is modeled after OpenBSD's strlcpy. See the manpage here:
+ * http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy
+ *
+ * @param dst The destination buffer.
+ * @param src The source string.
+ * @param size The size of the destination buffer.
+ * @return The length of the (non-truncated) result, i.e. strlen(src).
+ */
+size_t strlcpy(char *dst, const char *src, size_t size);
+
+/**
+ * Append the string src to the string dst. Note that both src and dst must be
+ * zero terminated. The result will be zero terminated. At most
+ * "size - strlen(dst) - 1" bytes will be appended.
+ *
+ * In case the dst string does not contain a zero within the first "size" bytes
+ * the dst string will not be changed and size + strlen(src) is returned.
+ *
+ * @note This is modeled after OpenBSD's strlcat. See the manpage here:
+ * http://www.openbsd.org/cgi-bin/man.cgi?query=strlcat
+ *
+ * @param dst The string the source string should be appended to.
+ * @param src The source string.
+ * @param size The (total) size of the destination buffer.
+ * @return The length of the (non-truncated) result. That is
+ * strlen(dst) + strlen(src). In case strlen(dst) > size
+ * size + strlen(src) is returned.
+ */
+size_t strlcat(char *dst, const char *src, size_t size);
+
+/**
+ * Convenience wrapper for tag2string which "returns" a C string.
+ * Note: It is *NOT* safe to do anything with the return value other than directly
+ * copying or printing it.
+ */
+#define tag2str(x) Common::tag2string(x).c_str()
+
+
+} // End of namespace Common
+
+extern int scumm_stricmp(const char *s1, const char *s2);
+extern int scumm_strnicmp(const char *s1, const char *s2, uint n);
+
+#endif
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index d76e168..fa650dc 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -71,6 +71,9 @@ toon.dat FILE "dists/engine-data/toon.dat"
#if ENABLE_WINTERMUTE == STATIC_PLUGIN
wintermute.zip FILE "dists/engine-data/wintermute.zip"
#endif
+#if ENABLE_XEEN == STATIC_PLUGIN
+xeen.ccs FILE "dists/engine-data/xeen.ccs"
+#endif
#if ENABLE_AGI == STATIC_PLUGIN
pred.dic FILE "dists/pred.dic"
#endif
diff --git a/dists/scummvm.rc.in b/dists/scummvm.rc.in
index f84418d..21cd8a4 100644
--- a/dists/scummvm.rc.in
+++ b/dists/scummvm.rc.in
@@ -71,6 +71,9 @@ toon.dat FILE "dists/engine-data/toon.dat"
#if ENABLE_WINTERMUTE == STATIC_PLUGIN
wintermute.zip FILE "dists/engine-data/wintermute.zip"
#endif
+#if ENABLE_XEEN == STATIC_PLUGIN
+xeen.ccs FILE "dists/engine-data/xeen.ccs"
+#endif
#if ENABLE_AGI == STATIC_PLUGIN
pred.dic FILE "dists/pred.dic"
#endif
diff --git a/engines/xeen/character.cpp b/engines/xeen/character.cpp
index 7fc17a5..d98142e 100644
--- a/engines/xeen/character.cpp
+++ b/engines/xeen/character.cpp
@@ -61,7 +61,7 @@ AttributeCategory XeenItem::getAttributeCategory() const {
return (AttributeCategory)idx;
}
-const char *XeenItem::getItemName(ItemCategory category, uint id) {
+const Common::String &XeenItem::getItemName(ItemCategory category, uint id) {
if (id < 82)
return Res.ITEM_NAMES[category][id];
@@ -294,7 +294,7 @@ Common::String WeaponItems::getFullDescription(int itemIndex, int displayNum) {
(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
displayNum,
- Res.WEAPON_NAMES[i._id],
+ Res.WEAPON_NAMES[i._id].c_str(),
!i._bonusFlags ? "" : Res.BONUS_NAMES[i._bonusFlags & ITEMFLAG_BONUS_MASK],
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._bonusFlags ? "\b " : ""
@@ -451,10 +451,10 @@ Common::String ArmorItems::getFullDescription(int itemIndex, int displayNum) {
return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
- (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
- (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
+ (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN.c_str() : "",
+ (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED.c_str() : "",
displayNum,
- Res.ARMOR_NAMES[i._id],
+ Res.ARMOR_NAMES[i._id].c_str(),
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._bonusFlags ? "\b " : ""
);
@@ -568,10 +568,10 @@ Common::String AccessoryItems::getFullDescription(int itemIndex, int displayNum)
return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
- (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
- (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
+ (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN.c_str() : "",
+ (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED.c_str() : "",
displayNum,
- Res.ARMOR_NAMES[i._id],
+ Res.ARMOR_NAMES[i._id].c_str(),
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._bonusFlags ? "\b " : ""
);
@@ -614,10 +614,10 @@ Common::String MiscItems::getFullDescription(int itemIndex, int displayNum) {
return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
- (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
- (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
+ (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN.c_str() : "",
+ (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED.c_str() : "",
displayNum,
- Res.ARMOR_NAMES[i._id],
+ Res.ARMOR_NAMES[i._id].c_str(),
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._id ? "\b " : ""
);
@@ -993,7 +993,7 @@ int Character::statColor(int amount, int threshold) {
int Character::statBonus(uint statValue) const {
int idx;
- for (idx = 0; Res.STAT_VALUES[idx] <= statValue; ++idx)
+ for (idx = 0; Res.STAT_VALUES[idx] <= (int)statValue; ++idx)
;
return Res.STAT_BONUSES[idx];
diff --git a/engines/xeen/character.h b/engines/xeen/character.h
index bf4966c..480215a 100644
--- a/engines/xeen/character.h
+++ b/engines/xeen/character.h
@@ -106,7 +106,7 @@ public:
/**
* Return the name of the item
*/
- static const char *getItemName(ItemCategory category, uint id);
+ static const Common::String &getItemName(ItemCategory category, uint id);
public:
XeenItem();
@@ -140,7 +140,7 @@ class InventoryItems : public Common::Array<XeenItem> {
protected:
Character *_character;
ItemCategory _category;
- const char *const *_names;
+ const Common::String *_names;
XeenEngine *getVm();
void equipError(int itemIndex1, ItemCategory category1, int itemIndex2,
diff --git a/engines/xeen/dialogs_char_info.cpp b/engines/xeen/dialogs_char_info.cpp
index b7a7df8..132fbd5 100644
--- a/engines/xeen/dialogs_char_info.cpp
+++ b/engines/xeen/dialogs_char_info.cpp
@@ -359,7 +359,7 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
stat1 = c.getStat((Attribute)attrib, false);
stat2 = c.getStat((Attribute)attrib, true);
idx = 0;
- while (Res.STAT_VALUES[idx] <= stat1)
+ while (Res.STAT_VALUES[idx] <= (int)stat1)
++idx;
msg = Common::String::format(Res.CURRENT_MAXIMUM_RATING_TEXT, Res.STAT_NAMES[attrib],
@@ -434,9 +434,9 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
if (c._skills[skill]) {
if (skill == THIEVERY) {
lines[0] = Common::String::format("\n\t020%s%u",
- Res.SKILL_NAMES[THIEVERY], c.getThievery());
+ Res.SKILL_NAMES[THIEVERY].c_str(), c.getThievery());
} else {
- lines[skill] = Common::String::format("\n\t020%s", Res.SKILL_NAMES[skill]);
+ lines[skill] = Common::String::format("\n\t020%s", Res.SKILL_NAMES[skill].c_str());
}
}
}
@@ -446,7 +446,7 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
}
msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- Res.STAT_NAMES[attrib], lines[0].c_str(), lines[1].c_str(),
+ Res.STAT_NAMES[attrib].c_str(), lines[0].c_str(), lines[1].c_str(),
lines[2].c_str(), lines[3].c_str(), lines[4].c_str(), lines[5].c_str(),
lines[17].c_str(), lines[6].c_str(), lines[7].c_str(), lines[8].c_str(),
lines[9].c_str(), lines[10].c_str(), lines[11].c_str(), lines[12].c_str(),
@@ -505,10 +505,10 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
if (c._conditions[condition]) {
if (condition >= UNCONSCIOUS) {
lines[condition] = Common::String::format("\n\t020%s",
- Res.CONDITION_NAMES[condition]);
+ Res.CONDITION_NAMES[condition].c_str());
} else {
lines[condition] = Common::String::format("\n\t020%s\t095-%d",
- Res.CONDITION_NAMES[condition], c._conditions[condition]);
+ Res.CONDITION_NAMES[condition].c_str(), c._conditions[condition]);
}
++total;
@@ -517,7 +517,7 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
Condition condition = c.worstCondition();
if (condition == NO_CONDITION) {
- lines[0] = Common::String::format("\n\t020%s", Res.GOOD);
+ lines[0] = Common::String::format("\n\t020%s", Res.GOOD.c_str());
++total;
}
@@ -531,7 +531,7 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
lines[19] = Common::String::format(Res.HEROISM, party._heroism);
msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1",
- Res.CONSUMABLE_NAMES[3], lines[0].c_str(), lines[1].c_str(),
+ Res.CONSUMABLE_NAMES[3].c_str(), lines[0].c_str(), lines[1].c_str(),
lines[2].c_str(), lines[3].c_str(), lines[4].c_str(),
lines[5].c_str(), lines[6].c_str(), lines[7].c_str(),
lines[8].c_str(), lines[9].c_str(), lines[10].c_str(),
diff --git a/engines/xeen/dialogs_create_char.cpp b/engines/xeen/dialogs_create_char.cpp
index 73aa4b3..c1c6bc8 100644
--- a/engines/xeen/dialogs_create_char.cpp
+++ b/engines/xeen/dialogs_create_char.cpp
@@ -384,7 +384,7 @@ int CreateCharacterDialog::newCharDetails(Race race, Sex sex, int classId,
// If a class is provided, set the class name
if (classId != -1) {
- classStr = Common::String::format("\t062\v168%s", Res.CLASS_NAMES[classId]);
+ classStr = Common::String::format("\t062\v168%s", Res.CLASS_NAMES[classId].c_str());
}
// Set up default skill for the race, if any
diff --git a/engines/xeen/dialogs_items.cpp b/engines/xeen/dialogs_items.cpp
index c9249f3..bbf7fa4 100644
--- a/engines/xeen/dialogs_items.cpp
+++ b/engines/xeen/dialogs_items.cpp
@@ -1052,7 +1052,7 @@ void ItemsDialog::itemToGold(Character &c, int itemIndex, ItemCategory category,
if (category == CATEGORY_WEAPON && item._id == 34) {
sound.playFX(21);
ErrorScroll::show(_vm, Common::String::format("\v012\t000\x03""c%s",
- Res.SPELL_FAILED));
+ Res.SPELL_FAILED.c_str()));
} else if (item._id != 0) {
// There is a valid item present
// Calculate cost of item and add it to the party's total
diff --git a/engines/xeen/dialogs_quests.cpp b/engines/xeen/dialogs_quests.cpp
index 5e5171e..73035b3 100644
--- a/engines/xeen/dialogs_quests.cpp
+++ b/engines/xeen/dialogs_quests.cpp
@@ -91,7 +91,7 @@ void Quests::execute() {
case 83:
case 84:
lines[count++] = Common::String::format("%d %s%c",
- party._questItems[idx], Res.QUEST_ITEM_NAMES[idx],
+ party._questItems[idx], Res.QUEST_ITEM_NAMES[idx].c_str(),
party._questItems[idx] == 1 ? ' ' : 's');
break;
default:
diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp
index cd31d5b..96917e2 100644
--- a/engines/xeen/dialogs_spells.cpp
+++ b/engines/xeen/dialogs_spells.cpp
@@ -345,7 +345,7 @@ const char *SpellsDialog::setSpellText(Character *c, int isCasting) {
if (party._mazeId == 49 || party._mazeId == 37) {
for (uint spellId = 0; spellId < 76; ++spellId) {
int idx = 0;
- while (idx < MAX_SPELLS_PER_CLASS && Res.SPELLS_ALLOWED[category][idx] != spellId)
+ while (idx < MAX_SPELLS_PER_CLASS && Res.SPELLS_ALLOWED[category][idx] != (int)spellId)
++idx;
// Handling if the spell is appropriate for the character's class
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index 3d536a4..2ba3b6f 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -218,16 +218,25 @@ Common::SeekableReadStream *CCArchive::createReadStreamForMember(const Common::S
/*------------------------------------------------------------------------*/
FileManager::FileManager(XeenEngine *vm) {
- Common::File f;
_isDarkCc = vm->getGameID() == GType_DarkSide;
-
- if (vm->getGameID() == GType_Swords) {
+ File::_xeenCc = File::_darkCc = nullptr;
+}
+
+FileManager::~FileManager() {
+ SearchMan.remove("intro");
+ SearchMan.remove("data");
+ delete File::_xeenCc;
+ delete File::_darkCc;
+}
+
+bool FileManager::setup() {
+ if (g_vm->getGameID() == GType_Swords) {
File::_xeenCc = nullptr;
File::_darkCc = new CCArchive("swrd.cc", "xeen", true);
} else {
- File::_xeenCc = (vm->getGameID() == GType_DarkSide) ? nullptr :
+ File::_xeenCc = (g_vm->getGameID() == GType_DarkSide) ? nullptr :
new CCArchive("xeen.cc", "xeen", true);
- File::_darkCc = (vm->getGameID() == GType_Clouds) ? nullptr :
+ File::_darkCc = (g_vm->getGameID() == GType_Clouds) ? nullptr :
new CCArchive("dark.cc", "dark", true);
}
@@ -236,15 +245,26 @@ FileManager::FileManager(XeenEngine *vm) {
SearchMan.add("intro", File::_introCc);
}
- File::_currentArchive = vm->getGameID() == GType_DarkSide || vm->getGameID() == GType_Swords ?
+ File::_currentArchive = g_vm->getGameID() == GType_DarkSide || g_vm->getGameID() == GType_Swords ?
File::_darkCc : File::_xeenCc;
assert(File::_currentArchive);
-}
-FileManager::~FileManager() {
- SearchMan.remove("intro");
- delete File::_xeenCc;
- delete File::_darkCc;
+ // Ensure the custom CC archive is present
+ File f;
+ if (!f.exists("xeen.ccs")) {
+ g_vm->GUIError("Could not find xeen.ccs data file");
+ return false;
+ }
+
+ // Verify the version of the CC is correct
+ CCArchive *dataCc = new CCArchive("xeen.ccs", "data", true);
+ if (!f.open("VERSION", *dataCc) || f.readUint32LE() != 1) {
+ g_vm->GUIError("xeen.ccs is out of date");
+ return false;
+ }
+ SearchMan.add("data", dataCc);
+
+ return true;
}
void FileManager::setGameCc(int ccMode) {
diff --git a/engines/xeen/files.h b/engines/xeen/files.h
index 3a4c4b1..4ceadcd 100644
--- a/engines/xeen/files.h
+++ b/engines/xeen/files.h
@@ -90,6 +90,12 @@ public:
~FileManager();
/**
+ * Sets up the CC files
+ * @returns Returns true if the setup was successful
+ */
+ bool setup();
+
+ /**
* Set which game side files to use
* @param ccMode 0=Clouds, 1=Dark Side
*/
diff --git a/engines/xeen/locations.cpp b/engines/xeen/locations.cpp
index 7a82905..53a1c80 100644
--- a/engines/xeen/locations.cpp
+++ b/engines/xeen/locations.cpp
@@ -69,7 +69,7 @@ int BaseLocation::show() {
// Load the needed sprite sets for the location
for (uint idx = 0; idx < _townSprites.size(); ++idx) {
Common::String shapesName = Common::String::format("%s%d.twn",
- Res.TOWN_ACTION_SHAPES[_locationActionId], idx + 1);
+ Res.TOWN_ACTION_SHAPES[_locationActionId].c_str(), idx + 1);
_townSprites[idx].load(shapesName);
}
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index 8bb04b1..58a294c 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -38,24 +38,6 @@ const int MAP_GRID_PRIOR_INDEX2[] = { 0, 0, 0, 0, 2, 3, 4, 1, 0 };
const int MAP_GRID_PRIOR_DIRECTION2[] = { 0, 1, 2, 3, 0, 1, 2, 3, 0 };
-const char *const MUSIC_FILES1[5] = {
- "outdoors.m", "town.m", "cavern.m", "dungeon.m", "castle.m"
-};
-
-const char *const MUSIC_FILES2[6][7] = {
- { "outday1.m", "outday2.m", "outday4.m", "outnght1.m",
- "outnght2.m", "outnght4.m", "daydesrt.m" },
- { "townday1.m", "twnwlk.m", "newbrigh.m", "twnnitea.m",
- "twnniteb.m", "twnwlk.m", "townday1.m" },
- { "cavern1.m", "cavern2.m", "cavern3a.m", "cavern1.m",
- "cavern2.m", "cavern3a.m", "cavern1.m" },
- { "dngon1.m", "dngon2.m", "dngon3.m", "dngon1.m",
- "dngon2.m", "dngon3.m", "dngon1.m" },
- { "cstl1rev.m", "cstl2rev.m", "cstl3rev.m", "cstl1rev.m",
- "cstl2rev.m", "cstl3rev.m", "cstl1rev.m" },
- { "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m" }
-};
-
MonsterStruct::MonsterStruct() {
_experience = 0;
_hp = 0;
@@ -1194,7 +1176,7 @@ void Map::load(int mapId) {
if (_vm->_files->_isDarkCc) {
int randIndex = _vm->getRandomNumber(6);
- musName = MUSIC_FILES2[_mazeData->_wallKind][randIndex];
+ musName = Res.MUSIC_FILES2[_mazeData->_wallKind][randIndex];
} else {
musName = "outdoors.m";
}
@@ -1213,7 +1195,7 @@ void Map::load(int mapId) {
if (_mazeData[0]._wallTypes[i] != 0) {
_wallSprites._surfaces[i].load(Common::String::format("%s.wal",
- Res.OUTDOORS_WALL_TYPES[_mazeData[0]._wallTypes[i]]));
+ Res.OUTDOORS_WALL_TYPES[_mazeData[0]._wallTypes[i]].c_str()));
}
_surfaceSprites[i].clear();
@@ -1232,20 +1214,20 @@ void Map::load(int mapId) {
_sideMusic = isDarkCc;
if (isDarkCc) {
int randIndex = _vm->getRandomNumber(6);
- musName = MUSIC_FILES2[MUS_INDEXES[_mazeData->_wallKind]][randIndex];
+ musName = Res.MUSIC_FILES2[MUS_INDEXES[_mazeData->_wallKind]][randIndex];
} else {
- musName = MUSIC_FILES1[MUS_INDEXES[_mazeData->_wallKind]];
+ musName = Res.MUSIC_FILES1[MUS_INDEXES[_mazeData->_wallKind]];
}
if (musName != sound._currentMusic)
sound.playSong(musName, 207);
// Load sprite sets needed for scene rendering
_skySprites[1].load(Common::String::format("%s.sky",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
_groundSprites.load(Common::String::format("%s.gnd",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
_tileSprites.load(Common::String::format("%s.til",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
for (int i = 0; i < TOTAL_SURFACES; ++i) {
_surfaceSprites[i].clear();
@@ -1258,15 +1240,15 @@ void Map::load(int mapId) {
_wallSprites._surfaces[i].clear();
_wallSprites._fwl1.load(Common::String::format("f%s1.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
_wallSprites._fwl2.load(Common::String::format("f%s2.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
_wallSprites._fwl3.load(Common::String::format("f%s3.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
_wallSprites._fwl4.load(Common::String::format("f%s4.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
_wallSprites._swl.load(Common::String::format("s%s.swl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
// Set entries in the indoor draw list to the correct sprites
// for drawing various parts of the background
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index dcbc7de..68bc768 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -720,7 +720,7 @@ void Party::giveTreasureToCharacter(Character &c, ItemCategory category, int ite
w.update();
events.ipause(5);
- const char *itemName = XeenItem::getItemName(category, treasureItem._id);
+ const char *itemName = XeenItem::getItemName(category, treasureItem._id).c_str();
w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), itemName));
w.update();
events.ipause(5);
@@ -817,7 +817,7 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
}
for (int idx = 0; idx < 39; ++idx) {
- if (Res.SPELLS_ALLOWED[idx2][idx] == takeVal) {
+ if (Res.SPELLS_ALLOWED[idx2][idx] == (int)takeVal) {
ps._spells[idx] = false;
break;
}
@@ -1086,7 +1086,7 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
}
for (int idx = 0; idx < 39; ++idx) {
- if (Res.SPELLS_ALLOWED[idx2][idx] == giveVal) {
+ if (Res.SPELLS_ALLOWED[idx2][idx] == (int)giveVal) {
ps._spells[idx] = true;
intf.spellFX(&ps);
break;
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 7048726..86dc441 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -30,16 +30,6 @@ namespace Xeen {
Resources *g_resources;
-Resources *Resources::init(XeenEngine *vm) {
- if (vm->getGameID() == GType_Clouds || vm->getGameID() == GType_DarkSide
- || vm->getGameID() == GType_WorldOfXeen)
- g_resources = new WorldOfXeen::WorldOfXeenResources();
- else
- g_resources = new Resources();
-
- return g_resources;
-}
-
Resources::Resources() {
g_resources = this;
g_vm->_files->setGameCc(1);
@@ -50,1702 +40,343 @@ Resources::Resources() {
while (f.pos() < f.size())
_maeNames.push_back(f.readString());
f.close();
-}
-
-/*------------------------------------------------------------------------*/
-
-const char *const Resources::CREDITS =
- "\013""012\010""000\003""c\014""35Designed and Directed By:\n"
- "\014""17Jon Van Caneghem\003""l\n"
- "\n"
- "\t025\014""35Programming:\n"
- "\t035\014""17Mark Caldwell\n"
- "\t035Dave Hathaway\n"
- "\n"
- "\t025\014""35Sound System & FX:\n"
- "\t035\014""17Mike Heilemann\n"
- "\n"
- "\t025\014""35Music & Speech:\n"
- "\t035\014""17Tim Tully\n"
- "\n"
- "\t025\014""35Writing:\n"
- "\t035\014""17Paul Rattner\n"
- "\t035Debbie Van Caneghem\n"
- "\t035Jon Van Caneghem\013""012\n"
- "\n"
- "\n"
- "\t180\014""35Graphics:\n"
- "\t190\014""17Jonathan P. Gwyn\n"
- "\t190Bonita Long-Hemsath\n"
- "\t190Julia Ulano\n"
- "\t190Ricardo Barrera\n"
- "\n"
- "\t180\014""35Testing:\n"
- "\t190\014""17Benjamin Bent\n"
- "\t190Christian Dailey\n"
- "\t190Mario Escamilla\n"
- "\t190Marco Hunter\n"
- "\t190Robert J. Lupo\n"
- "\t190Clayton Retzer\n"
- "\t190David Vela\003""c";
-
-const char *const Resources::OPTIONS_TITLE =
- "\x0D\x01\003""c\014""dMight and Magic Options\n"
- "World of Xeen\x02\n"
- "\v117Copyright (c) 1993 NWC, Inc.\n"
- "All Rights Reserved\x01";
-
-const char *const Resources::THE_PARTY_NEEDS_REST = "\x0B""012The Party needs rest!";
-
-const char *const Resources::WHO_WILL = "\x03""c\x0B""000\x09""000%s\x0A\x0A"
- "Who will\x0A%s?\x0A\x0B""055F1 - F%d";
-
-const char *const Resources::HOW_MUCH = "\x3""cHow Much\n\n";
-
-const char *const Resources::WHATS_THE_PASSWORD = "What's the Password?";
-
-const char *const Resources::IN_NO_CONDITION = "\x0B""007%s is not in any condition to perform actions!";
-
-const char *const Resources::NOTHING_HERE = "\x03""c\x0B""010Nothing here.";
-
-const char *const Resources::TERRAIN_TYPES[6] = {
- "town", "cave", "towr", "cstl", "dung", "scfi"
-};
-
-const char *const Resources::OUTDOORS_WALL_TYPES[16] = {
- nullptr, "mount", "ltree", "dtree", "grass", "snotree", "dsnotree",
- "snomnt", "dedltree", "mount", "lavamnt", "palm", "dmount", "dedltree",
- "dedltree", "dedltree"
-};
-
-const char *const Resources::SURFACE_NAMES[16] = {
- "water.srf", "dirt.srf", "grass.srf", "snow.srf", "swamp.srf",
- "lava.srf", "desert.srf", "road.srf", "dwater.srf", "tflr.srf",
- "sky.srf", "croad.srf", "sewer.srf", "cloud.srf", "scortch.srf",
- "space.srf"
-};
-
-const char *const Resources::WHO_ACTIONS[32] = {
- "search", "open", "drink", "mine", "touch", "read", "learn", "take",
- "bang", "steal", "bribe", "pay", "sit", "try", "turn", "bathe",
- "destroy", "pull", "descend", "toss a coin", "pray", "join", "act",
- "play", "push", "rub", "pick", "eat", "sign", "close", "look", "try"
-};
-
-const char *const Resources::WHO_WILL_ACTIONS[4] = {
- "Open Grate", "Open Door", "Open Scroll", "Select Char"
-};
-
-const byte Resources::SYMBOLS[20][64] = {
- { // 0
- 0x00, 0x00, 0xA8, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x00, 0xA8, 0x9E, 0x9C, 0x9C, 0x9E, 0x9E, 0x9E,
- 0xAC, 0x9C, 0xA4, 0xAC, 0xAC, 0x9A, 0x9A, 0x9A, 0xAC, 0x9E, 0xAC, 0xA8, 0xA8, 0xA6, 0x97, 0x98,
- 0xAC, 0xA0, 0xAC, 0xAC, 0xA4, 0xA6, 0x98, 0x99, 0x00, 0xAC, 0xA0, 0xA0, 0xA8, 0xAC, 0x9A, 0x9A,
- 0x00, 0x00, 0xAC, 0xAC, 0xAC, 0xA4, 0x9B, 0x9A, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xA0, 0x9B, 0x9B,
- },
- { // 1
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
- 0x99, 0x9A, 0x9A, 0x99, 0x99, 0x99, 0x9A, 0x99, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x99, 0x98, 0x98, 0x99, 0x98, 0x98, 0x99, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
- 0x9A, 0x9B, 0x9B, 0x9C, 0x9B, 0x9A, 0x9C, 0x9A, 0x9B, 0x9A, 0x99, 0x99, 0x99, 0x9A, 0x9A, 0x9B,
- },
- { // 2
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
- 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x99, 0x98, 0x98, 0x99, 0x98, 0x98, 0x97, 0x98, 0x98,
- 0x99, 0x98, 0x98, 0x98, 0x99, 0x99, 0x98, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
- 0x9B, 0x9B, 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0x9B, 0x99, 0x9A, 0x9B, 0x9B, 0x9A, 0x9A, 0x99, 0x9A,
- },
- { // 3
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
- 0x99, 0x9A, 0x9A, 0x9A, 0x99, 0x99, 0x99, 0x9A, 0x98, 0x98, 0x97, 0x97, 0x98, 0x98, 0x98, 0x98,
- 0x99, 0x99, 0x98, 0x99, 0x98, 0x98, 0x99, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
- 0x9B, 0x9C, 0x9B, 0x9B, 0x9C, 0x9C, 0x9C, 0x9C, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x99, 0x99, 0x9A,
- },
- { // 4
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
- 0x9A, 0x9A, 0x9A, 0x99, 0x99, 0x99, 0x99, 0x9A, 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98,
- 0x99, 0x99, 0x98, 0x99, 0x99, 0x98, 0x98, 0x98, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
- 0x9A, 0x9C, 0x9B, 0x9B, 0x9C, 0x9B, 0x9B, 0x9B, 0x9A, 0x99, 0x9B, 0x9B, 0x9A, 0x99, 0x9A, 0x9A,
- },
- { // 5
- 0xA4, 0xA4, 0xA8, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x9E, 0x9E, 0xA0, 0xA8, 0xAC, 0x00, 0x00,
- 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9E, 0xAC, 0x00, 0x97, 0x97, 0x97, 0x98, 0x9C, 0x9C, 0xA0, 0xAC,
- 0x99, 0x98, 0x99, 0x99, 0x99, 0x9B, 0xA0, 0xAC, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9B, 0xA0, 0xAC,
- 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x9A, 0x9A, 0x9B, 0x9B, 0xA4, 0xAC, 0x00,
- },
- { // 6
- 0x00, 0x00, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x00, 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x9B, 0x99,
- 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x98, 0x99, 0x99,
- 0x00, 0xAC, 0xA0, 0x9C, 0x9C, 0xA0, 0x9C, 0x9A, 0x00, 0x00, 0xAC, 0xA4, 0xA0, 0x99, 0x99, 0x99,
- 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99,
- },
- { // 7
- 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0xAC, 0xA4, 0x9C, 0x9C, 0x99, 0x99,
- 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99,
- 0x00, 0x00, 0xAC, 0xA0, 0x9B, 0xA0, 0x9E, 0x9C, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x9C, 0x99, 0x99,
- },
- { // 8
- 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x9B, 0x99, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x9C, 0x99, 0x00, 0xAC, 0xA4, 0x9C, 0x99, 0x9E, 0x9C, 0x99,
- },
- { // 9
- 0x00, 0x00, 0xAC, 0xA4, 0xA0, 0x9C, 0x99, 0x99, 0x00, 0xAC, 0xA0, 0x9C, 0x9C, 0xA0, 0x9C, 0x9A,
- 0xAC, 0xA4, 0x9C, 0x9A, 0x99, 0x99, 0x99, 0x99, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0xAC, 0xA4, 0x9C, 0x99, 0x99, 0x99, 0x99, 0x99, 0x00, 0xAC, 0xA0, 0x9C, 0x99, 0x99, 0x99, 0x99,
- 0x00, 0xAC, 0xA4, 0x9C, 0x9A, 0x9C, 0x99, 0x99, 0x00, 0x00, 0xAC, 0xA0, 0x9C, 0x9A, 0x99, 0x99,
- },
- { // 10
- 0x99, 0x99, 0x99, 0x9A, 0xA0, 0xAC, 0x00, 0x00, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x00,
- 0x99, 0x99, 0x9C, 0x9E, 0xA4, 0xAC, 0x00, 0x00, 0x99, 0x99, 0x9C, 0x99, 0x9C, 0xA4, 0xAC, 0x00,
- 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x00,
- 0x99, 0x99, 0x99, 0xA0, 0xA4, 0xAC, 0x00, 0x00, 0x9A, 0x9B, 0x9E, 0x9C, 0x9C, 0xA4, 0xAC, 0x00,
- },
- { // 11
- 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0x9E, 0xAC,
- 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
- 0x9C, 0x99, 0x99, 0x99, 0x9C, 0x9C, 0xA4, 0xAC, 0x99, 0x9E, 0x9E, 0x9C, 0x9C, 0xA0, 0xAC, 0x00,
- },
- { // 12
- 0x99, 0x99, 0x9C, 0xA0, 0xA4, 0xAC, 0x00, 0x00, 0x9B, 0x9C, 0x9E, 0x9C, 0x9C, 0xA4, 0xAC, 0x00,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
- 0x99, 0x99, 0x99, 0x99, 0x9C, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xA4, 0xAC, 0x00,
- 0x99, 0x99, 0x9C, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
- },
- { // 13
- 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC, 0x00, 0x00,
- 0x99, 0x9B, 0x9C, 0xA0, 0xA4, 0xAC, 0x00, 0x00, 0x99, 0x99, 0x9A, 0x99, 0x9C, 0xA0, 0xAC, 0x00,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9C, 0xA0, 0xAC,
- 0x99, 0x99, 0x99, 0x99, 0x9A, 0x9C, 0xA4, 0xAC, 0x99, 0x99, 0x99, 0x9A, 0x9C, 0xA4, 0xAC, 0x00,
- },
- { // 14
- 0x00, 0x00, 0xAC, 0x9E, 0x9C, 0x9C, 0x9C, 0x9B, 0x00, 0xAC, 0x9C, 0xA0, 0x9E, 0xA4, 0xA4, 0xA4,
- 0xAC, 0x9C, 0xA4, 0xAC, 0xAC, 0xAC, 0x9C, 0x9E, 0xAC, 0xA0, 0xAC, 0xA8, 0x9E, 0xA8, 0xAC, 0x99,
- 0xAC, 0x9E, 0xAC, 0xA8, 0xAC, 0x9E, 0xA4, 0xAC, 0xAC, 0xA4, 0xA0, 0xAC, 0xAC, 0xA0, 0xA4, 0xAC,
- 0x00, 0xAC, 0xA4, 0xA0, 0xA0, 0xA4, 0xAC, 0xA4, 0x00, 0x00, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
- },
- { // 15
- 0x9C, 0x9C, 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0x9B, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
- 0x9E, 0x9E, 0x9E, 0x9C, 0x9E, 0x9E, 0x9E, 0x9E, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x99, 0x98,
- 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0x9C, 0x9C, 0x9C, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0x9E, 0x9E, 0xA0,
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
- },
- { // 16
- 0x9B, 0x9B, 0x9B, 0x9B, 0x9C, 0x9B, 0x9C, 0x9C, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
- 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9E, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99,
- 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0xA0, 0xA0, 0xA0, 0x9E, 0xA0, 0x9E, 0x9E, 0xA0,
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
- },
- { // 17
- 0x9C, 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0x9C, 0x9B, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
- 0x9E, 0x9E, 0x9E, 0x9C, 0x9C, 0x9C, 0x9E, 0x9E, 0x98, 0x98, 0x98, 0x99, 0x9A, 0x9A, 0x99, 0x98,
- 0x9C, 0x9B, 0x9C, 0x9C, 0x9C, 0x9B, 0x9B, 0x9C, 0xA0, 0x9E, 0x9E, 0xA0, 0xA0, 0xA0, 0xA0, 0x9E,
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
- },
- { // 18
- 0x9B, 0x9B, 0x9C, 0x9C, 0x9C, 0x9B, 0x9B, 0x9B, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4,
- 0x9E, 0x9E, 0x9E, 0x9E, 0x9C, 0x9C, 0x9C, 0x9E, 0x98, 0x98, 0x98, 0x98, 0x9A, 0x9A, 0x98, 0x99,
- 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9B, 0x9C, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0xA0, 0xA0, 0xA0,
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC,
- },
- { // 19
- 0x9C, 0x9B, 0x9C, 0x9C, 0xA0, 0xA4, 0xAC, 0x00, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0x00, 0x00,
- 0x9E, 0x9E, 0x9C, 0x9C, 0x9E, 0xA0, 0xAC, 0x00, 0x99, 0x98, 0x98, 0x99, 0x9A, 0x9A, 0xA0, 0xAC,
- 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0xA0, 0xAC, 0xA0, 0xA0, 0x9E, 0xA0, 0xA0, 0xA0, 0xA0, 0xAC,
- 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xAC, 0x00, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0x00, 0x00,
- }
-};
-
-const byte Resources::TEXT_COLORS[40][4] = {
- { 0x00, 0x19, 0x19, 0x19 },
- { 0x00, 0x08, 0x08, 0x08 },
- { 0x00, 0x0F, 0x0F, 0x0F },
- { 0x00, 0x15, 0x15, 0x15 },
- { 0x00, 0x01, 0x01, 0x01 },
- { 0x00, 0x21, 0x21, 0x21 },
- { 0x00, 0x26, 0x26, 0x26 },
- { 0x00, 0x2B, 0x2B, 0x2B },
- { 0x00, 0x31, 0x31, 0x31 },
- { 0x00, 0x36, 0x36, 0x36 },
- { 0x00, 0x3D, 0x3D, 0x3D },
- { 0x00, 0x41, 0x41, 0x41 },
- { 0x00, 0x46, 0x46, 0x46 },
- { 0x00, 0x4C, 0x4C, 0x4C },
- { 0x00, 0x50, 0x50, 0x50 },
- { 0x00, 0x55, 0x55, 0x55 },
- { 0x00, 0x5D, 0x5D, 0x5D },
- { 0x00, 0x60, 0x60, 0x60 },
- { 0x00, 0x65, 0x65, 0x65 },
- { 0x00, 0x6C, 0x6C, 0x6C },
- { 0x00, 0x70, 0x70, 0x70 },
- { 0x00, 0x75, 0x75, 0x75 },
- { 0x00, 0x7B, 0x7B, 0x7B },
- { 0x00, 0x80, 0x80, 0x80 },
- { 0x00, 0x85, 0x85, 0x85 },
- { 0x00, 0x8D, 0x8D, 0x8D },
- { 0x00, 0x90, 0x90, 0x90 },
- { 0x00, 0x97, 0x97, 0x97 },
- { 0x00, 0x9D, 0x9D, 0x9D },
- { 0x00, 0xA4, 0xA4, 0xA4 },
- { 0x00, 0xAB, 0xAB, 0xAB },
- { 0x00, 0xB0, 0xB0, 0xB0 },
- { 0x00, 0xB6, 0xB6, 0xB6 },
- { 0x00, 0xBD, 0xBD, 0xBD },
- { 0x00, 0xC0, 0xC0, 0xC0 },
- { 0x00, 0xC6, 0xC6, 0xC6 },
- { 0x00, 0xCD, 0xCD, 0xCD },
- { 0x00, 0xD0, 0xD0, 0xD0 },
- { 0x00, 0xD6, 0xD6, 0xD6 },
- { 0x00, 0xDB, 0xDB, 0xDB },
-};
-
-const char *const Resources::DIRECTION_TEXT_UPPER[4] = { "NORTH", "EAST", "SOUTH", "WEST" };
-
-const char *const Resources::DIRECTION_TEXT[4] = { "North", "East", "South", "West" };
-
-const char *const Resources::RACE_NAMES[5] = { "Human", "Elf", "Dwarf", "Gnome", "H-Orc" };
-
-const int Resources::RACE_HP_BONUSES[5] = { 0, -2, 1, -1, 2 };
-
-const int Resources::RACE_SP_BONUSES[5][2] = {
- { 0, 0 }, { 2, 0 }, { -1, -1 }, { 1, 1 }, { -2, -2 }
-};
-
-const char *const Resources::ALIGNMENT_NAMES[3] = { "Good", "Neutral", "Evil" };
-
-const char *const Resources::SEX_NAMES[2] = { "Male", "Female" };
-
-const char *const Resources::SKILL_NAMES[18] = {
- "Thievery\t100", "Arms Master", "Astrologer", "Body Builder", "Cartographer",
- "Crusader", "Direction Sense", "Linguist", "Merchant", "Mountaineer",
- "Navigator", "Path Finder", "Prayer Master", "Prestidigitator",
- "Swimmer", "Tracker", "Spot Secret Door", "Danger Sense"
-};
-
-const char *const Resources::CLASS_NAMES[11] = {
- "Knight", "Paladin", "Archer", "Cleric", "Sorcerer", "Robber",
- "Ninja", "Barbarian", "Druid", "Ranger", nullptr
-};
-
-const uint Resources::CLASS_EXP_LEVELS[10] = {
- 1500, 2000, 2000, 1500, 2000, 1000, 1500, 1500, 1500, 2000
-};
-
-const char *const Resources::CONDITION_NAMES[17] = {
- "Cursed", "Heart Broken", "Weak", "Poisoned", "Diseased",
- "Insane", "In Love", "Drunk", "Asleep", "Depressed", "Confused",
- "Paralyzed", "Unconscious", "Dead", "Stone", "Eradicated", "Good"
-};
-
-const int Resources::CONDITION_COLORS[17] = {
- 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32, 32, 6, 6, 6, 6, 15
-};
-
-const char *const Resources::GOOD = "Good";
-
-const char *const Resources::BLESSED = "\n\t020Blessed\t095%+d";
-
-const char *const Resources::POWER_SHIELD = "\n\t020Power Shield\t095%+d";
-
-const char *const Resources::HOLY_BONUS = "\n\t020Holy Bonus\t095%+d";
-
-const char *const Resources::HEROISM = "\n\t020Heroism\t095%+d";
-
-const char *const Resources::IN_PARTY = "\014""15In Party\014""d";
-
-const char *const Resources::PARTY_DETAILS = "\015\003l\002\014""00"
- "\013""001""\011""035%s"
- "\013""009""\011""035%s"
- "\013""017""\011""035%s"
- "\013""025""\011""035%s"
- "\013""001""\011""136%s"
- "\013""009""\011""136%s"
- "\013""017""\011""136%s"
- "\013""025""\011""136%s"
- "\013""044""\011""035%s"
- "\013""052""\011""035%s"
- "\013""060""\011""035%s"
- "\013""068""\011""035%s"
- "\013""044""\011""136%s"
- "\013""052""\011""136%s"
- "\013""060""\011""136%s"
- "\013""068""\011""136%s";
-const char *const Resources::PARTY_DIALOG_TEXT =
- "%s\x2\x3""c\v106\t013Up\t048Down\t083\f37D\fdel\t118\f37R\fdem"
- "\t153\f37C\fdreate\t188E\f37x\fdit\x1";
-
-const int Resources::FACE_CONDITION_FRAMES[17] = {
- 2, 2, 2, 1, 1, 4, 4, 4, 3, 2, 4, 3, 3, 5, 6, 7, 0
-};
-
-const int Resources::CHAR_FACES_X[6] = { 10, 45, 81, 117, 153, 189 };
-
-const int Resources::HP_BARS_X[6] = { 13, 50, 86, 122, 158, 194 };
-
-const char *const Resources::NO_ONE_TO_ADVENTURE_WITH = "You have no one to adventure with";
-
-const char *const Resources::YOUR_ROSTER_IS_FULL = "Your Roster is full!";
-
-const byte Resources::DARKNESS_XLAT[3][256] = {
- {
- 0, 25, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 44, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 60, 61, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 108, 109, 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 124, 125, 126, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 140, 141, 142, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 168, 169, 170, 171, 172, 173, 174, 175, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 188, 189, 190, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 204, 205, 206, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 220, 221, 222, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 236, 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 252, 253, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, {
- 0, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0,
- 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0,
- 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0,
- 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0,
- 104, 105, 106, 107, 108, 109, 110, 111, 0, 0, 0, 0, 0, 0, 0, 0,
- 120, 121, 122, 123, 124, 125, 126, 127, 0, 0, 0, 0, 0, 0, 0, 0,
- 136, 137, 138, 139, 140, 141, 142, 143, 0, 0, 0, 0, 0, 0, 0, 0,
- 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 184, 185, 186, 187, 188, 189, 190, 191, 0, 0, 0, 0, 0, 0, 0, 0,
- 200, 201, 202, 203, 204, 205, 206, 207, 0, 0, 0, 0, 0, 0, 0, 0,
- 216, 217, 218, 219, 220, 221, 222, 223, 0, 0, 0, 0, 0, 0, 0, 0,
- 232, 233, 234, 235, 236, 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, 0,
- 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0
- }, {
- 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0,
- 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0,
- 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 0, 0, 0, 0,
- 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 0, 0, 0, 0,
- 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 0, 0, 0, 0,
- 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
- 168, 169, 170, 171, 172, 173, 174, 175, 0, 0, 0, 0, 0, 0, 0, 0,
- 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 0, 0, 0, 0,
- 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, 0, 0, 0,
- 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 0, 0, 0, 0,
- 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 0, 0, 0, 0,
- 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, 0, 0
- }
-};
-
-const char *const Resources::PLEASE_WAIT = "\014""d\003""c\011""000"
- "\013""002Please Wait...";
-
-const char *const Resources::OOPS = "\003""c\011""000\013""002Oops...";
-
-const int8 Resources::SCREEN_POSITIONING_X[4][48] = {
- {
- -1, 0, 0, 0, 1, -1, 0, 0, 0, 1, -2, -1,
- -1, 0, 0, 0, 1, 1, 2, -4, -3, -3, -2, -2,
- -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4,
- -3, -2, -1, 0, 0, 1, 2, 3, -4, 4, 0, 0
- }, {
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 1
- }, {
- 1, 0, 0, 0, -1, 1, 0, 0, 0, -1, 2, 1,
- 1, 0, 0, 0, -1, -1, -2, 4, 3, 3, 2, 2,
- 1, 1, 0, 0, 0, -1, -1, -2, -2, -3, -3, -4,
- 3, 2, 1, 0, 0, -1, -2, -3, 4, -4, 0, 0
- }, {
- 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -2, -2,
- -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3,
- -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
- -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 0, -1
- }
-};
-
-const int8 Resources::SCREEN_POSITIONING_Y[4][48] = {
- {
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 1
- }, {
- 1, 0, 0, 0, -1, 1, 0, 0, 0, -1, 2, 1,
- 1, 0, 0, 0, -1, -1, -2, 4, 3, 3, 2, 2,
- 1, 1, 0, 0, 0, -1, -1, -2, -2, -3, -3, -4,
- 3, 2, 1, 0, 0, -1, -2, -3, 4, -4, 0, 0
- }, {
- 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -2, -2,
- -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3,
- -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
- -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 0, -1
- }, {
- -1, 0, 0, 0, 1, -1, 0, 0, 0, 1, -2, -1,
- -1, 0, 0, 0, 1, 1, 2, -4, -3, -3, -2, -2,
- -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4,
- -3, -2, -1, 0, 0, 1, 2, 3, -4, 4, 0, 0
- }
-};
-
-const int Resources::MONSTER_GRID_BITMASK[12] = {
- 0xC, 8, 4, 0, 0xF, 0xF000, 0xF00, 0xF0, 0xF00, 0xF0, 0x0F, 0xF000
-};
-
-const int Resources::INDOOR_OBJECT_X[2][12] = {
- { 5, -7, -112, 98, -8, -65, 49, -9, -34, 16, -58, 40 },
- { -35, -35, -142, 68, -35, -95, 19, -35, -62, -14, -98, 16 }
-};
-
-const int Resources::MAP_OBJECT_Y[2][12] = {
- { 2, 25, 25, 25, 50, 50, 50, 58, 58, 58, 58, 58 },
- { -65, -6, -6, -6, 36, 36, 36, 54, 54, 54, 54, 54 }
-};
-
-const int Resources::INDOOR_MONSTERS_Y[4] = { 2, 34, 53, 59 };
-
-const int Resources::OUTDOOR_OBJECT_X[2][12] = {
- { -5, -7, -112, 98, -8, -77, 61, -9, -43, 25, -74, 56 },
- { -35, -35, -142, 68, -35, -95, 19, -35, -62, -24, -98, 16 }
-};
-
-const int Resources::OUTDOOR_MONSTER_INDEXES[26] = {
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 69, 70,
- 71, 72, 73, 74, 75, 90, 91, 92, 93, 94, 112, 115, 118
-};
-
-const int Resources::OUTDOOR_MONSTERS_Y[26] = {
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 53, 53,
- 53, 53, 53, 53, 53, 34, 34, 34, 34, 34, 2, 2, 2
-};
-
-const int Resources::DIRECTION_ANIM_POSITIONS[4][4] = {
- { 0, 1, 2, 3 }, { 3, 0, 1, 2 }, { 2, 3, 0, 1 }, { 1, 2, 3, 0 }
-};
-
-const byte Resources::WALL_SHIFTS[4][48] = {
- {
- 12, 0, 12, 8, 12, 12, 0, 12, 8, 12, 12, 0,
- 12, 0, 12, 8, 12, 8, 12, 12, 0, 12, 0, 12,
- 0, 12, 0, 12, 8, 12, 8, 12, 8, 12, 8, 12,
- 0, 0, 0, 0, 8, 8, 8, 8, 0, 0, 4, 4
- }, {
- 8, 12, 8, 4, 8, 8, 12, 8, 4, 8, 8, 12,
- 8, 12, 8, 4, 8, 4, 8, 8, 12, 8, 12, 8,
- 12, 8, 12, 8, 4, 8, 4, 8, 4, 8, 4, 8,
- 12, 12, 12, 12, 4, 4, 4, 4, 0, 0, 0, 0
- }, {
- 4, 8, 4, 0, 4, 4, 8, 4, 0, 4, 4, 8,
- 4, 8, 4, 0, 4, 0, 4, 4, 8, 4, 8, 4,
- 8, 4, 8, 4, 0, 4, 0, 4, 0, 4, 0, 4,
- 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 12, 12
- }, {
- 0, 4, 0, 12, 0, 0, 4, 0, 12, 0, 0, 4,
- 0, 4, 0, 12, 0, 12, 0, 0, 4, 0, 4, 0,
- 4, 0, 4, 0, 12, 0, 12, 0, 12, 0, 12, 0,
- 4, 4, 4, 4, 12, 12, 12, 12, 0, 0, 8, 8
- }
-};
-
-const int Resources::DRAW_NUMBERS[25] = {
- 36, 37, 38, 43, 42, 41,
- 39, 20, 22, 24, 33, 31,
- 29, 26, 10, 11, 18, 16,
- 13, 5, 9, 6, 0, 4, 1
-};
-
-const int Resources::DRAW_FRAMES[25][2] = {
- { 18, 24 }, { 19, 23 }, { 20, 22 }, { 24, 18 }, { 23, 19 }, { 22, 20 },
- { 21, 21 }, { 11, 17 }, { 12, 16 }, { 13, 15 }, { 17, 11 }, { 16, 12 },
- { 15, 13 }, { 14, 14 }, { 6, 10 }, { 7, 9 }, { 10, 6 }, { 9, 7 },
- { 8, 8 }, { 3, 5 }, { 5, 3 }, { 4, 4 }, { 0, 2 }, { 2, 0 },
- { 1, 1 }
-};
-
-const int Resources::COMBAT_FLOAT_X[8] = { -2, -1, 0, 1, 2, 1, 0, -1 };
-
-const int Resources::COMBAT_FLOAT_Y[8] = { -2, 0, 2, 0, -1, 0, 2, 0 };
-
-const int Resources::MONSTER_EFFECT_FLAGS[15][8] = {
- { 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10A, 0x10B },
- { 0x10C, 0x10D, 0x10E, 0x10F, 0x0, 0x0, 0x0, 0x0 },
- { 0x110, 0x111, 0x112, 0x113, 0x0, 0x0, 0x0, 0x0 },
- { 0x114, 0x115, 0x116, 0x117, 0x0, 0x0, 0x0, 0x0 },
- { 0x200, 0x201, 0x202, 0x203, 0x0, 0x0, 0x0, 0x0 },
- { 0x300, 0x301, 0x302, 0x303, 0x400, 0x401, 0x402, 0x403 },
- { 0x500, 0x501, 0x502, 0x503, 0x0, 0x0, 0x0, 0x0 },
- { 0x600, 0x601, 0x602, 0x603, 0x0, 0x0, 0x0, 0x0 },
- { 0x604, 0x605, 0x606, 0x607, 0x608, 0x609, 0x60A, 0x60B },
- { 0x60C, 0x60D, 0x60E, 0x60F, 0x0, 0x0, 0x0, 0x0 },
- { 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100 },
- { 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101 },
- { 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102, 0x102 },
- { 0x103, 0x103, 0x103, 0x103, 0x103, 0x103, 0x103, 0x103 },
- { 0x108, 0x108, 0x108, 0x108, 0x108, 0x108, 0x108, 0x108 }
-};
-
-const uint Resources::SPELLS_ALLOWED[3][40] = {
- {
- 0, 1, 2, 3, 5, 6, 7, 8, 9, 10,
- 12, 14, 16, 23, 26, 27, 28, 30, 31, 32,
- 33, 42, 46, 48, 49, 50, 52, 55, 56, 58,
- 59, 62, 64, 65, 67, 68, 71, 73, 74, 76
- }, {
- 1, 4, 11, 13, 15, 17, 18, 19, 20, 21,
- 22, 24, 25, 29, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 47, 51, 53, 54,
- 57, 60, 61, 63, 66, 69, 70, 72, 75, 76
- }, {
- 0, 1, 2, 3, 4, 5, 7, 9, 10, 20,
- 25, 26, 27, 28, 30, 31, 34, 38, 40, 41,
- 42, 43, 44, 45, 49, 50, 52, 53, 55, 59,
- 60, 61, 62, 67, 68, 72, 73, 74, 75, 76
- }
-};
-
-const int Resources::BASE_HP_BY_CLASS[10] = { 10, 8, 7, 5, 4, 8, 7, 12, 6, 9 };
-
-const int Resources::AGE_RANGES[10] = { 1, 6, 11, 18, 36, 51, 76, 101, 201, 0xffff };
-
-const int Resources::AGE_RANGES_ADJUST[2][10] = {
- { -250, -50, -20, -10, 0, -2, -5, -10, -20, -50 },
- { -250, -50, -20, -10, 0, 2, 5, 10, 20, 50 }
-};
-
-const uint Resources::STAT_VALUES[24] = {
- 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 25, 30, 35, 40,
- 50, 75, 100, 125, 150, 175, 200, 225, 250,
-};
-
-const int Resources::STAT_BONUSES[24] = {
- -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20
-};
-
-const int Resources::ELEMENTAL_CATEGORIES[6] = { 8, 15, 20, 25, 33, 36 };
-
-const int Resources::ATTRIBUTE_CATEGORIES[10] = {
- 9, 17, 25, 33, 39, 45, 50, 56, 61, 72 };
-
-const int Resources::ATTRIBUTE_BONUSES[72] = {
- 2, 3, 5, 8, 12, 17, 23, 30, 38, 47, // Might bonus
- 2, 3, 5, 8, 12, 17, 23, 30, // INT bonus
- 2, 3, 5, 8, 12, 17, 23, 30, // PER bonus
- 2, 3, 5, 8, 12, 17, 23, 30, // SPD bonus
- 3, 5, 10, 15, 20, 30, // ACC bonus
- 5, 10, 15, 20, 25, 30, // LUC bonus
- 4, 6, 10, 20, 50, // HP bonus
- 4, 8, 12, 16, 20, 25, // SP bonus
- 2, 4, 6, 10, 16, // AC bonus
- 4, 6, 8, 10, 12, 14, 16, 18, 20, 25 // Thievery bonus
-};
-
-const int Resources::ELEMENTAL_RESISTENCES[37] = {
- 0, 5, 7, 9, 12, 15, 20, 25, 30, 5, 7, 9, 12, 15, 20, 25,
- 5, 10, 15, 20, 25, 10, 15, 20, 25, 40, 5, 7, 9, 11, 13, 15, 20, 25,
- 5, 10, 20
-};
-
-const int Resources::ELEMENTAL_DAMAGE[37] = {
- 0, 2, 3, 4, 5, 10, 15, 20, 30, 2, 3, 4, 5, 10, 15, 20, 2, 4, 5, 10, 20,
- 2, 4, 8, 16, 32, 2, 3, 4, 5, 10, 15, 20, 30, 5, 10, 25
-};
-
-const int Resources::WEAPON_DAMAGE_BASE[35] = {
- 0, 3, 2, 3, 2, 2, 4, 1, 2, 4, 2, 3,
- 2, 2, 1, 1, 1, 1, 4, 4, 3, 2, 4, 2,
- 2, 2, 5, 3, 3, 3, 3, 5, 4, 2, 6
-};
-
-const int Resources::WEAPON_DAMAGE_MULTIPLIER[35] = {
- 0, 3, 3, 4, 5, 4, 2, 3, 3, 3, 3, 3,
- 2, 4, 10, 6, 8, 9, 4, 3, 6, 8, 5, 6,
- 4, 5, 3, 5, 6, 7, 2, 2, 2, 2, 4
-};
-
-const int Resources::METAL_DAMAGE[22] = {
- -3, -6, -4, -2, 2, 4, 6, 8, 10, 0, 1,
- 1, 2, 2, 3, 4, 5, 12, 15, 20, 30, 50
-};
-
-const int Resources::METAL_DAMAGE_PERCENT[22] = {
- 253, 252, 3, 2, 1, 2, 3, 4, 6, 0, 1,
- 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10
-};
-
-const int Resources::METAL_LAC[9] = { -3, 0, -2, -1, 1, 2, 4, 6, 8 };
-
-const int Resources::ARMOR_STRENGTHS[14] = { 0, 2, 4, 5, 6, 7, 8, 10, 4, 2, 1, 1, 1, 1 };
-
-const int Resources::MAKE_ITEM_ARR1[6] = { 0, 8, 15, 20, 25, 33 };
-
-const int Resources::MAKE_ITEM_ARR2[6][7][2] = {
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 7 }, { 7, 7 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 1, 2 }, { 2, 2 }, { 2, 3 }, { 3, 3 } }
-};
-
-const int Resources::MAKE_ITEM_ARR3[10][7][2] = {
- { { 0, 0 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 10 }, { 10, 10 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } },
- { { 0, 0 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, { 5, 6 }, { 6, 6 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 2 }, { 1, 4 }, { 3, 6 }, { 5, 8 }, { 7, 10 }, { 10, 10 } }
-};
-
-const int Resources::MAKE_ITEM_ARR4[2][7][2] = {
- { { 0, 0 }, { 1, 4 }, { 3, 7 }, { 4, 8 }, { 5, 9 }, { 8, 9 }, { 9, 9 } },
- { { 0, 0 }, { 1, 4 }, { 2, 6 }, { 4, 7 }, { 6, 10 }, { 9, 13 }, { 13, 13 } }
-};
-
-
-const int Resources::MAKE_ITEM_ARR5[8][2] = {
- { 0, 0 }, { 1, 15 }, { 16, 30 }, { 31, 40 }, { 41, 50 },
- { 51, 60 }, { 61, 73 }, { 61, 73 }
-};
-
-const int Resources::OUTDOOR_DRAWSTRUCT_INDEXES[44] = {
- 37, 38, 39, 40, 41, 44, 42, 43, 47, 45, 46,
- 48, 49, 52, 50, 51, 66, 67, 68, 69, 70, 71,
- 72, 75, 73, 74, 87, 88, 89, 90, 91, 94, 92,
- 93, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120
-};
-
-const int Resources::TOWN_MAXES[2][11] = {
- { 23, 13, 32, 16, 26, 16, 16, 16, 16, 16, 16 },
- { 26, 19, 48, 27, 26, 37, 16, 16, 16, 16, 16 }
-};
-
-const char *const Resources::TOWN_ACTION_MUSIC[2][7] = {
- { "bank.m", "smith.m", "guild.m", "tavern.m",
- "temple.m", "grounds.m", "endgame.m" },
- { "bank.m", "sf09.m", "guild.m", "tavern.m",
- "temple.m", "smith.m", "endgame.m" }
-};
-
-const char *const Resources::TOWN_ACTION_SHAPES[7] = {
- "bnkr", "blck", "gild", "tvrn", "tmpl", "trng", "eface08"
-};
-
-const int Resources::TOWN_ACTION_FILES[2][7] = {
- { 3, 2, 4, 2, 4, 2, 1 }, { 5, 3, 7, 5, 4, 6, 1 }
-};
-
-const char *const Resources::BANK_TEXT = "\xD\x2\x3""c\xB""122\t013"
- "\xC""37D\xC""dep\t040\xC""37W\xC""dith\t067ESC"
- "\x1\t000\xB""000Bank of Xeen\xB""015\n"
- "Bank\x3l\n"
- "Gold\x3r\t000%s\x3l\n"
- "Gems\x3r\t000%s\x3""c\n"
- "\n"
- "Party\x3l\n"
- "Gold\x3r\t000%s\x3l\n"
- "Gems\x3r\t000%s";
-
-const char *const Resources::BLACKSMITH_TEXT = "\x01\x0D\x03""c\x0B""000\x09""000"
- "Store Options for\x09""039\x0B""027%s\x03""l\x0B""046\n"
- "\x09""011\x0C""37B\x0C""drowse\n"
- "\x09""000\x0B""090Gold\x03r\x09""000%s"
- "\x02\x03""c\x0B""122\x09""040ESC\x01";
-
-const char *const Resources::GUILD_NOT_MEMBER_TEXT =
- "\n\nYou have to be a member to shop here.";
-
-const char *const Resources::GUILD_TEXT = "\x03""c\x0B""027\x09""039%s"
- "\x03l\x0B""046\n"
- "\x09""012\x0C""37B\x0C""duy Spells\n"
- "\x09""012\x0C""37S\x0C""dpell Info";
-
-const char *const Resources::TAVERN_TEXT =
- "\x0D\x03""c\x0B""000\x09""000Tavern Options for\x09""039"
- "\x0B""027%s%s\x03l\x09""000"
- "\x0B""090Gold\x03r\x09""000%s\x02\x03""c\x0B""122"
- "\x09""021\x0C""37S\x0C""dign in\x09""060ESC\x01";
-
-const char *const Resources::FOOD_AND_DRINK =
- "\x03l\x09""017\x0B""046\x0C""37D\x0C""drink\n"
- "\x09""017\x0C""37F\x0C""dood\n"
- "\x09""017\x0C""37T\x0C""dip\n"
- "\x09""017\x0C""37R\x0C""dumors";
-
-const char *const Resources::GOOD_STUFF = "\n"
- "\n"
- "Good Stuff\n"
- "\n"
- "Hit a key!";
-
-const char *const Resources::HAVE_A_DRINK = "\n\nHave a Drink\n\nHit a key!";
-
-const char *const Resources::YOURE_DRUNK = "\n\nYou're Drunk\n\nHit a key!";
-
-const int Resources::TAVERN_EXIT_LIST[2][6][5][2] = {
- {
- { { 21, 17 }, { 0, 0 }, { 20, 3 }, { 0, 0 }, { 0, 0 } },
- { { 13, 4 }, { 0, 0 }, { 19, 9 }, { 0, 0 }, { 0, 0 } },
- { { 20, 10 }, { 12, 8 }, { 5, 26 }, { 3, 4 }, { 7, 5 } },
- { { 18, 4 }, { 0, 0 }, { 19, 16 }, { 0, 0 }, { 11, 12 } },
- { { 15, 21 }, { 0, 0 }, { 13, 21 }, { 0, 0 }, { 0, 0 } },
- { { 10, 8 }, { 0, 0 }, { 15, 12 }, { 0, 0 }, { 0, 0 } },
- }, {
- { { 21, 17 }, { 0, 0 }, { 20, 3 }, { 0, 0 }, { 0, 0 } },
- { { 13, 4 }, { 0, 0 }, { 19, 9 }, { 0, 0 }, { 0, 0 } },
- { { 20, 10 }, { 12, 8 }, { 5, 26 }, { 3, 4 }, { 7, 5 } },
- { { 17, 24 }, { 14, 13 }, { 0, 0 }, { 0, 0 }, { 9, 4 } },
- { { 15, 21 }, { 0, 0 }, { 13, 21 }, { 0, 0 }, { 0, 0 } },
- { { 10, 8 }, { 0, 0 }, { 15, 12 }, { 0, 0 }, { 0, 0 } }
- }
-};
-
-const char *const Resources::TEMPLE_TEXT =
- "\x0D\x03""c\x0B""000\x09""000Temple Options for"
- "\x09""039\x0B""027%s\x03l\x09""000\x0B""046"
- "\x0C""37H\x0C""deal\x03r\x09""000%lu\x03l\n"
- "\x0C""37D\x0C""donation\x03r\x09""000%lu\x03l\n"
- "\x0C""37U\x0C""dnCurse\x03r\x09""000%s"
- "\x03l\x09""000\x0B""090Gold\x03r\x09""000%s"
- "\x02\x03""c\x0B""122\x09""040ESC\x01";
-
-const char *const Resources::EXPERIENCE_FOR_LEVEL =
- "%s needs %lu experience for level %u.";
-
-const char *const Resources::LEARNED_ALL = "%s has learned all we can teach!";
-
-const char *const Resources::ELIGIBLE_FOR_LEVEL = "%s is eligible for level %d.";
-
-const char *const Resources::TRAINING_TEXT =
- "\x0D\x03""cTraining Options\n"
- "\n"
- "%s\x03l\x0B""090\x09""000Gold\x03r\x09"
- "000%s\x02\x03""c\x0B""122\x09""021"
- "\x0C""37T\x0C""drain\x09""060ESC\x01";
-
-const char *const Resources::GOLD_GEMS =
- "\x03""c\x0B""000\x09""000%s\x03l\n"
- "\n"
- "Gold\x03r\x09""000%s\x03l\n"
- "Gems\x03r\x09""000%s\x02\x03""c\x0B""096\x09""013G"
- "\x0C""37o\x0C""dld\x09""040G\x0C\x03""7e"
- "\x0C""dms\x09""067ESC\x01";
-
-const char *const Resources::GOLD_GEMS_2 =
- "\x09""000\x0B""000\x03""c%s\x03l\n"
- "\n"
- "\x04""077Gold\x03r\x09""000%s\x03l\n"
- "\x04""077Gems\x03r\x09""000%s\x03l\x09""000\x0B""051\x04""077\n"
- "\x04""077";
-
-const char *const Resources::DEPOSIT_WITHDRAWL[2] = { "Deposit", "Withdrawl" };
-
-const char *const Resources::NOT_ENOUGH_X_IN_THE_Y =
- "\x03""c\x0B""012Not enough %s in the %s!\x03l";
-
-const char *const Resources::NO_X_IN_THE_Y = "\x03""c\x0B""012No %s in the %s!\x03l";
-
-const char *const Resources::STAT_NAMES[16] = {
- "Might", "Intellect", "Personality", "Endurance", "Speed",
- "Accuracy", "Luck", "Age", "Level", "Armor Class", "Hit Points",
- "Spell Points", "Resistances", "Skills", "Awards", "Experience"
-};
-
-const char *const Resources::CONSUMABLE_NAMES[4] = { "Gold", "Gems", "Food", "Condition" };
-
-const char *const Resources::WHERE_NAMES[2] = { "Party", "Bank" };
-
-const char *const Resources::AMOUNT = "\x03""c\x09""000\x0B""051Amount\x03l\n";
-
-const char *const Resources::FOOD_PACKS_FULL = "\v007Your food packs are already full!";
-
-const char *const Resources::BUY_SPELLS =
- "\x03""c\x0B""027\x09""039%s\x03l\x0B""046\n"
- "\x09""012\x0C""37B\x0C""duy Spells\n"
- "\x09""012\x0C""37S\x0C""dpell Info";
-
-const char *const Resources::GUILD_OPTIONS =
- "\x0D\x0C""00\x03""c\x0B""000\x09""000Guild Options for%s"
- "\x03l\x09""000\x0B""090Gold"
- "\x03r\x09""000%s\x02\x03""c\x0B""122\x09""040ESC\x01";
-
-const int Resources::MISC_SPELL_INDEX[74] = {
- NO_SPELL, MS_Light, MS_Awaken, MS_MagicArrow,
- MS_FirstAid, MS_FlyingFist, MS_EnergyBlast, MS_Sleep,
- MS_Revitalize, MS_CureWounds, MS_Sparks, MS_Shrapmetal,
- MS_InsectSpray, MS_ToxicCloud, MS_ProtFromElements, MS_Pain,
- MS_Jump, MS_BeastMaster, MS_Clairvoyance, MS_TurnUndead,
- MS_Levitate, MS_WizardEye, MS_Bless, MS_IdentifyMonster,
- MS_LightningBolt, MS_HolyBonus, MS_PowerCure, MS_NaturesCure,
- MS_LloydsBeacon, MS_PowerShield, MS_Heroism, MS_Hynotize,
- MS_WalkOnWater, MS_FrostBite, MS_DetectMonster, MS_Fireball,
- MS_ColdRay, MS_CurePoison, MS_AcidSpray, MS_TimeDistortion,
- MS_DragonSleep, MS_CureDisease, MS_Teleport, MS_FingerOfDeath,
- MS_CureParalysis, MS_GolemStopper, MS_PoisonVolley, MS_DeadlySwarm,
- MS_SuperShelter, MS_DayOfProtection, MS_DayOfSorcery, MS_CreateFood,
- MS_FieryFlail, MS_RechargeItem, MS_FantasticFreeze, MS_TownPortal,
- MS_StoneToFlesh, MS_RaiseDead, MS_Etheralize, MS_DancingSword,
- MS_MoonRay, MS_MassDistortion, MS_PrismaticLight, MS_EnchantItem,
- MS_Incinerate, MS_HolyWord, MS_Resurrection, MS_ElementalStorm,
- MS_MegaVolts, MS_Inferno, MS_SunRay, MS_Implosion,
- MS_StarBurst, MS_DivineIntervention
-};
-
-const int Resources::SPELL_COSTS[77] = {
- 8, 1, 5, -2, 5, -2, 20, 10, 12, 8, 3,
- - 3, 75, 40, 12, 6, 200, 10, 100, 30, -1, 30,
- 15, 25, 10, -2, 1, 2, 7, 20, -2, -2, 100,
- 15, 5, 100, 35, 75, 5, 20, 4, 5, 1, -2,
- 6, 2, 75, 40, 60, 6, 4, 25, -2, -2, 60,
- - 1, 50, 15, 125, 2, -1, 3, -1, 200, 35, 150,
- 15, 5, 4, 10, 8, 30, 4, 5, 7, 5, 0
-};
-
-const int Resources::DARK_SPELL_RANGES[12][2] = {
- { 0, 20 }, { 16, 35 }, { 27, 37 }, { 29, 39 },
- { 0, 17 }, { 14, 34 }, { 26, 37 }, { 29, 39 },
- { 0, 20 }, { 16, 35 }, { 27, 37 }, { 29, 39 }
-};
-
-const int Resources::CLOUDS_SPELL_OFFSETS[5][20] = {
- {
- 1, 10, 20, 26, 27, 38, 40, 42, 45, 50,
- 55, 59, 60, 61, 62, 68, 72, 75, 77, 77
- }, {
- 3, 4, 5, 14, 15, 25, 30, 31, 34, 41,
- 49, 51, 53, 67, 73, 75, -1, -1, -1, -1
- }, {
- 4, 8, 9, 12, 13, 22, 23, 24, 28, 34,
- 41, 44, 52, 70, 73, 74, -1, -1, -1, -1
- }, {
- 6, 7, 9, 11, 12, 13, 17, 21, 22, 24,
- 29, 36, 56, 58, 64, 71, -1, -1, -1, -1
- }, {
- 6, 7, 9, 11, 12, 13, 18, 21, 29, 32,
- 36, 37, 46, 51, 56, 58, 69, -1, -1, -1
- }
-};
-
-const uint Resources::DARK_SPELL_OFFSETS[3][39] = {
- {
- 42, 1, 26, 59, 27, 10, 50, 68, 55, 62, 67, 73, 2,
- 5, 3, 31, 30, 52, 49, 28, 74, 0, 9, 7, 14, 8,
- 33, 6, 23, 71, 64, 56, 48, 46, 12, 32, 58, 65, 16
- }, {
- 42, 1, 45, 61, 72, 40, 20, 60, 38, 41, 75, 34, 4,
- 43, 25, 53, 44, 15, 70, 17, 24, 69, 22, 66, 57, 11,
- 29, 39, 51, 21, 19, 36, 47, 13, 54, 37, 18, 35, 63
- }, {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
- }
-};
-
-const int Resources::SPELL_GEM_COST[77] = {
- 0, 0, 2, 1, 2, 4, 5, 0, 0, 0, 0, 10, 10, 10, 0, 0, 20, 4, 10, 20, 1, 10,
- 5, 5, 4, 2, 0, 0, 0, 10, 3, 1, 20, 4, 0, 20, 10, 10, 1, 10, 0, 0, 0, 2,
- 2, 0, 10, 10, 10, 0, 0, 10, 3, 2, 10, 1, 10, 10, 20, 0, 0, 1, 1, 20, 5, 20,
- 5, 0, 0, 0, 0, 5, 1, 2, 0, 2, 0
-};
-
-const char *const Resources::NOT_A_SPELL_CASTER = "Not a spell caster...";
-
-const char *const Resources::SPELLS_FOR = "\xD\xC""d%s\x2\x3""c\x9""000\xB""002Spells for %s";
-
-const char *const Resources::SPELL_LINES_0_TO_9 =
- "\x2\x3l\xB""015\x9""0011\n2\n3\n4\n5\n6\n7\n8\n9\n0";
-
-const char *const Resources::SPELLS_DIALOG_SPELLS = "\x3l\xB""015"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l\n"
- "\x9""010\xC""%2u%s\xC""d\x3l"
- "\x9""004\xB""110%s - %lu\x1";
-
-const char *const Resources::SPELL_PTS = "Spell Pts";
-const char *const Resources::GOLD = "Gold";
+ // Set up items array to map to the names of items in each category
+ ITEM_NAMES[CATEGORY_WEAPON] = &WEAPON_NAMES[0];
+ ITEM_NAMES[CATEGORY_ARMOR] = &ARMOR_NAMES[0];
+ ITEM_NAMES[CATEGORY_ACCESSORY] = &ACCESSORY_NAMES[0];
+ ITEM_NAMES[CATEGORY_MISC] = &MISC_NAMES[0];
-const char *const Resources::SPELLS_PRESS_A_KEY =
- "\x3""c\xC""09%s\xC""d\x3l\n"
- "\n"
- "%s\x3""c\x9""000\xB""100Press a Key!";
-
-const char *const Resources::SPELLS_PURCHASE =
- "\x3l\xB""000\x9""000\xC""d%s Do you wish to purchase "
- "\xC""09%s\xC""d for %u?";
-
-const char *const Resources::MAP_TEXT =
- "\x3""c\xB""000\x9""000%s\x3l\xB""139"
- "\x9""000X = %d\x3r\x9""000Y = %d\x3""c\x9""000%s";
-
-const char *const Resources::LIGHT_COUNT_TEXT = "\x3l\n\n\t024Light\x3r\t124%d";
-
-const char *const Resources::FIRE_RESISTENCE_TEXT = "%c%sFire%s%u";
-
-const char *const Resources::ELECRICITY_RESISTENCE_TEXT = "%c%sElectricity%s%u";
-
-const char *const Resources::COLD_RESISTENCE_TEXT = "c%sCold%s%u";
-
-const char *const Resources::POISON_RESISTENCE_TEXT = "%c%sPoison/Acid%s%u";
-
-const char *const Resources::CLAIRVOYANCE_TEXT = "%c%sClairvoyance%s";
-
-const char *const Resources::LEVITATE_TEXT = "%c%sLevitate%s";
-
-const char *const Resources::WALK_ON_WATER_TEXT = "%c%sWalk on Water";
-
-const char *const Resources::GAME_INFORMATION =
- "\xD\x3""c\x9""000\xB""001\xC""37%s of Xeen\xC""d\n"
- "Game Information\n"
- "\n"
- "Today is \xC""37%ssday\xC""d\n"
- "\n"
- "\x9""032Time\x9""072Day\x9""112Year\n"
- "\x9""032\xC""37%d:%02d%c\x9""072%u\x9""112%u\xC""d%s";
-
-const char *const Resources::WORLD_GAME_TEXT = "World";
-const char *const Resources::DARKSIDE_GAME_TEXT = "Darkside";
-const char *const Resources::CLOUDS_GAME_TEXT = "Clouds";
-const char *const Resources::SWORDS_GAME_TEXT = "Swords";
-
-const char *const Resources::WEEK_DAY_STRINGS[10] = {
- "Ten", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"
-};
-
-const char *const Resources::CHARACTER_DETAILS =
- "\x3l\xB""041\x9""196%s\x9""000\xB""002%s : %s %s %s"
- "\x3r\x9""053\xB""028\xC%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
- "\x3l\x9""131\xC""%02u%d\xC""d\x9""196\xC""15%lu\xC""d\x3r"
- "\x9""053\xB""051\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
- "\x3l\x9""131\xC""%02u%u\xC""d\x9""196\xC""15%lu\xC""d"
- "\x3r\x9""053\xB""074\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
- "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""15%lu\xC""d"
- "\x3r\x9""053\xB""097\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
- "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""15%u day%c\xC""d"
- "\x3r\x9""053\xB""120\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
- "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""%02u%s\xC""d"
- "\x9""230%s%s%s%s\xC""d";
-
-const char *const Resources::PARTY_GOLD = "Party Gold";
-
-const char *const Resources::PLUS_14 = "14+";
-
-const char *const Resources::CHARACTER_TEMPLATE =
- "\x1\xC""00\xD\x3l\x9""029\xB""018Mgt\x9""080Acy\x9""131H.P.\x9""196Experience"
- "\x9""029\xB""041Int\x9""080Lck\x9""131S.P.\x9""029\xB""064Per\x9""080Age"
- "\x9""131Resis\x9""196Party Gems\x9""029\xB""087End\x9""080Lvl\x9""131Skills"
- "\x9""196Party Food\x9""029\xB""110Spd\x9""080AC\x9""131Awrds\x9""196Condition\x3""c"
- "\x9""290\xB""025\xC""37I\xC""dtem\x9""290\xB""057\xC""37Q"
- "\xC""duick\x9""290\xB""089\xC""37E\xC""dxch\x9""290\xB""121Exit\x3l%s";
-
-const char *const Resources::EXCHANGING_IN_COMBAT = "\x3""c\xB""007\x9""000Exchanging in combat is not allowed!";
-
-const char *const Resources::CURRENT_MAXIMUM_RATING_TEXT = "\x2\x3""c%s\n"
- "Current / Maximum\n"
- "\x3r\x9""054%lu\x3l\x9""058/ %lu\n"
- "\x3""cRating: %s";
-
-const char *const Resources::CURRENT_MAXIMUM_TEXT = "\x2\x3""c%s\n"
- "Current / Maximum\n"
- "\x3r\x9""054%u\x3l\x9""058/ %u";
-
-const char *const Resources::RATING_TEXT[24] = {
- "Nonexistant", "Very Poor", "Poor", "Very Low", "Low", "Averarage", "Good",
- "Very Good", "High", "Very High", "Great", "Super", "Amazing", "Incredible",
- "Gigantic", "Fantastic", "Astoundig", "Astonishing", "Monumental", "Tremendous",
- "Collosal", "Awesome", "AweInspiring", "aUltimate"
-};
-
-const char *const Resources::AGE_TEXT = "\x2\x3""c%s\n"
- "Current / Natural\n"
- "\x3r\x9""057%u\x3l\x9""061/ %u\n"
- "\x3""cBorn: %u / %u\x1";
-
-const char *const Resources::LEVEL_TEXT =
- "\x2\x3""c%s\n"
- "Current / Maximum\n"
- "\x3r\x9""054%u\x3l\x9""058/ %u\n"
- "\x3""c%u Attack%s/Round\x1";
-
-const char *const Resources::RESISTENCES_TEXT =
- "\x2\x3""c%s\x3l\n"
- "\x9""020Fire\x9""100%u\n"
- "\x9""020Cold\x9""100%u\n"
- "\x9""020Electricity\x9""100%u\n"
- "\x9""020Poison\x9""100%u\n"
- "\x9""020Energy\x9""100%u\n"
- "\x9""020Magic\x9""100%u";
-
-const char *const Resources::NONE = "\n\x9""020";
-
-const char *const Resources::EXPERIENCE_TEXT = "\x2\x3""c%s\x3l\n"
- "\x9""010Current:\x9""070%lu\n"
- "\x9""010Next Level:\x9""070%s\x1";
-
-const char *const Resources::ELIGIBLE = "\xC""12Eligible\xC""d";
-
-const char *const Resources::IN_PARTY_IN_BANK =
- "\x2\x3""cParty %s\n"
- "%lu on hand\n"
- "%lu in bank\x1\x3l";
-
-const char *const Resources::FOOD_TEXT =
- "\x2\x3""cParty %s\n"
- "%u on hand\n"
- "Enough for %u day%s\x3l";
-
-const char *const Resources::EXCHANGE_WITH_WHOM = "\t010\v005Exchange with whom?";
-
-const char *const Resources::QUICK_REF_LINE =
- "\xB%3d\x9""007%u)\x9""027%s\x9""110%c%c%c\x3r\x9""160\xC%02u%u\xC""d"
- "\x3l\x9""170\xC%02u%d\xC""d\x9""208\xC%02u%u\xC""d\x9""247\xC"
- "%02u%u\xC""d\x9""270\xC%02u%c%c%c%c\xC""d";
-
-const char *const Resources::QUICK_REFERENCE =
- "\xD\x3""cQuick Reference Chart\xB""012\x3l"
- "\x9""007#\x9""027Name\x9""110Cls\x9""140Lvl\x9""176H.P."
- "\x9""212S.P.\x9""241A.C.\x9""270Cond"
- "%s%s%s%s%s%s%s%s"
- "\xB""110\x9""064\x3""cGold\x9""144Gems\x9""224Food\xB""119"
- "\x9""064\xC""15%lu\x9""144%lu\x9""224%u day%s\xC""d";
-
-const uint Resources::BLACKSMITH_MAP_IDS[2][4] = { { 28, 30, 73, 49 }, { 29, 31, 37, 43 } };
-
-const char *const Resources::ITEMS_DIALOG_TEXT1 =
- "\r\x2\x3""c\v021\t017\f37W\fdeap\t051\f37A\fdrmor\t085A"
- "\f37c\fdces\t119\f37M\fdisc\t153%s\t187%s\t221%s"
- "\t255%s\t289Exit";
-const char *const Resources::ITEMS_DIALOG_TEXT2 =
- "\r\x2\x3""c\v021\t017\f37W\fdeap\t051\f37A\fdrmor\t085A"
- "\f37c\fdces\t119\f37M\fdisc\t153\f37%s\t289Exit";
-const char *const Resources::ITEMS_DIALOG_LINE1 = "\x3r\f%02u\f023%2d)\x3l\t028%s\n";
-const char *const Resources::ITEMS_DIALOG_LINE2 = "\x3r\f%02u\t023%2d)\x3l\t028%s\x3r\t000%lu\n";
-
-const char *const Resources::BTN_BUY = "\f37B\fduy";
-const char *const Resources::BTN_SELL = "\f37S\fdell";
-const char *const Resources::BTN_IDENTIFY = "\f37I\fddentify";
-const char *const Resources::BTN_FIX = "\f37F\fdix";
-const char *const Resources::BTN_USE = "\f37U\fdse";
-const char *const Resources::BTN_EQUIP = "\f37E\fdquip";
-const char *const Resources::BTN_REMOVE = "\f37R\fdem";
-const char *const Resources::BTN_DISCARD = "\f37D\fdisc";
-const char *const Resources::BTN_QUEST = "\f37Q\fduest";
-const char *const Resources::BTN_ENCHANT = "E\fdnchant";
-const char *const Resources::BTN_RECHARGE = "R\fdechrg";
-const char *const Resources::BTN_GOLD = "G\fdold";
-
-const char *const Resources::ITEM_BROKEN = "\f32broken ";
-const char *const Resources::ITEM_CURSED = "\f09cursed ";
-const char *const Resources::BONUS_NAMES[7] = {
- "", "Dragon Slayer", "Undead Eater", "Golem Smasher",
- "Bug Zapper", "Monster Masher", "Beast Bopper"
-};
-
-const char *const Resources::WEAPON_NAMES[35] = {
- nullptr, "long sword ", "short sword ", "broad sword ", "scimitar ",
- "cutlass ", "sabre ", "club ", "hand axe ", "katana ", "nunchakas ",
- "wakazashi ", "dagger ", "mace ", "flail ", "cudgel ", "maul ", "spear ",
- "bardiche ", "glaive ", "halberd ", "pike ", "flamberge ", "trident ",
- "staff ", "hammer ", "naginata ", "battle axe ", "grand axe ", "great axe ",
- "short bow ", "long bow ", "crossbow ", "sling ", "Xeen Slayer Sword"
-};
-
-const char *const Resources::ARMOR_NAMES[14] = {
- nullptr, "robes ", "sale armor ", "ring mail ", "chain mail ",
- "splint mail ", "plate mail ", "plate armor ", "shield ",
- "helm ", "boots ", "cloak ", "cape ", "gauntlets "
-};
-
-const char *const Resources::ACCESSORY_NAMES[11] = {
- nullptr, "ring ", "belt ", "broach ", "medal ", "charm ", "cameo ",
- "scarab ", "pendant ", "necklace ", "amulet "
-};
-
-const char *const Resources::MISC_NAMES[22] = {
- nullptr, "rod ", "jewel ", "gem ", "box ", "orb ", "horn ", "coin ",
- "wand ", "whistle ", "potion ", "scroll ", "RogueVM",
- "bogusg", "bogus", "bogus", "bogus", "bogus",
- "bogus", "bogus", "bogus", "bogus"
-};
-
-const char *const *Resources::ITEM_NAMES[4] = {
- &Resources::WEAPON_NAMES[0], &Resources::ARMOR_NAMES[0],
- &Resources::ACCESSORY_NAMES[0], &Resources::MISC_NAMES[0]
-};
-
-const char *const Resources::ELEMENTAL_NAMES[6] = {
- "Fire", "Elec", "Cold", "Acid/Poison", "Energy", "Magic"
-};
-
-const char *const Resources::ATTRIBUTE_NAMES[10] = {
- "might", "Intellect", "Personality", "Speed", "accuracy", "Luck",
- "Hit Points", "Spell Points", "Armor Class", "Thievery"
-};
-
-const char *const Resources::EFFECTIVENESS_NAMES[7] = {
- nullptr, "Dragons", "Undead", "Golems", "Bugs", "Monsters", "Beasts"
-};
-
-const char *const Resources::QUEST_ITEM_NAMES[85] = {
- "Deed to New Castle",
- "Crystal Key to Witch Tower",
- "Skeleton Key to Darzog's Tower",
- "Enchanted Key to Tower of High Magic",
- "Jeweled Amulet of the Northern Sphinx",
- "Stone of a Thousand Terrors",
- "Golem Stone of Admittance",
- "Yak Stone of Opening",
- "Xeen's Scepter of Temporal Distortion",
- "Alacorn of Falista",
- "Elixir of Restoration",
- "Wand of Faery Magic",
- "Princess Roxanne's Tiara",
- "Holy Book of Elvenkind",
- "Scarab of Imaging",
- "Crystals of Piezoelectricity",
- "Scroll of Insight",
- "Phirna Root",
- "Orothin's Bone Whistle",
- "Barok's Magic Pendant",
- "Ligono's Missing Skull",
- "Last Flower of Summer",
- "Last Raindrop of Spring",
- "Last Snowflake of Winter",
- "Last Leaf of Autumn",
- "Ever Hot Lava Rock",
- "King's Mega Credit",
- "Excavation Permit",
- "Cupie Doll",
- "Might Doll",
- "Speed Doll",
- "Endurance Doll",
- "Accuracy Doll",
- "Luck Doll",
- "Widget",
- "Pass to Castleview",
- "Pass to Sandcaster",
- "Pass to Lakeside",
- "Pass to Necropolis",
- "Pass to Olympus",
- "Key to Great Western Tower",
- "Key to Great Southern Tower",
- "Key to Great Eastern Tower",
- "Key to Great Northern Tower",
- "Key to Ellinger's Tower",
- "Key to Dragon Tower",
- "Key to Darkstone Tower",
- "Key to Temple of Bark",
- "Key to Dungeon of Lost Souls",
- "Key to Ancient Pyramid",
- "Key to Dungeon of Death",
- "Amulet of the Southern Sphinx",
- "Dragon Pharoah's Orb",
- "Cube of Power",
- "Chime of Opening",
- "Gold ID Card",
- "Silver ID Card",
- "Vulture Repellant",
- "Bridle",
- "Enchanted Bridle",
- "Treasure Map (Goto E1 x1, y11)",
- "",
- "Fake Map",
- "Onyx Necklace",
- "Dragon Egg",
- "Tribble",
- "Golden Pegasus Statuette",
- "Golden Dragon Statuette",
- "Golden Griffin Statuette",
- "Chalice of Protection",
- "Jewel of Ages",
- "Songbird of Serenity",
- "Sandro's Heart",
- "Ector's Ring",
- "Vespar's Emerald Handle",
- "Queen Kalindra's Crown",
- "Caleb's Magnifying Glass",
- "Soul Box",
- "Soul Box with Corak inside",
- "Ruby Rock",
- "Emerald Rock",
- "Sapphire Rock",
- "Diamond Rock",
- "Monga Melon",
- "Energy Disk"
-};
-
-const int Resources::WEAPON_BASE_COSTS[35] = {
- 0, 50, 15, 100, 80, 40, 60, 1, 10, 150, 30, 60, 8, 50,
- 100, 15, 30, 15, 200, 80, 250, 150, 400, 100, 40, 120,
- 300, 100, 200, 300, 25, 100, 50, 15, 0
-};
-const int Resources::ARMOR_BASE_COSTS[14] = {
- 0, 20, 100, 200, 400, 600, 1000, 2000, 100, 60, 40, 250, 200, 100
-};
-const int Resources::ACCESSORY_BASE_COSTS[11] = {
- 0, 100, 100, 250, 100, 50, 300, 200, 500, 1000, 2000
-};
-const int Resources::MISC_MATERIAL_COSTS[22] = {
- 0, 50, 1000, 500, 10, 100, 20, 10, 50, 10, 10, 100,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-};
-const int Resources::MISC_BASE_COSTS[76] = {
- 0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 200, 200, 200, 200, 200, 200, 200, 200,
- 200, 200, 200, 200, 200, 200, 200, 300, 300, 300, 300, 300,
- 300, 300, 300, 300, 300, 400, 400, 400, 400, 400, 400, 400,
- 400, 400, 400, 500, 500, 500, 500, 500, 500, 500, 500, 500,
- 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
- 600, 600, 600, 600
-};
-const int Resources::METAL_BASE_MULTIPLIERS[22] = {
- 10, 25, 5, 75, 2, 5, 10, 20, 50, 2, 3, 5, 10, 20, 30, 40,
- 50, 60, 70, 80, 90, 100
-};
-const int Resources::ITEM_SKILL_DIVISORS[4] = { 1, 2, 100, 10 };
-
-const int Resources::RESTRICTION_OFFSETS[4] = { 0, 35, 49, 60 };
-
-const int Resources::ITEM_RESTRICTIONS[86] = {
- 0, 86, 86, 86, 86, 86, 86, 0, 6, 239, 239, 239, 2, 4, 4, 4, 4,
- 6, 70, 70, 70, 70, 94, 70, 0, 4, 239, 86, 86, 86, 70, 70, 70, 70,
- 0, 0, 0, 68, 100, 116, 125, 255, 255, 85, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-const char *const Resources::NOT_PROFICIENT =
- "\t000\v007\x3""c%ss are not proficient with a %s!";
-
-const char *const Resources::NO_ITEMS_AVAILABLE = "\x3""c\n"
- "\t000No items available.";
-
-const char *const Resources::CATEGORY_NAMES[4] = { "Weapons", "Armor", "Accessories", "Miscellaneous" };
-
-const char *const Resources::X_FOR_THE_Y =
- "\x1\fd\r%s\v000\t000%s for %s the %s%s\v011\x2%s%s%s%s%s%s%s%s%s\x1\fd";
-
-const char *const Resources::X_FOR_Y =
- "\x1\xC""d\r\x3l\v000\t000%s for %s\x3r\t000%s\x3l\v011\x2%s%s%s%s%s%s%s%s%s\x1\xC""d";
-
-const char *const Resources::X_FOR_Y_GOLD =
- "\x1\fd\r\x3l\v000\t000%s for %s\t150Gold - %lu%s\x3l\v011"
- "\x2%s%s%s%s%s%s%s%s%s\x1\fd";
-
-const char *const Resources::FMT_CHARGES = "\x3rr\t000Charges\x3l";
-
-const char *const Resources::AVAILABLE_GOLD_COST =
- "\x1\fd\r\x3l\v000\t000Available %s\t150Gold - %lu\x3r\t000Cost"
- "\x3l\v011\x2%s%s%s%s%s%s%s%s%s\x1\xC""d";
-
-const char *const Resources::CHARGES = "Charges";
-
-const char *const Resources::COST = "Cost";
-
-const char *const Resources::ITEM_ACTIONS[7] = {
- "Equip", "Remove", "Use", "Discard", "Enchant", "Recharge", "Gold"
-};
-const char *const Resources::WHICH_ITEM = "\t010\v005%s which item?";
-
-const char *const Resources::WHATS_YOUR_HURRY = "\v007What's your hurry?\n"
- "Wait till you get out of here!";
-
-const char *const Resources::USE_ITEM_IN_COMBAT =
- "\v007To use an item in Combat, invoke the Use command on your turn!";
-
-const char *const Resources::NO_SPECIAL_ABILITIES = "\v005\x3""c%s\fdhas no special abilities!";
-
-const char *const Resources::CANT_CAST_WHILE_ENGAGED = "\x3""c\v007Can't cast %s while engaged!";
-
-const char *const Resources::EQUIPPED_ALL_YOU_CAN = "\x3""c\v007You have equipped all the %ss you can!";
-const char *const Resources::REMOVE_X_TO_EQUIP_Y = "\x3""c\v007You must remove %sto equip %s\x8!";
-const char *const Resources::RING = "ring";
-const char *const Resources::MEDAL = "medal";
-
-const char *const Resources::CANNOT_REMOVE_CURSED_ITEM = "\x3""You cannot remove a cursed item!";
-
-const char *const Resources::CANNOT_DISCARD_CURSED_ITEM = "\3x""cYou cannot discard a cursed item!";
-
-const char *const Resources::PERMANENTLY_DISCARD = "\v000\t000\x03lPermanently discard %s\fd?";
-
-const char *const Resources::BACKPACK_IS_FULL = "\v005\x3""c\fd%s's backpack is full.";
-
-const char *const Resources::CATEGORY_BACKPACK_IS_FULL[4] = {
- "\v010\t000\x3""c%s's weapons backpack is full.",
- "\v010\t000\x3""c%s's armor backpack is full.",
- "\v010\t000\x3""c%s's accessories backpack is full.",
- "\v010\t000\x3""c%s's miscellaneous backpack is full."
-};
-
-const char *const Resources::BUY_X_FOR_Y_GOLD = "\x3l\v000\t000\fdBuy %s\fd for %lu gold?";
-
-const char *const Resources::SELL_X_FOR_Y_GOLD = "\x3l\v000\t000\fdSell %s\fd for %lu gold?";
-
-const char *const Resources::NO_NEED_OF_THIS = "\v005\x3""c\fdWe have no need of this %s\f!";
-
-const char *const Resources::NOT_RECHARGABLE = "\v012\x3""c\fdNot Rechargeable. %s";
-
-const char *const Resources::NOT_ENCHANTABLE = "\v012\t000\x3""cNot Enchantable. %s";
-
-const char *const Resources::SPELL_FAILED = "Spell Failed!";
-
-const char *const Resources::ITEM_NOT_BROKEN = "\fdThat item is not broken!";
-
-const char *const Resources::FIX_IDENTIFY[2] = { "Fix", "Identify" };
-
-const char *const Resources::FIX_IDENTIFY_GOLD = "\x3l\v000\t000%s %s\fd for %lu gold?";
-
-const char *const Resources::IDENTIFY_ITEM_MSG = "\fd\v000\t000\x3""cIdentify Item\x3l\n"
- "\n"
- "\v012%s\fd\n"
- "\n"
- "%s";
-
-const char *const Resources::ITEM_DETAILS =
- "Proficient Classes\t132:\t140%s\n"
- "to Hit Modifier\t132:\t140%s\n"
- "Physical Damage\t132:\t140%s\n"
- "Elemental Damage\t132:\t140%s\n"
- "Elemental Resistance\t132:\t140%s\n"
- "Armor Class Bonus\t132:\t140%s\n"
- "Attribute Bonus\t132:\t140%s\n"
- "Special Power\t132:\t140%s";
-
-const char *const Resources::ALL = "All";
-const char *const Resources::FIELD_NONE = "None";
-const char *const Resources::DAMAGE_X_TO_Y = "%d to %d";
-const char *const Resources::ELEMENTAL_XY_DAMAGE = "%+d %s Damage";
-const char *const Resources::ATTR_XY_BONUS = "%+d %s";
-const char *const Resources::EFFECTIVE_AGAINST = "x3 vs %s";
-
-const char *const Resources::QUESTS_DIALOG_TEXT =
- "\r\x2\x3""c\v021\t017\f37I\fdtems\t085\f37Q\fduests\t153"
- "\f37A\fduto Notes 221\f37U\fdp\t255\f37D\fdown"
- "\t289Exit";
-const char *const Resources::CLOUDS_OF_XEEN_LINE = "\b \b*-- \f04Clouds of Xeen\fd --";
-const char *const Resources::DARKSIDE_OF_XEEN_LINE = "\b \b*-- \f04Darkside of Xeen\fd --";
-
-const char *const Resources::NO_QUEST_ITEMS =
- "\r\x3""c\v000 000Quest Items\x3l\x2\n"
- "\n"
- "\x3""cNo Quest Items";
-const char *const Resources::NO_CURRENT_QUESTS =
- "\x3""c\v000\t000\n"
- "\n"
- "No Current Quests";
-const char *const Resources::NO_AUTO_NOTES = "\x3""cNo Auto Notes";
-
-const char *const Resources::QUEST_ITEMS_DATA =
- "\r\x1\fd\x3""c\v000\t000Quest Items\x3l\x2\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s\n"
- "\f04 * \fd%s";
-const char *const Resources::CURRENT_QUESTS_DATA =
- "\r\x1\fd\x3""c\t000\v000Current Quests\x3l\x2\n"
- "%s\n"
- "\n"
- "%s\n"
- "\n"
- "%s";
-const char *const Resources::AUTO_NOTES_DATA =
- "\r\x1\fd\x3""c\t000\v000Auto Notes\x3l\x2\n"
- "%s\x3l\n"
- "%s\x3l\n"
- "%s\x3l\n"
- "%s\x3l\n"
- "%s\x3l\n"
- "%s\x3l\n"
- "%s\x3l\n"
- "%s\x3l\n"
- "%s\x3l";
-
-const char *const Resources::REST_COMPLETE =
- "\v000\t0008 hours pass. Rest complete.\n"
- "%s\n"
- "%d food consumed.";
-const char *const Resources::PARTY_IS_STARVING = "\f07The Party is Starving!\fd";
-const char *const Resources::HIT_SPELL_POINTS_RESTORED = "Hit Pts and Spell Pts restored.";
-const char *const Resources::TOO_DANGEROUS_TO_REST = "Too dangerous to rest here!";
-const char *const Resources::SOME_CHARS_MAY_DIE = "Some Chars may die. Rest anyway?";
-
-const char *const Resources::CANT_DISMISS_LAST_CHAR = "You cannot dismiss your last character!";
-
-const char *const Resources::REMOVE_DELETE[2] = { "Remove", "Delete" };
-
-const char *const Resources::REMOVE_OR_DELETE_WHICH = "\x3l\t010\v005%s which character?";
-
-const char *const Resources::YOUR_PARTY_IS_FULL = "\v007Your party is full!";
-
-const char *const Resources::HAS_SLAYER_SWORD =
- "\v000\t000This character has the Xeen Slayer Sword and cannot be deleted!";
-const char *const Resources::SURE_TO_DELETE_CHAR =
- "Are you sure you want to delete %s the %s?";
-
-const char *const Resources::CREATE_CHAR_DETAILS =
- "\f04\x3""c\x2\t144\v119\f37R\f04oll\t144\v149\f37C\f04reate"
- "\t144\v179\f37ESC\f04\x3l\x1\t195\v021\f37M\f04gt"
- "\t195\v045\f37I\f04nt\t195\v069\f37P\f04er\t195\v093\f37E\f04nd"
- "\t195\v116\f37S\f04pd\t195\v140\f37A\f04cy\t195\v164\f37L\f04ck%s";
-
-const char *const Resources::NEW_CHAR_STATS =
- "\f04\x3l\t022\v148Race\t055: %s\n"
- "\t022Sex\t055: %s\n"
- "\t022Class\t055:\n"
- "\x3r\t215\v031%d\t215\v055%d\t215\v079%d\t215\v103%d\t215\v127%d"
- "\t215\v151%d\t215\v175%d\x3l\t242\v020\f%.2dKnight\t242\v031\f%.2d"
- "Paladin\t242\v042\f%.2dArcher\t242\v053\f%.2dCleric\t242\v064\f%.2d"
- "Sorcerer\t242\v075\f%.2dRobber\t242\v086\f%.2dNinja\t242\v097\f%.2d"
- "Barbarian\t242\v108\f%.2dDruid\t242\v119\f%.2dRanger\f04\x3""c"
- "\t265\v142Skills\x3l\t223\v155%s\t223\v170%s%s";
-
-const char *const Resources::NAME_FOR_NEW_CHARACTER =
- "\x3""cEnter a Name for this Character\n\n";
-const char *const Resources::SELECT_CLASS_BEFORE_SAVING =
- "\v006\x3""cSelect a Class before saving.\x3l";
-const char *const Resources::EXCHANGE_ATTR_WITH = "Exchange %s with...";
-
-const int Resources::NEW_CHAR_SKILLS[10] = { 1, 5, -1, -1, 4, 0, 0, -1, 6, 11 };
-const int Resources::NEW_CHAR_SKILLS_LEN[10] = { 11, 8, 0, 0, 12, 8, 8, 0, 9, 11 };
-const int Resources::NEW_CHAR_RACE_SKILLS[10] = { 14, -1, 17, 16, -1, 0, 0, 0, 0, 0 };
-
-const int Resources::RACE_MAGIC_RESISTENCES[5] = { 7, 5, 20, 0, 0 };
-const int Resources::RACE_FIRE_RESISTENCES[5] = { 7, 0, 2, 5, 10 };
-const int Resources::RACE_ELECTRIC_RESISTENCES[5] = { 7, 0, 2, 5, 10 };
-const int Resources::RACE_COLD_RESISTENCES[5] = { 7, 0, 2, 5, 10 };
-const int Resources::RACE_ENERGY_RESISTENCES[5] = { 7, 5, 2, 5, 0 };
-const int Resources::RACE_POISON_RESISTENCES[5] = { 7, 0, 2, 20, 0 };
-const int Resources::NEW_CHARACTER_SPELLS[10][4] = {
- { -1, -1, -1, -1 },
- { 21, -1, -1, -1 },
- { 22, -1, -1, -1 },
- { 21, 1, 14, -1 },
- { 22, 0, 25, -1 },
- { -1, -1, -1, -1 },
- { -1, -1, -1, -1 },
- { -1, -1, -1, -1 },
- { 20, 1, 11, 23 },
- { 20, 1, -1, -1 }
-};
-
-const char *const Resources::COMBAT_DETAILS = "\r\f00\x3""c\v000\t000\x2""Combat%s%s%s\x1";
-
-const char *Resources::NOT_ENOUGH_TO_CAST = "\x3""c\v010Not enough %s to Cast %s";
-const char *Resources::SPELL_CAST_COMPONENTS[2] = { "Spell Points", "Gems" };
-
-const char *const Resources::CAST_SPELL_DETAILS =
- "\r\x2\x3""c\v122\t013\f37C\fdast\t040\f37N\fdew"
- "\t067ESC\x1\t000\v000\x3""cCast Spell\n"
- "\n"
- "%s\x3l\n"
- "\n"
- "Spell Ready:\x3""c\n"
- "\n"
- "\f09%s\fd\x2\x3l\n"
- "\v082Cost\x3r\t000%u/%u\x3l\n"
- "Cur SP\x3r\t000%u\x1";
-
-const char *const Resources::PARTY_FOUND =
- "\x3""cThe Party Found:\n"
- "\n"
- "\x3r\t000%lu Gold\n"
- "%lu Gems";
-
-const char *const Resources::BACKPACKS_FULL_PRESS_KEY =
- "\v007\f12Warning! BackPacks Full!\fd\n"
- "Press a Key";
-
-const char *const Resources::HIT_A_KEY = "\x3l\v120\t000\x4""077\x3""c\f37Hit a key\xC""d";
-
-const char *const Resources::GIVE_TREASURE_FORMATTING =
- "\x3l\v060\t000\x4""077\n"
- "\x4""077\n"
- "\x4""077\n"
- "\x4""077\n"
- "\x4""077\n"
- "\x4""077";
-
-const char *const Resources::X_FOUND_Y = "\v060\t000\x3""c%s found: %s";
-
-const char *const Resources::ON_WHO = "\x3""c\v009On Who?";
-
-const char *const Resources::WHICH_ELEMENT1 =
- "\r\x3""c\x1Which Element?\x2\v034\t014\f15F\fdire\t044"
- "\f15E\fdlec\t074\f15C\fdold\t104\f15A\fdcid\x1";
-
-const char *const Resources::WHICH_ELEMENT2 =
- "\r\x3""cWhich Element?', 2, 0Bh, '034\t014\f15F\fdire\t044"
- "\f15E\fdlec\t074\f15C\fdold\t104\f15A\fdcid\x1";
-
-const char *const Resources::DETECT_MONSTERS = "\x3""cDetect Monsters";
-
-const char *const Resources::LLOYDS_BEACON =
- "\r\x3""c\v000\t000\x1Lloyd's Beacon\n"
- "\n"
- "Last Location\n"
- "\n"
- "%s\x3l\n"
- "x = %d\x3r\t000y = %d\x3""c\x2\v122\t021\f15S\fdet\t060\f15R\fdeturn\x1";
-
-const char *const Resources::HOW_MANY_SQUARES = "\x3""cTeleport\nHow many squares %s (1-9)";
-
-const char *const Resources::TOWN_PORTAL =
- "\x3""cTown Portal\x3l\n"
- "\n"
- "\t0101. %s\n"
- "\t0102. %s\n"
- "\t0103. %s\n"
- "\t0104. %s\n"
- "\t0105. %s\x3""c\n"
- "\n"
- "To which Town (1-5)\n"
- "\n";
-
-const int Resources::TOWN_MAP_NUMBERS[2][5] = {
- { 28, 29, 30, 31, 32 }, { 29, 31, 33, 35, 37 }
-};
-
-const char *const Resources::MONSTER_DETAILS =
- "\x3l\n"
- "%s\x3""c\t100%s\t140%u\t180%u\x3r\t000%s";
-
-const char *const Resources::MONSTER_SPECIAL_ATTACKS[23] = {
- "None", "Magic", "Fire", "Elec", "Cold", "Poison", "Energy", "Disease",
- "Insane", "Asleep", "CurseItm", "InLove", "DrnSPts", "Curse", "Paralys",
- "Uncons", "Confuse", "BrkWpn", "Weak", "Erad", "Age+5", "Dead", "Stone"
-};
-
-const char *const Resources::IDENTIFY_MONSTERS =
- "Name\x3""c\t100HP\t140AC\t177#Atks\x3r\t000Special%s%s%s";
-
-const char *const Resources::EVENT_SAMPLES[6] = {
- "ahh.voc", "whereto.voc", "gulp.voc", "null.voc", "scream.voc", "laff1.voc"
-};
-
-const char *const Resources::MOONS_NOT_ALIGNED =
-"\x3""c\xB""012\t000The moons are not aligned. Passage to the %s is unavailable";
-
-const char *const Resources::AWARDS_FOR =
- "\r\x1\fd\x3""c\v000\t000Awards for %s the %s\x3""l\x2\n"
- "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\x1";
-
-const char *const Resources::AWARDS_TEXT =
- "\r\x2\x3""c\xB""021\t221\xC""37U\xC""dp\t255\xC""37D\xC""down\t289Exit";
-
-const char *const Resources::NO_AWARDS = "\x3""cNo Awards";
-
-const char *const Resources::WARZONE_BATTLE_MASTER = "The Warzone\n\t125Battle Master";
-
-const char *const Resources::WARZONE_MAXED = "What! You again? Go pick on someone your own size!";
-
-const char *const Resources::WARZONE_LEVEL = "What level of monsters? (1-10)\n";
-
-const char *const Resources::WARZONE_HOW_MANY = "How many monsters? (1-20)\n";
-
-const char *const Resources::PICKS_THE_LOCK = "\x3""c\xB""010%s picks the lock!\nPress any key.";
-
-const char *const Resources::UNABLE_TO_PICK_LOCK = "\x3""c\v010%s was unable to pick the lock!\nPress any key.";
-
-const char *const Resources::CONTROL_PANEL_TEXT =
- "\x1\xC""00\x3""c\xB""000\t000Control Panel\x3r"
- "\xB""022\t045\xC""06L\xC""doad:\t124\xC""06E\xC""dfx:"
- "\xB""041\t045\xC""06S\xC""dave:\t124\xC""06M\xC""dusic:"
- "\xB""060\t045\xC""06Q\xC""duit:"
- "\xB""080\t084Mr \xC""06W\xC""dizard:%s\t000\x1";
-const char *const Resources::CONTROL_PANEL_BUTTONS =
- "\x3""c\f11"
- "\xB""022\t062load\t141%s"
- "\xB""041\t062save\t141%s"
- "\xB""060\t062exit"
- "\xB""079\t102Help\xC""d";
-const char *const Resources::ON = "\f15on\f11";
-const char *const Resources::OFF = "\f32off\f11";
-const char *const Resources::CONFIRM_QUIT = "Are you sure you want to quit?";
-const char *const Resources::MR_WIZARD =
- "Are you sure you want Mr.Wizard's Help ?";
-const char *const Resources::NO_LOADING_IN_COMBAT =
- "No Loading Allowed in Combat!";
-const char *const Resources::NO_SAVING_IN_COMBAT =
- "No Saving Allowed in Combat!";
-const char *const Resources::QUICK_FIGHT_TEXT = "\r\fd\x3""c\v000\t000QuickFight Options\n\n"
- "%s\x3l\n\n"
- "Current\x3r\n"
- "\t000%s\x2\x3""c\v122\t021\f37N\f04ext\t060Exit\x1";
-const char *const Resources::QUICK_FIGHT_OPTIONS[4] = { "Attack", "Cast", "Block", "Run" };
-
-const char *const Resources::WORLD_END_TEXT[9] = {
- "\n\n\n\n\n\n\n"
- "Congratulations Adventurers!\n\n"
- "Let the unification ceremony begin!",
- "And so the call went out to the people throughout the lands of Xeen"
- " that the prophecy was nearing completion.",
- "They came in great numbers to witness the momentous occasion.",
- "\xB""026The Dragon Pharoah presided over the ceremony.",
- "\xB""026Queen Kalindra presented the Cube of Power.",
- "\xB""026Prince Roland presented the Xeen Sceptre.",
- "\xB""026Together, they placed the Cube of Power...",
- "\xB""026and the Sceptre, onto the Altar of Joining.",
- "With the prophecy complete, the two sides of Xeen were united as one",
-};
+ // Load the data from the resource
+ loadData();
+}
-const char *const Resources::WORLD_CONGRATULATIONS =
- "\x3""cCongratulations\n\n"
- "Your Final Score is:\n\n"
- "%010lu\n"
- "\x3l\n"
- "Please send this score to the Ancient's Headquarters where "
- "you'll be added to the Hall of Legends!\n\n"
- "Ancient's Headquarters\n"
- "New World Computing, Inc.\n"
- "P.O. Box 4302\n"
- "Hollywood, CA 90078";
-const char *const Resources::WORLD_CONGRATULATIONS2 =
- "\n\n\n\n\n\n"
- "But wait... there's more!\n"
- "\n\n"
- "Include the message\n"
- "\"%s\"\n"
- "with your final score and receive a special bonus.";
-const char *const Resources::CLOUDS_CONGRATULATIONS1 =
- "\xC""23\x3l"
- "\xB""000\t000Please send this score to the Ancient's Headquarters "
- "where you'll be added to the Hall of Legends!\xC""33\x3""c"
- "\xB""070\t000Press a Key";
-const char *const Resources::CLOUDS_CONGRATULATIONS2 =
- "\xC""23\x3l"
- "\xB""000\t000Ancient's Headquarters\n"
- "New World Computing, Inc.\n"
- "P.O. Box 4302\n"
- "Hollywood, CA 90078-4302\xC""33\x3""c"
- "\xB""070\t000Press a Key";
-const char *const Resources::GOOBER[3] = {
- "", "I am a Goober!", "I am a Super Goober!"
-};
+void Resources::loadData() {
+ ResFile file;
+ file.syncString(CREDITS);
+ file.syncString(OPTIONS_TITLE);
+ file.syncString(THE_PARTY_NEEDS_REST);
+ file.syncString(WHO_WILL);
+ file.syncString(HOW_MUCH);
+ file.syncString(WHATS_THE_PASSWORD);
+ file.syncString(IN_NO_CONDITION);
+ file.syncString(NOTHING_HERE);
+ file.syncStrings(TERRAIN_TYPES, 6);
+ file.syncStrings(OUTDOORS_WALL_TYPES, 16);
+ file.syncStrings(SURFACE_NAMES, 16);
+ file.syncStrings(WHO_ACTIONS, 32);
+ file.syncStrings(WHO_WILL_ACTIONS, 4);
+ file.syncBytes2D((byte *)SYMBOLS, 20, 64);
+ file.syncBytes2D((byte *)TEXT_COLORS, 40, 4);
+ file.syncStrings(DIRECTION_TEXT_UPPER, 4);
+ file.syncStrings(DIRECTION_TEXT, 4);
+ file.syncStrings(RACE_NAMES, 5);
+ file.syncNumbers(RACE_HP_BONUSES, 5);
+ file.syncNumbers2D((int *)RACE_SP_BONUSES, 5, 2);
+ file.syncStrings(CLASS_NAMES, 11);
+ file.syncNumbers(CLASS_EXP_LEVELS, 10);
+ file.syncStrings(ALIGNMENT_NAMES, 3);
+ file.syncStrings(SEX_NAMES, 2);
+ file.syncStrings(SKILL_NAMES, 18);
+ file.syncStrings(CONDITION_NAMES, 17);
+ file.syncNumbers(CONDITION_COLORS, 17);
+ file.syncString(GOOD);
+ file.syncString(BLESSED);
+ file.syncString(POWER_SHIELD);
+ file.syncString(HOLY_BONUS);
+ file.syncString(HEROISM);
+ file.syncString(IN_PARTY);
+ file.syncString(PARTY_DETAILS);
+ file.syncString(PARTY_DIALOG_TEXT);
+ file.syncNumbers(FACE_CONDITION_FRAMES, 17);
+ file.syncNumbers(CHAR_FACES_X, 6);
+ file.syncNumbers(HP_BARS_X, 6);
+ file.syncString(NO_ONE_TO_ADVENTURE_WITH);
+ file.syncBytes2D((byte *)DARKNESS_XLAT, 3, 256);
+ file.syncString(YOUR_ROSTER_IS_FULL);
+ file.syncString(PLEASE_WAIT);
+ file.syncString(OOPS);
+ file.syncNumbers2D((int *)SCREEN_POSITIONING_X, 4, 48);
+ file.syncNumbers2D((int *)SCREEN_POSITIONING_Y, 4, 48);
+ file.syncNumbers(MONSTER_GRID_BITMASK, 12);
+ file.syncNumbers2D((int *)INDOOR_OBJECT_X, 2, 12);
+ file.syncNumbers2D((int *)MAP_OBJECT_Y, 2, 12);
+ file.syncNumbers(INDOOR_MONSTERS_Y, 4);
+ file.syncNumbers2D((int *)OUTDOOR_OBJECT_X, 2, 12);
+ file.syncNumbers(OUTDOOR_MONSTER_INDEXES, 26);
+ file.syncNumbers(OUTDOOR_MONSTERS_Y, 26);
+ file.syncNumbers2D((int *)DIRECTION_ANIM_POSITIONS, 4, 4);
+ file.syncBytes2D((byte *)WALL_SHIFTS, 4, 48);
+ file.syncNumbers(DRAW_NUMBERS, 25);
+ file.syncNumbers2D((int *)DRAW_FRAMES, 25, 2);
+ file.syncNumbers(COMBAT_FLOAT_X, 8);
+ file.syncNumbers(COMBAT_FLOAT_Y, 8);
+ file.syncNumbers2D((int *)MONSTER_EFFECT_FLAGS, 15, 8);
+ file.syncNumbers2D((int *)SPELLS_ALLOWED, 3, 40);
+ file.syncNumbers(BASE_HP_BY_CLASS, 10);
+ file.syncNumbers(AGE_RANGES, 10);
+ file.syncNumbers2D((int *)AGE_RANGES_ADJUST, 2, 10);
+ file.syncNumbers(STAT_VALUES, 24);
+ file.syncNumbers(STAT_BONUSES, 24);
+ file.syncNumbers(ELEMENTAL_CATEGORIES, 6);
+ file.syncNumbers(ATTRIBUTE_CATEGORIES, 10);
+ file.syncNumbers(ATTRIBUTE_BONUSES, 72);
+ file.syncNumbers(ELEMENTAL_RESISTENCES, 37);
+ file.syncNumbers(ELEMENTAL_DAMAGE, 37);
+ file.syncNumbers(WEAPON_DAMAGE_BASE, 35);
+ file.syncNumbers(WEAPON_DAMAGE_MULTIPLIER, 35);
+ file.syncNumbers(METAL_DAMAGE, 22);
+ file.syncNumbers(METAL_DAMAGE_PERCENT, 22);
+ file.syncNumbers(METAL_LAC, 9);
+ file.syncNumbers(ARMOR_STRENGTHS, 14);
+ file.syncNumbers(MAKE_ITEM_ARR1, 6);
+ file.syncNumbers3D((int *)MAKE_ITEM_ARR2, 6, 7, 2);
+ file.syncNumbers3D((int *)MAKE_ITEM_ARR3, 10, 7, 2);
+ file.syncNumbers3D((int *)MAKE_ITEM_ARR4, 2, 7, 2);
+ file.syncNumbers2D((int *)MAKE_ITEM_ARR5, 8, 2);
+ file.syncNumbers(OUTDOOR_DRAWSTRUCT_INDEXES, 44);
+ file.syncNumbers2D((int *)TOWN_MAXES, 2, 11);
+ file.syncStrings2D((String *)TOWN_ACTION_MUSIC, 2, 7);
+ file.syncStrings(TOWN_ACTION_SHAPES, 7);
+ file.syncNumbers2D((int *)TOWN_ACTION_FILES, 2, 7);
+ file.syncString(BANK_TEXT);
+ file.syncString(BLACKSMITH_TEXT);
+ file.syncString(GUILD_NOT_MEMBER_TEXT);
+ file.syncString(GUILD_TEXT);
+ file.syncString(TAVERN_TEXT);
+ file.syncString(GOOD_STUFF);
+ file.syncString(HAVE_A_DRINK);
+ file.syncString(YOURE_DRUNK);
+ file.syncNumbers4D((int *)TAVERN_EXIT_LIST, 2, 6, 5, 2);
+ file.syncString(FOOD_AND_DRINK);
+ file.syncString(TEMPLE_TEXT);
+ file.syncString(EXPERIENCE_FOR_LEVEL);
+ file.syncString(LEARNED_ALL);
+ file.syncString(ELIGIBLE_FOR_LEVEL);
+ file.syncString(TRAINING_TEXT);
+ file.syncString(GOLD_GEMS);
+ file.syncString(GOLD_GEMS_2);
+ file.syncString(DEPOSIT_WITHDRAWL[2]);
+ file.syncString(NOT_ENOUGH_X_IN_THE_Y);
+ file.syncString(NO_X_IN_THE_Y);
+ file.syncString(STAT_NAMES[16]);
+ file.syncString(CONSUMABLE_NAMES[4]);
+ file.syncString(WHERE_NAMES[2]);
+ file.syncString(AMOUNT);
+ file.syncString(FOOD_PACKS_FULL);
+ file.syncString(BUY_SPELLS);
+ file.syncString(GUILD_OPTIONS);
+ file.syncNumbers((int *)MISC_SPELL_INDEX, 74);
+ file.syncNumbers((int *)SPELL_COSTS, 77);
+ file.syncNumbers2D((int *)CLOUDS_SPELL_OFFSETS, 5, 20);
+ file.syncNumbers2D((int *)DARK_SPELL_OFFSETS, 3, 39);
+ file.syncNumbers2D((int *)DARK_SPELL_RANGES, 12, 2);
+ file.syncNumbers((int *)SPELL_GEM_COST, 77);
+ file.syncString(NOT_A_SPELL_CASTER);
+ file.syncString(SPELLS_FOR);
+ file.syncString(SPELL_LINES_0_TO_9);
+ file.syncString(SPELLS_DIALOG_SPELLS);
+ file.syncString(SPELL_PTS);
+ file.syncString(GOLD);
+ file.syncString(SPELLS_PRESS_A_KEY);
+ file.syncString(SPELLS_PURCHASE);
+ file.syncString(MAP_TEXT);
+ file.syncString(LIGHT_COUNT_TEXT);
+ file.syncString(FIRE_RESISTENCE_TEXT);
+ file.syncString(ELECRICITY_RESISTENCE_TEXT);
+ file.syncString(COLD_RESISTENCE_TEXT);
+ file.syncString(POISON_RESISTENCE_TEXT);
+ file.syncString(CLAIRVOYANCE_TEXT);
+ file.syncString(LEVITATE_TEXT);
+ file.syncString(WALK_ON_WATER_TEXT);
+ file.syncString(GAME_INFORMATION);
+ file.syncString(WORLD_GAME_TEXT);
+ file.syncString(DARKSIDE_GAME_TEXT);
+ file.syncString(CLOUDS_GAME_TEXT);
+ file.syncString(SWORDS_GAME_TEXT);
+ file.syncStrings(WEEK_DAY_STRINGS, 10);
+ file.syncString(CHARACTER_DETAILS);
+ file.syncString(PARTY_GOLD);
+ file.syncString(PLUS_14);
+ file.syncString(CHARACTER_TEMPLATE);
+ file.syncString(EXCHANGING_IN_COMBAT);
+ file.syncString(CURRENT_MAXIMUM_RATING_TEXT);
+ file.syncString(CURRENT_MAXIMUM_TEXT);
+ file.syncStrings(RATING_TEXT, 24);
+ file.syncString(AGE_TEXT);
+ file.syncString(LEVEL_TEXT);
+ file.syncString(RESISTENCES_TEXT);
+ file.syncString(NONE);
+ file.syncString(EXPERIENCE_TEXT);
+ file.syncString(ELIGIBLE);
+ file.syncString(IN_PARTY_IN_BANK);
+ file.syncString(FOOD_TEXT);
+ file.syncString(EXCHANGE_WITH_WHOM);
+ file.syncString(QUICK_REF_LINE);
+ file.syncString(QUICK_REFERENCE);
+ file.syncNumbers2D((int *)BLACKSMITH_MAP_IDS, 2, 4);
+ file.syncString(ITEMS_DIALOG_TEXT1);
+ file.syncString(ITEMS_DIALOG_TEXT2);
+ file.syncString(ITEMS_DIALOG_LINE1);
+ file.syncString(ITEMS_DIALOG_LINE2);
+ file.syncString(BTN_BUY);
+ file.syncString(BTN_SELL);
+ file.syncString(BTN_IDENTIFY);
+ file.syncString(BTN_FIX);
+ file.syncString(BTN_USE);
+ file.syncString(BTN_EQUIP);
+ file.syncString(BTN_REMOVE);
+ file.syncString(BTN_DISCARD);
+ file.syncString(BTN_QUEST);
+ file.syncString(BTN_ENCHANT);
+ file.syncString(BTN_RECHARGE);
+ file.syncString(BTN_GOLD);
+ file.syncString(ITEM_BROKEN);
+ file.syncString(ITEM_CURSED);
+ file.syncStrings(BONUS_NAMES, 7);
+ file.syncStrings(WEAPON_NAMES, 35);
+ file.syncStrings(ARMOR_NAMES, 14);
+ file.syncStrings(ACCESSORY_NAMES, 11);
+ file.syncStrings(MISC_NAMES, 22);
+ file.syncStrings(ELEMENTAL_NAMES, 6);
+ file.syncStrings(ATTRIBUTE_NAMES, 10);
+ file.syncStrings(EFFECTIVENESS_NAMES, 7);
+ file.syncStrings(QUEST_ITEM_NAMES, 85);
+ file.syncNumbers((int *)WEAPON_BASE_COSTS, 35);
+ file.syncNumbers((int *)ARMOR_BASE_COSTS, 14);
+ file.syncNumbers((int *)ACCESSORY_BASE_COSTS, 11);
+ file.syncNumbers((int *)MISC_MATERIAL_COSTS, 22);
+ file.syncNumbers((int *)MISC_BASE_COSTS, 76);
+ file.syncNumbers((int *)METAL_BASE_MULTIPLIERS, 22);
+ file.syncNumbers((int *)ITEM_SKILL_DIVISORS, 4);
+ file.syncNumbers((int *)RESTRICTION_OFFSETS, 4);
+ file.syncNumbers((int *)ITEM_RESTRICTIONS, 86);
+ file.syncString(NOT_PROFICIENT);
+ file.syncString(NO_ITEMS_AVAILABLE);
+ file.syncStrings(CATEGORY_NAMES, 4);
+ file.syncString(X_FOR_THE_Y);
+ file.syncString(X_FOR_Y);
+ file.syncString(X_FOR_Y_GOLD);
+ file.syncString(FMT_CHARGES);
+ file.syncString(AVAILABLE_GOLD_COST);
+ file.syncString(CHARGES);
+ file.syncString(COST);
+ file.syncStrings(ITEM_ACTIONS, 7);
+ file.syncString(WHICH_ITEM);
+ file.syncString(WHATS_YOUR_HURRY);
+ file.syncString(USE_ITEM_IN_COMBAT);
+ file.syncString(NO_SPECIAL_ABILITIES);
+ file.syncString(CANT_CAST_WHILE_ENGAGED);
+ file.syncString(EQUIPPED_ALL_YOU_CAN);
+ file.syncString(REMOVE_X_TO_EQUIP_Y);
+ file.syncString(RING);
+ file.syncString(MEDAL);
+ file.syncString(CANNOT_REMOVE_CURSED_ITEM);
+ file.syncString(CANNOT_DISCARD_CURSED_ITEM);
+ file.syncString(PERMANENTLY_DISCARD);
+ file.syncString(BACKPACK_IS_FULL);
+ file.syncStrings(CATEGORY_BACKPACK_IS_FULL, 4);
+ file.syncString(BUY_X_FOR_Y_GOLD);
+ file.syncString(SELL_X_FOR_Y_GOLD);
+ file.syncString(NO_NEED_OF_THIS);
+ file.syncString(NOT_RECHARGABLE);
+ file.syncString(SPELL_FAILED);
+ file.syncString(NOT_ENCHANTABLE);
+ file.syncString(ITEM_NOT_BROKEN);
+ file.syncStrings(FIX_IDENTIFY, 2);
+ file.syncString(FIX_IDENTIFY_GOLD);
+ file.syncString(IDENTIFY_ITEM_MSG);
+ file.syncString(ITEM_DETAILS);
+ file.syncString(ALL);
+ file.syncString(FIELD_NONE);
+ file.syncString(DAMAGE_X_TO_Y);
+ file.syncString(ELEMENTAL_XY_DAMAGE);
+ file.syncString(ATTR_XY_BONUS);
+ file.syncString(EFFECTIVE_AGAINST);
+ file.syncString(QUESTS_DIALOG_TEXT);
+ file.syncString(CLOUDS_OF_XEEN_LINE);
+ file.syncString(DARKSIDE_OF_XEEN_LINE);
+ file.syncString(NO_QUEST_ITEMS);
+ file.syncString(NO_CURRENT_QUESTS);
+ file.syncString(NO_AUTO_NOTES);
+ file.syncString(QUEST_ITEMS_DATA);
+ file.syncString(CURRENT_QUESTS_DATA);
+ file.syncString(AUTO_NOTES_DATA);
+ file.syncString(REST_COMPLETE);
+ file.syncString(PARTY_IS_STARVING);
+ file.syncString(HIT_SPELL_POINTS_RESTORED);
+ file.syncString(TOO_DANGEROUS_TO_REST);
+ file.syncString(SOME_CHARS_MAY_DIE);
+ file.syncString(CANT_DISMISS_LAST_CHAR);
+ file.syncStrings(REMOVE_DELETE, 2);
+ file.syncString(REMOVE_OR_DELETE_WHICH);
+ file.syncString(YOUR_PARTY_IS_FULL);
+ file.syncString(HAS_SLAYER_SWORD);
+ file.syncString(SURE_TO_DELETE_CHAR);
+ file.syncString(CREATE_CHAR_DETAILS);
+ file.syncString(NEW_CHAR_STATS);
+ file.syncString(NAME_FOR_NEW_CHARACTER);
+ file.syncString(SELECT_CLASS_BEFORE_SAVING);
+ file.syncString(EXCHANGE_ATTR_WITH);
+ file.syncNumbers((int *)NEW_CHAR_SKILLS, 10);
+ file.syncNumbers((int *)NEW_CHAR_SKILLS_LEN, 10);
+ file.syncNumbers((int *)NEW_CHAR_RACE_SKILLS, 10);
+ file.syncNumbers((int *)RACE_MAGIC_RESISTENCES, 5);
+ file.syncNumbers((int *)RACE_FIRE_RESISTENCES, 5);
+ file.syncNumbers((int *)RACE_ELECTRIC_RESISTENCES, 5);
+ file.syncNumbers((int *)RACE_COLD_RESISTENCES, 5);
+ file.syncNumbers((int *)RACE_ENERGY_RESISTENCES, 5);
+ file.syncNumbers((int *)RACE_POISON_RESISTENCES, 5);
+ file.syncNumbers2D((int *)NEW_CHARACTER_SPELLS, 10, 4);
+ file.syncString(COMBAT_DETAILS);
+ file.syncString(NOT_ENOUGH_TO_CAST);
+ file.syncStrings(SPELL_CAST_COMPONENTS, 2);
+ file.syncString(CAST_SPELL_DETAILS);
+ file.syncString(PARTY_FOUND);
+ file.syncString(BACKPACKS_FULL_PRESS_KEY);
+ file.syncString(HIT_A_KEY);
+ file.syncString(GIVE_TREASURE_FORMATTING);
+ file.syncString(X_FOUND_Y);
+ file.syncString(ON_WHO);
+ file.syncString(WHICH_ELEMENT1);
+ file.syncString(WHICH_ELEMENT2);
+ file.syncString(DETECT_MONSTERS);
+ file.syncString(LLOYDS_BEACON);
+ file.syncString(HOW_MANY_SQUARES);
+ file.syncString(TOWN_PORTAL);
+ file.syncNumbers2D((int *)TOWN_MAP_NUMBERS, 2, 5);
+ file.syncString(MONSTER_DETAILS);
+ file.syncStrings(MONSTER_SPECIAL_ATTACKS, 23);
+ file.syncString(IDENTIFY_MONSTERS);
+ file.syncStrings(EVENT_SAMPLES, 6);
+ file.syncString(MOONS_NOT_ALIGNED);
+ file.syncString(AWARDS_FOR);
+ file.syncString(AWARDS_TEXT);
+ file.syncString(NO_AWARDS);
+ file.syncString(WARZONE_BATTLE_MASTER);
+ file.syncString(WARZONE_MAXED);
+ file.syncString(WARZONE_LEVEL);
+ file.syncString(WARZONE_HOW_MANY);
+ file.syncString(PICKS_THE_LOCK);
+ file.syncString(UNABLE_TO_PICK_LOCK);
+ file.syncString(CONTROL_PANEL_TEXT);
+ file.syncString(CONTROL_PANEL_BUTTONS);
+ file.syncString(ON);
+ file.syncString(OFF);
+ file.syncString(CONFIRM_QUIT);
+ file.syncString(MR_WIZARD);
+ file.syncString(NO_LOADING_IN_COMBAT);
+ file.syncString(NO_SAVING_IN_COMBAT);
+ file.syncString(QUICK_FIGHT_TEXT);
+ file.syncStrings(QUICK_FIGHT_OPTIONS, 4);
+ file.syncStrings(WORLD_END_TEXT, 9);
+ file.syncString(WORLD_CONGRATULATIONS);
+ file.syncString(WORLD_CONGRATULATIONS2);
+ file.syncString(CLOUDS_CONGRATULATIONS1);
+ file.syncString(CLOUDS_CONGRATULATIONS2);
+ file.syncStrings(GOOBER, 3);
+ file.syncStrings(MUSIC_FILES1, 5);
+ file.syncStrings2D((String *)MUSIC_FILES2, 6, 7);
+}
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index c9e0c2f..513e70d 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/str-array.h"
#include "gui/debugger.h"
+#include "xeen/files.h"
#include "xeen/party.h"
#include "xeen/spells.h"
@@ -36,344 +37,419 @@ namespace Xeen {
class XeenEngine;
class Resources {
-protected:
- Resources();
+ /**
+ * Derived string class to fix automatic type conversion to const char *
+ */
+ class String : public Common::String {
+ public:
+ String() : Common::String() {}
+ String(const Common::String &s) : Common::String(s) {}
+ operator const char *() { return c_str(); }
+ };
+
+ /**
+ * Derived file class with sync method aliases so that the same
+ * code from create_xeen can be re-used for both reading and
+ * writing the resource data
+ */
+ class ResFile : public File {
+ public:
+ ResFile() : File("CONSTANTS") {}
+
+ void syncString(String &str) {
+ str = readString();
+ }
+ void syncStrings(String *str, int count) {
+ uint tag = readUint32LE();
+ assert(tag == MKTAG(count, 0, 0, 0));
+ for (int idx = 0; idx < count; ++idx)
+ str[idx] = readString();
+ }
+ void syncStrings2D(String *str, int count1, int count2) {
+ uint tag = readUint32LE();
+ assert(tag == MKTAG(count1, count2, 0, 0));
+ for (int idx = 0; idx < count1 * count2; ++idx)
+ str[idx] = readString();
+ }
+ void syncNumber(int &val) {
+ val = readSint32LE();
+ }
+ void syncNumbers(int *vals, int count) {
+ uint tag = readUint32LE();
+ assert(tag == MKTAG(count, 0, 0, 0));
+ for (int idx = 0; idx < count; ++idx)
+ vals[idx] = readSint32LE();
+ }
+ void syncNumbers2D(int *vals, int count1, int count2) {
+ uint tag = readUint32LE();
+ assert(tag == MKTAG(count1, count2, 0, 0));
+ for (int idx = 0; idx < count1 * count2; ++idx)
+ vals[idx] = readSint32LE();
+ }
+ void syncNumbers3D(int *vals, int count1, int count2, int count3) {
+ uint tag = readUint32LE();
+ assert(tag == MKTAG(count1, count2, count3, 0));
+ for (int idx = 0; idx < count1 * count2 * count3; ++idx)
+ vals[idx] = readSint32LE();
+ }
+ void syncNumbers4D(int *vals, int count1, int count2, int count3, int count4) {
+ uint tag = readUint32LE();
+ assert(tag == MKTAG(count1, count2, count3, count4));
+ for (int idx = 0; idx < count1 * count2 * count3 * count4; ++idx)
+ vals[idx] = readSint32LE();
+ }
+ void syncBytes2D(byte *vals, int count1, int count2) {
+ uint tag = readUint32LE();
+ assert(tag == MKTAG(count1, count2, 0, 0));
+ read(vals, count1 * count2);
+ }
+ };
+private:
+ /**
+ * Loads all the constants data stored in the xeen.css
+ */
+ void loadData();
public:
SpriteResource _globalSprites;
Common::StringArray _maeNames; // Magic and equipment names
- static const char *const CREDITS;
- static const char *const OPTIONS_TITLE;
- static const char *const THE_PARTY_NEEDS_REST;
- static const char *const WHO_WILL;
- static const char *const HOW_MUCH;
- static const char *const WHATS_THE_PASSWORD;
- static const char *const IN_NO_CONDITION;
- static const char *const NOTHING_HERE;
- static const char *const TERRAIN_TYPES[6];
- static const char *const OUTDOORS_WALL_TYPES[16];
- static const char *const SURFACE_NAMES[16];
- static const char *const WHO_ACTIONS[32];
- static const char *const WHO_WILL_ACTIONS[4];
- static const byte SYMBOLS[20][64];
- static const byte TEXT_COLORS[40][4];
- static const char *const DIRECTION_TEXT_UPPER[4];
- static const char *const DIRECTION_TEXT[4];
- static const char *const RACE_NAMES[5];
- static const int RACE_HP_BONUSES[5];
- static const int RACE_SP_BONUSES[5][2];
- static const char *const CLASS_NAMES[11];
- static const uint CLASS_EXP_LEVELS[10];
- static const char *const ALIGNMENT_NAMES[3];
- static const char *const SEX_NAMES[2];
- static const char *const SKILL_NAMES[18];
- static const char *const CONDITION_NAMES[17];
- static const int CONDITION_COLORS[17];
- static const char *const GOOD;
- static const char *const BLESSED;
- static const char *const POWER_SHIELD;
- static const char *const HOLY_BONUS;
- static const char *const HEROISM;
- static const char *const IN_PARTY;
- static const char *const PARTY_DETAILS;
- static const char *const PARTY_DIALOG_TEXT;
- static const int FACE_CONDITION_FRAMES[17];
- static const int CHAR_FACES_X[6];
- static const int HP_BARS_X[6];
- static const char *const NO_ONE_TO_ADVENTURE_WITH;
- static const byte DARKNESS_XLAT[3][256];
- static const char *const YOUR_ROSTER_IS_FULL;
- static const char *const PLEASE_WAIT;
- static const char *const OOPS;
- static const int8 SCREEN_POSITIONING_X[4][48];
- static const int8 SCREEN_POSITIONING_Y[4][48];
- static const int MONSTER_GRID_BITMASK[12];
- static const int INDOOR_OBJECT_X[2][12];
- static const int MAP_OBJECT_Y[2][12];
- static const int INDOOR_MONSTERS_Y[4];
- static const int OUTDOOR_OBJECT_X[2][12];
- static const int OUTDOOR_MONSTER_INDEXES[26];
- static const int OUTDOOR_MONSTERS_Y[26];
- static const int DIRECTION_ANIM_POSITIONS[4][4];
- static const byte WALL_SHIFTS[4][48];
- static const int DRAW_NUMBERS[25];
- static const int DRAW_FRAMES[25][2];
- static const int COMBAT_FLOAT_X[8];
- static const int COMBAT_FLOAT_Y[8];
- static const int MONSTER_EFFECT_FLAGS[15][8];
- static const uint SPELLS_ALLOWED[3][40];
- static const int BASE_HP_BY_CLASS[10];
- static const int AGE_RANGES[10];
- static const int AGE_RANGES_ADJUST[2][10];
- static const uint STAT_VALUES[24];
- static const int STAT_BONUSES[24];
- static const int ELEMENTAL_CATEGORIES[6];
- static const int ATTRIBUTE_CATEGORIES[10];
- static const int ATTRIBUTE_BONUSES[72];
- static const int ELEMENTAL_RESISTENCES[37];
- static const int ELEMENTAL_DAMAGE[37];
- static const int WEAPON_DAMAGE_BASE[35];
- static const int WEAPON_DAMAGE_MULTIPLIER[35];
- static const int METAL_DAMAGE[22];
- static const int METAL_DAMAGE_PERCENT[22];
- static const int METAL_LAC[9];
- static const int ARMOR_STRENGTHS[14];
- static const int MAKE_ITEM_ARR1[6];
- static const int MAKE_ITEM_ARR2[6][7][2];
- static const int MAKE_ITEM_ARR3[10][7][2];
- static const int MAKE_ITEM_ARR4[2][7][2];
- static const int MAKE_ITEM_ARR5[8][2];
- static const int OUTDOOR_DRAWSTRUCT_INDEXES[44];
- static const int TOWN_MAXES[2][11];
- static const char *const TOWN_ACTION_MUSIC[2][7];
- static const char *const TOWN_ACTION_SHAPES[7];
- static const int TOWN_ACTION_FILES[2][7];
- static const char *const BANK_TEXT;
- static const char *const BLACKSMITH_TEXT;
- static const char *const GUILD_NOT_MEMBER_TEXT;
- static const char *const GUILD_TEXT;
- static const char *const TAVERN_TEXT;
- static const char *const GOOD_STUFF;
- static const char *const HAVE_A_DRINK;
- static const char *const YOURE_DRUNK;
- static const int TAVERN_EXIT_LIST[2][6][5][2];
- static const char *const FOOD_AND_DRINK;
- static const char *const TEMPLE_TEXT;
- static const char *const EXPERIENCE_FOR_LEVEL;
- static const char *const LEARNED_ALL;
- static const char *const ELIGIBLE_FOR_LEVEL;
- static const char *const TRAINING_TEXT;
- static const char *const GOLD_GEMS;
- static const char *const GOLD_GEMS_2;
- static const char *const DEPOSIT_WITHDRAWL[2];
- static const char *const NOT_ENOUGH_X_IN_THE_Y;
- static const char *const NO_X_IN_THE_Y;
- static const char *const STAT_NAMES[16];
- static const char *const CONSUMABLE_NAMES[4];
- static const char *const WHERE_NAMES[2];
- static const char *const AMOUNT;
- static const char *const FOOD_PACKS_FULL;
- static const char *const BUY_SPELLS;
- static const char *const GUILD_OPTIONS;
- static const int MISC_SPELL_INDEX[74];
- static const int SPELL_COSTS[77];
- static const int CLOUDS_SPELL_OFFSETS[5][20];
- static const uint DARK_SPELL_OFFSETS[3][39];
- static const int DARK_SPELL_RANGES[12][2];
- static const int SPELL_LEVEL_OFFSETS[3][39];
- static const int SPELL_GEM_COST[77];
- static const char *const NOT_A_SPELL_CASTER;
- static const char *const SPELLS_FOR;
- static const char *const SPELL_LINES_0_TO_9;
- static const char *const SPELLS_DIALOG_SPELLS;
- static const char *const SPELL_PTS;
- static const char *const GOLD;
- static const char *const SPELLS_PRESS_A_KEY;
- static const char *const SPELLS_PURCHASE;
- static const char *const MAP_TEXT;
- static const char *const LIGHT_COUNT_TEXT;
- static const char *const FIRE_RESISTENCE_TEXT;
- static const char *const ELECRICITY_RESISTENCE_TEXT;
- static const char *const COLD_RESISTENCE_TEXT;
- static const char *const POISON_RESISTENCE_TEXT;
- static const char *const CLAIRVOYANCE_TEXT;
- static const char *const LEVITATE_TEXT;
- static const char *const WALK_ON_WATER_TEXT;
- static const char *const GAME_INFORMATION;
- static const char *const WORLD_GAME_TEXT;
- static const char *const DARKSIDE_GAME_TEXT;
- static const char *const CLOUDS_GAME_TEXT;
- static const char *const SWORDS_GAME_TEXT;
- static const char *const WEEK_DAY_STRINGS[10];
- static const char *const CHARACTER_DETAILS;
- static const char *const PARTY_GOLD;
- static const char *const PLUS_14;
- static const char *const CHARACTER_TEMPLATE;
- static const char *const EXCHANGING_IN_COMBAT;
- static const char *const CURRENT_MAXIMUM_RATING_TEXT;
- static const char *const CURRENT_MAXIMUM_TEXT;
- static const char *const RATING_TEXT[24];
- static const char *const AGE_TEXT;
- static const char *const LEVEL_TEXT;
- static const char *const RESISTENCES_TEXT;
- static const char *const NONE;
- static const char *const EXPERIENCE_TEXT;
- static const char *const ELIGIBLE;
- static const char *const IN_PARTY_IN_BANK;
- static const char *const FOOD_TEXT;
- static const char *const EXCHANGE_WITH_WHOM;
- static const char *const QUICK_REF_LINE;
- static const char *const QUICK_REFERENCE;
- static const uint BLACKSMITH_MAP_IDS[2][4];
- static const char *const ITEMS_DIALOG_TEXT1;
- static const char *const ITEMS_DIALOG_TEXT2;
- static const char *const ITEMS_DIALOG_LINE1;
- static const char *const ITEMS_DIALOG_LINE2;
- static const char *const BTN_BUY;
- static const char *const BTN_SELL;
- static const char *const BTN_IDENTIFY;
- static const char *const BTN_FIX;
- static const char *const BTN_USE;
- static const char *const BTN_EQUIP;
- static const char *const BTN_REMOVE;
- static const char *const BTN_DISCARD;
- static const char *const BTN_QUEST;
- static const char *const BTN_ENCHANT;
- static const char *const BTN_RECHARGE;
- static const char *const BTN_GOLD;
- static const char *const ITEM_BROKEN;
- static const char *const ITEM_CURSED;
- static const char *const BONUS_NAMES[7];
- static const char *const WEAPON_NAMES[35];
- static const char *const ARMOR_NAMES[14];
- static const char *const ACCESSORY_NAMES[11];
- static const char *const MISC_NAMES[22];
- static const char *const *ITEM_NAMES[4];
- static const char *const ELEMENTAL_NAMES[6];
- static const char *const ATTRIBUTE_NAMES[10];
- static const char *const EFFECTIVENESS_NAMES[7];
- static const char *const QUEST_ITEM_NAMES[85];
- static const int WEAPON_BASE_COSTS[35];
- static const int ARMOR_BASE_COSTS[14];
- static const int ACCESSORY_BASE_COSTS[11];
- static const int MISC_MATERIAL_COSTS[22];
- static const int MISC_BASE_COSTS[76];
- static const int METAL_BASE_MULTIPLIERS[22];
- static const int ITEM_SKILL_DIVISORS[4];
- static const int RESTRICTION_OFFSETS[4];
- static const int ITEM_RESTRICTIONS[86];
- static const char *const NOT_PROFICIENT;
- static const char *const NO_ITEMS_AVAILABLE;
- static const char *const CATEGORY_NAMES[4];
- static const char *const X_FOR_THE_Y;
- static const char *const X_FOR_Y;
- static const char *const X_FOR_Y_GOLD;
- static const char *const FMT_CHARGES;
- static const char *const AVAILABLE_GOLD_COST;
- static const char *const CHARGES;
- static const char *const COST;
- static const char *const ITEM_ACTIONS[7];
- static const char *const WHICH_ITEM;
- static const char *const WHATS_YOUR_HURRY;
+ String *ITEM_NAMES[4];
- static const char *const USE_ITEM_IN_COMBAT;
-
- static const char *const NO_SPECIAL_ABILITIES;
-
- static const char *const CANT_CAST_WHILE_ENGAGED;
-
- static const char *const EQUIPPED_ALL_YOU_CAN;
- static const char *const REMOVE_X_TO_EQUIP_Y;
- static const char *const RING;
- static const char *const MEDAL;
- static const char *const CANNOT_REMOVE_CURSED_ITEM;
- static const char *const CANNOT_DISCARD_CURSED_ITEM;
- static const char *const PERMANENTLY_DISCARD;
- static const char *const BACKPACK_IS_FULL;
- static const char *const CATEGORY_BACKPACK_IS_FULL[4];
- static const char *const BUY_X_FOR_Y_GOLD;
- static const char *const SELL_X_FOR_Y_GOLD;
- static const char *const NO_NEED_OF_THIS;
- static const char *const NOT_RECHARGABLE;
- static const char *const SPELL_FAILED;
- static const char *const NOT_ENCHANTABLE;
- static const char *const ITEM_NOT_BROKEN;
- static const char *const FIX_IDENTIFY[2];
- static const char *const FIX_IDENTIFY_GOLD;
- static const char *const IDENTIFY_ITEM_MSG;
- static const char *const ITEM_DETAILS;
- static const char *const ALL;
- static const char *const FIELD_NONE;
- static const char *const DAMAGE_X_TO_Y;
- static const char *const ELEMENTAL_XY_DAMAGE;
- static const char *const ATTR_XY_BONUS;
- static const char *const EFFECTIVE_AGAINST;
- static const char *const QUESTS_DIALOG_TEXT;
- static const char *const CLOUDS_OF_XEEN_LINE;
- static const char *const DARKSIDE_OF_XEEN_LINE;
- static const char *const NO_QUEST_ITEMS;
- static const char *const NO_CURRENT_QUESTS;
- static const char *const NO_AUTO_NOTES;
- static const char *const QUEST_ITEMS_DATA;
- static const char *const CURRENT_QUESTS_DATA;
- static const char *const AUTO_NOTES_DATA;
- static const char *const REST_COMPLETE;
- static const char *const PARTY_IS_STARVING;
- static const char *const HIT_SPELL_POINTS_RESTORED;
- static const char *const TOO_DANGEROUS_TO_REST;
- static const char *const SOME_CHARS_MAY_DIE;
- static const char *const CANT_DISMISS_LAST_CHAR;
- static const char *const REMOVE_DELETE[2];
- static const char *const REMOVE_OR_DELETE_WHICH;
- static const char *const YOUR_PARTY_IS_FULL;
- static const char *const HAS_SLAYER_SWORD;
- static const char *const SURE_TO_DELETE_CHAR;
- static const char *const CREATE_CHAR_DETAILS;
- static const char *const NEW_CHAR_STATS;
- static const char *const NAME_FOR_NEW_CHARACTER;
- static const char *const SELECT_CLASS_BEFORE_SAVING;
- static const char *const EXCHANGE_ATTR_WITH;
- static const int NEW_CHAR_SKILLS[10];
- static const int NEW_CHAR_SKILLS_LEN[10];
- static const int NEW_CHAR_RACE_SKILLS[10];
- static const int RACE_MAGIC_RESISTENCES[5];
- static const int RACE_FIRE_RESISTENCES[5];
- static const int RACE_ELECTRIC_RESISTENCES[5];
- static const int RACE_COLD_RESISTENCES[5];
- static const int RACE_ENERGY_RESISTENCES[5];
- static const int RACE_POISON_RESISTENCES[5];
- static const int NEW_CHARACTER_SPELLS[10][4];
- static const char *const COMBAT_DETAILS;
- static const char *NOT_ENOUGH_TO_CAST;
- static const char *SPELL_CAST_COMPONENTS[2];
- static const char *const CAST_SPELL_DETAILS;
- static const char *const PARTY_FOUND;
- static const char *const BACKPACKS_FULL_PRESS_KEY;
- static const char *const HIT_A_KEY;
- static const char *const GIVE_TREASURE_FORMATTING;
- static const char *const X_FOUND_Y;
- static const char *const ON_WHO;
- static const char *const WHICH_ELEMENT1;
- static const char *const WHICH_ELEMENT2;
- static const char *const DETECT_MONSTERS;
- static const char *const LLOYDS_BEACON;
- static const char *const HOW_MANY_SQUARES;
- static const char *const TOWN_PORTAL;
- static const int TOWN_MAP_NUMBERS[2][5];
- static const char *const MONSTER_DETAILS;
- static const char *const MONSTER_SPECIAL_ATTACKS[23];
- static const char *const IDENTIFY_MONSTERS;
- static const char *const EVENT_SAMPLES[6];
- static const char *const MOONS_NOT_ALIGNED;
- static const char *const AWARDS_FOR;
- static const char *const AWARDS_TEXT;
- static const char *const NO_AWARDS;
- static const char *const WARZONE_BATTLE_MASTER;
- static const char *const WARZONE_MAXED;
- static const char *const WARZONE_LEVEL;
- static const char *const WARZONE_HOW_MANY;
- static const char *const PICKS_THE_LOCK;
- static const char *const UNABLE_TO_PICK_LOCK;
- static const char *const CONTROL_PANEL_TEXT;
- static const char *const CONTROL_PANEL_BUTTONS;
- static const char *const ON;
- static const char *const OFF;
- static const char *const CONFIRM_QUIT;
- static const char *const MR_WIZARD;
- static const char *const NO_LOADING_IN_COMBAT;
- static const char *const NO_SAVING_IN_COMBAT;
- static const char *const QUICK_FIGHT_TEXT;
- static const char *const QUICK_FIGHT_OPTIONS[4];
- static const char *const WORLD_END_TEXT[9];
- static const char *const WORLD_CONGRATULATIONS;
- static const char *const WORLD_CONGRATULATIONS2;
- static const char *const CLOUDS_CONGRATULATIONS1;
- static const char *const CLOUDS_CONGRATULATIONS2;
- static const char *const GOOBER[3];
+ // Data loaded from xeen.ccs
+ String CREDITS;
+ String OPTIONS_TITLE;
+ String THE_PARTY_NEEDS_REST;
+ String WHO_WILL;
+ String HOW_MUCH;
+ String WHATS_THE_PASSWORD;
+ String IN_NO_CONDITION;
+ String NOTHING_HERE;
+ String TERRAIN_TYPES[6];
+ String OUTDOORS_WALL_TYPES[16];
+ String SURFACE_NAMES[16];
+ String WHO_ACTIONS[32];
+ String WHO_WILL_ACTIONS[4];
+ byte SYMBOLS[20][64];
+ byte TEXT_COLORS[40][4];
+ String DIRECTION_TEXT_UPPER[4];
+ String DIRECTION_TEXT[4];
+ String RACE_NAMES[5];
+ int RACE_HP_BONUSES[5];
+ int RACE_SP_BONUSES[5][2];
+ String CLASS_NAMES[11];
+ int CLASS_EXP_LEVELS[10];
+ String ALIGNMENT_NAMES[3];
+ String SEX_NAMES[2];
+ String SKILL_NAMES[18];
+ String CONDITION_NAMES[17];
+ int CONDITION_COLORS[17];
+ String GOOD;
+ String BLESSED;
+ String POWER_SHIELD;
+ String HOLY_BONUS;
+ String HEROISM;
+ String IN_PARTY;
+ String PARTY_DETAILS;
+ String PARTY_DIALOG_TEXT;
+ int FACE_CONDITION_FRAMES[17];
+ int CHAR_FACES_X[6];
+ int HP_BARS_X[6];
+ String NO_ONE_TO_ADVENTURE_WITH;
+ byte DARKNESS_XLAT[3][256];
+ String YOUR_ROSTER_IS_FULL;
+ String PLEASE_WAIT;
+ String OOPS;
+ int SCREEN_POSITIONING_X[4][48];
+ int SCREEN_POSITIONING_Y[4][48];
+ int MONSTER_GRID_BITMASK[12];
+ int INDOOR_OBJECT_X[2][12];
+ int MAP_OBJECT_Y[2][12];
+ int INDOOR_MONSTERS_Y[4];
+ int OUTDOOR_OBJECT_X[2][12];
+ int OUTDOOR_MONSTER_INDEXES[26];
+ int OUTDOOR_MONSTERS_Y[26];
+ int DIRECTION_ANIM_POSITIONS[4][4];
+ byte WALL_SHIFTS[4][48];
+ int DRAW_NUMBERS[25];
+ int DRAW_FRAMES[25][2];
+ int COMBAT_FLOAT_X[8];
+ int COMBAT_FLOAT_Y[8];
+ int MONSTER_EFFECT_FLAGS[15][8];
+ int SPELLS_ALLOWED[3][40];
+ int BASE_HP_BY_CLASS[10];
+ int AGE_RANGES[10];
+ int AGE_RANGES_ADJUST[2][10];
+ int STAT_VALUES[24];
+ int STAT_BONUSES[24];
+ int ELEMENTAL_CATEGORIES[6];
+ int ATTRIBUTE_CATEGORIES[10];
+ int ATTRIBUTE_BONUSES[72];
+ int ELEMENTAL_RESISTENCES[37];
+ int ELEMENTAL_DAMAGE[37];
+ int WEAPON_DAMAGE_BASE[35];
+ int WEAPON_DAMAGE_MULTIPLIER[35];
+ int METAL_DAMAGE[22];
+ int METAL_DAMAGE_PERCENT[22];
+ int METAL_LAC[9];
+ int ARMOR_STRENGTHS[14];
+ int MAKE_ITEM_ARR1[6];
+ int MAKE_ITEM_ARR2[6][7][2];
+ int MAKE_ITEM_ARR3[10][7][2];
+ int MAKE_ITEM_ARR4[2][7][2];
+ int MAKE_ITEM_ARR5[8][2];
+ int OUTDOOR_DRAWSTRUCT_INDEXES[44];
+ int TOWN_MAXES[2][11];
+ String TOWN_ACTION_MUSIC[2][7];
+ String TOWN_ACTION_SHAPES[7];
+ int TOWN_ACTION_FILES[2][7];
+ String BANK_TEXT;
+ String BLACKSMITH_TEXT;
+ String GUILD_NOT_MEMBER_TEXT;
+ String GUILD_TEXT;
+ String TAVERN_TEXT;
+ String GOOD_STUFF;
+ String HAVE_A_DRINK;
+ String YOURE_DRUNK;
+ int TAVERN_EXIT_LIST[2][6][5][2];
+ String FOOD_AND_DRINK;
+ String TEMPLE_TEXT;
+ String EXPERIENCE_FOR_LEVEL;
+ String LEARNED_ALL;
+ String ELIGIBLE_FOR_LEVEL;
+ String TRAINING_TEXT;
+ String GOLD_GEMS;
+ String GOLD_GEMS_2;
+ String DEPOSIT_WITHDRAWL[2];
+ String NOT_ENOUGH_X_IN_THE_Y;
+ String NO_X_IN_THE_Y;
+ String STAT_NAMES[16];
+ String CONSUMABLE_NAMES[4];
+ String WHERE_NAMES[2];
+ String AMOUNT;
+ String FOOD_PACKS_FULL;
+ String BUY_SPELLS;
+ String GUILD_OPTIONS;
+ int MISC_SPELL_INDEX[74];
+ int SPELL_COSTS[77];
+ int CLOUDS_SPELL_OFFSETS[5][20];
+ int DARK_SPELL_OFFSETS[3][39];
+ int DARK_SPELL_RANGES[12][2];
+ int SPELL_LEVEL_OFFSETS[3][39];
+ int SPELL_GEM_COST[77];
+ String NOT_A_SPELL_CASTER;
+ String SPELLS_FOR;
+ String SPELL_LINES_0_TO_9;
+ String SPELLS_DIALOG_SPELLS;
+ String SPELL_PTS;
+ String GOLD;
+ String SPELLS_PRESS_A_KEY;
+ String SPELLS_PURCHASE;
+ String MAP_TEXT;
+ String LIGHT_COUNT_TEXT;
+ String FIRE_RESISTENCE_TEXT;
+ String ELECRICITY_RESISTENCE_TEXT;
+ String COLD_RESISTENCE_TEXT;
+ String POISON_RESISTENCE_TEXT;
+ String CLAIRVOYANCE_TEXT;
+ String LEVITATE_TEXT;
+ String WALK_ON_WATER_TEXT;
+ String GAME_INFORMATION;
+ String WORLD_GAME_TEXT;
+ String DARKSIDE_GAME_TEXT;
+ String CLOUDS_GAME_TEXT;
+ String SWORDS_GAME_TEXT;
+ String WEEK_DAY_STRINGS[10];
+ String CHARACTER_DETAILS;
+ String PARTY_GOLD;
+ String PLUS_14;
+ String CHARACTER_TEMPLATE;
+ String EXCHANGING_IN_COMBAT;
+ String CURRENT_MAXIMUM_RATING_TEXT;
+ String CURRENT_MAXIMUM_TEXT;
+ String RATING_TEXT[24];
+ String AGE_TEXT;
+ String LEVEL_TEXT;
+ String RESISTENCES_TEXT;
+ String NONE;
+ String EXPERIENCE_TEXT;
+ String ELIGIBLE;
+ String IN_PARTY_IN_BANK;
+ String FOOD_TEXT;
+ String EXCHANGE_WITH_WHOM;
+ String QUICK_REF_LINE;
+ String QUICK_REFERENCE;
+ int BLACKSMITH_MAP_IDS[2][4];
+ String ITEMS_DIALOG_TEXT1;
+ String ITEMS_DIALOG_TEXT2;
+ String ITEMS_DIALOG_LINE1;
+ String ITEMS_DIALOG_LINE2;
+ String BTN_BUY;
+ String BTN_SELL;
+ String BTN_IDENTIFY;
+ String BTN_FIX;
+ String BTN_USE;
+ String BTN_EQUIP;
+ String BTN_REMOVE;
+ String BTN_DISCARD;
+ String BTN_QUEST;
+ String BTN_ENCHANT;
+ String BTN_RECHARGE;
+ String BTN_GOLD;
+ String ITEM_BROKEN;
+ String ITEM_CURSED;
+ String BONUS_NAMES[7];
+ String WEAPON_NAMES[35];
+ String ARMOR_NAMES[14];
+ String ACCESSORY_NAMES[11];
+ String MISC_NAMES[22];
+ String ELEMENTAL_NAMES[6];
+ String ATTRIBUTE_NAMES[10];
+ String EFFECTIVENESS_NAMES[7];
+ String QUEST_ITEM_NAMES[85];
+ int WEAPON_BASE_COSTS[35];
+ int ARMOR_BASE_COSTS[14];
+ int ACCESSORY_BASE_COSTS[11];
+ int MISC_MATERIAL_COSTS[22];
+ int MISC_BASE_COSTS[76];
+ int METAL_BASE_MULTIPLIERS[22];
+ int ITEM_SKILL_DIVISORS[4];
+ int RESTRICTION_OFFSETS[4];
+ int ITEM_RESTRICTIONS[86];
+ String NOT_PROFICIENT;
+ String NO_ITEMS_AVAILABLE;
+ String CATEGORY_NAMES[4];
+ String X_FOR_THE_Y;
+ String X_FOR_Y;
+ String X_FOR_Y_GOLD;
+ String FMT_CHARGES;
+ String AVAILABLE_GOLD_COST;
+ String CHARGES;
+ String COST;
+ String ITEM_ACTIONS[7];
+ String WHICH_ITEM;
+ String WHATS_YOUR_HURRY;
+ String USE_ITEM_IN_COMBAT;
+ String NO_SPECIAL_ABILITIES;
+ String CANT_CAST_WHILE_ENGAGED;
+ String EQUIPPED_ALL_YOU_CAN;
+ String REMOVE_X_TO_EQUIP_Y;
+ String RING;
+ String MEDAL;
+ String CANNOT_REMOVE_CURSED_ITEM;
+ String CANNOT_DISCARD_CURSED_ITEM;
+ String PERMANENTLY_DISCARD;
+ String BACKPACK_IS_FULL;
+ String CATEGORY_BACKPACK_IS_FULL[4];
+ String BUY_X_FOR_Y_GOLD;
+ String SELL_X_FOR_Y_GOLD;
+ String NO_NEED_OF_THIS;
+ String NOT_RECHARGABLE;
+ String SPELL_FAILED;
+ String NOT_ENCHANTABLE;
+ String ITEM_NOT_BROKEN;
+ String FIX_IDENTIFY[2];
+ String FIX_IDENTIFY_GOLD;
+ String IDENTIFY_ITEM_MSG;
+ String ITEM_DETAILS;
+ String ALL;
+ String FIELD_NONE;
+ String DAMAGE_X_TO_Y;
+ String ELEMENTAL_XY_DAMAGE;
+ String ATTR_XY_BONUS;
+ String EFFECTIVE_AGAINST;
+ String QUESTS_DIALOG_TEXT;
+ String CLOUDS_OF_XEEN_LINE;
+ String DARKSIDE_OF_XEEN_LINE;
+ String NO_QUEST_ITEMS;
+ String NO_CURRENT_QUESTS;
+ String NO_AUTO_NOTES;
+ String QUEST_ITEMS_DATA;
+ String CURRENT_QUESTS_DATA;
+ String AUTO_NOTES_DATA;
+ String REST_COMPLETE;
+ String PARTY_IS_STARVING;
+ String HIT_SPELL_POINTS_RESTORED;
+ String TOO_DANGEROUS_TO_REST;
+ String SOME_CHARS_MAY_DIE;
+ String CANT_DISMISS_LAST_CHAR;
+ String REMOVE_DELETE[2];
+ String REMOVE_OR_DELETE_WHICH;
+ String YOUR_PARTY_IS_FULL;
+ String HAS_SLAYER_SWORD;
+ String SURE_TO_DELETE_CHAR;
+ String CREATE_CHAR_DETAILS;
+ String NEW_CHAR_STATS;
+ String NAME_FOR_NEW_CHARACTER;
+ String SELECT_CLASS_BEFORE_SAVING;
+ String EXCHANGE_ATTR_WITH;
+ int NEW_CHAR_SKILLS[10];
+ int NEW_CHAR_SKILLS_LEN[10];
+ int NEW_CHAR_RACE_SKILLS[10];
+ int RACE_MAGIC_RESISTENCES[5];
+ int RACE_FIRE_RESISTENCES[5];
+ int RACE_ELECTRIC_RESISTENCES[5];
+ int RACE_COLD_RESISTENCES[5];
+ int RACE_ENERGY_RESISTENCES[5];
+ int RACE_POISON_RESISTENCES[5];
+ int NEW_CHARACTER_SPELLS[10][4];
+ String COMBAT_DETAILS;
+ String NOT_ENOUGH_TO_CAST;
+ String SPELL_CAST_COMPONENTS[2];
+ String CAST_SPELL_DETAILS;
+ String PARTY_FOUND;
+ String BACKPACKS_FULL_PRESS_KEY;
+ String HIT_A_KEY;
+ String GIVE_TREASURE_FORMATTING;
+ String X_FOUND_Y;
+ String ON_WHO;
+ String WHICH_ELEMENT1;
+ String WHICH_ELEMENT2;
+ String DETECT_MONSTERS;
+ String LLOYDS_BEACON;
+ String HOW_MANY_SQUARES;
+ String TOWN_PORTAL;
+ int TOWN_MAP_NUMBERS[2][5];
+ String MONSTER_DETAILS;
+ String MONSTER_SPECIAL_ATTACKS[23];
+ String IDENTIFY_MONSTERS;
+ String EVENT_SAMPLES[6];
+ String MOONS_NOT_ALIGNED;
+ String AWARDS_FOR;
+ String AWARDS_TEXT;
+ String NO_AWARDS;
+ String WARZONE_BATTLE_MASTER;
+ String WARZONE_MAXED;
+ String WARZONE_LEVEL;
+ String WARZONE_HOW_MANY;
+ String PICKS_THE_LOCK;
+ String UNABLE_TO_PICK_LOCK;
+ String CONTROL_PANEL_TEXT;
+ String CONTROL_PANEL_BUTTONS;
+ String ON;
+ String OFF;
+ String CONFIRM_QUIT;
+ String MR_WIZARD;
+ String NO_LOADING_IN_COMBAT;
+ String NO_SAVING_IN_COMBAT;
+ String QUICK_FIGHT_TEXT;
+ String QUICK_FIGHT_OPTIONS[4];
+ String WORLD_END_TEXT[9];
+ String WORLD_CONGRATULATIONS;
+ String WORLD_CONGRATULATIONS2;
+ String CLOUDS_CONGRATULATIONS1;
+ String CLOUDS_CONGRATULATIONS2;
+ String GOOBER[3];
+ String MUSIC_FILES1[5];
+ String MUSIC_FILES2[6][7];
public:
/**
+ * Constructor
+ */
+ Resources();
+
+ /**
* Initializes an instnace of the resources
*/
- static Resources *init(XeenEngine *vm);
+ Resources *init(XeenEngine *vm);
};
extern Resources *g_resources;
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 51c22dd..27d3382 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -1560,7 +1560,7 @@ bool Scripts::ifProc(int action, uint32 val, int mode, int charIndex) {
// Check if the character class can cast the particular spell
for (int idx = 0; idx < 39; ++idx) {
- if (Res.SPELLS_ALLOWED[category][idx] == val) {
+ if (Res.SPELLS_ALLOWED[category][idx] == (int)val) {
// Can cast it. Check if the player has it in their spellbook
if (ps._spells[idx])
v = val;
diff --git a/engines/xeen/worldofxeen/darkside_cutscenes.cpp b/engines/xeen/worldofxeen/darkside_cutscenes.cpp
index a772500..b02e7d9 100644
--- a/engines/xeen/worldofxeen/darkside_cutscenes.cpp
+++ b/engines/xeen/worldofxeen/darkside_cutscenes.cpp
@@ -1203,7 +1203,7 @@ void DarkSideCutscenes::showDarkSideScore(uint endingScore) {
saves.saveGame();
}
-void DarkSideCutscenes::showPharaohEndText(const char *msg1, const char *msg2, const char *msg3) {
+void DarkSideCutscenes::showPharaohEndText(const Common::String &msg1, const Common::String &msg2, const Common::String &msg3) {
const int YLIST[32] = {
-3, -3, -3, -3, -3, -3, -3, -3, -1, 0, 0, 0, 0, 0, 0, 0,
-1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3
@@ -1225,8 +1225,12 @@ void DarkSideCutscenes::showPharaohEndText(const char *msg1, const char *msg2, c
Windows &windows = *_vm->_windows;
SpriteResource claw("claw.int");
SpriteResource dragon1("dragon1.int");
- int numPages = 0 + (msg1 ? 1 : 0) + (msg2 ? 1 : 0) + (msg3 ? 1 : 0);
- const char *const text[3] = { msg1, msg2, msg3 };
+ int numPages = 0 + (msg1.empty() ? 0 : 1) + (msg2.empty() ? 0 : 1) + (msg3.empty() ? 0 : 1);
+ const char *const text[3] = {
+ msg1.empty() ? nullptr : msg1.c_str(),
+ msg2.empty() ? nullptr : msg2.c_str(),
+ msg3.empty() ? nullptr : msg3.c_str()
+ };
screen.loadBackground("3room.raw");
screen.saveBackground();
diff --git a/engines/xeen/worldofxeen/darkside_cutscenes.h b/engines/xeen/worldofxeen/darkside_cutscenes.h
index f2dd5c5..9c8db4d 100644
--- a/engines/xeen/worldofxeen/darkside_cutscenes.h
+++ b/engines/xeen/worldofxeen/darkside_cutscenes.h
@@ -61,7 +61,13 @@ protected:
/**
* Shows the Pharaoh ending screen where score text is shown
*/
- void showPharaohEndText(const char *msg1, const char *msg2 = nullptr, const char *msg3 = nullptr);
+ void showPharaohEndText(const Common::String &msg1, const Common::String &msg2, const Common::String &msg3);
+ void showPharaohEndText(const Common::String &msg1) {
+ showPharaohEndText(msg1, "", "");
+ }
+ void showPharaohEndText(const Common::String &msg1, const Common::String &msg2) {
+ showPharaohEndText(msg1, msg2, "");
+ }
public:
DarkSideCutscenes(XeenEngine *vm) : Cutscenes(vm) {}
diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp
index 0730760..8e22965 100644
--- a/engines/xeen/xeen.cpp
+++ b/engines/xeen/xeen.cpp
@@ -86,10 +86,13 @@ XeenEngine::~XeenEngine() {
g_vm = nullptr;
}
-void XeenEngine::initialize() {
+bool XeenEngine::initialize() {
// Create sub-objects of the engine
_files = new FileManager(this);
- _resources = Resources::init(this);
+ if (!_files->setup())
+ return false;
+
+ _resources = new Resources();
_combat = new Combat(this);
_debugger = new Debugger(this);
_events = new EventsManager(this);
@@ -119,12 +122,13 @@ void XeenEngine::initialize() {
if (saveSlot >= 0 && saveSlot <= 999)
_loadSaveSlot = saveSlot;
}
+
+ return true;
}
Common::Error XeenEngine::run() {
- initialize();
-
- outerGameLoop();
+ if (initialize())
+ outerGameLoop();
return Common::kNoError;
}
@@ -256,4 +260,16 @@ void XeenEngine::syncSoundSettings() {
_sound->updateSoundSettings();
}
+void XeenEngine::GUIError(const char *msg, ...) {
+ char buffer[STRINGBUFLEN];
+ va_list va;
+
+ // Generate the full error message
+ va_start(va, msg);
+ vsnprintf(buffer, STRINGBUFLEN, msg, va);
+ va_end(va);
+
+ GUIErrorMessage(buffer);
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h
index cbf9ff3..652284b 100644
--- a/engines/xeen/xeen.h
+++ b/engines/xeen/xeen.h
@@ -108,7 +108,10 @@ private:
const XeenGameDescription *_gameDescription;
Common::RandomSource _randomSource;
private:
- void initialize();
+ /**
+ * Initializes all the engine sub-objects
+ */
+ bool initialize();
// Engine APIs
virtual Common::Error run();
@@ -176,6 +179,11 @@ public:
int getRandomNumber(int minNumber, int maxNumber);
/**
+ * Displays an error message in a GUI dialog
+ */
+ void GUIError(const char *msg, ...) GCC_PRINTF(2, 3);
+
+ /**
* Returns true if the game should be exited (and likely return to game menu)
*/
bool shouldExit() const { return _quitMode != QMODE_NONE || shouldQuit(); }
Commit: ad7b947da324c7e3219e4fb2e47bce1006327d97
https://github.com/scummvm/scummvm/commit/ad7b947da324c7e3219e4fb2e47bce1006327d97
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Change Resource String fields to const char *
All too many of the resource strings are used as parameters in
Common::String::format calls, and it proved too laborious trying
to add .c_str() suffixes everywhere it'd be appropriate. Easier
to simply change all the Reosucre fields back to being const char *
Changed paths:
engines/xeen/character.cpp
engines/xeen/character.h
engines/xeen/dialogs_char_info.cpp
engines/xeen/dialogs_create_char.cpp
engines/xeen/dialogs_items.cpp
engines/xeen/dialogs_quests.cpp
engines/xeen/locations.cpp
engines/xeen/map.cpp
engines/xeen/party.cpp
engines/xeen/resources.cpp
engines/xeen/resources.h
diff --git a/engines/xeen/character.cpp b/engines/xeen/character.cpp
index d98142e..69fbc16 100644
--- a/engines/xeen/character.cpp
+++ b/engines/xeen/character.cpp
@@ -61,7 +61,7 @@ AttributeCategory XeenItem::getAttributeCategory() const {
return (AttributeCategory)idx;
}
-const Common::String &XeenItem::getItemName(ItemCategory category, uint id) {
+const char *XeenItem::getItemName(ItemCategory category, uint id) {
if (id < 82)
return Res.ITEM_NAMES[category][id];
@@ -294,7 +294,7 @@ Common::String WeaponItems::getFullDescription(int itemIndex, int displayNum) {
(i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
(i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
displayNum,
- Res.WEAPON_NAMES[i._id].c_str(),
+ Res.WEAPON_NAMES[i._id],
!i._bonusFlags ? "" : Res.BONUS_NAMES[i._bonusFlags & ITEMFLAG_BONUS_MASK],
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._bonusFlags ? "\b " : ""
@@ -451,10 +451,10 @@ Common::String ArmorItems::getFullDescription(int itemIndex, int displayNum) {
return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
- (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN.c_str() : "",
- (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED.c_str() : "",
+ (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
+ (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
displayNum,
- Res.ARMOR_NAMES[i._id].c_str(),
+ Res.ARMOR_NAMES[i._id],
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._bonusFlags ? "\b " : ""
);
@@ -568,10 +568,10 @@ Common::String AccessoryItems::getFullDescription(int itemIndex, int displayNum)
return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
- (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN.c_str() : "",
- (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED.c_str() : "",
+ (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
+ (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
displayNum,
- Res.ARMOR_NAMES[i._id].c_str(),
+ Res.ARMOR_NAMES[i._id],
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._bonusFlags ? "\b " : ""
);
@@ -614,10 +614,10 @@ Common::String MiscItems::getFullDescription(int itemIndex, int displayNum) {
return Common::String::format("\f%02u%s%s%s\f%02u%s%s", displayNum,
!i._bonusFlags ? "" : res._maeNames[i._material].c_str(),
- (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN.c_str() : "",
- (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED.c_str() : "",
+ (i._bonusFlags & ITEMFLAG_BROKEN) ? Res.ITEM_BROKEN : "",
+ (i._bonusFlags & ITEMFLAG_CURSED) ? Res.ITEM_CURSED : "",
displayNum,
- Res.ARMOR_NAMES[i._id].c_str(),
+ Res.ARMOR_NAMES[i._id],
(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED)) ||
!i._id ? "\b " : ""
);
diff --git a/engines/xeen/character.h b/engines/xeen/character.h
index 480215a..649da7e 100644
--- a/engines/xeen/character.h
+++ b/engines/xeen/character.h
@@ -106,7 +106,7 @@ public:
/**
* Return the name of the item
*/
- static const Common::String &getItemName(ItemCategory category, uint id);
+ static const char *getItemName(ItemCategory category, uint id);
public:
XeenItem();
@@ -140,7 +140,7 @@ class InventoryItems : public Common::Array<XeenItem> {
protected:
Character *_character;
ItemCategory _category;
- const Common::String *_names;
+ const char **_names;
XeenEngine *getVm();
void equipError(int itemIndex1, ItemCategory category1, int itemIndex2,
diff --git a/engines/xeen/dialogs_char_info.cpp b/engines/xeen/dialogs_char_info.cpp
index 132fbd5..3d9ebfb 100644
--- a/engines/xeen/dialogs_char_info.cpp
+++ b/engines/xeen/dialogs_char_info.cpp
@@ -434,9 +434,9 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
if (c._skills[skill]) {
if (skill == THIEVERY) {
lines[0] = Common::String::format("\n\t020%s%u",
- Res.SKILL_NAMES[THIEVERY].c_str(), c.getThievery());
+ Res.SKILL_NAMES[THIEVERY], c.getThievery());
} else {
- lines[skill] = Common::String::format("\n\t020%s", Res.SKILL_NAMES[skill].c_str());
+ lines[skill] = Common::String::format("\n\t020%s", Res.SKILL_NAMES[skill]);
}
}
}
@@ -446,7 +446,7 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
}
msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- Res.STAT_NAMES[attrib].c_str(), lines[0].c_str(), lines[1].c_str(),
+ Res.STAT_NAMES[attrib], lines[0].c_str(), lines[1].c_str(),
lines[2].c_str(), lines[3].c_str(), lines[4].c_str(), lines[5].c_str(),
lines[17].c_str(), lines[6].c_str(), lines[7].c_str(), lines[8].c_str(),
lines[9].c_str(), lines[10].c_str(), lines[11].c_str(), lines[12].c_str(),
@@ -505,10 +505,10 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
if (c._conditions[condition]) {
if (condition >= UNCONSCIOUS) {
lines[condition] = Common::String::format("\n\t020%s",
- Res.CONDITION_NAMES[condition].c_str());
+ Res.CONDITION_NAMES[condition]);
} else {
lines[condition] = Common::String::format("\n\t020%s\t095-%d",
- Res.CONDITION_NAMES[condition].c_str(), c._conditions[condition]);
+ Res.CONDITION_NAMES[condition], c._conditions[condition]);
}
++total;
@@ -517,7 +517,7 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
Condition condition = c.worstCondition();
if (condition == NO_CONDITION) {
- lines[0] = Common::String::format("\n\t020%s", Res.GOOD.c_str());
+ lines[0] = Common::String::format("\n\t020%s", Res.GOOD);
++total;
}
@@ -531,7 +531,7 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
lines[19] = Common::String::format(Res.HEROISM, party._heroism);
msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1",
- Res.CONSUMABLE_NAMES[3].c_str(), lines[0].c_str(), lines[1].c_str(),
+ Res.CONSUMABLE_NAMES[3], lines[0].c_str(), lines[1].c_str(),
lines[2].c_str(), lines[3].c_str(), lines[4].c_str(),
lines[5].c_str(), lines[6].c_str(), lines[7].c_str(),
lines[8].c_str(), lines[9].c_str(), lines[10].c_str(),
diff --git a/engines/xeen/dialogs_create_char.cpp b/engines/xeen/dialogs_create_char.cpp
index c1c6bc8..73aa4b3 100644
--- a/engines/xeen/dialogs_create_char.cpp
+++ b/engines/xeen/dialogs_create_char.cpp
@@ -384,7 +384,7 @@ int CreateCharacterDialog::newCharDetails(Race race, Sex sex, int classId,
// If a class is provided, set the class name
if (classId != -1) {
- classStr = Common::String::format("\t062\v168%s", Res.CLASS_NAMES[classId].c_str());
+ classStr = Common::String::format("\t062\v168%s", Res.CLASS_NAMES[classId]);
}
// Set up default skill for the race, if any
diff --git a/engines/xeen/dialogs_items.cpp b/engines/xeen/dialogs_items.cpp
index bbf7fa4..c9249f3 100644
--- a/engines/xeen/dialogs_items.cpp
+++ b/engines/xeen/dialogs_items.cpp
@@ -1052,7 +1052,7 @@ void ItemsDialog::itemToGold(Character &c, int itemIndex, ItemCategory category,
if (category == CATEGORY_WEAPON && item._id == 34) {
sound.playFX(21);
ErrorScroll::show(_vm, Common::String::format("\v012\t000\x03""c%s",
- Res.SPELL_FAILED.c_str()));
+ Res.SPELL_FAILED));
} else if (item._id != 0) {
// There is a valid item present
// Calculate cost of item and add it to the party's total
diff --git a/engines/xeen/dialogs_quests.cpp b/engines/xeen/dialogs_quests.cpp
index 73035b3..5e5171e 100644
--- a/engines/xeen/dialogs_quests.cpp
+++ b/engines/xeen/dialogs_quests.cpp
@@ -91,7 +91,7 @@ void Quests::execute() {
case 83:
case 84:
lines[count++] = Common::String::format("%d %s%c",
- party._questItems[idx], Res.QUEST_ITEM_NAMES[idx].c_str(),
+ party._questItems[idx], Res.QUEST_ITEM_NAMES[idx],
party._questItems[idx] == 1 ? ' ' : 's');
break;
default:
diff --git a/engines/xeen/locations.cpp b/engines/xeen/locations.cpp
index 53a1c80..7a82905 100644
--- a/engines/xeen/locations.cpp
+++ b/engines/xeen/locations.cpp
@@ -69,7 +69,7 @@ int BaseLocation::show() {
// Load the needed sprite sets for the location
for (uint idx = 0; idx < _townSprites.size(); ++idx) {
Common::String shapesName = Common::String::format("%s%d.twn",
- Res.TOWN_ACTION_SHAPES[_locationActionId].c_str(), idx + 1);
+ Res.TOWN_ACTION_SHAPES[_locationActionId], idx + 1);
_townSprites[idx].load(shapesName);
}
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index 58a294c..e3ab879 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -1195,7 +1195,7 @@ void Map::load(int mapId) {
if (_mazeData[0]._wallTypes[i] != 0) {
_wallSprites._surfaces[i].load(Common::String::format("%s.wal",
- Res.OUTDOORS_WALL_TYPES[_mazeData[0]._wallTypes[i]].c_str()));
+ Res.OUTDOORS_WALL_TYPES[_mazeData[0]._wallTypes[i]]));
}
_surfaceSprites[i].clear();
@@ -1223,11 +1223,11 @@ void Map::load(int mapId) {
// Load sprite sets needed for scene rendering
_skySprites[1].load(Common::String::format("%s.sky",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
_groundSprites.load(Common::String::format("%s.gnd",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
_tileSprites.load(Common::String::format("%s.til",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
for (int i = 0; i < TOTAL_SURFACES; ++i) {
_surfaceSprites[i].clear();
@@ -1240,15 +1240,15 @@ void Map::load(int mapId) {
_wallSprites._surfaces[i].clear();
_wallSprites._fwl1.load(Common::String::format("f%s1.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
_wallSprites._fwl2.load(Common::String::format("f%s2.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
_wallSprites._fwl3.load(Common::String::format("f%s3.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
_wallSprites._fwl4.load(Common::String::format("f%s4.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
_wallSprites._swl.load(Common::String::format("s%s.swl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind].c_str()));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
// Set entries in the indoor draw list to the correct sprites
// for drawing various parts of the background
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index 68bc768..d45c7fa 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -720,7 +720,7 @@ void Party::giveTreasureToCharacter(Character &c, ItemCategory category, int ite
w.update();
events.ipause(5);
- const char *itemName = XeenItem::getItemName(category, treasureItem._id).c_str();
+ const char *itemName = XeenItem::getItemName(category, treasureItem._id);
w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), itemName));
w.update();
events.ipause(5);
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 86dc441..cd794a3 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -52,7 +52,7 @@ Resources::Resources() {
}
void Resources::loadData() {
- ResFile file;
+ ResFile file(_buffer);
file.syncString(CREDITS);
file.syncString(OPTIONS_TITLE);
file.syncString(THE_PARTY_NEEDS_REST);
@@ -61,7 +61,7 @@ void Resources::loadData() {
file.syncString(WHATS_THE_PASSWORD);
file.syncString(IN_NO_CONDITION);
file.syncString(NOTHING_HERE);
- file.syncStrings(TERRAIN_TYPES, 6);
+ file.syncStrings(&TERRAIN_TYPES[0], 6);
file.syncStrings(OUTDOORS_WALL_TYPES, 16);
file.syncStrings(SURFACE_NAMES, 16);
file.syncStrings(WHO_ACTIONS, 32);
@@ -136,7 +136,7 @@ void Resources::loadData() {
file.syncNumbers2D((int *)MAKE_ITEM_ARR5, 8, 2);
file.syncNumbers(OUTDOOR_DRAWSTRUCT_INDEXES, 44);
file.syncNumbers2D((int *)TOWN_MAXES, 2, 11);
- file.syncStrings2D((String *)TOWN_ACTION_MUSIC, 2, 7);
+ file.syncStrings2D(&TOWN_ACTION_MUSIC[0][0], 2, 7);
file.syncStrings(TOWN_ACTION_SHAPES, 7);
file.syncNumbers2D((int *)TOWN_ACTION_FILES, 2, 7);
file.syncString(BANK_TEXT);
@@ -376,7 +376,7 @@ void Resources::loadData() {
file.syncString(CLOUDS_CONGRATULATIONS2);
file.syncStrings(GOOBER, 3);
file.syncStrings(MUSIC_FILES1, 5);
- file.syncStrings2D((String *)MUSIC_FILES2, 6, 7);
+ file.syncStrings2D(&MUSIC_FILES2[0][0], 6, 7);
}
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 513e70d..8cdeaf4 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -33,43 +33,40 @@
namespace Xeen {
#define Res (*g_resources)
+#define STRING_BUFFER_SIZE 32768
class XeenEngine;
class Resources {
/**
- * Derived string class to fix automatic type conversion to const char *
- */
- class String : public Common::String {
- public:
- String() : Common::String() {}
- String(const Common::String &s) : Common::String(s) {}
- operator const char *() { return c_str(); }
- };
-
- /**
* Derived file class with sync method aliases so that the same
* code from create_xeen can be re-used for both reading and
* writing the resource data
*/
class ResFile : public File {
+ private:
+ char *_buffer;
+ char *_buffStart;
public:
- ResFile() : File("CONSTANTS") {}
+ ResFile(char *buffer) : File("CONSTANTS"), _buffer(buffer), _buffStart(buffer) {}
- void syncString(String &str) {
- str = readString();
+ void syncString(const char *&str) {
+ str = _buffer;
+ strcpy(_buffer, readString().c_str());
+ _buffer += strlen(_buffer) + 1;
+ assert((_buffer - _buffStart) < STRING_BUFFER_SIZE);
}
- void syncStrings(String *str, int count) {
+ void syncStrings(const char **str, int count) {
uint tag = readUint32LE();
assert(tag == MKTAG(count, 0, 0, 0));
for (int idx = 0; idx < count; ++idx)
- str[idx] = readString();
+ syncString(str[idx]);
}
- void syncStrings2D(String *str, int count1, int count2) {
+ void syncStrings2D(const char **str, int count1, int count2) {
uint tag = readUint32LE();
assert(tag == MKTAG(count1, count2, 0, 0));
for (int idx = 0; idx < count1 * count2; ++idx)
- str[idx] = readString();
+ syncString(str[idx]);
}
void syncNumber(int &val) {
val = readSint32LE();
@@ -105,6 +102,8 @@ class Resources {
}
};
private:
+ char _buffer[STRING_BUFFER_SIZE];
+private:
/**
* Loads all the constants data stored in the xeen.css
*/
@@ -112,52 +111,52 @@ private:
public:
SpriteResource _globalSprites;
Common::StringArray _maeNames; // Magic and equipment names
- String *ITEM_NAMES[4];
+ const char **ITEM_NAMES[4];
// Data loaded from xeen.ccs
- String CREDITS;
- String OPTIONS_TITLE;
- String THE_PARTY_NEEDS_REST;
- String WHO_WILL;
- String HOW_MUCH;
- String WHATS_THE_PASSWORD;
- String IN_NO_CONDITION;
- String NOTHING_HERE;
- String TERRAIN_TYPES[6];
- String OUTDOORS_WALL_TYPES[16];
- String SURFACE_NAMES[16];
- String WHO_ACTIONS[32];
- String WHO_WILL_ACTIONS[4];
+ const char *CREDITS;
+ const char *OPTIONS_TITLE;
+ const char *THE_PARTY_NEEDS_REST;
+ const char *WHO_WILL;
+ const char *HOW_MUCH;
+ const char *WHATS_THE_PASSWORD;
+ const char *IN_NO_CONDITION;
+ const char *NOTHING_HERE;
+ const char *TERRAIN_TYPES[6];
+ const char *OUTDOORS_WALL_TYPES[16];
+ const char *SURFACE_NAMES[16];
+ const char *WHO_ACTIONS[32];
+ const char *WHO_WILL_ACTIONS[4];
byte SYMBOLS[20][64];
byte TEXT_COLORS[40][4];
- String DIRECTION_TEXT_UPPER[4];
- String DIRECTION_TEXT[4];
- String RACE_NAMES[5];
+ const char *DIRECTION_TEXT_UPPER[4];
+ const char *DIRECTION_TEXT[4];
+ const char *RACE_NAMES[5];
int RACE_HP_BONUSES[5];
int RACE_SP_BONUSES[5][2];
- String CLASS_NAMES[11];
+ const char *CLASS_NAMES[11];
int CLASS_EXP_LEVELS[10];
- String ALIGNMENT_NAMES[3];
- String SEX_NAMES[2];
- String SKILL_NAMES[18];
- String CONDITION_NAMES[17];
+ const char *ALIGNMENT_NAMES[3];
+ const char *SEX_NAMES[2];
+ const char *SKILL_NAMES[18];
+ const char *CONDITION_NAMES[17];
int CONDITION_COLORS[17];
- String GOOD;
- String BLESSED;
- String POWER_SHIELD;
- String HOLY_BONUS;
- String HEROISM;
- String IN_PARTY;
- String PARTY_DETAILS;
- String PARTY_DIALOG_TEXT;
+ const char *GOOD;
+ const char *BLESSED;
+ const char *POWER_SHIELD;
+ const char *HOLY_BONUS;
+ const char *HEROISM;
+ const char *IN_PARTY;
+ const char *PARTY_DETAILS;
+ const char *PARTY_DIALOG_TEXT;
int FACE_CONDITION_FRAMES[17];
int CHAR_FACES_X[6];
int HP_BARS_X[6];
- String NO_ONE_TO_ADVENTURE_WITH;
+ const char *NO_ONE_TO_ADVENTURE_WITH;
byte DARKNESS_XLAT[3][256];
- String YOUR_ROSTER_IS_FULL;
- String PLEASE_WAIT;
- String OOPS;
+ const char *YOUR_ROSTER_IS_FULL;
+ const char *PLEASE_WAIT;
+ const char *OOPS;
int SCREEN_POSITIONING_X[4][48];
int SCREEN_POSITIONING_Y[4][48];
int MONSTER_GRID_BITMASK[12];
@@ -198,36 +197,36 @@ public:
int MAKE_ITEM_ARR5[8][2];
int OUTDOOR_DRAWSTRUCT_INDEXES[44];
int TOWN_MAXES[2][11];
- String TOWN_ACTION_MUSIC[2][7];
- String TOWN_ACTION_SHAPES[7];
+ const char *TOWN_ACTION_MUSIC[2][7];
+ const char *TOWN_ACTION_SHAPES[7];
int TOWN_ACTION_FILES[2][7];
- String BANK_TEXT;
- String BLACKSMITH_TEXT;
- String GUILD_NOT_MEMBER_TEXT;
- String GUILD_TEXT;
- String TAVERN_TEXT;
- String GOOD_STUFF;
- String HAVE_A_DRINK;
- String YOURE_DRUNK;
+ const char *BANK_TEXT;
+ const char *BLACKSMITH_TEXT;
+ const char *GUILD_NOT_MEMBER_TEXT;
+ const char *GUILD_TEXT;
+ const char *TAVERN_TEXT;
+ const char *GOOD_STUFF;
+ const char *HAVE_A_DRINK;
+ const char *YOURE_DRUNK;
int TAVERN_EXIT_LIST[2][6][5][2];
- String FOOD_AND_DRINK;
- String TEMPLE_TEXT;
- String EXPERIENCE_FOR_LEVEL;
- String LEARNED_ALL;
- String ELIGIBLE_FOR_LEVEL;
- String TRAINING_TEXT;
- String GOLD_GEMS;
- String GOLD_GEMS_2;
- String DEPOSIT_WITHDRAWL[2];
- String NOT_ENOUGH_X_IN_THE_Y;
- String NO_X_IN_THE_Y;
- String STAT_NAMES[16];
- String CONSUMABLE_NAMES[4];
- String WHERE_NAMES[2];
- String AMOUNT;
- String FOOD_PACKS_FULL;
- String BUY_SPELLS;
- String GUILD_OPTIONS;
+ const char *FOOD_AND_DRINK;
+ const char *TEMPLE_TEXT;
+ const char *EXPERIENCE_FOR_LEVEL;
+ const char *LEARNED_ALL;
+ const char *ELIGIBLE_FOR_LEVEL;
+ const char *TRAINING_TEXT;
+ const char *GOLD_GEMS;
+ const char *GOLD_GEMS_2;
+ const char *DEPOSIT_WITHDRAWL[2];
+ const char *NOT_ENOUGH_X_IN_THE_Y;
+ const char *NO_X_IN_THE_Y;
+ const char *STAT_NAMES[16];
+ const char *CONSUMABLE_NAMES[4];
+ const char *WHERE_NAMES[2];
+ const char *AMOUNT;
+ const char *FOOD_PACKS_FULL;
+ const char *BUY_SPELLS;
+ const char *GUILD_OPTIONS;
int MISC_SPELL_INDEX[74];
int SPELL_COSTS[77];
int CLOUDS_SPELL_OFFSETS[5][20];
@@ -235,76 +234,76 @@ public:
int DARK_SPELL_RANGES[12][2];
int SPELL_LEVEL_OFFSETS[3][39];
int SPELL_GEM_COST[77];
- String NOT_A_SPELL_CASTER;
- String SPELLS_FOR;
- String SPELL_LINES_0_TO_9;
- String SPELLS_DIALOG_SPELLS;
- String SPELL_PTS;
- String GOLD;
- String SPELLS_PRESS_A_KEY;
- String SPELLS_PURCHASE;
- String MAP_TEXT;
- String LIGHT_COUNT_TEXT;
- String FIRE_RESISTENCE_TEXT;
- String ELECRICITY_RESISTENCE_TEXT;
- String COLD_RESISTENCE_TEXT;
- String POISON_RESISTENCE_TEXT;
- String CLAIRVOYANCE_TEXT;
- String LEVITATE_TEXT;
- String WALK_ON_WATER_TEXT;
- String GAME_INFORMATION;
- String WORLD_GAME_TEXT;
- String DARKSIDE_GAME_TEXT;
- String CLOUDS_GAME_TEXT;
- String SWORDS_GAME_TEXT;
- String WEEK_DAY_STRINGS[10];
- String CHARACTER_DETAILS;
- String PARTY_GOLD;
- String PLUS_14;
- String CHARACTER_TEMPLATE;
- String EXCHANGING_IN_COMBAT;
- String CURRENT_MAXIMUM_RATING_TEXT;
- String CURRENT_MAXIMUM_TEXT;
- String RATING_TEXT[24];
- String AGE_TEXT;
- String LEVEL_TEXT;
- String RESISTENCES_TEXT;
- String NONE;
- String EXPERIENCE_TEXT;
- String ELIGIBLE;
- String IN_PARTY_IN_BANK;
- String FOOD_TEXT;
- String EXCHANGE_WITH_WHOM;
- String QUICK_REF_LINE;
- String QUICK_REFERENCE;
+ const char *NOT_A_SPELL_CASTER;
+ const char *SPELLS_FOR;
+ const char *SPELL_LINES_0_TO_9;
+ const char *SPELLS_DIALOG_SPELLS;
+ const char *SPELL_PTS;
+ const char *GOLD;
+ const char *SPELLS_PRESS_A_KEY;
+ const char *SPELLS_PURCHASE;
+ const char *MAP_TEXT;
+ const char *LIGHT_COUNT_TEXT;
+ const char *FIRE_RESISTENCE_TEXT;
+ const char *ELECRICITY_RESISTENCE_TEXT;
+ const char *COLD_RESISTENCE_TEXT;
+ const char *POISON_RESISTENCE_TEXT;
+ const char *CLAIRVOYANCE_TEXT;
+ const char *LEVITATE_TEXT;
+ const char *WALK_ON_WATER_TEXT;
+ const char *GAME_INFORMATION;
+ const char *WORLD_GAME_TEXT;
+ const char *DARKSIDE_GAME_TEXT;
+ const char *CLOUDS_GAME_TEXT;
+ const char *SWORDS_GAME_TEXT;
+ const char *WEEK_DAY_STRINGS[10];
+ const char *CHARACTER_DETAILS;
+ const char *PARTY_GOLD;
+ const char *PLUS_14;
+ const char *CHARACTER_TEMPLATE;
+ const char *EXCHANGING_IN_COMBAT;
+ const char *CURRENT_MAXIMUM_RATING_TEXT;
+ const char *CURRENT_MAXIMUM_TEXT;
+ const char *RATING_TEXT[24];
+ const char *AGE_TEXT;
+ const char *LEVEL_TEXT;
+ const char *RESISTENCES_TEXT;
+ const char *NONE;
+ const char *EXPERIENCE_TEXT;
+ const char *ELIGIBLE;
+ const char *IN_PARTY_IN_BANK;
+ const char *FOOD_TEXT;
+ const char *EXCHANGE_WITH_WHOM;
+ const char *QUICK_REF_LINE;
+ const char *QUICK_REFERENCE;
int BLACKSMITH_MAP_IDS[2][4];
- String ITEMS_DIALOG_TEXT1;
- String ITEMS_DIALOG_TEXT2;
- String ITEMS_DIALOG_LINE1;
- String ITEMS_DIALOG_LINE2;
- String BTN_BUY;
- String BTN_SELL;
- String BTN_IDENTIFY;
- String BTN_FIX;
- String BTN_USE;
- String BTN_EQUIP;
- String BTN_REMOVE;
- String BTN_DISCARD;
- String BTN_QUEST;
- String BTN_ENCHANT;
- String BTN_RECHARGE;
- String BTN_GOLD;
- String ITEM_BROKEN;
- String ITEM_CURSED;
- String BONUS_NAMES[7];
- String WEAPON_NAMES[35];
- String ARMOR_NAMES[14];
- String ACCESSORY_NAMES[11];
- String MISC_NAMES[22];
- String ELEMENTAL_NAMES[6];
- String ATTRIBUTE_NAMES[10];
- String EFFECTIVENESS_NAMES[7];
- String QUEST_ITEM_NAMES[85];
+ const char *ITEMS_DIALOG_TEXT1;
+ const char *ITEMS_DIALOG_TEXT2;
+ const char *ITEMS_DIALOG_LINE1;
+ const char *ITEMS_DIALOG_LINE2;
+ const char *BTN_BUY;
+ const char *BTN_SELL;
+ const char *BTN_IDENTIFY;
+ const char *BTN_FIX;
+ const char *BTN_USE;
+ const char *BTN_EQUIP;
+ const char *BTN_REMOVE;
+ const char *BTN_DISCARD;
+ const char *BTN_QUEST;
+ const char *BTN_ENCHANT;
+ const char *BTN_RECHARGE;
+ const char *BTN_GOLD;
+ const char *ITEM_BROKEN;
+ const char *ITEM_CURSED;
+ const char *BONUS_NAMES[7];
+ const char *WEAPON_NAMES[35];
+ const char *ARMOR_NAMES[14];
+ const char *ACCESSORY_NAMES[11];
+ const char *MISC_NAMES[22];
+ const char *ELEMENTAL_NAMES[6];
+ const char *ATTRIBUTE_NAMES[10];
+ const char *EFFECTIVENESS_NAMES[7];
+ const char *QUEST_ITEM_NAMES[85];
int WEAPON_BASE_COSTS[35];
int ARMOR_BASE_COSTS[14];
int ACCESSORY_BASE_COSTS[11];
@@ -314,73 +313,73 @@ public:
int ITEM_SKILL_DIVISORS[4];
int RESTRICTION_OFFSETS[4];
int ITEM_RESTRICTIONS[86];
- String NOT_PROFICIENT;
- String NO_ITEMS_AVAILABLE;
- String CATEGORY_NAMES[4];
- String X_FOR_THE_Y;
- String X_FOR_Y;
- String X_FOR_Y_GOLD;
- String FMT_CHARGES;
- String AVAILABLE_GOLD_COST;
- String CHARGES;
- String COST;
- String ITEM_ACTIONS[7];
- String WHICH_ITEM;
- String WHATS_YOUR_HURRY;
- String USE_ITEM_IN_COMBAT;
- String NO_SPECIAL_ABILITIES;
- String CANT_CAST_WHILE_ENGAGED;
- String EQUIPPED_ALL_YOU_CAN;
- String REMOVE_X_TO_EQUIP_Y;
- String RING;
- String MEDAL;
- String CANNOT_REMOVE_CURSED_ITEM;
- String CANNOT_DISCARD_CURSED_ITEM;
- String PERMANENTLY_DISCARD;
- String BACKPACK_IS_FULL;
- String CATEGORY_BACKPACK_IS_FULL[4];
- String BUY_X_FOR_Y_GOLD;
- String SELL_X_FOR_Y_GOLD;
- String NO_NEED_OF_THIS;
- String NOT_RECHARGABLE;
- String SPELL_FAILED;
- String NOT_ENCHANTABLE;
- String ITEM_NOT_BROKEN;
- String FIX_IDENTIFY[2];
- String FIX_IDENTIFY_GOLD;
- String IDENTIFY_ITEM_MSG;
- String ITEM_DETAILS;
- String ALL;
- String FIELD_NONE;
- String DAMAGE_X_TO_Y;
- String ELEMENTAL_XY_DAMAGE;
- String ATTR_XY_BONUS;
- String EFFECTIVE_AGAINST;
- String QUESTS_DIALOG_TEXT;
- String CLOUDS_OF_XEEN_LINE;
- String DARKSIDE_OF_XEEN_LINE;
- String NO_QUEST_ITEMS;
- String NO_CURRENT_QUESTS;
- String NO_AUTO_NOTES;
- String QUEST_ITEMS_DATA;
- String CURRENT_QUESTS_DATA;
- String AUTO_NOTES_DATA;
- String REST_COMPLETE;
- String PARTY_IS_STARVING;
- String HIT_SPELL_POINTS_RESTORED;
- String TOO_DANGEROUS_TO_REST;
- String SOME_CHARS_MAY_DIE;
- String CANT_DISMISS_LAST_CHAR;
- String REMOVE_DELETE[2];
- String REMOVE_OR_DELETE_WHICH;
- String YOUR_PARTY_IS_FULL;
- String HAS_SLAYER_SWORD;
- String SURE_TO_DELETE_CHAR;
- String CREATE_CHAR_DETAILS;
- String NEW_CHAR_STATS;
- String NAME_FOR_NEW_CHARACTER;
- String SELECT_CLASS_BEFORE_SAVING;
- String EXCHANGE_ATTR_WITH;
+ const char *NOT_PROFICIENT;
+ const char *NO_ITEMS_AVAILABLE;
+ const char *CATEGORY_NAMES[4];
+ const char *X_FOR_THE_Y;
+ const char *X_FOR_Y;
+ const char *X_FOR_Y_GOLD;
+ const char *FMT_CHARGES;
+ const char *AVAILABLE_GOLD_COST;
+ const char *CHARGES;
+ const char *COST;
+ const char *ITEM_ACTIONS[7];
+ const char *WHICH_ITEM;
+ const char *WHATS_YOUR_HURRY;
+ const char *USE_ITEM_IN_COMBAT;
+ const char *NO_SPECIAL_ABILITIES;
+ const char *CANT_CAST_WHILE_ENGAGED;
+ const char *EQUIPPED_ALL_YOU_CAN;
+ const char *REMOVE_X_TO_EQUIP_Y;
+ const char *RING;
+ const char *MEDAL;
+ const char *CANNOT_REMOVE_CURSED_ITEM;
+ const char *CANNOT_DISCARD_CURSED_ITEM;
+ const char *PERMANENTLY_DISCARD;
+ const char *BACKPACK_IS_FULL;
+ const char *CATEGORY_BACKPACK_IS_FULL[4];
+ const char *BUY_X_FOR_Y_GOLD;
+ const char *SELL_X_FOR_Y_GOLD;
+ const char *NO_NEED_OF_THIS;
+ const char *NOT_RECHARGABLE;
+ const char *SPELL_FAILED;
+ const char *NOT_ENCHANTABLE;
+ const char *ITEM_NOT_BROKEN;
+ const char *FIX_IDENTIFY[2];
+ const char *FIX_IDENTIFY_GOLD;
+ const char *IDENTIFY_ITEM_MSG;
+ const char *ITEM_DETAILS;
+ const char *ALL;
+ const char *FIELD_NONE;
+ const char *DAMAGE_X_TO_Y;
+ const char *ELEMENTAL_XY_DAMAGE;
+ const char *ATTR_XY_BONUS;
+ const char *EFFECTIVE_AGAINST;
+ const char *QUESTS_DIALOG_TEXT;
+ const char *CLOUDS_OF_XEEN_LINE;
+ const char *DARKSIDE_OF_XEEN_LINE;
+ const char *NO_QUEST_ITEMS;
+ const char *NO_CURRENT_QUESTS;
+ const char *NO_AUTO_NOTES;
+ const char *QUEST_ITEMS_DATA;
+ const char *CURRENT_QUESTS_DATA;
+ const char *AUTO_NOTES_DATA;
+ const char *REST_COMPLETE;
+ const char *PARTY_IS_STARVING;
+ const char *HIT_SPELL_POINTS_RESTORED;
+ const char *TOO_DANGEROUS_TO_REST;
+ const char *SOME_CHARS_MAY_DIE;
+ const char *CANT_DISMISS_LAST_CHAR;
+ const char *REMOVE_DELETE[2];
+ const char *REMOVE_OR_DELETE_WHICH;
+ const char *YOUR_PARTY_IS_FULL;
+ const char *HAS_SLAYER_SWORD;
+ const char *SURE_TO_DELETE_CHAR;
+ const char *CREATE_CHAR_DETAILS;
+ const char *NEW_CHAR_STATS;
+ const char *NAME_FOR_NEW_CHARACTER;
+ const char *SELECT_CLASS_BEFORE_SAVING;
+ const char *EXCHANGE_ATTR_WITH;
int NEW_CHAR_SKILLS[10];
int NEW_CHAR_SKILLS_LEN[10];
int NEW_CHAR_RACE_SKILLS[10];
@@ -391,55 +390,55 @@ public:
int RACE_ENERGY_RESISTENCES[5];
int RACE_POISON_RESISTENCES[5];
int NEW_CHARACTER_SPELLS[10][4];
- String COMBAT_DETAILS;
- String NOT_ENOUGH_TO_CAST;
- String SPELL_CAST_COMPONENTS[2];
- String CAST_SPELL_DETAILS;
- String PARTY_FOUND;
- String BACKPACKS_FULL_PRESS_KEY;
- String HIT_A_KEY;
- String GIVE_TREASURE_FORMATTING;
- String X_FOUND_Y;
- String ON_WHO;
- String WHICH_ELEMENT1;
- String WHICH_ELEMENT2;
- String DETECT_MONSTERS;
- String LLOYDS_BEACON;
- String HOW_MANY_SQUARES;
- String TOWN_PORTAL;
+ const char *COMBAT_DETAILS;
+ const char *NOT_ENOUGH_TO_CAST;
+ const char *SPELL_CAST_COMPONENTS[2];
+ const char *CAST_SPELL_DETAILS;
+ const char *PARTY_FOUND;
+ const char *BACKPACKS_FULL_PRESS_KEY;
+ const char *HIT_A_KEY;
+ const char *GIVE_TREASURE_FORMATTING;
+ const char *X_FOUND_Y;
+ const char *ON_WHO;
+ const char *WHICH_ELEMENT1;
+ const char *WHICH_ELEMENT2;
+ const char *DETECT_MONSTERS;
+ const char *LLOYDS_BEACON;
+ const char *HOW_MANY_SQUARES;
+ const char *TOWN_PORTAL;
int TOWN_MAP_NUMBERS[2][5];
- String MONSTER_DETAILS;
- String MONSTER_SPECIAL_ATTACKS[23];
- String IDENTIFY_MONSTERS;
- String EVENT_SAMPLES[6];
- String MOONS_NOT_ALIGNED;
- String AWARDS_FOR;
- String AWARDS_TEXT;
- String NO_AWARDS;
- String WARZONE_BATTLE_MASTER;
- String WARZONE_MAXED;
- String WARZONE_LEVEL;
- String WARZONE_HOW_MANY;
- String PICKS_THE_LOCK;
- String UNABLE_TO_PICK_LOCK;
- String CONTROL_PANEL_TEXT;
- String CONTROL_PANEL_BUTTONS;
- String ON;
- String OFF;
- String CONFIRM_QUIT;
- String MR_WIZARD;
- String NO_LOADING_IN_COMBAT;
- String NO_SAVING_IN_COMBAT;
- String QUICK_FIGHT_TEXT;
- String QUICK_FIGHT_OPTIONS[4];
- String WORLD_END_TEXT[9];
- String WORLD_CONGRATULATIONS;
- String WORLD_CONGRATULATIONS2;
- String CLOUDS_CONGRATULATIONS1;
- String CLOUDS_CONGRATULATIONS2;
- String GOOBER[3];
- String MUSIC_FILES1[5];
- String MUSIC_FILES2[6][7];
+ const char *MONSTER_DETAILS;
+ const char *MONSTER_SPECIAL_ATTACKS[23];
+ const char *IDENTIFY_MONSTERS;
+ const char *EVENT_SAMPLES[6];
+ const char *MOONS_NOT_ALIGNED;
+ const char *AWARDS_FOR;
+ const char *AWARDS_TEXT;
+ const char *NO_AWARDS;
+ const char *WARZONE_BATTLE_MASTER;
+ const char *WARZONE_MAXED;
+ const char *WARZONE_LEVEL;
+ const char *WARZONE_HOW_MANY;
+ const char *PICKS_THE_LOCK;
+ const char *UNABLE_TO_PICK_LOCK;
+ const char *CONTROL_PANEL_TEXT;
+ const char *CONTROL_PANEL_BUTTONS;
+ const char *ON;
+ const char *OFF;
+ const char *CONFIRM_QUIT;
+ const char *MR_WIZARD;
+ const char *NO_LOADING_IN_COMBAT;
+ const char *NO_SAVING_IN_COMBAT;
+ const char *QUICK_FIGHT_TEXT;
+ const char *QUICK_FIGHT_OPTIONS[4];
+ const char *WORLD_END_TEXT[9];
+ const char *WORLD_CONGRATULATIONS;
+ const char *WORLD_CONGRATULATIONS2;
+ const char *CLOUDS_CONGRATULATIONS1;
+ const char *CLOUDS_CONGRATULATIONS2;
+ const char *GOOBER[3];
+ const char *MUSIC_FILES1[5];
+ const char *MUSIC_FILES2[6][7];
public:
/**
* Constructor
Commit: 5e0782c8da3becccfc5f647d346b44cd1860756e
https://github.com/scummvm/scummvm/commit/5e0782c8da3becccfc5f647d346b44cd1860756e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Fix loading maps with no monsters
Changed paths:
engines/xeen/map.cpp
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index e3ab879..c62fc71 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -808,17 +808,18 @@ void MonsterObjectData::synchronize(XeenSerializer &s, MonsterData &monsterData)
mon._sprites = &_monsterSprites[mon._id]._sprites;
mon._attackSprites = &_monsterSprites[mon._id]._attackSprites;
mon._monsterData = &monsterData[mon._spriteId];
+
+ MonsterStruct &md = *mon._monsterData;
+ mon._hp = md._hp;
+ mon._effect1 = mon._effect2 = md._animationEffect;
+ if (md._animationEffect)
+ mon._effect3 = _vm->getRandomNumber(7);
+
+ _monsters.push_back(mon);
} else {
assert(!mon._id);
}
- MonsterStruct &md = *mon._monsterData;
- mon._hp = md._hp;
- mon._effect1 = mon._effect2 = md._animationEffect;
- if (md._animationEffect)
- mon._effect3 = _vm->getRandomNumber(7);
-
- _monsters.push_back(mon);
mobStruct.synchronize(s);
} while (mobStruct._id != 255 || mobStruct._pos.x != -1);
Commit: 81b9f9b0fcfcb9f9a782d3ba6d276a4aca1e6ecc
https://github.com/scummvm/scummvm/commit/81b9f9b0fcfcb9f9a782d3ba6d276a4aca1e6ecc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Add _filename field to SpriteResource
This will be useful for debug purposes, so it be determined where
a given sprite resource was loaded from
Changed paths:
engines/xeen/sprites.cpp
engines/xeen/sprites.h
diff --git a/engines/xeen/sprites.cpp b/engines/xeen/sprites.cpp
index ea0400b..3555658 100644
--- a/engines/xeen/sprites.cpp
+++ b/engines/xeen/sprites.cpp
@@ -71,11 +71,13 @@ SpriteResource &SpriteResource::operator=(const SpriteResource &src) {
}
void SpriteResource::load(const Common::String &filename) {
+ _filename = filename;
File f(filename);
load(f);
}
void SpriteResource::load(const Common::String &filename, int ccMode) {
+ _filename = filename;
File f(filename, ccMode);
load(f);
}
diff --git a/engines/xeen/sprites.h b/engines/xeen/sprites.h
index ce04c25..a86f5ab 100644
--- a/engines/xeen/sprites.h
+++ b/engines/xeen/sprites.h
@@ -54,6 +54,7 @@ private:
int32 _filesize;
byte *_data;
int _scaledWidth, _scaledHeight;
+ Common::String _filename;
/**
* Load a sprite resource from a stream
Commit: a8961fc1457504c55c3c00c0f3fb86846db14508
https://github.com/scummvm/scummvm/commit/a8961fc1457504c55c3c00c0f3fb86846db14508
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Fix saving maps with no objects and/or monsters
Changed paths:
engines/xeen/map.cpp
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index c62fc71..d3e3d77 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -738,27 +738,37 @@ void MonsterObjectData::synchronize(XeenSerializer &s, MonsterData &monsterData)
if (s.isSaving()) {
// Save objects
- for (uint i = 0; i < _objects.size(); ++i) {
- mobStruct._pos = _objects[i]._position;
- mobStruct._id = _objects[i]._id;
- mobStruct._direction = _objects[i]._direction;
- mobStruct.synchronize(s);
+ if (_objects.empty()) {
+ MobStruct nullStruct;
+ nullStruct.synchronize(s);
+ } else {
+ for (uint i = 0; i < _objects.size(); ++i) {
+ mobStruct._pos = _objects[i]._position;
+ mobStruct._id = _objects[i]._id;
+ mobStruct._direction = _objects[i]._direction;
+ mobStruct.synchronize(s);
+ }
}
mobStruct.endOfList();
mobStruct.synchronize(s);
// Save monsters
- for (uint i = 0; i < _monsters.size(); ++i) {
- mobStruct._pos = _monsters[i]._position;
- mobStruct._id = _monsters[i]._id;
- mobStruct._direction = DIR_NORTH;
- mobStruct.synchronize(s);
+ if (_monsters.empty()) {
+ MobStruct nullStruct;
+ nullStruct.synchronize(s);
+ } else {
+ for (uint i = 0; i < _monsters.size(); ++i) {
+ mobStruct._pos = _monsters[i]._position;
+ mobStruct._id = _monsters[i]._id;
+ mobStruct._direction = DIR_NORTH;
+ mobStruct.synchronize(s);
+ }
}
mobStruct.endOfList();
mobStruct.synchronize(s);
// Save wall items
- if (_wallItems.size() == 0) {
+ if (_wallItems.empty()) {
MobStruct nullStruct;
nullStruct._pos.x = nullStruct._pos.y = 0x80;
nullStruct.synchronize(s);
Commit: eca55e500c5cc771c8ba377dee72c798d5da6a65
https://github.com/scummvm/scummvm/commit/eca55e500c5cc771c8ba377dee72c798d5da6a65
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Make mirror text entry matching case insensitive
Changed paths:
engines/xeen/dialogs_input.cpp
diff --git a/engines/xeen/dialogs_input.cpp b/engines/xeen/dialogs_input.cpp
index e44fb39..0bf95f7 100644
--- a/engines/xeen/dialogs_input.cpp
+++ b/engines/xeen/dialogs_input.cpp
@@ -165,14 +165,24 @@ int StringInput::execute(bool type, const Common::String &expected,
}
} else {
// Load in the mirror list
- File f(Common::String::format("%smirr.txt", files._isDarkCc ? "dark" : "xeen"), 1);
MirrorEntry me;
scripts._mirror.clear();
+
+ File f(Common::String::format("%smirr.txt", files._isDarkCc ? "dark" : "xeen"), 1);
while (me.synchronize(f))
scripts._mirror.push_back(me);
+ f.close();
+
+ // Load in any extended mirror entries
+ Common::File f2;
+ if (f2.open(Common::String::format("%smirr.ext", files._isDarkCc ? "dark" : "xeen"))) {
+ while (me.synchronize(f2))
+ scripts._mirror.push_back(me);
+ f2.close();
+ }
for (uint idx = 0; idx < scripts._mirror.size(); ++idx) {
- if (line == scripts._mirror[idx]._name) {
+ if (!line.compareToIgnoreCase(scripts._mirror[idx]._name)) {
result = idx + 1;
sound.playFX(_vm->_files->_isDarkCc ? 35 : 61);
break;
Commit: 2f6ca8f45ec6ef8bf86adc3ab60346fa9d14f6a9
https://github.com/scummvm/scummvm/commit/2f6ca8f45ec6ef8bf86adc3ab60346fa9d14f6a9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Fix exiting ScummVM when 'Nothing here' dialog is active
Changed paths:
engines/xeen/scripts.cpp
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 27d3382..9228afb 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -253,7 +253,7 @@ int Scripts::checkEvents() {
intf.draw3d(true);
events.updateGameCounter();
events.wait(1);
- } while (!events.isKeyMousePressed());
+ } while (!events.isKeyMousePressed() && !_vm->shouldExit());
events.clearEvents();
w.close();
Commit: bb19a6c771396e415e5007968ae843d220a5f2e5
https://github.com/scummvm/scummvm/commit/bb19a6c771396e415e5007968ae843d220a5f2e5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Add custom maze to the create_xeen tool
This could be used as an example of how other new maps could be
added in the future, and it also gives people a cool result if
they try typing 'ScummVM' into the teleport mirror
Changed paths:
A devtools/create_xeen/map.cpp
A devtools/create_xeen/map.h
devtools/create_xeen/create_xeen.cpp
devtools/create_xeen/file.h
devtools/create_xeen/module.mk
engines/xeen/files.cpp
engines/xeen/files.h
diff --git a/devtools/create_xeen/create_xeen.cpp b/devtools/create_xeen/create_xeen.cpp
index 94af74f..92c7a3b 100644
--- a/devtools/create_xeen/create_xeen.cpp
+++ b/devtools/create_xeen/create_xeen.cpp
@@ -35,6 +35,7 @@
#include "cc.h"
#include "file.h"
#include "constants.h"
+#include "map.h"
#define VERSION_NUMBER 1
@@ -59,6 +60,7 @@ int main(int argc, char *argv[]) {
CCArchive cc(outputFile);
writeVersion(cc);
writeConstants(cc);
+ writeMap(cc);
cc.close();
return 0;
diff --git a/devtools/create_xeen/file.h b/devtools/create_xeen/file.h
index 8fdb9b4..7ea5acf 100644
--- a/devtools/create_xeen/file.h
+++ b/devtools/create_xeen/file.h
@@ -98,6 +98,9 @@ public:
void writeByte(byte v) {
write(&v, sizeof(byte));
}
+ void writeShort(int8 v) {
+ write(&v, sizeof(int8));
+ }
void writeByte(byte v, int len) {
byte *b = new byte[len];
memset(b, v, len);
diff --git a/devtools/create_xeen/map.cpp b/devtools/create_xeen/map.cpp
new file mode 100644
index 0000000..254528c
--- /dev/null
+++ b/devtools/create_xeen/map.cpp
@@ -0,0 +1,248 @@
+/* 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.
+ *
+ */
+
+ // Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include "file.h"
+#include "map.h"
+
+#define MAP_WIDTH 16
+#define MAP_HEIGHT 16
+#define FLAG_IS_OUTDOORS 32768
+
+#define MIRROR_COUNT 1
+const MirrorEntry MIRROR_TEXT[MIRROR_COUNT] = {
+ { "scummvm", 255, 7, 1, 0 }
+};
+
+const byte MAZE_255[MAP_HEIGHT][MAP_WIDTH] = {
+ { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 },
+ { 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9 },
+ { 9, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 9 },
+ { 9, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4,14,14,14,14,14,14, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4,14, 6, 6, 6, 6,14, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4,14, 6, 7, 7, 6,14, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4,14, 6, 7, 7, 6,14, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4,14, 6, 6, 6, 6,14, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4,14,14,14,14,14,14, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 9 },
+ { 9, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 9 },
+ { 9, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 9 },
+ { 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9 },
+ { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }
+};
+
+const byte WALL_TYPES_255[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+const byte SURFACE_TYPES_255[16] = { 1, 1, 2, 3, 4, 0, 6, 7, 0, 9, 0, 0, 0, 0, 14, 15 };
+
+/**
+ * Write out new mirror entries
+ */
+void writeMirrorText(CCArchive &cc) {
+ Common::MemFile f;
+
+ for (int idx = 0; idx < MIRROR_COUNT; ++idx) {
+ const MirrorEntry &me = MIRROR_TEXT[idx];
+ f.write(me._name, 28);
+ f.writeByte(me._mapId);
+ f.writeShort(me._posX);
+ f.writeShort(me._posY);
+ f.writeByte(me._direction);
+ }
+
+ cc.add("xeenmirr.ext", f);
+}
+
+/**
+ * Write out the maze
+ */
+void writeMaze(CCArchive &cc) {
+ Common::MemFile f;
+
+ // Wall data
+ for (int y = 0; y < MAP_HEIGHT; ++y)
+ for (int x = 0; x < MAP_WIDTH; ++x)
+ f.writeWord(MAZE_255[y][x]);
+
+ // Surface and flags
+ for (int y = 0; y < MAP_HEIGHT; ++y)
+ f.write(MAZE_255[y], MAP_WIDTH);
+
+ f.writeWord(255); // Maze number
+ for (int idx = 0; idx < 4; ++idx)
+ f.writeWord(0); // No surrounding mazes
+ f.writeWord(0); // Maze flags 1
+ f.writeWord(FLAG_IS_OUTDOORS); // Maze flags 2
+ f.write(WALL_TYPES_255, 16);
+ f.write(SURFACE_TYPES_255, 16);
+ f.writeByte(0); // Floor type (unused)
+ f.writeByte(7); // Run position X
+ f.writeByte(0, 8); // Difficulties
+ f.writeByte(0); // Run position Y
+ f.writeByte(0); // Trap damage
+ f.writeByte(0); // Wall kind
+ f.writeByte(0); // Tavern tips
+ f.writeByte(0, MAP_WIDTH * MAP_HEIGHT / 8); // Seen tiles
+ f.writeByte(0, MAP_WIDTH * MAP_HEIGHT / 8); // Stepped on tiles
+
+ cc.add("mazex255.dat", f);
+}
+
+/**
+ * Write out the maze name
+ */
+void writeMazeName(CCArchive &cc) {
+ Common::MemFile f;
+ char mazeName[33];
+ memset(mazeName, 0, 33);
+ strcpy(mazeName, "ScummVM");
+ f.write(mazeName, 33);
+
+ cc.add("xeenx255.txt", f);
+}
+
+/**
+ * Write out maze events
+ */
+void writeMazeEvents(CCArchive &cc) {
+ Common::MemFile f;
+
+ // Mirror events
+ const byte MIRROR_EVENTS[32] = {
+ 6, 7, 0, 2, 0, 40, 1, // Play VOC: "Where to?"
+ 9, 7, 0, 2, 1, 21, 0, 3, 0, 0, // Get destination
+ 5, 7, 0, 2, 2, 18, // Exit
+ 8, 7, 0, 2, 3, 7, 0, 0, 0 // Teleport and exit
+ };
+ f.write(MIRROR_EVENTS, 32);
+
+ // Bench 1 events
+ const byte BENCH1_EVENTS[21] = {
+ 14, 7, 8, 0, 0, 20, 34, 10000 % 256, 10000 / 256, 0, 0, 0, 0, 0, 0, // Give gold
+ 5, 7, 8, 0, 1, 18 // Exit
+ };
+ const byte BENCH2_EVENTS[19] = {
+ 14, 8, 8, 0, 0, 20, 35, 1000 % 256, 1000 / 256, 0, 0, 0, 0, // Give gems
+ 5, 8, 8, 0, 1, 18 // Exit
+ };
+ f.write(BENCH1_EVENTS, 21);
+ f.write(BENCH2_EVENTS, 19);
+
+ cc.add("mazex255.evt", f);
+}
+
+/**
+ * Write out maze event text
+ */
+void writeMazeText(CCArchive &cc) {
+ Common::MemFile f;
+
+ f.writeString("Where to?");
+
+ cc.add("aazex255.txt", f);
+}
+
+/**
+ * Write out the monster/object data
+ */
+void writeMonstersObjects(CCArchive &cc) {
+ Common::MemFile f;
+ f.writeByte(8); // Object sprites
+ f.writeByte(2);
+ f.writeByte(0xff, 14);
+
+ f.writeByte(0xff, 16); // Monster sprites
+ f.writeByte(0xff, 16); // Wall item sprites
+
+ for (int idx = 0; idx < 6; ++idx) {
+ switch (idx) {
+ case 0:
+ // Mirror
+ f.writeShort(7);
+ f.writeShort(0);
+ f.writeByte(0);
+ f.writeShort(2);
+ // Benches
+ f.writeShort(7);
+ f.writeShort(8);
+ f.writeShort(1);
+ f.writeShort(0);
+ f.writeShort(8);
+ f.writeShort(8);
+ f.writeShort(1);
+ f.writeShort(0);
+ break;
+ case 2:
+ // End of monster/objects
+ f.writeShort(0);
+ f.writeShort(0);
+ f.writeByte(0);
+ f.writeShort(0);
+ break;
+ case 4:
+ f.writeShort(0x80);
+ f.writeShort(0x80);
+ f.writeByte(0);
+ f.writeShort(0);
+ break;
+ default:
+ f.writeShort(-1);
+ f.writeShort(-1);
+ f.writeByte(0xff);
+ f.writeShort(-1);
+ break;
+ }
+ }
+
+ cc.add("mazex255.mob", f);
+}
+
+/**
+ * Write out the data for the head danger senses
+ */
+void writeHeadData(CCArchive &cc) {
+ Common::MemFile f;
+ f.writeByte(0, MAP_HEIGHT * MAP_HEIGHT * 2);
+ cc.add("aazex255.hed", f);
+}
+
+/**
+ * Write out the new ScummVM map
+ */
+void writeMap(CCArchive &cc) {
+ writeMirrorText(cc);
+ writeMaze(cc);
+ writeMazeName(cc);
+ writeMazeEvents(cc);
+ writeMazeText(cc);
+ writeMonstersObjects(cc);
+ writeHeadData(cc);
+}
diff --git a/devtools/create_xeen/map.h b/devtools/create_xeen/map.h
new file mode 100644
index 0000000..fa64789
--- /dev/null
+++ b/devtools/create_xeen/map.h
@@ -0,0 +1,38 @@
+/* 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 MAP_H
+#define MAP_H
+
+#include "common/scummsys.h"
+#include "cc.h"
+
+struct MirrorEntry {
+ char _name[28];
+ byte _mapId;
+ int8 _posX, _posY;
+ byte _direction;
+};
+
+extern void writeMap(CCArchive &cc);
+
+#endif
diff --git a/devtools/create_xeen/module.mk b/devtools/create_xeen/module.mk
index d382fc6..e325d6e 100644
--- a/devtools/create_xeen/module.mk
+++ b/devtools/create_xeen/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
cc.o \
constants.o \
hashmap.o \
+ map.o \
memorypool.o \
str.o
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index 2ba3b6f..a424bd5 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -328,7 +328,11 @@ bool File::open(const Common::String &filename, int ccMode) {
int oldMode = files._isDarkCc ? 1 : 0;
files.setGameCc(ccMode);
- File::open(filename, *_currentArchive);
+ if (File::exists(filename, *_currentArchive))
+ File::open(filename, *_currentArchive);
+ else
+ File::open(filename);
+
files.setGameCc(oldMode);
return true;
@@ -390,6 +394,10 @@ bool File::exists(const Common::String &filename, int ccMode) {
return result;
}
+bool File::exists(const Common::String &filename, Common::Archive &archive) {
+ return archive.hasFile(filename);
+}
+
void File::syncBitFlags(Common::Serializer &s, bool *startP, bool *endP) {
byte data = 0;
diff --git a/engines/xeen/files.h b/engines/xeen/files.h
index 4ceadcd..306ec96 100644
--- a/engines/xeen/files.h
+++ b/engines/xeen/files.h
@@ -187,9 +187,19 @@ public:
* Checks if a given file exists
*
* @param filename the file to check for
+ * @param ccMode Archive to use
* @return true if the file exists, false otherwise
*/
static bool exists(const Common::String &filename, int ccMode);
+
+ /**
+ * Checks if a given file exists
+ *
+ * @param filename the file to check for
+ * @param archive Archive to use
+ * @return true if the file exists, false otherwise
+ */
+ static bool exists(const Common::String &filename, Common::Archive &archive);
};
/**
Commit: 6614d8df1790c77f20b53b9627bd98c03fdde80d
https://github.com/scummvm/scummvm/commit/6614d8df1790c77f20b53b9627bd98c03fdde80d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Remove un-needed initialization of monsters list in code
The original had a static monsters list in the executable, but
it then goes ahead and loads in the list from a resource anyway
Changed paths:
engines/xeen/map.cpp
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index d3e3d77..af50fcd 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -137,341 +137,6 @@ void MonsterStruct::synchronize(Common::SeekableReadStream &s) {
}
MonsterData::MonsterData() {
- push_back(MonsterStruct("", 0, 0, 0, 0, 0, CLASS_KNIGHT, 1, 1, DT_PHYSICAL,
- SA_NONE, 1, 0, MONSTER_0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, false, 0, 0, 0, 100, "Slime"));
- push_back(MonsterStruct("Whirlwind", 250000, 1000, 10, 250, 1, CLASS_15, 5,
- 100, DT_PHYSICAL, SA_CONFUSE, 250, 0, MONSTER_0, 100,
- 100, 100, 100, 0, 0, 100, 0, 0, 0, 0, false, 1, 0, 0, 176,
- "airmon"));
- push_back(MonsterStruct("Annihilator", 1000000, 1500, 40, 200, 12, CLASS_16, 5,
- 50, DT_ENERGY, SA_NONE, 1, 1, MONSTER_0, 80, 80, 100,
- 100, 0, 0, 80, 0, 0, 0, 0, false, 2, 0, 0, 102, "alien1"));
- push_back(MonsterStruct("Autobot", 1000000, 2500, 100, 200, 2, CLASS_16, 5,
- 100, DT_ENERGY, SA_NONE, 1, 0, MONSTER_0, 50, 50, 100,
- 100, 0, 0, 50, 0, 0, 0, 0, true, 3, 0, 0, 101, "alien2"));
- push_back(MonsterStruct("Sewer Stalker", 50000, 250, 30, 25, 1, CLASS_16, 3,
- 100, DT_PHYSICAL, SA_NONE, 50, 0, MONSTER_ANIMAL, 0,
- 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, false, 4, 0, 0, 113,
- "iguana"));
- push_back(MonsterStruct("Armadillo", 60000, 800, 50, 15, 1, CLASS_16, 100, 6,
- DT_PHYSICAL, SA_BREAKWEAPON, 60, 0, MONSTER_ANIMAL,
- 50, 0, 80, 80, 50, 0, 50, 0, 0, 0, 0, false, 5, 1, 0, 113,
- "unnh"));
- push_back(MonsterStruct("Barbarian", 5000, 50, 5, 40, 3, CLASS_SORCERER, 1, 20,
- DT_PHYSICAL, SA_NONE, 20, 1, MONSTER_HUMANOID, 0, 0,
- 0, 0, 0, 0, 0, 0, 100, 0, 3, false, 6, 0, 0, 100,
- "barbarch"));
- push_back(MonsterStruct("Electrapede", 10000, 200, 10, 50, 1, CLASS_PALADIN,
- 50, 1, DT_ELECTRICAL, SA_PARALYZE, 1, 0,
- MONSTER_INSECT, 50, 100, 50, 50, 50, 0, 0, 0, 0, 0, 0,
- false, 7, 1, 0, 107, "centi"));
- push_back(MonsterStruct("Cleric of Mok", 30000, 125, 10, 40, 1, CLASS_CLERIC,
- 250, 1, DT_ELECTRICAL, SA_NONE, 1, 1, MONSTER_HUMANOID,
- 10, 100, 10, 10, 10, 10, 0, 0, 0, 10, 0, false, 8, 0, 0,
- 117, "cleric"));
- push_back(MonsterStruct("Mok Heretic", 50000, 150, 12, 50, 1, CLASS_CLERIC,
- 500, 1, DT_MAGICAL, SA_NONE, 1, 1, MONSTER_HUMANOID, 20, 50,
- 20, 20, 20, 30, 0, 0, 0, 25, 4, false, 8, 0, 0, 117,
- "cleric"));
- push_back(MonsterStruct("Mantis Ant", 40000, 300, 30, 40, 2, CLASS_16, 2, 100,
- DT_PHYSICAL, SA_POISON, 30, 0, MONSTER_INSECT, 0, 0,
- 0, 100, 0, 0, 30, 0, 0, 0, 0, false, 10, 0, 0, 104,
- "spell001"));
- push_back(MonsterStruct("Cloud Dragon", 500000, 2000, 40, 150, 1, CLASS_15,
- 600, 1, DT_COLD, SA_NONE, 1, 1, MONSTER_DRAGON, 0, 50,
- 100, 100, 50, 25, 50, 0, 0, 10, 0, false, 11, 0, 0, 140,
- "tiger1"));
- push_back(MonsterStruct("Phase Dragon", 2000000, 4000, 80, 200, 1, CLASS_15,
- 750, 1, DT_COLD, SA_NONE, 1, 1, MONSTER_DRAGON, 0, 50,
- 100, 100, 80, 50, 50, 0, 0, 20, 0, false, 11, 0, 10, 140,
- "Begger"));
- push_back(MonsterStruct("Green Dragon", 500000, 2500, 50, 150, 1, CLASS_15,
- 500, 1, DT_FIRE, SA_NONE, 1, 1, MONSTER_DRAGON, 100,
- 50, 0, 100, 50, 25, 50, 0, 0, 10, 0, false, 13, 0, 0, 140,
- "tiger1"));
- push_back(MonsterStruct("Energy Dragon", 2000000, 5000, 100, 250, 1, CLASS_15,
- 1000, 1, DT_ENERGY, SA_NONE, 1, 1, MONSTER_DRAGON, 80,
- 80, 60, 100, 100, 30, 50, 0, 0, 20, 0, false, 13, 0, 7,
- 140, "begger"));
- push_back(MonsterStruct("Dragon Mummy", 2000000, 3000, 30, 100, 1,
- CLASS_CLERIC, 2000, 2, DT_PHYSICAL, SA_DISEASE, 200,
- 0, MONSTER_DRAGON, 0, 80, 100, 100, 0, 10, 90, 0, 0, 0,
- 0, false, 15, 0, 0, 140, "dragmum"));
- push_back(MonsterStruct("Scraps", 2000000, 3000, 30, 100, 1, CLASS_16, 2000, 2,
- DT_PHYSICAL, SA_NONE, 200, 0, MONSTER_DRAGON, 0, 80,
- 100, 100, 0, 10, 90, 0, 0, 0, 0, false, 15, 0, 0, 140,
- "dragmum"));
- push_back(MonsterStruct("Earth Blaster", 250000, 1000, 10, 100, 1, CLASS_15, 5,
- 100, DT_PHYSICAL, SA_NONE, 200, 0, MONSTER_0, 100, 90,
- 90, 100, 0, 0, 90, 0, 0, 0, 0, false, 17, 0, 0, 100,
- "earthmon"));
- push_back(MonsterStruct("Beholder Bat", 10000, 75, 15, 80, 1, CLASS_15, 5, 5,
- DT_FIRE, SA_NONE, 1, 0, MONSTER_0, 100, 50, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, true, 18, 0, 0, 120, "eyeball"));
- push_back(MonsterStruct("Fire Blower", 250000, 1000, 20, 60, 1, CLASS_15, 5,
- 100, DT_FIRE, SA_NONE, 1, 0, MONSTER_0, 100, 50, 0,
- 100, 50, 0, 50, 0, 0, 0, 0, false, 19, 0, 0, 110, "fire"));
- push_back(MonsterStruct("Hell Hornet", 50000, 250, 30, 50, 2, CLASS_DRUID, 2,
- 250, DT_POISON, SA_WEAKEN, 1, 0, MONSTER_INSECT, 50,
- 50, 50, 100, 50, 0, 50, 0, 0, 0, 0, true, 20, 0, 0, 123,
- "insect"));
- push_back(MonsterStruct("Gargoyle", 30000, 150, 35, 30, 2, CLASS_16, 5, 50,
- DT_PHYSICAL, SA_NONE, 60, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 20, 0, 0, 0, 0, 0, false, 21, 0, 10, 100, "gargrwl"));
- push_back(MonsterStruct("Giant", 100000, 500, 25, 45, 2, CLASS_16, 100, 5,
- DT_PHYSICAL, SA_UNCONSCIOUS, 100, 0, MONSTER_0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1000, 0, 5, false, 22, 0, 0, 100,
- "giant"));
- push_back(MonsterStruct("Goblin", 1000, 10, 5, 30, 2, CLASS_16, 2, 6,
- DT_PHYSICAL, SA_NONE, 1, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, false, 25, 0, 0, 131, "gremlin"));
- push_back(MonsterStruct("Onyx Golem", 1000000, 10000, 50, 100, 1, CLASS_15, 2,
- 250, DT_MAGICAL, SA_DRAINSP, 1, 0, MONSTER_GOLEM, 100, 100,
- 100, 100, 100, 100, 50, 0, 0, 100, 0, true, 24, 0, 10,
- 100, "golem"));
- push_back(MonsterStruct("Gremlin", 2000, 20, 7, 35, 2, CLASS_16, 2, 10,
- DT_PHYSICAL, SA_NONE, 10, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, false, 26, 0, 0, 101, "gremlink"));
- push_back(MonsterStruct("Gremlin Guard", 3000, 50, 10, 35, 2, CLASS_16, 6, 5,
- DT_PHYSICAL, SA_NONE, 20, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, false, 26, 0, 0, 101, "gremlink"));
- push_back(MonsterStruct("Griffin", 60000, 800, 35, 150, 2, CLASS_KNIGHT, 50, 6,
- DT_PHYSICAL, SA_NONE, 150, 0, MONSTER_ANIMAL, 0, 0, 0,
- 0, 0, 80, 0, 0, 0, 0, 0, false, 27, 0, 0, 120, "screech"));
- push_back(MonsterStruct("Gamma Gazer", 1000000, 5000, 60, 200, 7, CLASS_16, 10,
- 20, DT_ENERGY, SA_NONE, 1, 0, MONSTER_0, 100, 100, 0,
- 100, 100, 0, 60, 0, 0, 0, 0, false, 28, 0, 0, 140, "hydra"));
- push_back(MonsterStruct("Iguanasaurus", 100000, 2500, 20, 30, 1, CLASS_16, 10,
- 50, DT_PHYSICAL, SA_INSANE, 150, 0, MONSTER_ANIMAL, 50,
- 50, 50, 50, 50, 0, 20, 0, 0, 0, 0, false, 29, 0, 0, 113,
- "iguana"));
- push_back(MonsterStruct("Slayer Knight", 50000, 500, 30, 50, 1, CLASS_PALADIN,
- 2, 250, DT_PHYSICAL, SA_NONE, 100, 0, MONSTER_HUMANOID,
- 50, 50, 50, 50, 50, 0, 0, 0, 50, 0, 5, false, 30, 0, 0,
- 141, "knight"));
- push_back(MonsterStruct("Death Knight", 100000, 750, 50, 80, 2, CLASS_PALADIN,
- 2, 250, DT_PHYSICAL, SA_NONE, 150, 0, MONSTER_HUMANOID,
- 50, 50, 50, 50, 50, 10, 0, 0, 100, 0, 6, false, 30, 0, 0,
- 141, "knight"));
- push_back(MonsterStruct("Lava Dweller", 500000, 1500, 30, 40, 1, CLASS_15, 5,
- 100, DT_FIRE, SA_NONE, 1, 0, MONSTER_0, 100, 100, 0,
- 100, 50, 0, 50, 0, 0, 0, 0, false, 19, 0, 0, 110, "fire"));
- push_back(MonsterStruct("Lava Roach", 50000, 500, 20, 70, 1, CLASS_16, 5, 50,
- DT_FIRE, SA_NONE, 1, 0, MONSTER_INSECT, 100, 100, 0,
- 100, 0, 0, 0, 0, 0, 0, 0, false, 33, 0, 0, 131, "Phantom"));
- push_back(MonsterStruct("Power Lich", 200000, 500, 20, 60, 1, CLASS_15, 10, 10,
- DT_MAGICAL, SA_UNCONSCIOUS, 1, 1, MONSTER_UNDEAD, 0, 0, 0, 0,
- 0, 80, 70, 0, 0, 0, 0, true, 34, 0, 0, 141, "lich"));
- push_back(MonsterStruct("Mystic Mage", 100000, 200, 20, 70, 1, CLASS_15, 10,
- 20, DT_ELECTRICAL, SA_NONE, 1, 1, MONSTER_0, 50, 100,
- 50, 50, 50, 30, 0, 0, 0, 50, 0, true, 35, 0, 0, 163,
- "monsterb"));
- push_back(MonsterStruct("Magic Mage", 200000, 300, 25, 80, 1, CLASS_15, 10, 30,
- DT_ELECTRICAL, SA_NONE, 1, 1, MONSTER_0, 50, 100, 50,
- 50, 50, 50, 0, 0, 0, 75, 0, true, 35, 0, 0, 163,
- "monsterb"));
- push_back(MonsterStruct("Minotaur", 250000, 3000, 80, 120, 1, CLASS_16, 100, 4,
- DT_PHYSICAL, SA_AGING, 150, 0, MONSTER_0, 0, 0, 10, 0,
- 0, 50, 60, 0, 0, 0, 0, false, 37, 0, 0, 141, "stonegol"));
- push_back(MonsterStruct("Gorgon", 250000, 4000, 90, 100, 1, CLASS_16, 100, 3,
- DT_PHYSICAL, SA_STONE, 100, 0, MONSTER_0, 0, 0, 0, 0,
- 0, 60, 70, 0, 0, 0, 0, false, 37, 0, 0, 141, "stonegol"));
- push_back(MonsterStruct("Higher Mummy", 100000, 400, 20, 60, 1, CLASS_CLERIC,
- 10, 40, DT_PHYSICAL, SA_CURSEITEM, 100, 0,
- MONSTER_UNDEAD, 0, 50, 50, 100, 50, 20, 75, 0, 0, 0, 0,
- false, 39, 0, 0, 141, "mummy"));
- push_back(MonsterStruct("Orc Guard", 5000, 60, 10, 20, 1, CLASS_12, 3, 10,
- DT_PHYSICAL, SA_NONE, 20, 0, MONSTER_HUMANOID, 0, 0,
- 0, 0, 0, 0, 0, 0, 50, 0, 2, false, 40, 0, 0, 125, "orc"));
- push_back(MonsterStruct("Octopod", 250000, 2500, 40, 80, 1, CLASS_15, 2, 100,
- DT_POISON, SA_POISON, 1, 0, MONSTER_ANIMAL, 0, 0, 50,
- 100, 0, 0, 0, 0, 0, 0, 0, true, 41, 0, 0, 101, "photon"));
- push_back(MonsterStruct("Ogre", 10000, 100, 15, 30, 1, CLASS_16, 4, 10,
- DT_PHYSICAL, SA_NONE, 30, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 0, 0, 0, 100, 0, 0, false, 42, 0, 0, 136, "ogre"));
- push_back(MonsterStruct("Orc Shaman", 10000, 50, 15, 30, 1, CLASS_15, 5, 5,
- DT_COLD, SA_SLEEP, 1, 1, MONSTER_HUMANOID, 0, 0, 0, 0,
- 0, 10, 0, 0, 75, 10, 2, false, 43, 0, 0, 125, "fx7"));
- push_back(MonsterStruct("Sabertooth", 10000, 100, 20, 60, 3, CLASS_16, 5, 10,
- DT_PHYSICAL, SA_NONE, 30, 0, MONSTER_ANIMAL, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, false, 44, 1, 0, 101, "saber"));
- push_back(MonsterStruct("Sand Flower", 10000, 100, 10, 50, 5, CLASS_16, 5, 5,
- DT_PHYSICAL, SA_INLOVE, 50, 0, MONSTER_0, 0, 0, 0, 0,
- 0, 50, 50, 0, 0, 0, 0, false, 45, 0, 0, 106, "sand"));
- push_back(MonsterStruct("Killer Cobra", 25000, 1000, 25, 100, 1, CLASS_16, 2,
- 100, DT_PHYSICAL, SA_AGING, 30, 0, MONSTER_ANIMAL, 0,
- 0, 0, 100, 0, 50, 0, 0, 0, 0, 0, false, 46, 0, 0, 100,
- "hiss"));
- push_back(MonsterStruct("Sewer Rat", 2000, 40, 5, 35, 1, CLASS_16, 3, 10,
- DT_PHYSICAL, SA_NONE, 10, 0, MONSTER_ANIMAL, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, false, 47, 0, 0, 136, "rat"));
- push_back(MonsterStruct("Sewer Slug", 1000, 25, 2, 25, 1, CLASS_16, 2, 10,
- DT_PHYSICAL, SA_NONE, 5, 0, MONSTER_INSECT, 0, 0, 0,
- 100, 0, 0, 0, 0, 0, 0, 0, false, 48, 0, 0, 111, "zombie"));
- push_back(MonsterStruct("Skeletal Lich", 500000, 2000, 30, 200, 1,
- CLASS_SORCERER, 1000, 1, DT_ENERGY, SA_ERADICATE, 1, 1,
- MONSTER_UNDEAD, 80, 70, 80, 100, 100, 50, 50, 0, 0, 0,
- 0, false, 49, 0, 0, 140, "elecbolt"));
- push_back(MonsterStruct("Enchantress", 40000, 100, 25, 60, 1, CLASS_CLERIC, 3,
- 150, DT_ELECTRICAL, SA_NONE, 1, 1, MONSTER_HUMANOID,
- 10, 100, 10, 10, 10, 20, 0, 0, 0, 20, 0, false, 50, 0, 0,
- 163, "disint"));
- push_back(MonsterStruct("Sorceress", 80000, 200, 30, 80, 1, CLASS_15, 2, 50,
- DT_MAGICAL, SA_NONE, 1, 1, MONSTER_HUMANOID, 10, 20, 10, 10,
- 10, 80, 0, 0, 0, 50, 5, false, 50, 0, 0, 163, "disint"));
- push_back(MonsterStruct("Arachnoid", 4000, 50, 10, 40, 1, CLASS_16, 3, 5,
- DT_POISON, SA_POISON, 1, 0, MONSTER_INSECT, 0, 0, 0,
- 100, 0, 0, 0, 0, 0, 0, 0, false, 52, 0, 0, 104, "web"));
- push_back(MonsterStruct("Medusa Sprite", 5000, 30, 5, 30, 1, CLASS_RANGER, 3,
- 3, DT_PHYSICAL, SA_STONE, 10, 0, MONSTER_0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, true, 53, 0, 0, 42, "hiss"));
- push_back(MonsterStruct("Rogue", 5000, 50, 10, 30, 1, CLASS_ROBBER, 1, 60,
- DT_PHYSICAL, SA_NONE, 10, 0, MONSTER_HUMANOID, 0, 0,
- 0, 0, 0, 0, 0, 0, 70, 0, 0, false, 54, 0, 0, 100, "thief"));
- push_back(MonsterStruct("Thief", 10000, 100, 15, 40, 1, CLASS_ROBBER, 1, 100,
- DT_PHYSICAL, SA_NONE, 20, 0, MONSTER_HUMANOID, 0, 0,
- 0, 0, 0, 0, 0, 0, 200, 0, 0, false, 54, 0, 0, 100,
- "thief"));
- push_back(MonsterStruct("Troll Grunt", 10000, 100, 5, 50, 1, CLASS_16, 2, 25,
- DT_PHYSICAL, SA_NONE, 30, 0, MONSTER_0, 50, 50, 50,
- 50, 0, 0, 0, 0, 0, 0, 0, false, 56, 0, 0, 136, "troll"));
- push_back(MonsterStruct("Vampire", 200000, 400, 30, 80, 1, CLASS_CLERIC, 10,
- 10, DT_PHYSICAL, SA_WEAKEN, 100, 0, MONSTER_UNDEAD, 50,
- 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, false, 57, 0, 0, 42,
- "vamp"));
- push_back(MonsterStruct("Vampire Lord", 300000, 500, 35, 100, 1, CLASS_CLERIC,
- 10, 30, DT_PHYSICAL, SA_SLEEP, 120, 0, MONSTER_UNDEAD,
- 50, 50, 50, 50, 50, 50, 70, 0, 0, 0, 0, false, 58, 0, 0,
- 42, "vamp"));
- push_back(MonsterStruct("Vulture Roc", 200000, 2500, 50, 150, 1, CLASS_16, 5,
- 60, DT_PHYSICAL, SA_NONE, 100, 0, MONSTER_ANIMAL, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, true, 59, 0, 0, 120, "vulture"));
- push_back(MonsterStruct("Sewer Hag", 50000, 75, 10, 40, 1, CLASS_PALADIN, 10,
- 25, DT_ELECTRICAL, SA_INSANE, 1, 1, MONSTER_HUMANOID,
- 0, 100, 0, 100, 0, 20, 0, 0, 0, 10, 0, false, 62, 0, 0,
- 108, "elecspel"));
- push_back(MonsterStruct("Tidal Terror", 500000, 1000, 10, 200, 1, CLASS_15, 5,
- 100, DT_COLD, SA_NONE, 1, 0, MONSTER_0, 100, 50, 50,
- 100, 50, 0, 100, 0, 0, 0, 0, true, 61, 0, 0, 101,
- "splash3"));
- push_back(MonsterStruct("Witch", 80000, 150, 15, 70, 1, CLASS_15, 10, 10,
- DT_ELECTRICAL, SA_NONE, 1, 1, MONSTER_HUMANOID, 0, 100,
- 0, 20, 0, 20, 0, 0, 0, 10, 0, false, 63, 0, 0, 114,
- "elecspel"));
- push_back(MonsterStruct("Coven Leader", 120000, 250, 20, 100, 1, CLASS_15, 10,
- 15, DT_ENERGY, SA_DRAINSP, 1, 1, MONSTER_HUMANOID, 10,
- 100, 0, 50, 100, 50, 0, 0, 0, 20, 6, false, 63, 0, 10, 114,
- "elecspel"));
- push_back(MonsterStruct("Master Wizard", 120000, 500, 25, 150, 2, CLASS_KNIGHT,
- 10, 40, DT_FIRE, SA_NONE, 1, 1, MONSTER_HUMANOID, 100,
- 50, 50, 50, 50, 50, 0, 0, 0, 50, 0, false, 64, 0, 0, 163,
- "boltelec"));
- push_back(MonsterStruct("Wizard", 60000, 250, 20, 125, 1, CLASS_PALADIN, 10,
- 25, DT_MAGICAL, SA_NONE, 1, 1, MONSTER_HUMANOID, 50, 30, 30,
- 30, 30, 30, 0, 0, 0, 20, 0, false, 65, 0, 0, 163, "wizard"));
- push_back(MonsterStruct("Dark Wolf", 10000, 70, 10, 70, 3, CLASS_16, 3, 8,
- DT_PHYSICAL, SA_NONE, 10, 0, MONSTER_ANIMAL, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, false, 66, 1, 0, 100, "wolf"));
- push_back(MonsterStruct("Screamer", 500000, 3000, 50, 200, 1, CLASS_15, 10, 20,
- DT_POISON, SA_POISON, 1, 0, MONSTER_0, 0, 0, 0, 100, 0,
- 0, 60, 0, 0, 0, 0, false, 67, 0, 0, 110, "dragon"));
- push_back(MonsterStruct("Cult Leader", 100000, 100, 20, 60, 1, CLASS_15, 10,
- 10, DT_ENERGY, SA_NONE, 1, 1, MONSTER_HUMANOID, 50, 50,
- 50, 50, 100, 50, 0, 0, 0, 100, 6, false, 8, 0, 0, 100,
- "cleric"));
- push_back(MonsterStruct("Mega Dragon", 100000000, 64000, 100, 200, 1, CLASS_15,
- 10, 200, DT_ENERGY, SA_ERADICATE, 1, 1, MONSTER_DRAGON,
- 100, 100, 100, 100, 100, 100, 90, 0, 0, 232, 0, false, 11,
- 0, 7, 100, "tiger1"));
- push_back(MonsterStruct("Gettlewaithe", 5000, 100, 15, 35, 2, CLASS_16, 5, 5,
- DT_PHYSICAL, SA_NONE, 10, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 0, 0, 0, 2000, 0, 5, false, 25, 0, 0, 100, "gremlin"));
- push_back(MonsterStruct("Doom Knight", 500000, 1000, 50, 100, 4, CLASS_PALADIN,
- 2, 250, DT_PHYSICAL, SA_DEATH, 150, 0,
- MONSTER_HUMANOID, 80, 80, 80, 80, 80, 20, 0, 0, 200,
- 0, 7, false, 30, 0, 10, 100, "knight"));
- push_back(MonsterStruct("Sandro", 200000, 1000, 20, 75, 1, CLASS_15, 10, 10,
- DT_MAGICAL, SA_DEATH, 1, 1, MONSTER_UNDEAD, 0, 0, 0, 0, 0,
- 90, 80, 0, 0, 100, 7, true, 34, 0, 10, 100, "lich"));
- push_back(MonsterStruct("Mega Mage", 500000, 500, 35, 100, 1, CLASS_15, 10, 40,
- DT_ELECTRICAL, SA_NONE, 1, 1, MONSTER_0, 80, 100, 80,
- 80, 80, 80, 0, 0, 0, 100, 6, true, 35, 0, 11, 100,
- "monsterb"));
- push_back(MonsterStruct("Orc Elite", 15000, 200, 15, 40, 2, CLASS_12, 5, 10,
- DT_PHYSICAL, SA_NONE, 20, 0, MONSTER_HUMANOID, 0, 0,
- 0, 0, 0, 0, 0, 0, 100, 0, 3, false, 40, 0, 0, 100, "orc"));
- push_back(MonsterStruct("Shaalth", 20000, 300, 15, 50, 1, CLASS_15, 5, 10,
- DT_COLD, SA_SLEEP, 1, 0, MONSTER_HUMANOID, 0, 0, 0, 0,
- 0, 20, 0, 0, 1000, 50, 5, false, 43, 0, 10, 100, "fx7"));
- push_back(MonsterStruct("Rooka", 5000, 60, 5, 40, 1, CLASS_16, 3, 10,
- DT_PHYSICAL, SA_DISEASE, 15, 0, MONSTER_ANIMAL, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 10, 4, false, 47, 0, 0, 100, "rat"));
- push_back(MonsterStruct("Morgana", 200000, 300, 35, 100, 1, CLASS_15, 2, 60,
- DT_ENERGY, SA_PARALYZE, 1, 1, MONSTER_HUMANOID, 50, 50,
- 50, 50, 100, 80, 0, 0, 0, 100, 6, false, 50, 0, 10, 100,
- "disint"));
- push_back(MonsterStruct("Master Thief", 20000, 100, 20, 50, 1, CLASS_ROBBER, 1,
- 250, DT_PHYSICAL, SA_NONE, 40, 0, MONSTER_HUMANOID, 0,
- 0, 0, 0, 0, 0, 0, 0, 250, 20, 4, false, 54, 0, 14, 100,
- "thief"));
- push_back(MonsterStruct("Royal Vampire", 400000, 750, 40, 125, 1, CLASS_CLERIC,
- 10, 50, DT_PHYSICAL, SA_CURSEITEM, 120, 0,
- MONSTER_UNDEAD, 50, 50, 50, 50, 50, 50, 65, 0, 0, 0, 0,
- false, 57, 0, 0, 100, "vamp"));
- push_back(MonsterStruct("Ct. Blackfang", 2000000, 1500, 50, 150, 1,
- CLASS_CLERIC, 10, 100, DT_PHYSICAL, SA_DEATH, 120, 0,
- MONSTER_UNDEAD, 75, 75, 75, 75, 75, 75, 75, 0, 0, 0, 0,
- false, 58, 0, 10, 100, "vamp"));
- push_back(MonsterStruct("Troll Guard", 15000, 200, 10, 60, 1, CLASS_16, 2, 35,
- DT_PHYSICAL, SA_NONE, 30, 0, MONSTER_0, 50, 50, 50,
- 50, 0, 0, 0, 0, 0, 0, 0, false, 56, 0, 0, 100, "troll"));
- push_back(MonsterStruct("Troll Chief", 20000, 300, 15, 65, 1, CLASS_16, 2, 50,
- DT_PHYSICAL, SA_NONE, 30, 0, MONSTER_0, 50, 50, 50,
- 50, 0, 0, 0, 0, 0, 0, 0, false, 56, 0, 0, 100, "troll"));
- push_back(MonsterStruct("Hobstadt", 25000, 400, 20, 70, 1, CLASS_16, 2, 50,
- DT_PHYSICAL, SA_NONE, 30, 0, MONSTER_0, 50, 50, 50,
- 50, 0, 0, 0, 0, 1000, 0, 4, false, 56, 0, 0, 100, "troll"));
- push_back(MonsterStruct("Graalg", 20000, 200, 15, 50, 1, CLASS_16, 5, 10,
- DT_PHYSICAL, SA_NONE, 30, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1000, 0, 5, false, 42, 0, 0, 100, "ogre"));
- push_back(MonsterStruct("Vampire King", 3000000, 10000, 60, 200, 1,
- CLASS_CLERIC, 10, 250, DT_PHYSICAL, SA_ERADICATE, 150,
- 0, MONSTER_UNDEAD, 80, 80, 80, 80, 80, 80, 90, 0, 0, 0,
- 0, false, 58, 0, 0, 100, "vamp"));
- push_back(MonsterStruct("Valio", 60000, 150, 15, 60, 1, CLASS_PALADIN, 10, 25,
- DT_MAGICAL, SA_NONE, 1, 0, MONSTER_HUMANOID, 50, 30, 30, 30,
- 40, 30, 0, 0, 0, 0, 0, false, 65, 0, 0, 100, "wizard"));
- push_back(MonsterStruct("Sky Golem", 200000, 1000, 50, 100, 1, CLASS_15, 2,
- 100, DT_COLD, SA_NONE, 1, 1, MONSTER_GOLEM, 50, 50,
- 100, 50, 50, 50, 50, 0, 0, 0, 0, true, 24, 0, 0, 100,
- "golem"));
- push_back(MonsterStruct("Gurodel", 100000, 750, 30, 60, 2, CLASS_16, 100, 6,
- DT_PHYSICAL, SA_UNCONSCIOUS, 110, 0, MONSTER_0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5000, 0, 6, false, 22, 0, 0, 100,
- "giant"));
- push_back(MonsterStruct("Yog", 25000, 100, 5, 60, 1, CLASS_SORCERER, 1, 30,
- DT_PHYSICAL, SA_NONE, 25, 0, MONSTER_HUMANOID, 0, 0,
- 0, 0, 0, 0, 0, 0, 200, 0, 4, false, 6, 0, 10, 100,
- "barbarch"));
- push_back(MonsterStruct("Sharla", 10000, 50, 5, 50, 1, CLASS_RANGER, 3, 4,
- DT_PHYSICAL, SA_NONE, 20, 0, MONSTER_0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, true, 53, 0, 0, 100, "hiss"));
- push_back(MonsterStruct("Ghost Mummy", 500000, 500, 35, 175, 1, CLASS_CLERIC,
- 200, 5, DT_PHYSICAL, SA_AGING, 150, 0, MONSTER_UNDEAD,
- 0, 60, 80, 80, 80, 50, 80, 0, 0, 0, 0, false, 40, 0, 6,
- 100, "orc"));
- push_back(MonsterStruct("Phase Mummy", 500000, 500, 35, 175, 1, CLASS_CLERIC,
- 200, 6, DT_PHYSICAL, SA_DRAINSP, 150, 0,
- MONSTER_UNDEAD, 0, 70, 80, 80, 80, 60, 85, 0, 0, 0, 0,
- false, 39, 0, 7, 100, "mummy"));
- push_back(MonsterStruct("Xenoc", 250000, 700, 35, 175, 1, CLASS_15, 10, 50,
- DT_ENERGY, SA_NONE, 1, 0, MONSTER_HUMANOID, 50, 50, 50,
- 50, 100, 50, 0, 0, 0, 100, 6, false, 64, 0, 0, 100,
- "boltelec"));
- push_back(MonsterStruct("Barkman", 4000000, 40000, 25, 100, 3, CLASS_16, 250,
- 1, DT_FIRE, SA_NONE, 1, 0, MONSTER_0, 100, 50, 0, 100,
- 0, 0, 0, 0, 0, 0, 6, false, 19, 0, 11, 100, "fire"));
}
void MonsterData::load(const Common::String &name) {
Commit: 7dde659bf6d986110a1daf741c1698962d9419a4
https://github.com/scummvm/scummvm/commit/7dde659bf6d986110a1daf741c1698962d9419a4
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Fix some incorrect string arrays in create_xeen
Changed paths:
devtools/create_xeen/constants.cpp
engines/xeen/resources.cpp
diff --git a/devtools/create_xeen/constants.cpp b/devtools/create_xeen/constants.cpp
index a744558..1ab1a7a 100644
--- a/devtools/create_xeen/constants.cpp
+++ b/devtools/create_xeen/constants.cpp
@@ -1872,12 +1872,12 @@ void writeConstants(CCArchive &cc) {
file.syncString(TRAINING_TEXT);
file.syncString(GOLD_GEMS);
file.syncString(GOLD_GEMS_2);
- file.syncString(DEPOSIT_WITHDRAWL[2]);
+ file.syncStrings(DEPOSIT_WITHDRAWL, 2);
file.syncString(NOT_ENOUGH_X_IN_THE_Y);
file.syncString(NO_X_IN_THE_Y);
- file.syncString(STAT_NAMES[16]);
- file.syncString(CONSUMABLE_NAMES[4]);
- file.syncString(WHERE_NAMES[2]);
+ file.syncStrings(STAT_NAMES, 16);
+ file.syncStrings(CONSUMABLE_NAMES, 4);
+ file.syncStrings(WHERE_NAMES, 2);
file.syncString(AMOUNT);
file.syncString(FOOD_PACKS_FULL);
file.syncString(BUY_SPELLS);
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index cd794a3..632cf3d 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -61,7 +61,7 @@ void Resources::loadData() {
file.syncString(WHATS_THE_PASSWORD);
file.syncString(IN_NO_CONDITION);
file.syncString(NOTHING_HERE);
- file.syncStrings(&TERRAIN_TYPES[0], 6);
+ file.syncStrings(TERRAIN_TYPES, 6);
file.syncStrings(OUTDOORS_WALL_TYPES, 16);
file.syncStrings(SURFACE_NAMES, 16);
file.syncStrings(WHO_ACTIONS, 32);
@@ -156,12 +156,12 @@ void Resources::loadData() {
file.syncString(TRAINING_TEXT);
file.syncString(GOLD_GEMS);
file.syncString(GOLD_GEMS_2);
- file.syncString(DEPOSIT_WITHDRAWL[2]);
+ file.syncStrings(DEPOSIT_WITHDRAWL, 2);
file.syncString(NOT_ENOUGH_X_IN_THE_Y);
file.syncString(NO_X_IN_THE_Y);
- file.syncString(STAT_NAMES[16]);
- file.syncString(CONSUMABLE_NAMES[4]);
- file.syncString(WHERE_NAMES[2]);
+ file.syncStrings(STAT_NAMES, 16);
+ file.syncStrings(CONSUMABLE_NAMES, 4);
+ file.syncStrings(WHERE_NAMES, 2);
file.syncString(AMOUNT);
file.syncString(FOOD_PACKS_FULL);
file.syncString(BUY_SPELLS);
Commit: 6b523a1d04da385d08d5b38f9e51cdb9b6c5fd33
https://github.com/scummvm/scummvm/commit/6b523a1d04da385d08d5b38f9e51cdb9b6c5fd33
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Properly erase items dialog when exited
Changed paths:
engines/xeen/dialogs_items.cpp
diff --git a/engines/xeen/dialogs_items.cpp b/engines/xeen/dialogs_items.cpp
index c9249f3..379efe0 100644
--- a/engines/xeen/dialogs_items.cpp
+++ b/engines/xeen/dialogs_items.cpp
@@ -506,6 +506,9 @@ Character *ItemsDialog::execute(Character *c, ItemsMode mode) {
}
}
+ windows[30].close();
+ windows[29].close();
+
intf.drawParty(true);
if (updateStock)
charData2BlackData();
Commit: d132d66c2825cddf215b19d787a2797e8dbad8ed
https://github.com/scummvm/scummvm/commit/d132d66c2825cddf215b19d787a2797e8dbad8ed
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:20-05:00
Commit Message:
XEEN: Add Clouds of Xeen MAE and Spells to xeen.ccs
The later games stored them in resources, but Clouds of Xeen had
them hardcoded. So this adds them under the same resource names
as the later games, so the existing code can load them
Changed paths:
devtools/create_xeen/constants.cpp
engines/xeen/files.cpp
engines/xeen/map.cpp
engines/xeen/xeen.cpp
engines/xeen/xeen.h
diff --git a/devtools/create_xeen/constants.cpp b/devtools/create_xeen/constants.cpp
index 1ab1a7a..3df02df 100644
--- a/devtools/create_xeen/constants.cpp
+++ b/devtools/create_xeen/constants.cpp
@@ -1767,6 +1767,49 @@ const char *const MUSIC_FILES2[6][7] = {
{ "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m" }
};
+const char *const SPELL_NAMES[77] = {
+ "Acid Spray", "Awaken", "Beast Master", "Bless", "Clairvoyance", "Cold Ray",
+ "Create Food", "Cure Disease", "Cure Paralysis", "Cure Poison", "Cure Wounds",
+ "Dancing Sword", "Day of Protection", "Day of Sorcery", "Deadly Swarm",
+ "Detect Monster", "Divine Intervention", "Dragon Sleep", "Elemental Storm",
+ "Enchant Item", "Energy Blast", "Etherealize", "Fantastic Freeze", "Fiery Flail",
+ "Finger of Death", "Fire Ball", "First Aid", "Flying Fist", "Frost Bite",
+ "Golem Stopper", "Heroism", "Holy Bonus", "Holy Word", "Hypnotize",
+ "Identify Monster", "Implosion", "Incinerate", "Inferno", "Insect Spray",
+ "Item to Gold", "Jump", "Levitate", "Light", "Lightning Bolt", "Lloyd's Beacon",
+ "Magic Arrow", "Mass Distortion", "Mega Volts", "Moon Ray", "Nature's Cure",
+ "Pain", "Poison Volley", "Power Cure", "Power Shield", "Prismatic Light",
+ "Prot. from Elements", "Raise Dead", "Recharge Item", "Resurrect", "Revitalize",
+ "Shrapmetal", "Sleep", "Sparks", "Star Burst", "Stone to Flesh", "Sun Ray",
+ "Super Shelter", "Suppress Disease", "Suppress Poison", "Teleport",
+ "Time Distortion", "Town Portal", "Toxic Cloud", "Turn Undead", "Walk on Water",
+ "Wizard Eye", "None Ready"
+};
+
+const char *const MAE_NAMES[131] = {
+ "", "burning ", "fiery ", "pyric ", "fuming ", "flaming ", "seething ",
+ "blazing ", "scorching ", "flickering ", "sparking ", "static ",
+ "flashing ", "shocking ", "electric ", "dyna ", "icy ", "frost ",
+ "freezing ", "cold ", "cryo ", "acidic ", "venemous ", "poisonous ",
+ "toxic ", "noxious ", "glowing ", "incandescent ", "dense ", "sonic ",
+ "power ", "thermal ", "radiating ", "kinetic ", "mystic ", "magical ",
+ "ectoplasmic ", "wooden ", "leather ", "brass ", "bronze ", "iron ",
+ "silver ", "steel ", "gold ", "platinum ", "glass ", "coral ", "crystal ",
+ "lapis ", "pearl ", "amber ", "ebony ", "quartz ", "ruby ", "emerald ",
+ "sapphire ", "diamond ", "obsidian ", "might ", "strength ", "warrior ",
+ "ogre ", "giant ", "thunder ", "force ", "power ", "dragon ", "photon ",
+ "clever ", "mind ", "sage ", "thought ", "knowledge ", "intellect ",
+ "wisdom ", "genius ", "buddy ", "friendship ", "charm ", "personality ",
+ "charisma ", "leadership ", "ego ", "holy ", "quick ", "swift ", "fast ",
+ "rapid ", "speed ", "wind ", "accelerator ", "velocity ", "sharp ",
+ "accurate ", "marksman ", "precision ", "true ", "exacto ", "clover ",
+ "chance ", "winners ", "lucky ", "gamblers ", "leprechauns ", "vigor ",
+ "health ", "life ", "troll ", "vampiric ", "spell ", "castors ", "witch ",
+ "mage ", "archmage ", "arcane ", "protection ", "armored ", "defender ",
+ "stealth ", "divine ", "mugger ", "burgler ", "looter ", "brigand ",
+ "filch ", "thief ", "rogue ", "plunder ", "criminal ", "pirate "
+};
+
void writeConstants(CCArchive &cc) {
Common::MemFile file;
file.syncString(CREDITS);
@@ -2095,4 +2138,14 @@ void writeConstants(CCArchive &cc) {
file.syncStrings2D((const char *const *)MUSIC_FILES2, 6, 7);
cc.add("CONSTANTS", file);
+
+ // Fallback spell names list needed for Clouds of Xeen
+ Common::MemFile spells;
+ spells.syncStrings(SPELL_NAMES, 77);
+ cc.add("spells.xen", spells);
+
+ // Fallback MAE names list needed for Clouds of Xeen
+ Common::MemFile mae;
+ mae.syncStrings(MAE_NAMES, 131);
+ cc.add("mae.xen", mae);
}
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index a424bd5..9cbc36f 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -219,7 +219,10 @@ Common::SeekableReadStream *CCArchive::createReadStreamForMember(const Common::S
FileManager::FileManager(XeenEngine *vm) {
_isDarkCc = vm->getGameID() == GType_DarkSide;
- File::_xeenCc = File::_darkCc = nullptr;
+ File::_xeenCc = File::_darkCc = File::_introCc = nullptr;
+ File::_xeenSave = File::_darkSave = nullptr;
+ File::_currentSave = nullptr;
+ File::_currentArchive = nullptr;
}
FileManager::~FileManager() {
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index af50fcd..abe91e5 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -916,15 +916,15 @@ void Map::load(int mapId) {
_wallSprites._surfaces[i].clear();
_wallSprites._fwl1.load(Common::String::format("f%s1.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]), _sidePictures);
_wallSprites._fwl2.load(Common::String::format("f%s2.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]), _sidePictures);
_wallSprites._fwl3.load(Common::String::format("f%s3.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]), _sidePictures);
_wallSprites._fwl4.load(Common::String::format("f%s4.fwl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]), _sidePictures);
_wallSprites._swl.load(Common::String::format("s%s.swl",
- Res.TERRAIN_TYPES[_mazeData[0]._wallKind]));
+ Res.TERRAIN_TYPES[_mazeData[0]._wallKind]), _sidePictures);
// Set entries in the indoor draw list to the correct sprites
// for drawing various parts of the background
diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp
index 8e22965..39fc773 100644
--- a/engines/xeen/xeen.cpp
+++ b/engines/xeen/xeen.cpp
@@ -56,7 +56,6 @@ XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc)
_sound = nullptr;
_spells = nullptr;
_windows = nullptr;
- _eventData = nullptr;
_noDirectionSense = false;
_startupWindowActive = false;
_quitMode = QMODE_NONE;
@@ -80,7 +79,6 @@ XeenEngine::~XeenEngine() {
delete _sound;
delete _spells;
delete _windows;
- delete _eventData;
delete _resources;
delete _files;
g_vm = nullptr;
@@ -107,9 +105,6 @@ bool XeenEngine::initialize() {
_spells = new Spells(this);
_windows = new Windows();
- File f("029.obj", 1);
- _eventData = f.readStream(f.size());
-
// Set graphics mode
initGraphics(320, 200);
diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h
index 652284b..561d928 100644
--- a/engines/xeen/xeen.h
+++ b/engines/xeen/xeen.h
@@ -158,7 +158,6 @@ public:
Windows *_windows;
Mode _mode;
GameEvent _gameEvent;
- Common::SeekableReadStream *_eventData;
QuitMode _quitMode;
bool _noDirectionSense;
bool _startupWindowActive;
Commit: 6b4d3f70dd8f6b13dcf379c239363559e2a82278
https://github.com/scummvm/scummvm/commit/6b4d3f70dd8f6b13dcf379c239363559e2a82278
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-02-23T15:23:21-05:00
Commit Message:
XEEN: Add data to create_xeen for Clouds of Xeen on it's own
Changed paths:
A devtools/create_xeen/clouds.cpp
A devtools/create_xeen/clouds.h
devtools/create_xeen/cc.cpp
devtools/create_xeen/cc.h
devtools/create_xeen/constants.cpp
devtools/create_xeen/create_xeen.cpp
devtools/create_xeen/file.h
devtools/create_xeen/module.mk
engines/xeen/map.cpp
engines/xeen/resources.cpp
engines/xeen/resources.h
engines/xeen/spells.cpp
engines/xeen/xeen.cpp
diff --git a/devtools/create_xeen/cc.cpp b/devtools/create_xeen/cc.cpp
index 4020301..14f605f 100644
--- a/devtools/create_xeen/cc.cpp
+++ b/devtools/create_xeen/cc.cpp
@@ -57,6 +57,33 @@ uint16 CCArchive::convertNameToId(const Common::String &resourceName) {
return total;
}
+void CCArchive::loadIndex() {
+ int count = _file.readUint16LE();
+
+ // Read in the data for the archive's index
+ byte *rawIndex = new byte[count * 8];
+ _file.read(rawIndex, count * 8);
+
+ // Decrypt the index
+ int seed = 0xac;
+ for (int i = 0; i < count * 8; ++i, seed += 0x67) {
+ rawIndex[i] = (byte)((((rawIndex[i] << 2) | (rawIndex[i] >> 6)) + seed) & 0xff);
+ }
+
+ // Extract the index data into entry structures
+ _index.resize(count);
+ const byte *entryP = &rawIndex[0];
+ for (int idx = 0; idx < count; ++idx, entryP += 8) {
+ CCEntry &entry = _index[idx];
+ entry._id = READ_LE_UINT16(entryP);
+ entry._offset = READ_LE_UINT32(entryP + 2) & 0xffffff;
+ entry._size = READ_LE_UINT16(entryP + 5);
+ assert(!entryP[7]);
+ }
+
+ delete[] rawIndex;
+}
+
void CCArchive::saveIndex() {
// Fill up the data for the index entries into a raw data block
byte *rawIndex = new byte[_index.size() * 8];
@@ -107,10 +134,34 @@ void CCArchive::saveEntries() {
}
void CCArchive::close() {
- saveIndex();
- saveEntries();
+ if (_mode == kWrite) {
+ saveIndex();
+ saveEntries();
+ }
}
void CCArchive::add(const Common::String &name, Common::MemFile &f) {
+ assert(_mode == kWrite);
_index.push_back(CCEntry(convertNameToId(name), f.getData(), f.size()));
}
+
+Common::MemFile CCArchive::getMember(const Common::String &name) {
+ uint16 id = convertNameToId(name);
+
+ for (uint idx = 0; idx < _index.size(); ++idx) {
+ CCEntry &entry = _index[idx];
+ if (entry._id == id) {
+ assert(entry._size < MAX_MEM_SIZE);
+ _file.seek(entry._offset);
+ _file.read(entry._data, entry._size);
+
+ // Decrypt the entry
+ for (int i = 0; i < entry._size; ++i)
+ entry._data[i] ^= 0x35;
+
+ return Common::MemFile(entry._data, entry._size);
+ }
+ }
+
+ error("Failed to find %s", name.c_str());
+}
\ No newline at end of file
diff --git a/devtools/create_xeen/cc.h b/devtools/create_xeen/cc.h
index 192a7d5..47a5112 100644
--- a/devtools/create_xeen/cc.h
+++ b/devtools/create_xeen/cc.h
@@ -45,10 +45,13 @@ struct CCEntry {
}
};
+enum CCAccess { kRead = 0, kWrite = 1 };
+
class CCArchive {
private:
Common::Array<CCEntry> _index;
Common::File &_file;
+ CCAccess _mode;
private:
/**
* Convert a resource name to it's equivalent hash key
@@ -56,6 +59,11 @@ private:
uint16 convertNameToId(const Common::String &resourceName);
/**
+ * Loads an index from the file
+ */
+ void loadIndex();
+
+ /**
* Saves the index to the file
*/
void saveIndex();
@@ -68,10 +76,13 @@ public:
/**
* Constructor
*/
- CCArchive(Common::File &file) : _file(file) {}
+ CCArchive(Common::File &file, CCAccess mode) : _file(file), _mode(mode) {
+ if (mode == kRead)
+ loadIndex();
+ }
/**
- * Finishes the CC file, writing out the resulting content
+ * In write mode, finishes the CC file, writing out the resulting content
*/
void close();
@@ -79,6 +90,11 @@ public:
* Adds an entry to the CC
*/
void add(const Common::String &name, Common::MemFile &f);
+
+ /**
+ * In read mode, gets a member
+ */
+ Common::MemFile getMember(const Common::String &name);
};
#endif
diff --git a/devtools/create_xeen/clouds.cpp b/devtools/create_xeen/clouds.cpp
new file mode 100644
index 0000000..2e41263
--- /dev/null
+++ b/devtools/create_xeen/clouds.cpp
@@ -0,0 +1,82 @@
+/* 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.
+ *
+ */
+
+ // Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+// HACK to allow building with the SDL backend on MinGW
+// see bug #1800764 "TOOLS: MinGW tools building broken"
+#ifdef main
+#undef main
+#endif // main
+
+#include "file.h"
+#include "clouds.h"
+
+static const char *const MAP_NAMES[86] = {
+ "", "Area A1", "Area A2", "Area A3", "Area A4", "Area B1", "Area B2",
+ "Area B3", "Area B4", "Area C1", "Area C2", "Area C3", "Area C4",
+ "Area D1", "Area D2", "Area D3", "Area D4", "Area E1", "Area E2",
+ "Area E3", "Area E4", "Area F1", "Area F2", "Area F3", "Area F4",
+ "Witch Clouds", "High Magic Clouds", "Clouds of Xeen", "Vertigo",
+ "Nightshadow", "Rivercity", "Asp", "Winterkill", "Dwarf Mine 1",
+ "Dwarf Mine 2", "Dwarf Mine 3", "Dwarf Mine 4", "Dwarf Mine 5",
+ "Deep Mine Alpha", "Deep Mine Theta", "Deep Mine Kappa",
+ "Deep Mine Omega", "Cave of Illusion Level 1", "Cave of Illusion Level 2",
+ "Cave of Illusion Level 3", "Cave of Illusion Level 4",
+ "Volcano Cave Level 1", "Volcano Cave Level 2", "Volcano Cave Level 3",
+ "Shangri-La", "Dragon Cave", "Witch Tower Level 1", "Witch Tower Level 2",
+ "Witch Tower Level 3", "Witch Tower Level 4", "Tower of High Magic Level 1",
+ "Tower of High Magic Level 2", "Tower of High Magic Level 3",
+ "Tower of High Magic Level 4", "Darzog's Tower Level 1",
+ "Darzog's Tower Level 2", "Darzog's Tower Level 3", "Darzog's Tower Level 4",
+ "Burlock Dungeon", "Castle Burlock Level 1", "Castle Burlock Level 2",
+ "Castle Burlock Level 3", "Basenji Dungeon", "Castle Basenji Level 1",
+ "Castle Basenji Level 2", "Castle Basenji Level 3", "Newcastle Dungeon",
+ "Newcastle Foundation", "Newcastle Level 1", "Newcastle Level 2",
+ "Xeen's Castle Level 1", "Xeen's Castle Level 2", "Xeen's Castle Level 3",
+ "Xeen's Castle Level 4", "Ancient Temple of Yak", "Tomb of a 1000 Terrors",
+ "Golem Dungeon", "Sphinx Body", "Sphinx Head", "Sphinx Dungeon",
+ "The Warzone"
+};
+
+void writeCloudsData(CCArchive &cc, const char *darkName) {
+ Common::File darkFile;
+ if (darkFile.open(darkName, Common::kFileReadMode)) {
+ CCArchive darkCc(darkFile, kRead);
+
+ cc.add("mae.cld", darkCc.getMember("mae.xen"));
+ cc.add("spells.cld", darkCc.getMember("spells.xen"));
+ cc.add("animinfo.cld", darkCc.getMember("clouds.dat"));
+ cc.add("monsters.cld", darkCc.getMember("xeen.mon"));
+ cc.add("wallpics.cld", darkCc.getMember("xeenpic.dat"));
+
+ Common::MemFile mapNames;
+ for (int idx = 0; idx < 86; ++idx)
+ mapNames.syncString(MAP_NAMES[idx]);
+ cc.add("mapnames.cld", mapNames);
+
+ darkFile.close();
+ } else {
+ printf("Could not find %s to get Clouds data\n", darkName);
+ }
+}
diff --git a/devtools/create_xeen/clouds.h b/devtools/create_xeen/clouds.h
new file mode 100644
index 0000000..4c07718
--- /dev/null
+++ b/devtools/create_xeen/clouds.h
@@ -0,0 +1,31 @@
+/* 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 CLOUDS_H
+#define CLOUDS_H
+
+#include "common/scummsys.h"
+#include "cc.h"
+
+extern void writeCloudsData(CCArchive &cc, const char *darkName);
+
+#endif
diff --git a/devtools/create_xeen/constants.cpp b/devtools/create_xeen/constants.cpp
index 3df02df..1ab1a7a 100644
--- a/devtools/create_xeen/constants.cpp
+++ b/devtools/create_xeen/constants.cpp
@@ -1767,49 +1767,6 @@ const char *const MUSIC_FILES2[6][7] = {
{ "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m", "sf05.m" }
};
-const char *const SPELL_NAMES[77] = {
- "Acid Spray", "Awaken", "Beast Master", "Bless", "Clairvoyance", "Cold Ray",
- "Create Food", "Cure Disease", "Cure Paralysis", "Cure Poison", "Cure Wounds",
- "Dancing Sword", "Day of Protection", "Day of Sorcery", "Deadly Swarm",
- "Detect Monster", "Divine Intervention", "Dragon Sleep", "Elemental Storm",
- "Enchant Item", "Energy Blast", "Etherealize", "Fantastic Freeze", "Fiery Flail",
- "Finger of Death", "Fire Ball", "First Aid", "Flying Fist", "Frost Bite",
- "Golem Stopper", "Heroism", "Holy Bonus", "Holy Word", "Hypnotize",
- "Identify Monster", "Implosion", "Incinerate", "Inferno", "Insect Spray",
- "Item to Gold", "Jump", "Levitate", "Light", "Lightning Bolt", "Lloyd's Beacon",
- "Magic Arrow", "Mass Distortion", "Mega Volts", "Moon Ray", "Nature's Cure",
- "Pain", "Poison Volley", "Power Cure", "Power Shield", "Prismatic Light",
- "Prot. from Elements", "Raise Dead", "Recharge Item", "Resurrect", "Revitalize",
- "Shrapmetal", "Sleep", "Sparks", "Star Burst", "Stone to Flesh", "Sun Ray",
- "Super Shelter", "Suppress Disease", "Suppress Poison", "Teleport",
- "Time Distortion", "Town Portal", "Toxic Cloud", "Turn Undead", "Walk on Water",
- "Wizard Eye", "None Ready"
-};
-
-const char *const MAE_NAMES[131] = {
- "", "burning ", "fiery ", "pyric ", "fuming ", "flaming ", "seething ",
- "blazing ", "scorching ", "flickering ", "sparking ", "static ",
- "flashing ", "shocking ", "electric ", "dyna ", "icy ", "frost ",
- "freezing ", "cold ", "cryo ", "acidic ", "venemous ", "poisonous ",
- "toxic ", "noxious ", "glowing ", "incandescent ", "dense ", "sonic ",
- "power ", "thermal ", "radiating ", "kinetic ", "mystic ", "magical ",
- "ectoplasmic ", "wooden ", "leather ", "brass ", "bronze ", "iron ",
- "silver ", "steel ", "gold ", "platinum ", "glass ", "coral ", "crystal ",
- "lapis ", "pearl ", "amber ", "ebony ", "quartz ", "ruby ", "emerald ",
- "sapphire ", "diamond ", "obsidian ", "might ", "strength ", "warrior ",
- "ogre ", "giant ", "thunder ", "force ", "power ", "dragon ", "photon ",
- "clever ", "mind ", "sage ", "thought ", "knowledge ", "intellect ",
- "wisdom ", "genius ", "buddy ", "friendship ", "charm ", "personality ",
- "charisma ", "leadership ", "ego ", "holy ", "quick ", "swift ", "fast ",
- "rapid ", "speed ", "wind ", "accelerator ", "velocity ", "sharp ",
- "accurate ", "marksman ", "precision ", "true ", "exacto ", "clover ",
- "chance ", "winners ", "lucky ", "gamblers ", "leprechauns ", "vigor ",
- "health ", "life ", "troll ", "vampiric ", "spell ", "castors ", "witch ",
- "mage ", "archmage ", "arcane ", "protection ", "armored ", "defender ",
- "stealth ", "divine ", "mugger ", "burgler ", "looter ", "brigand ",
- "filch ", "thief ", "rogue ", "plunder ", "criminal ", "pirate "
-};
-
void writeConstants(CCArchive &cc) {
Common::MemFile file;
file.syncString(CREDITS);
@@ -2138,14 +2095,4 @@ void writeConstants(CCArchive &cc) {
file.syncStrings2D((const char *const *)MUSIC_FILES2, 6, 7);
cc.add("CONSTANTS", file);
-
- // Fallback spell names list needed for Clouds of Xeen
- Common::MemFile spells;
- spells.syncStrings(SPELL_NAMES, 77);
- cc.add("spells.xen", spells);
-
- // Fallback MAE names list needed for Clouds of Xeen
- Common::MemFile mae;
- mae.syncStrings(MAE_NAMES, 131);
- cc.add("mae.xen", mae);
}
diff --git a/devtools/create_xeen/create_xeen.cpp b/devtools/create_xeen/create_xeen.cpp
index 92c7a3b..5b66870 100644
--- a/devtools/create_xeen/create_xeen.cpp
+++ b/devtools/create_xeen/create_xeen.cpp
@@ -34,6 +34,7 @@
#include <string.h>
#include "cc.h"
#include "file.h"
+#include "clouds.h"
#include "constants.h"
#include "map.h"
@@ -57,11 +58,14 @@ int main(int argc, char *argv[]) {
error("Could not open input file");
}
- CCArchive cc(outputFile);
+ CCArchive cc(outputFile, kWrite);
writeVersion(cc);
writeConstants(cc);
writeMap(cc);
+ const char *darkName = argc > 2 ? argv[2] : "dark.cc";
+ writeCloudsData(cc, darkName);
+
cc.close();
return 0;
}
diff --git a/devtools/create_xeen/file.h b/devtools/create_xeen/file.h
index 7ea5acf..15091bc 100644
--- a/devtools/create_xeen/file.h
+++ b/devtools/create_xeen/file.h
@@ -118,8 +118,7 @@ public:
void writeString(const char *msg) {
if (!msg) {
writeByte(0);
- }
- else {
+ } else {
do {
writeByte(*msg);
} while (*msg++);
@@ -179,6 +178,9 @@ public:
MemFile() : _size(0), _offset(0) {
memset(_data, 0, MAX_MEM_SIZE);
}
+ MemFile(const byte *data, size_t size) : _size(size), _offset(0) {
+ memcpy(_data, data, size);
+ }
virtual ~MemFile() {}
bool open() {
diff --git a/devtools/create_xeen/module.mk b/devtools/create_xeen/module.mk
index e325d6e..29f2f30 100644
--- a/devtools/create_xeen/module.mk
+++ b/devtools/create_xeen/module.mk
@@ -3,6 +3,7 @@ MODULE := devtools/create_xeen
MODULE_OBJS := \
create_xeen.o \
cc.o \
+ clouds.o \
constants.o \
hashmap.o \
map.o \
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index abe91e5..2200d14 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -655,9 +655,9 @@ void Map::load(int mapId) {
_monsterData.load("dark.mon");
_wallPicSprites.load("darkpic.dat");
} else if (_vm->getGameID() == GType_Clouds) {
- _animationInfo.load("clouds.dat");
- _monsterData.load("xeen.mon");
- _wallPicSprites.load("xeenpic.dat");
+ _animationInfo.load("animinfo.cld");
+ _monsterData.load("monsters.cld");
+ _wallPicSprites.load("wallpics.cld");
} else if (_vm->getGameID() == GType_WorldOfXeen) {
files.setGameCc(1);
@@ -747,15 +747,19 @@ void Map::load(int mapId) {
if (!textLoaded) {
textLoaded = true;
- Common::String txtName = Common::String::format("%s%c%03d.txt",
- isDarkCc ? "dark" : "xeen", mapId >= 100 ? 'x' : '0', mapId);
- File fText(txtName, 1);
- char mazeName[33];
- fText.read(mazeName, 33);
- mazeName[32] = '\0';
-
- _mazeName = Common::String(mazeName);
- fText.close();
+ if (g_vm->getGameID() == GType_Clouds) {
+ _mazeName = Res._cloudsMapNames[mapId];
+ } else {
+ Common::String txtName = Common::String::format("%s%c%03d.txt",
+ isDarkCc ? "dark" : "xeen", mapId >= 100 ? 'x' : '0', mapId);
+ File fText(txtName, 1);
+ char mazeName[33];
+ fText.read(mazeName, 33);
+ mazeName[32] = '\0';
+
+ _mazeName = Common::String(mazeName);
+ fText.close();
+ }
// Load the monster/object data
Common::String mobName = Common::String::format("maze%c%03d.mob",
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 632cf3d..bed8a1a 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -36,11 +36,18 @@ Resources::Resources() {
_globalSprites.load("global.icn");
- File f("mae.xen");
+ File f((g_vm->getGameID() == GType_Clouds) ? "mae.cld" : "mae.xen");
while (f.pos() < f.size())
_maeNames.push_back(f.readString());
f.close();
+ if (g_vm->getGameID() == GType_Clouds) {
+ f.open("mapnames.cld");
+ while (f.pos() < f.size())
+ _cloudsMapNames.push_back(f.readString());
+ f.close();
+ }
+
// Set up items array to map to the names of items in each category
ITEM_NAMES[CATEGORY_WEAPON] = &WEAPON_NAMES[0];
ITEM_NAMES[CATEGORY_ARMOR] = &ARMOR_NAMES[0];
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 8cdeaf4..2761f40 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -110,7 +110,8 @@ private:
void loadData();
public:
SpriteResource _globalSprites;
- Common::StringArray _maeNames; // Magic and equipment names
+ Common::StringArray _maeNames; // Magic and equipment names
+ Common::StringArray _cloudsMapNames; // Clouds of Xeen map names
const char **ITEM_NAMES[4];
// Data loaded from xeen.ccs
diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp
index 53303c3..72140a2 100644
--- a/engines/xeen/spells.cpp
+++ b/engines/xeen/spells.cpp
@@ -36,7 +36,7 @@ Spells::Spells(XeenEngine *vm) : _vm(vm) {
}
void Spells::load() {
- File f1("spells.xen", 1);
+ File f1((g_vm->getGameID() == GType_Clouds) ? "spells.cld" : "spells.xen", 1);
while (f1.pos() < f1.size())
_spellNames.push_back(f1.readString());
f1.close();
diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp
index 39fc773..9acf2c5 100644
--- a/engines/xeen/xeen.cpp
+++ b/engines/xeen/xeen.cpp
@@ -167,8 +167,7 @@ void XeenEngine::play() {
_screen->loadBackground("back.raw");
_screen->loadPalette("mm4.pal");
- if (getGameID() != GType_WorldOfXeen && getGameID() != GType_Swords
- && !_map->_loadDarkSide) {
+ if (getGameID() == GType_DarkSide && !_map->_loadDarkSide) {
_map->_loadDarkSide = true;
_party->_mazeId = 29;
_party->_mazeDirection = DIR_NORTH;
More information about the Scummvm-git-logs
mailing list