Initial commit
This commit is contained in:
109
devtools/create_mm/create_xeen/cc.cpp
Normal file
109
devtools/create_mm/create_xeen/cc.cpp
Normal file
@@ -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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Disable symbol overrides so that we can use system headers.
|
||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||
|
||||
#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::loadIndex() {
|
||||
int count = _file.readUint16LE();
|
||||
long size = count * 8;
|
||||
|
||||
// Read in the data for the archive's index
|
||||
byte *rawIndex = new byte[size];
|
||||
|
||||
if (_file.read(rawIndex, size) != size) {
|
||||
delete[] rawIndex;
|
||||
error("Failed to read %ld bytes from CC archive", size);
|
||||
}
|
||||
|
||||
// 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::close() {
|
||||
}
|
||||
|
||||
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) {
|
||||
if (_file.seek(entry._offset) != 0)
|
||||
error("Failed to seek to %d for CC archive", entry._offset);
|
||||
|
||||
if (_file.read(entry._data, entry._size) != entry._size)
|
||||
error("Failed to read %hu bytes from CC archive", 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());
|
||||
}
|
||||
82
devtools/create_mm/create_xeen/cc.h
Normal file
82
devtools/create_mm/create_xeen/cc.h
Normal file
@@ -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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CC_H
|
||||
#define CC_H
|
||||
|
||||
#include "file.h"
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/str.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);
|
||||
|
||||
/**
|
||||
* Loads an index from the file
|
||||
*/
|
||||
void loadIndex();
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CCArchive(Common::File &file) : _file(file) {
|
||||
loadIndex();
|
||||
}
|
||||
|
||||
~CCArchive() {
|
||||
_file.close();
|
||||
}
|
||||
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Gets a member
|
||||
*/
|
||||
Common::MemFile getMember(const Common::String &name);
|
||||
};
|
||||
|
||||
#endif
|
||||
84
devtools/create_mm/create_xeen/clouds.cpp
Normal file
84
devtools/create_mm/create_xeen/clouds.cpp
Normal file
@@ -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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Disable symbol overrides so that we can use system headers.
|
||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||
|
||||
#include "clouds.h"
|
||||
#include "cc.h"
|
||||
#include "file.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(const char *darkName) {
|
||||
Common::File darkFile;
|
||||
if (darkFile.open(darkName, Common::kFileReadMode)) {
|
||||
CCArchive darkCc(darkFile);
|
||||
|
||||
Common::MemFile mae = darkCc.getMember("mae.xen");
|
||||
Common::MemFile spells = darkCc.getMember("spells.xen");
|
||||
Common::MemFile animInfo = darkCc.getMember("clouds.dat");
|
||||
Common::MemFile monsters = darkCc.getMember("xeen.mon");
|
||||
Common::MemFile wallPics = darkCc.getMember("xeenpic.dat");
|
||||
Common::MemFile mirror = darkCc.getMember("xeenmirr.txt");
|
||||
|
||||
Common::File::write("mae.cld", mae);
|
||||
Common::File::write("spells.cld", spells);
|
||||
Common::File::write("animinfo.cld", animInfo);
|
||||
Common::File::write("monsters.cld", monsters);
|
||||
Common::File::write("wallpics.cld", wallPics);
|
||||
Common::File::write("xeenmirr.txt", mirror);
|
||||
|
||||
Common::MemFile mapNames;
|
||||
for (int idx = 0; idx < 86; ++idx)
|
||||
mapNames.syncString(MAP_NAMES[idx]);
|
||||
Common::File::write("mapnames.cld", mapNames);
|
||||
|
||||
darkFile.close();
|
||||
} else {
|
||||
error("Could not find %s to get Clouds data", darkName);
|
||||
}
|
||||
}
|
||||
27
devtools/create_mm/create_xeen/clouds.h
Normal file
27
devtools/create_mm/create_xeen/clouds.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CLOUDS_H
|
||||
#define CLOUDS_H
|
||||
|
||||
extern void writeCloudsData(const char *darkName);
|
||||
|
||||
#endif
|
||||
1302
devtools/create_mm/create_xeen/constants.cpp
Normal file
1302
devtools/create_mm/create_xeen/constants.cpp
Normal file
File diff suppressed because it is too large
Load Diff
623
devtools/create_mm/create_xeen/constants.h
Normal file
623
devtools/create_mm/create_xeen/constants.h
Normal file
@@ -0,0 +1,623 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "cc.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
|
||||
};
|
||||
|
||||
class LangConstants {
|
||||
public:
|
||||
static const char *const TERRAIN_TYPES[6];
|
||||
static const char *const OUTDOORS_WALL_TYPES[16];
|
||||
static const char *const SURFACE_NAMES[16];
|
||||
static const byte SYMBOLS[20][64];
|
||||
static const byte TEXT_COLORS[40][4];
|
||||
static const byte TEXT_COLORS_STARTUP[40][4];
|
||||
static const int RACE_HP_BONUSES[5];
|
||||
static const int RACE_SP_BONUSES[5][2];
|
||||
static const int CLASS_EXP_LEVELS[10];
|
||||
static const int CONDITION_COLORS[17];
|
||||
static const int FACE_CONDITION_FRAMES[17];
|
||||
static const int CHAR_FACES_X[6];
|
||||
static const int HP_BARS_X[6];
|
||||
static const byte DARKNESS_XLAT[3][256];
|
||||
static const int SCREEN_POSITIONING_X[4][48];
|
||||
static const int 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 int 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 int 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[22];
|
||||
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 int TAVERN_EXIT_LIST[2][6][5][2];
|
||||
static const int MISC_SPELL_INDEX[74];
|
||||
static const int SPELL_COSTS[77];
|
||||
static const int DARK_SPELL_RANGES[12][2];
|
||||
static const int SWORDS_SPELL_RANGES[12][2];
|
||||
static const int CLOUDS_GUILD_SPELLS[5][20];
|
||||
static const int DARK_SPELL_OFFSETS[3][39];
|
||||
static const int SPELL_GEM_COST[77];
|
||||
static const int BLACKSMITH_MAP_IDS[2][4];
|
||||
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 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 int TOWN_MAP_NUMBERS[3][5];
|
||||
static const char *const EVENT_SAMPLES[6];
|
||||
static const char *const MUSIC_FILES1[5];
|
||||
static const char *const MUSIC_FILES2[6][7];
|
||||
|
||||
virtual ~LangConstants() {}
|
||||
virtual const char *CLOUDS_CREDITS() = 0;
|
||||
virtual const char *DARK_SIDE_CREDITS() = 0;
|
||||
virtual const char *SWORDS_CREDITS1() = 0;
|
||||
virtual const char *SWORDS_CREDITS2() = 0;
|
||||
virtual const char *OPTIONS_MENU() = 0;
|
||||
virtual const char **GAME_NAMES() = 0;
|
||||
virtual const char *THE_PARTY_NEEDS_REST() = 0;
|
||||
virtual const char *WHO_WILL() = 0;
|
||||
virtual const char *HOW_MUCH() = 0;
|
||||
virtual const char *WHATS_THE_PASSWORD() = 0;
|
||||
virtual const char *PASSWORD_INCORRECT() = 0;
|
||||
virtual const char *IN_NO_CONDITION() = 0;
|
||||
virtual const char *NOTHING_HERE() = 0;
|
||||
virtual const char **WHO_ACTIONS() = 0;
|
||||
virtual const char **WHO_WILL_ACTIONS() = 0;
|
||||
virtual const char **DIRECTION_TEXT_UPPER() = 0;
|
||||
virtual const char **DIRECTION_TEXT() = 0;
|
||||
virtual const char **RACE_NAMES() = 0;
|
||||
virtual const char **ALIGNMENT_NAMES() = 0;
|
||||
virtual const char **SEX_NAMES() = 0;
|
||||
virtual const char **SKILL_NAMES() = 0;
|
||||
virtual const char **CLASS_NAMES() = 0;
|
||||
virtual const char **CONDITION_NAMES_M() = 0;
|
||||
virtual const char **CONDITION_NAMES_F() = 0;
|
||||
virtual const char *GOOD() = 0;
|
||||
virtual const char *BLESSED() = 0;
|
||||
virtual const char *POWER_SHIELD() = 0;
|
||||
virtual const char *HOLY_BONUS() = 0;
|
||||
virtual const char *HEROISM() = 0;
|
||||
virtual const char *IN_PARTY() = 0;
|
||||
virtual const char *PARTY_DETAILS() = 0;
|
||||
virtual const char *PARTY_DIALOG_TEXT() = 0;
|
||||
virtual const char *NO_ONE_TO_ADVENTURE_WITH() = 0;
|
||||
virtual const char *YOUR_ROSTER_IS_FULL() = 0;
|
||||
virtual const char *PLEASE_WAIT() = 0;
|
||||
virtual const char *OOPS() = 0;
|
||||
virtual const char *BANK_TEXT() = 0;
|
||||
virtual const char *BLACKSMITH_TEXT() = 0;
|
||||
virtual const char *GUILD_NOT_MEMBER_TEXT() = 0;
|
||||
virtual const char *GUILD_TEXT() = 0;
|
||||
virtual const char *TAVERN_TEXT() = 0;
|
||||
virtual const char *FOOD_AND_DRINK() = 0;
|
||||
virtual const char *GOOD_STUFF() = 0;
|
||||
virtual const char *HAVE_A_DRINK() = 0;
|
||||
virtual const char *YOURE_DRUNK() = 0;
|
||||
virtual const char *TEMPLE_TEXT() = 0;
|
||||
virtual const char *EXPERIENCE_FOR_LEVEL() = 0;
|
||||
virtual const char *TRAINING_LEARNED_ALL() = 0;
|
||||
virtual const char *ELIGIBLE_FOR_LEVEL() = 0;
|
||||
virtual const char *TRAINING_TEXT() = 0;
|
||||
virtual const char *GOLD_GEMS() = 0;
|
||||
virtual const char *GOLD_GEMS_2() = 0;
|
||||
virtual const char **DEPOSIT_WITHDRAWL() = 0;
|
||||
virtual const char *NOT_ENOUGH_X_IN_THE_Y() = 0;
|
||||
virtual const char *NO_X_IN_THE_Y() = 0;
|
||||
virtual const char **STAT_NAMES() = 0;
|
||||
virtual const char **CONSUMABLE_NAMES() = 0;
|
||||
virtual const char **CONSUMABLE_GOLD_FORMS() = 0;
|
||||
virtual const char **CONSUMABLE_GEM_FORMS() = 0;
|
||||
virtual const char **WHERE_NAMES() = 0;
|
||||
virtual const char *AMOUNT() = 0;
|
||||
virtual const char *FOOD_PACKS_FULL() = 0;
|
||||
virtual const char *BUY_SPELLS() = 0;
|
||||
virtual const char *GUILD_OPTIONS() = 0;
|
||||
virtual const char *NOT_A_SPELL_CASTER() = 0;
|
||||
virtual const char *SPELLS_LEARNED_ALL() = 0;
|
||||
virtual const char *SPELLS_FOR() = 0;
|
||||
virtual const char *SPELL_LINES_0_TO_9() = 0;
|
||||
virtual const char *SPELLS_DIALOG_SPELLS() = 0;
|
||||
virtual const char *SPELL_PTS() = 0;
|
||||
virtual const char *GOLD() = 0;
|
||||
virtual const char *SPELL_INFO() = 0;
|
||||
virtual const char *SPELL_PURCHASE() = 0;
|
||||
virtual const char *MAP_TEXT() = 0;
|
||||
virtual const char *LIGHT_COUNT_TEXT() = 0;
|
||||
virtual const char *FIRE_RESISTENCE_TEXT() = 0;
|
||||
virtual const char *ELECRICITY_RESISTENCE_TEXT() = 0;
|
||||
virtual const char *COLD_RESISTENCE_TEXT() = 0;
|
||||
virtual const char *POISON_RESISTENCE_TEXT() = 0;
|
||||
virtual const char *CLAIRVOYANCE_TEXT() = 0;
|
||||
virtual const char *LEVITATE_TEXT() = 0;
|
||||
virtual const char *WALK_ON_WATER_TEXT() = 0;
|
||||
virtual const char *GAME_INFORMATION() = 0;
|
||||
virtual const char *WORLD_GAME_TEXT() = 0;
|
||||
virtual const char *DARKSIDE_GAME_TEXT() = 0;
|
||||
virtual const char *CLOUDS_GAME_TEXT() = 0;
|
||||
virtual const char *SWORDS_GAME_TEXT() = 0;
|
||||
virtual const char **WEEK_DAY_STRINGS() = 0;
|
||||
virtual const char *CHARACTER_DETAILS() = 0;
|
||||
virtual const char **DAYS() = 0;
|
||||
virtual const char *PARTY_GOLD() = 0;
|
||||
virtual const char *PLUS_14() = 0;
|
||||
virtual const char *CHARACTER_TEMPLATE() = 0;
|
||||
virtual const char *EXCHANGING_IN_COMBAT() = 0;
|
||||
virtual const char *CURRENT_MAXIMUM_RATING_TEXT() = 0;
|
||||
virtual const char *CURRENT_MAXIMUM_TEXT() = 0;
|
||||
virtual const char **RATING_TEXT() = 0;
|
||||
virtual const char **BORN() = 0;
|
||||
virtual const char *AGE_TEXT() = 0;
|
||||
virtual const char *LEVEL_TEXT() = 0;
|
||||
virtual const char *RESISTENCES_TEXT() = 0;
|
||||
virtual const char *NONE() = 0;
|
||||
virtual const char *EXPERIENCE_TEXT() = 0;
|
||||
virtual const char *ELIGIBLE() = 0;
|
||||
virtual const char *IN_PARTY_IN_BANK() = 0;
|
||||
virtual const char **FOOD_ON_HAND() = 0;
|
||||
virtual const char *FOOD_TEXT() = 0;
|
||||
virtual const char *EXCHANGE_WITH_WHOM() = 0;
|
||||
virtual const char *QUICK_REF_LINE() = 0;
|
||||
virtual const char *QUICK_REFERENCE() = 0;
|
||||
virtual const char *ITEMS_DIALOG_TEXT1() = 0;
|
||||
virtual const char *ITEMS_DIALOG_TEXT2() = 0;
|
||||
virtual const char *ITEMS_DIALOG_LINE1() = 0;
|
||||
virtual const char *ITEMS_DIALOG_LINE2() = 0;
|
||||
virtual const char *BTN_BUY() = 0;
|
||||
virtual const char *BTN_SELL() = 0;
|
||||
virtual const char *BTN_IDENTIFY() = 0;
|
||||
virtual const char *BTN_FIX() = 0;
|
||||
virtual const char *BTN_USE() = 0;
|
||||
virtual const char *BTN_EQUIP() = 0;
|
||||
virtual const char *BTN_REMOVE() = 0;
|
||||
virtual const char *BTN_DISCARD() = 0;
|
||||
virtual const char *BTN_QUEST() = 0;
|
||||
virtual const char *BTN_ENCHANT() = 0;
|
||||
virtual const char *BTN_RECHARGE() = 0;
|
||||
virtual const char *BTN_GOLD() = 0;
|
||||
virtual const char *ITEM_BROKEN() = 0;
|
||||
virtual const char *ITEM_CURSED() = 0;
|
||||
virtual const char *ITEM_OF() = 0;
|
||||
virtual const char **BONUS_NAMES() = 0;
|
||||
virtual const char **WEAPON_NAMES() = 0;
|
||||
virtual const char **ARMOR_NAMES() = 0;
|
||||
virtual const char **ACCESSORY_NAMES() = 0;
|
||||
virtual const char **MISC_NAMES() = 0;
|
||||
virtual const char **SPECIAL_NAMES() = 0;
|
||||
virtual const char **ELEMENTAL_NAMES() = 0;
|
||||
virtual const char **ATTRIBUTE_NAMES() = 0;
|
||||
virtual const char **EFFECTIVENESS_NAMES() = 0;
|
||||
virtual const char **QUEST_ITEM_NAMES() = 0;
|
||||
virtual const char **QUEST_ITEM_NAMES_SWORDS() = 0;
|
||||
virtual const char *NOT_PROFICIENT() = 0;
|
||||
virtual const char *NO_ITEMS_AVAILABLE() = 0;
|
||||
virtual const char **CATEGORY_NAMES() = 0;
|
||||
virtual const char *X_FOR_THE_Y() = 0;
|
||||
virtual const char *X_FOR_Y() = 0;
|
||||
virtual const char *X_FOR_Y_GOLD() = 0;
|
||||
virtual const char *FMT_CHARGES() = 0;
|
||||
virtual const char *AVAILABLE_GOLD_COST() = 0;
|
||||
virtual const char *CHARGES() = 0;
|
||||
virtual const char *COST() = 0;
|
||||
virtual const char **ITEM_ACTIONS() = 0;
|
||||
virtual const char *WHICH_ITEM() = 0;
|
||||
virtual const char *WHATS_YOUR_HURRY() = 0;
|
||||
virtual const char *USE_ITEM_IN_COMBAT() = 0;
|
||||
virtual const char *NO_SPECIAL_ABILITIES() = 0;
|
||||
virtual const char *CANT_CAST_WHILE_ENGAGED() = 0;
|
||||
virtual const char *EQUIPPED_ALL_YOU_CAN() = 0;
|
||||
virtual const char *REMOVE_X_TO_EQUIP_Y() = 0;
|
||||
virtual const char *RING() = 0;
|
||||
virtual const char *MEDAL() = 0;
|
||||
virtual const char *CANNOT_REMOVE_CURSED_ITEM() = 0;
|
||||
virtual const char *CANNOT_DISCARD_CURSED_ITEM() = 0;
|
||||
virtual const char *PERMANENTLY_DISCARD() = 0;
|
||||
virtual const char *BACKPACK_IS_FULL() = 0;
|
||||
virtual const char **CATEGORY_BACKPACK_IS_FULL() = 0;
|
||||
virtual const char *BUY_X_FOR_Y_GOLD() = 0;
|
||||
virtual const char *SELL_X_FOR_Y_GOLD() = 0;
|
||||
virtual const char **GOLDS() = 0;
|
||||
virtual const char *NO_NEED_OF_THIS() = 0;
|
||||
virtual const char *NOT_RECHARGABLE() = 0;
|
||||
virtual const char *NOT_ENCHANTABLE() = 0;
|
||||
virtual const char *SPELL_FAILED() = 0;
|
||||
virtual const char *ITEM_NOT_BROKEN() = 0;
|
||||
virtual const char **FIX_IDENTIFY() = 0;
|
||||
virtual const char *FIX_IDENTIFY_GOLD() = 0;
|
||||
virtual const char *IDENTIFY_ITEM_MSG() = 0;
|
||||
virtual const char *ITEM_DETAILS() = 0;
|
||||
virtual const char *ALL() = 0;
|
||||
virtual const char *FIELD_NONE() = 0;
|
||||
virtual const char *DAMAGE_X_TO_Y() = 0;
|
||||
virtual const char *ELEMENTAL_XY_DAMAGE() = 0;
|
||||
virtual const char *ATTR_XY_BONUS() = 0;
|
||||
virtual const char *EFFECTIVE_AGAINST() = 0;
|
||||
virtual const char *QUESTS_DIALOG_TEXT() = 0;
|
||||
virtual const char *CLOUDS_OF_XEEN_LINE() = 0;
|
||||
virtual const char *DARKSIDE_OF_XEEN_LINE() = 0;
|
||||
virtual const char *SWORDS_OF_XEEN_LINE() = 0;
|
||||
virtual const char *NO_QUEST_ITEMS() = 0;
|
||||
virtual const char *NO_CURRENT_QUESTS() = 0;
|
||||
virtual const char *NO_AUTO_NOTES() = 0;
|
||||
virtual const char *QUEST_ITEMS_DATA() = 0;
|
||||
virtual const char *CURRENT_QUESTS_DATA() = 0;
|
||||
virtual const char *AUTO_NOTES_DATA() = 0;
|
||||
virtual const char *REST_COMPLETE() = 0;
|
||||
virtual const char *PARTY_IS_STARVING() = 0;
|
||||
virtual const char *HIT_SPELL_POINTS_RESTORED() = 0;
|
||||
virtual const char *TOO_DANGEROUS_TO_REST() = 0;
|
||||
virtual const char *SOME_CHARS_MAY_DIE() = 0;
|
||||
virtual const char *DISMISS_WHOM() = 0;
|
||||
virtual const char *CANT_DISMISS_LAST_CHAR() = 0;
|
||||
virtual const char *DELETE_CHAR_WITH_ELDER_WEAPON() = 0;
|
||||
virtual const char **REMOVE_DELETE() = 0;
|
||||
virtual const char *REMOVE_OR_DELETE_WHICH() = 0;
|
||||
virtual const char *YOUR_PARTY_IS_FULL() = 0;
|
||||
virtual const char *HAS_SLAYER_SWORD() = 0;
|
||||
virtual const char *SURE_TO_DELETE_CHAR() = 0;
|
||||
virtual const char *CREATE_CHAR_DETAILS() = 0;
|
||||
virtual const char *NEW_CHAR_STATS() = 0;
|
||||
virtual const char *NAME_FOR_NEW_CHARACTER() = 0;
|
||||
virtual const char *SELECT_CLASS_BEFORE_SAVING() = 0;
|
||||
virtual const char *EXCHANGE_ATTR_WITH() = 0;
|
||||
virtual const int *NEW_CHAR_SKILLS_OFFSET() = 0;
|
||||
virtual const char *COMBAT_DETAILS() = 0;
|
||||
virtual const char *NOT_ENOUGH_TO_CAST() = 0;
|
||||
virtual const char **SPELL_CAST_COMPONENTS() = 0;
|
||||
virtual const char *CAST_SPELL_DETAILS() = 0;
|
||||
virtual const char *PARTY_FOUND() = 0;
|
||||
virtual const char *BACKPACKS_FULL_PRESS_KEY() = 0;
|
||||
virtual const char *HIT_A_KEY() = 0;
|
||||
virtual const char *GIVE_TREASURE_FORMATTING() = 0;
|
||||
virtual const char **FOUND() = 0;
|
||||
virtual const char *X_FOUND_Y() = 0;
|
||||
virtual const char *ON_WHO() = 0;
|
||||
virtual const char *WHICH_ELEMENT1() = 0;
|
||||
virtual const char *WHICH_ELEMENT2() = 0;
|
||||
virtual const char *DETECT_MONSTERS() = 0;
|
||||
virtual const char *LLOYDS_BEACON() = 0;
|
||||
virtual const char *HOW_MANY_SQUARES() = 0;
|
||||
virtual const char *TOWN_PORTAL() = 0;
|
||||
virtual const char *TOWN_PORTAL_SWORDS() = 0;
|
||||
virtual const char *MONSTER_DETAILS() = 0;
|
||||
virtual const char **MONSTER_SPECIAL_ATTACKS() = 0;
|
||||
virtual const char *IDENTIFY_MONSTERS() = 0;
|
||||
virtual const char *MOONS_NOT_ALIGNED() = 0;
|
||||
virtual const char *AWARDS_FOR() = 0;
|
||||
virtual const char *AWARDS_TEXT() = 0;
|
||||
virtual const char *NO_AWARDS() = 0;
|
||||
virtual const char *WARZONE_BATTLE_MASTER() = 0;
|
||||
virtual const char *WARZONE_MAXED() = 0;
|
||||
virtual const char *WARZONE_LEVEL() = 0;
|
||||
virtual const char *WARZONE_HOW_MANY() = 0;
|
||||
virtual const char *PICKS_THE_LOCK() = 0;
|
||||
virtual const char **PICK_FORM() = 0;
|
||||
virtual const char *UNABLE_TO_PICK_LOCK() = 0;
|
||||
virtual const char **UNABLE_TO_PICK_FORM() = 0;
|
||||
virtual const char *CONTROL_PANEL_TEXT() = 0;
|
||||
virtual const char *CONTROL_PANEL_BUTTONS() = 0;
|
||||
virtual const char *ON() = 0;
|
||||
virtual const char *OFF() = 0;
|
||||
virtual const char *CONFIRM_QUIT() = 0;
|
||||
virtual const char *MR_WIZARD() = 0;
|
||||
virtual const char *NO_LOADING_IN_COMBAT() = 0;
|
||||
virtual const char *NO_SAVING_IN_COMBAT() = 0;
|
||||
virtual const char *QUICK_FIGHT_TEXT() = 0;
|
||||
virtual const char **QUICK_FIGHT_OPTIONS() = 0;
|
||||
virtual const char **WORLD_END_TEXT() = 0;
|
||||
virtual const char *WORLD_CONGRATULATIONS() = 0;
|
||||
virtual const char *WORLD_CONGRATULATIONS2() = 0;
|
||||
virtual const char *CLOUDS_CONGRATULATIONS1() = 0;
|
||||
virtual const char *CLOUDS_CONGRATULATIONS2() = 0;
|
||||
virtual const char **GOOBER() = 0;
|
||||
virtual const char *DIFFICULTY_TEXT() = 0;
|
||||
virtual const char *SAVE_OFF_LIMITS() = 0;
|
||||
virtual const char *CLOUDS_INTRO1() = 0;
|
||||
virtual const char *DARKSIDE_ENDING1() = 0;
|
||||
virtual const char *DARKSIDE_ENDING2() = 0;
|
||||
virtual const char *PHAROAH_ENDING_TEXT1() = 0;
|
||||
virtual const char *PHAROAH_ENDING_TEXT2() = 0;
|
||||
virtual const char **CLOUDS_MAE_NAMES() = 0;
|
||||
virtual const char **CLOUDS_MIRROR_LOCATIONS() = 0;
|
||||
virtual const char **CLOUDS_MAP_NAMES() = 0;
|
||||
virtual const char **CLOUDS_MONSTERS() = 0;
|
||||
virtual const char **CLOUDS_SPELLS() = 0;
|
||||
|
||||
void writeConstants(Common::String num);
|
||||
|
||||
class KeyConstants {
|
||||
public:
|
||||
class DialogsCharInfo {
|
||||
public:
|
||||
virtual int KEY_ITEM() = 0;
|
||||
virtual int KEY_QUICK() = 0;
|
||||
virtual int KEY_EXCHANGE() = 0;
|
||||
virtual ~DialogsCharInfo() {}
|
||||
};
|
||||
virtual DialogsCharInfo *dialogsCharInfo() = 0;
|
||||
|
||||
class DialogsControlPanel {
|
||||
public:
|
||||
virtual int KEY_FXON() = 0;
|
||||
virtual int KEY_MUSICON() = 0;
|
||||
virtual int KEY_LOAD() = 0;
|
||||
virtual int KEY_SAVE() = 0;
|
||||
virtual int KEY_QUIT() = 0;
|
||||
virtual int KEY_MRWIZARD() = 0;
|
||||
virtual ~DialogsControlPanel() {}
|
||||
};
|
||||
virtual DialogsControlPanel *dialogsControlPanel() = 0;
|
||||
|
||||
class DialogsCreateChar {
|
||||
public:
|
||||
virtual int KEY_ROLL() = 0;
|
||||
virtual int KEY_CREATE() = 0;
|
||||
virtual int KEY_MGT() = 0;
|
||||
virtual int KEY_INT() = 0;
|
||||
virtual int KEY_PER() = 0;
|
||||
virtual int KEY_END() = 0;
|
||||
virtual int KEY_SPD() = 0;
|
||||
virtual int KEY_ACY() = 0;
|
||||
virtual int KEY_LCK() = 0;
|
||||
virtual ~DialogsCreateChar() {}
|
||||
};
|
||||
virtual DialogsCreateChar *dialogsCreateChar() = 0;
|
||||
|
||||
class DialogsDifficulty {
|
||||
public:
|
||||
virtual int KEY_ADVENTURER() = 0;
|
||||
virtual int KEY_WARRIOR() = 0;
|
||||
virtual ~DialogsDifficulty() {}
|
||||
};
|
||||
virtual DialogsDifficulty *dialogsDifficulty() = 0;
|
||||
|
||||
class DialogsItems {
|
||||
public:
|
||||
virtual int KEY_WEAPONS() = 0;
|
||||
virtual int KEY_ARMOR() = 0;
|
||||
virtual int KEY_ACCESSORY() = 0;
|
||||
virtual int KEY_MISC() = 0;
|
||||
virtual int KEY_ENCHANT() = 0;
|
||||
virtual int KEY_USE() = 0;
|
||||
virtual int KEY_BUY() = 0;
|
||||
virtual int KEY_SELL() = 0;
|
||||
virtual int KEY_IDENTIFY() = 0;
|
||||
virtual int KEY_FIX() = 0;
|
||||
virtual int KEY_EQUIP() = 0;
|
||||
virtual int KEY_REM() = 0;
|
||||
virtual int KEY_DISC() = 0;
|
||||
virtual int KEY_QUEST() = 0;
|
||||
virtual int KEY_RECHRG() = 0;
|
||||
virtual int KEY_GOLD() = 0;
|
||||
virtual ~DialogsItems() {}
|
||||
};
|
||||
virtual DialogsItems *dialogsItems() = 0;
|
||||
|
||||
class DialogsParty {
|
||||
public:
|
||||
virtual int KEY_DELETE() = 0;
|
||||
virtual int KEY_REMOVE() = 0;
|
||||
virtual int KEY_CREATE() = 0;
|
||||
virtual int KEY_EXIT() = 0;
|
||||
virtual ~DialogsParty() {}
|
||||
};
|
||||
virtual DialogsParty *dialogsParty() = 0;
|
||||
|
||||
class DialogsQuests {
|
||||
public:
|
||||
virtual int KEY_QUEST_ITEMS() = 0;
|
||||
virtual int KEY_CURRENT_QUESTS() = 0;
|
||||
virtual int KEY_AUTO_NOTES() = 0;
|
||||
virtual ~DialogsQuests() {}
|
||||
};
|
||||
virtual DialogsQuests *dialogsQuests() = 0;
|
||||
|
||||
class DialogsQuickFight {
|
||||
public:
|
||||
virtual int KEY_NEXT() = 0;
|
||||
virtual ~DialogsQuickFight() {}
|
||||
};
|
||||
virtual DialogsQuickFight *dialogsQuickFight() = 0;
|
||||
|
||||
class DialogsSpells {
|
||||
public:
|
||||
virtual int KEY_CAST() = 0;
|
||||
virtual int KEY_NEW() = 0;
|
||||
virtual int KEY_FIRE() = 0;
|
||||
virtual int KEY_ELEC() = 0;
|
||||
virtual int KEY_COLD() = 0;
|
||||
virtual int KEY_ACID() = 0;
|
||||
virtual int KEY_SET() = 0;
|
||||
virtual int KEY_RETURN() = 0;
|
||||
virtual ~DialogsSpells() {}
|
||||
};
|
||||
virtual DialogsSpells *dialogsSpells() = 0;
|
||||
|
||||
class Locations {
|
||||
public:
|
||||
virtual int KEY_DEP() = 0;
|
||||
virtual int KEY_WITH() = 0;
|
||||
virtual int KEY_GOLD() = 0;
|
||||
virtual int KEY_GEMS() = 0;
|
||||
virtual int KEY_BROWSE() = 0;
|
||||
virtual int KEY_BUY_SPELLS() = 0;
|
||||
virtual int KEY_SPELL_INFO() = 0;
|
||||
virtual int KEY_SIGN_IN() = 0;
|
||||
virtual int KEY_DRINK() = 0;
|
||||
virtual int KEY_FOOD() = 0;
|
||||
virtual int KEY_TIP() = 0;
|
||||
virtual int KEY_RUMORS() = 0;
|
||||
virtual int KEY_HEAL() = 0;
|
||||
virtual int KEY_DONATION() = 0;
|
||||
virtual int KEY_UNCURSE() = 0;
|
||||
virtual int KEY_TRAIN() = 0;
|
||||
virtual ~Locations() {}
|
||||
};
|
||||
virtual Locations *locations() = 0;
|
||||
|
||||
class CloudsOfXeenMenu {
|
||||
public:
|
||||
virtual int KEY_START_NEW_GAME() = 0;
|
||||
virtual int KEY_LOAD_GAME() = 0;
|
||||
virtual int KEY_SHOW_CREDITS() = 0;
|
||||
virtual int KEY_VIEW_ENDGAME() = 0;
|
||||
virtual ~CloudsOfXeenMenu() {}
|
||||
};
|
||||
virtual CloudsOfXeenMenu *cloudsOfXeenMenu() = 0;
|
||||
virtual ~KeyConstants() {}
|
||||
};
|
||||
virtual KeyConstants *keyConstants() = 0;
|
||||
};
|
||||
|
||||
extern void writeConstants();
|
||||
|
||||
#endif
|
||||
78
devtools/create_mm/create_xeen/create_xeen.cpp
Normal file
78
devtools/create_mm/create_xeen/create_xeen.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Disable symbol overrides so that we can use system headers.
|
||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cc.h"
|
||||
#include "file.h"
|
||||
#include "clouds.h"
|
||||
#include "swords.h"
|
||||
#include "constants.h"
|
||||
#include "map.h"
|
||||
|
||||
void NORETURN_PRE error(const char *s, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, s);
|
||||
vfprintf(stderr, s, ap);
|
||||
va_end(ap);
|
||||
|
||||
fputc('\n', stderr);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void writeVersion() {
|
||||
Common::File f;
|
||||
if (!f.open("version.txt", Common::kFileWriteMode))
|
||||
error("Could not create version.txt");
|
||||
|
||||
f.write("1.1\n", 4);
|
||||
f.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the different files in the xeen/ subfolder of
|
||||
* the files/ folder. The files folder overall is zipped
|
||||
* up to form the xeen data file
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 3) {
|
||||
error("Format: %s dark.cc \"swords xeen.dat\"", argv[0]);
|
||||
}
|
||||
|
||||
writeVersion();
|
||||
writeConstants();
|
||||
writeMap();
|
||||
|
||||
const char *darkName = argv[1];
|
||||
writeCloudsData(darkName);
|
||||
|
||||
const char *swordsDatName = argv[2];
|
||||
writeSwordsData(swordsDatName);
|
||||
|
||||
printf("File creation done");
|
||||
return 0;
|
||||
}
|
||||
2170
devtools/create_mm/create_xeen/de_constants.h
Normal file
2170
devtools/create_mm/create_xeen/de_constants.h
Normal file
File diff suppressed because it is too large
Load Diff
2173
devtools/create_mm/create_xeen/en_constants.h
Normal file
2173
devtools/create_mm/create_xeen/en_constants.h
Normal file
File diff suppressed because it is too large
Load Diff
303
devtools/create_mm/create_xeen/file.h
Normal file
303
devtools/create_mm/create_xeen/file.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __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 {
|
||||
|
||||
#define MAX_MEM_SIZE 65536
|
||||
#define BUFFER_SIZE 16384
|
||||
|
||||
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 writeShort(int8 v) {
|
||||
write(&v, sizeof(int8));
|
||||
}
|
||||
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 MemFile : public Stream {
|
||||
private:
|
||||
byte *_data;
|
||||
size_t _size, _offset;
|
||||
public:
|
||||
MemFile() : _size(0), _offset(0) {
|
||||
_data = new byte[MAX_MEM_SIZE];
|
||||
memset(_data, 0, MAX_MEM_SIZE);
|
||||
}
|
||||
MemFile(const byte *data, size_t size) : _size(size), _offset(0) {
|
||||
assert(size <= MAX_MEM_SIZE);
|
||||
_data = new byte[MAX_MEM_SIZE];
|
||||
memcpy(_data, data, size);
|
||||
memset(_data + size, 0, MAX_MEM_SIZE - size);
|
||||
}
|
||||
virtual ~MemFile() {
|
||||
delete[] _data;
|
||||
}
|
||||
|
||||
bool open() {
|
||||
memset(_data, 0, MAX_MEM_SIZE);
|
||||
_size = _offset = 0;
|
||||
return true;
|
||||
}
|
||||
void close() {
|
||||
}
|
||||
|
||||
virtual int seek(int offset, int whence = SEEK_SET) {
|
||||
switch (whence) {
|
||||
default:
|
||||
// fallthrough intended
|
||||
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 = MIN(len, _size - _offset);
|
||||
memcpy(buffer, &_data[_offset], len);
|
||||
_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);
|
||||
}
|
||||
};
|
||||
|
||||
class File : public Stream {
|
||||
private:
|
||||
::FILE *_f;
|
||||
public:
|
||||
File() : _f(nullptr) {}
|
||||
virtual ~File() { close(); }
|
||||
|
||||
bool open(const char *filename, AccessMode mode = kFileReadMode) {
|
||||
if (mode == kFileReadMode) {
|
||||
_f = fopen(filename, "rb");
|
||||
} else {
|
||||
char fname[256];
|
||||
sprintf(fname, "../files/xeen/%s", filename);
|
||||
_f = fopen(fname, "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;
|
||||
}
|
||||
|
||||
static void write(const char *fname, MemFile &src) {
|
||||
File f;
|
||||
if (!f.open(fname, kFileWriteMode)) {
|
||||
printf("Could not open %s for writing", fname);
|
||||
exit(1);
|
||||
}
|
||||
src.seek(0);
|
||||
char buffer[BUFFER_SIZE];
|
||||
size_t count = 0;
|
||||
|
||||
while ((count = src.read(buffer, BUFFER_SIZE)) != 0) {
|
||||
f.write(buffer, count);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Common
|
||||
|
||||
#endif
|
||||
85
devtools/create_mm/create_xeen/hash-str.h
Normal file
85
devtools/create_mm/create_xeen/hash-str.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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
|
||||
108
devtools/create_mm/create_xeen/hashmap.cpp
Normal file
108
devtools/create_mm/create_xeen/hashmap.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// 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
|
||||
626
devtools/create_mm/create_xeen/hashmap.h
Normal file
626
devtools/create_mm/create_xeen/hashmap.h
Normal file
@@ -0,0 +1,626 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// 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 Intel C++ Compiler has difficulties with nested templates.
|
||||
#if 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 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);
|
||||
|
||||
template<class T> friend class IteratorImpl;
|
||||
|
||||
/**
|
||||
* Simple HashMap iterator implementation.
|
||||
*/
|
||||
template<class NodeType>
|
||||
class IteratorImpl {
|
||||
friend class HashMap;
|
||||
#if 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() : _defaultVal() {
|
||||
_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 RELEASE_BUILD
|
||||
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++;
|
||||
}
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
// 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);
|
||||
#endif
|
||||
|
||||
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
|
||||
246
devtools/create_mm/create_xeen/map.cpp
Normal file
246
devtools/create_mm/create_xeen/map.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Disable symbol overrides so that we can use system headers.
|
||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||
|
||||
#include "file.h"
|
||||
#include "map.h"
|
||||
|
||||
#define MAP_WIDTH 16
|
||||
#define MAP_HEIGHT 16
|
||||
#define FLAG_IS_OUTDOORS 32768
|
||||
|
||||
#define MIRROR_COUNT 1
|
||||
static const MirrorEntry MIRROR_TEXT[MIRROR_COUNT] = {
|
||||
{ "scummvm", 255, 7, 1, 0 }
|
||||
};
|
||||
|
||||
static 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 }
|
||||
};
|
||||
|
||||
static const byte WALL_TYPES_255[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static 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
|
||||
*/
|
||||
static void writeMirrorText() {
|
||||
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);
|
||||
}
|
||||
|
||||
Common::File::write("xeenmirr.ext", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the maze
|
||||
*/
|
||||
static void writeMaze() {
|
||||
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
|
||||
|
||||
Common::File::write("mazex255.dat", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the maze name
|
||||
*/
|
||||
static void writeMazeName() {
|
||||
Common::MemFile f;
|
||||
char mazeName[33];
|
||||
memset(mazeName, 0, 33);
|
||||
strcpy(mazeName, "ScummVM");
|
||||
f.write(mazeName, 33);
|
||||
|
||||
Common::File::write("xeenx255.txt", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out maze events
|
||||
*/
|
||||
static void writeMazeEvents() {
|
||||
Common::MemFile f;
|
||||
|
||||
// Mirror events
|
||||
static 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
|
||||
static const byte BENCH1_EVENTS[32] = {
|
||||
10, 7, 8, 0, 0, 5, 1, 2, 3, 1, 2, // NPC
|
||||
14, 7, 8, 0, 1, 20, 34, 10000 % 256, 10000 / 256, 0, 0, 0, 0, 0, 0, // Give gold
|
||||
5, 7, 8, 0, 2, 18 // Exit
|
||||
};
|
||||
static const byte BENCH2_EVENTS[30] = {
|
||||
10, 8, 8, 0, 0, 5, 1, 3, 3, 1, 2, // NPC
|
||||
14, 8, 8, 0, 1, 20, 35, 1000 % 256, 1000 / 256, 0, 0, 0, 0, // Give gems
|
||||
5, 8, 8, 0, 2, 18 // Exit
|
||||
};
|
||||
f.write(BENCH1_EVENTS, 32);
|
||||
f.write(BENCH2_EVENTS, 30);
|
||||
|
||||
Common::File::write("mazex255.evt", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out maze event text
|
||||
*/
|
||||
static void writeMazeText() {
|
||||
Common::MemFile f;
|
||||
|
||||
f.writeString("Where to?");
|
||||
f.writeString("Isle of ScummVM");
|
||||
f.writeString("You have done well to find this ancient isle. This will aid you on your journey.");
|
||||
f.writeString("It is my hope that this isle will be but the first of many such new destinations the mirror may take you.");
|
||||
|
||||
Common::File::write("aazex255.txt", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the monster/object data
|
||||
*/
|
||||
static void writeMonstersObjects() {
|
||||
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.writeByte(0x80);
|
||||
f.writeByte(0x80);
|
||||
f.writeByte(0);
|
||||
f.writeShort(0);
|
||||
break;
|
||||
default:
|
||||
f.writeShort(-1);
|
||||
f.writeShort(-1);
|
||||
f.writeByte(0xff);
|
||||
f.writeShort(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Common::File::write("mazex255.mob", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the data for the head danger senses
|
||||
*/
|
||||
static void writeHeadData() {
|
||||
Common::MemFile f;
|
||||
f.writeByte(0, MAP_HEIGHT * MAP_HEIGHT * 2);
|
||||
Common::File::write("aazex255.hed", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the new ScummVM map
|
||||
*/
|
||||
void writeMap() {
|
||||
writeMirrorText();
|
||||
writeMaze();
|
||||
writeMazeName();
|
||||
writeMazeEvents();
|
||||
writeMazeText();
|
||||
writeMonstersObjects();
|
||||
writeHeadData();
|
||||
}
|
||||
37
devtools/create_mm/create_xeen/map.h
Normal file
37
devtools/create_mm/create_xeen/map.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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();
|
||||
|
||||
#endif
|
||||
181
devtools/create_mm/create_xeen/memorypool.cpp
Normal file
181
devtools/create_mm/create_xeen/memorypool.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "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 = nullptr;
|
||||
|
||||
_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 = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 != nullptr) {
|
||||
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
|
||||
161
devtools/create_mm/create_xeen/memorypool.h
Normal file
161
devtools/create_mm/create_xeen/memorypool.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef 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.
|
||||
* <https://isocpp.org/wiki/faq/dtors#memory-pools>
|
||||
*/
|
||||
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
|
||||
18
devtools/create_mm/create_xeen/module.mk
Normal file
18
devtools/create_mm/create_xeen/module.mk
Normal file
@@ -0,0 +1,18 @@
|
||||
MODULE := devtools/create_mm/create_xeen
|
||||
|
||||
MODULE_OBJS := \
|
||||
create_xeen.o \
|
||||
cc.o \
|
||||
clouds.o \
|
||||
constants.o \
|
||||
hashmap.o \
|
||||
map.o \
|
||||
memorypool.o \
|
||||
str.o \
|
||||
swords.o
|
||||
|
||||
# Set the name of the executable
|
||||
TOOL_EXECUTABLE := create_xeen
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
2625
devtools/create_mm/create_xeen/ru_constants.h
Normal file
2625
devtools/create_mm/create_xeen/ru_constants.h
Normal file
File diff suppressed because it is too large
Load Diff
3
devtools/create_mm/create_xeen/str.cpp
Normal file
3
devtools/create_mm/create_xeen/str.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#define SCUMMVM_UTIL
|
||||
#include "../../../common/str-base.cpp"
|
||||
#include "../../../common/str.cpp"
|
||||
385
devtools/create_mm/create_xeen/str.h
Normal file
385
devtools/create_mm/create_xeen/str.h
Normal file
@@ -0,0 +1,385 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_STRING_H
|
||||
#define COMMON_STRING_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/**
|
||||
* Simple string class for ScummVM. Provides automatic storage management,
|
||||
* 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:
|
||||
* https://man.openbsd.org/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:
|
||||
* https://man.openbsd.org/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
|
||||
53
devtools/create_mm/create_xeen/swords.cpp
Normal file
53
devtools/create_mm/create_xeen/swords.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Disable symbol overrides so that we can use system headers.
|
||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||
|
||||
#include "file.h"
|
||||
#include "swords.h"
|
||||
|
||||
#define MONSTERS_COUNT 151
|
||||
|
||||
extern void NORETURN_PRE error(const char *s, ...);
|
||||
|
||||
void writeSwordsData(const char *swordsDatName) {
|
||||
Common::File f;
|
||||
Common::MemFile monsters;
|
||||
const int size = MONSTERS_COUNT * 60;
|
||||
const int32 offset = 0x44200;
|
||||
byte buffer[size];
|
||||
|
||||
if (!f.open(swordsDatName, Common::kFileReadMode))
|
||||
error("Could not open '%s'", swordsDatName);
|
||||
|
||||
if (f.seek(offset) != 0)
|
||||
error("Failed to seek to 0x%x for '%s'", offset, swordsDatName);
|
||||
|
||||
if (f.read(buffer, size) != size)
|
||||
error("Failed to read %d bytes from '%s'", size, swordsDatName);
|
||||
|
||||
if (strcmp((const char *)buffer + 0x33, "Slime"))
|
||||
error("Invalid '%s'", swordsDatName);
|
||||
|
||||
monsters.write(buffer, size);
|
||||
Common::File::write("monsters.swd", monsters);
|
||||
}
|
||||
27
devtools/create_mm/create_xeen/swords.h
Normal file
27
devtools/create_mm/create_xeen/swords.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SWORDS_H
|
||||
#define SWORDS_H
|
||||
|
||||
extern void writeSwordsData(const char *swordsDatName);
|
||||
|
||||
#endif
|
||||
BIN
devtools/create_mm/files/mm1/font.bmp
Normal file
BIN
devtools/create_mm/files/mm1/font.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
BIN
devtools/create_mm/files/mm1/gfx/monpix.dta
Normal file
BIN
devtools/create_mm/files/mm1/gfx/monpix.dta
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen0
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen0
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen1
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen1
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen2
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen2
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen3
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen3
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen4
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen4
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen5
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen5
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen6
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen6
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen7
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen7
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen8
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen8
Normal file
Binary file not shown.
BIN
devtools/create_mm/files/mm1/gfx/screen9
Normal file
BIN
devtools/create_mm/files/mm1/gfx/screen9
Normal file
Binary file not shown.
1
devtools/create_mm/files/mm1/gfx/version.txt
Normal file
1
devtools/create_mm/files/mm1/gfx/version.txt
Normal file
@@ -0,0 +1 @@
|
||||
Might & Magic 1 - Graphics Overhaul Mod
|
||||
BIN
devtools/create_mm/files/mm1/gfx/wallpix.dta
Normal file
BIN
devtools/create_mm/files/mm1/gfx/wallpix.dta
Normal file
Binary file not shown.
256
devtools/create_mm/files/mm1/items.txt
Normal file
256
devtools/create_mm/files/mm1/items.txt
Normal file
@@ -0,0 +1,256 @@
|
||||
"Club ", 0, 0, 0, 0, 0, 0, 1, 3, 0
|
||||
"Dagger ", 4, 0, 0, 0, 0, 0, 5, 4, 0
|
||||
"Hand axe ", 6, 0, 0, 0, 0, 0, 10, 5, 0
|
||||
"Spear ", 7, 0, 0, 0, 0, 0, 15, 6, 0
|
||||
"Short sword ", 6, 0, 0, 0, 0, 0, 20, 6, 0
|
||||
"Mace ", 2, 0, 0, 0, 0, 0, 40, 6, 0
|
||||
"Flail ", 2, 0, 0, 0, 0, 0, 40, 7, 0
|
||||
"Scimitar ", 6, 0, 0, 0, 0, 0, 40, 7, 0
|
||||
"Broad sword ", 6, 0, 0, 0, 0, 0, 50, 7, 0
|
||||
"Battle axe ", 6, 0, 0, 0, 0, 0, 60, 0, 0
|
||||
"Long sword ", 6, 0, 0, 0, 0, 0, 60, 8, 0
|
||||
"Club +1 ", 0, 0, 0, 0, 0, 0, 30, 3, 1
|
||||
"Club +2 ", 0, 0, 0, 0, 0, 0, 100, 3, 2
|
||||
"Dagger +1 ", 4, 0, 0, 0, 0, 0, 50, 4, 1
|
||||
"Hand axe +1 ", 134, 33, 1, 0, 0, 0, 75, 5, 1
|
||||
"Spear +1 ", 71, 33, 1, 0, 0, 0, 100, 6, 1
|
||||
"Short sword +1", 6, 0, 0, 0, 0, 0, 100, 6, 1
|
||||
"Mace +1 ", 2, 0, 0, 0, 0, 0, 125, 6, 1
|
||||
"Flail +1 ", 2, 0, 0, 0, 0, 0, 200, 7, 1
|
||||
"Scimitar +1 ", 70, 33, 2, 0, 0, 0, 250, 7, 1
|
||||
"Broad sword +1", 134, 33, 2, 0, 0, 0, 300, 7, 1
|
||||
"Battle axe +1 ", 6, 0, 0, 0, 0, 0, 300, 8, 1
|
||||
"Long sword +1 ", 6, 0, 0, 0, 0, 0, 300, 8, 1
|
||||
"Flaming club ", 0, 90, 20, 255, 50, 30, 500, 3, 3
|
||||
"Club of Noise ", 0, 255, 0, 0, 0, 0, 100, 3, 0
|
||||
"Dagger +2 ", 4, 0, 0, 255, 52, 25, 200, 4, 2
|
||||
"Hand axe +2 ", 70, 33, 2, 0, 0, 0, 225, 5, 2
|
||||
"Spear +2 ", 135, 33, 2, 0, 0, 0, 250, 6, 2
|
||||
"Short sword +2", 6, 0, 0, 255, 48, 15, 300, 6, 2
|
||||
"Mace +2 ", 2, 25, 1, 255, 7, 10, 325, 6, 2
|
||||
"Flail +2 ", 2, 25, 1, 255, 3, 15, 350, 7, 2
|
||||
"Scimitar +2 ", 134, 23, 1, 0, 0, 0, 400, 7, 2
|
||||
"Broad sword +2", 70, 23, 1, 0, 0, 0, 400, 7, 2
|
||||
"Battle axe +2 ", 6, 90, 20, 24, 2, 10, 500, 8, 2
|
||||
"Long sword +2 ", 6, 96, 20, 24, 2, 10, 550, 8, 2
|
||||
"Royal dagger ", 196, 0, 0, 0, 0, 0, 2500, 4, 0
|
||||
"Dagger of Mind", 61, 21, 3, 255, 77, 20, 750, 4, 3
|
||||
"Diamond dagger", 61, 23, 4, 0, 0, 0, 800, 10, 4
|
||||
"Electric spear", 7, 94, 40, 255, 55, 16, 1200, 6, 3
|
||||
"Holy mace ", 123, 25, 3, 255, 38, 5, 2000, 6, 4
|
||||
"Un-holy mace ", 187, 25, 3, 255, 37, 5, 2000, 6, 4
|
||||
"Dark flail ", 131, 255, 0, 255, 33, 10, 600, 3, 0
|
||||
"Flail of fear ", 59, 98, 40, 255, 62, 8, 1600, 7, 3
|
||||
"Lucky scimitar", 6, 33, 5, 0, 0, 0, 2200, 7, 4
|
||||
"Mace of Undead", 67, 255, 0, 37, 10, 5, 500, 6, 0
|
||||
"Cold axe ", 15, 92, 40, 255, 72, 10, 2500, 8, 3
|
||||
"Electric sword", 7, 94, 40, 255, 66, 10, 2200, 8, 3
|
||||
"Flaming sword ", 7, 90, 50, 255, 63, 10, 2200, 8, 3
|
||||
"Sword of Might", 31, 23, 6, 24, 5, 30, 8000, 8, 5
|
||||
"Sword of Speed", 7, 29, 6, 30, 5, 20, 7000, 8, 5
|
||||
"sharp sword ", 143, 88, 21, 255, 81, 5, 6500, 10, 4
|
||||
"Accurate sword", 71, 31, 6, 32, 5, 10, 6500, 8, 6
|
||||
"Sword of Magic", 6, 88, 30, 255, 87, 15, 10000, 8, 5
|
||||
"Immortal sword", 70, 33, 5, 255, 39, 25, 7000, 8, 4
|
||||
"Axe Protector ", 7, 88, 25, 255, 92, 15, 8000, 8, 5
|
||||
"axe Destroyer ", 143, 23, 4, 255, 85, 6, 8000, 8, 5
|
||||
"X!xx!x's Sword", 198, 33, 15, 34, 5, 10, 6000, 8, 4
|
||||
"Adamantine axe", 7, 33, 8, 255, 36, 5, 12000, 8, 5
|
||||
"Ultimate sword", 6, 23, 10, 30, 5, 20, 15000, 20, 6
|
||||
"Element sword ", 6, 88, 25, 255, 44, 10, 12000, 8, 5
|
||||
"Sling ", 6, 0, 0, 0, 0, 0, 10, 4, 0
|
||||
"Crossbow ", 6, 0, 0, 0, 0, 0, 50, 6, 0
|
||||
"Short bow ", 7, 0, 0, 0, 0, 0, 75, 8, 0
|
||||
"Long bow ", 7, 0, 0, 0, 0, 0, 100, 10, 0
|
||||
"Great bow ", 7, 0, 0, 0, 0, 0, 250, 12, 0
|
||||
"Sling +1 ", 6, 0, 0, 0, 0, 0, 50, 4, 1
|
||||
"Crossbow +1 ", 6, 0, 0, 0, 0, 0, 250, 6, 1
|
||||
"Short bow +1 ", 7, 0, 0, 0, 0, 0, 375, 8, 1
|
||||
"Long bow +1 ", 7, 0, 0, 0, 0, 0, 500, 10, 1
|
||||
"Great bow +1 ", 7, 0, 0, 0, 0, 0, 1250, 12, 1
|
||||
"Magic sling ", 6, 88, 10, 89, 20, 10, 800, 4, 3
|
||||
"Crossbow +2 ", 54, 31, 2, 0, 0, 0, 1000, 6, 2
|
||||
"Short bow +2 ", 135, 102, 10, 0, 0, 0, 1000, 8, 2
|
||||
"Long bow +2 ", 71, 102, 10, 0, 0, 0, 1200, 10, 2
|
||||
"Great bow +2 ", 7, 98, 30, 0, 0, 0, 2000, 12, 2
|
||||
"Crossbow Luck ", 54, 33, 3, 255, 1, 20, 2000, 6, 3
|
||||
"crossbow Speed", 6, 29, 4, 255, 2, 10, 2000, 6, 3
|
||||
"Lightning bow ", 71, 94, 20, 255, 63, 10, 3000, 10, 3
|
||||
"Flaming bow ", 135, 90, 20, 255, 66, 10, 3000, 10, 3
|
||||
"Giant's bow ", 7, 0, 0, 0, 0, 0, 2000, 20, 3
|
||||
"The Magic Bow ", 71, 88, 20, 255, 83, 5, 6000, 16, 4
|
||||
"Bow of Power ", 135, 98, 40, 36, 4, 15, 6000, 16, 4
|
||||
"Robber's x-bow", 62, 29, 4, 255, 61, 10, 8000, 10, 5
|
||||
"Archer's bow ", 55, 31, 5, 255, 85, 10, 12000, 20, 5
|
||||
"Obsidian bow ", 0, 255, 0, 255, 80, 3, 2000, 3, 0
|
||||
"Staff ", 1, 0, 0, 0, 0, 0, 30, 8, 0
|
||||
"Glaive ", 7, 0, 0, 0, 0, 0, 80, 10, 0
|
||||
"Bardiche ", 7, 0, 0, 0, 0, 0, 80, 10, 0
|
||||
"Halberd ", 7, 0, 0, 0, 0, 0, 100, 12, 0
|
||||
"Great hammer ", 3, 0, 0, 0, 0, 0, 150, 12, 0
|
||||
"Great axe ", 7, 0, 0, 0, 0, 0, 150, 12, 0
|
||||
"Flamberge ", 7, 0, 0, 0, 0, 0, 250, 14, 0
|
||||
"Staff +1 ", 1, 21, 1, 0, 0, 0, 200, 8, 1
|
||||
"Glaive +1 ", 135, 29, 1, 0, 0, 0, 350, 10, 1
|
||||
"Bardiche +1 ", 71, 29, 1, 0, 0, 0, 350, 10, 1
|
||||
"Halberd +1 ", 7, 0, 0, 0, 0, 0, 500, 12, 1
|
||||
"Great hammer+1", 3, 25, 1, 0, 0, 0, 550, 12, 1
|
||||
"Great axe +1 ", 7, 0, 0, 0, 0, 0, 500, 12, 1
|
||||
"Flamberge +1 ", 7, 0, 0, 0, 0, 0, 600, 14, 1
|
||||
"Staff +2 ", 1, 33, 2, 255, 54, 10, 600, 8, 2
|
||||
"Glaive +2 ", 135, 29, 2, 0, 0, 0, 900, 10, 2
|
||||
"Bardiche +2 ", 71, 29, 2, 0, 0, 0, 900, 10, 2
|
||||
"Halberd +2 ", 7, 29, 3, 255, 3, 20, 1200, 12, 2
|
||||
"Great hammer+2", 3, 25, 2, 255, 1, 20, 1200, 12, 2
|
||||
"Great axe +2 ", 7, 23, 2, 24, 2, 10, 1200, 12, 2
|
||||
"Flamberge +2 ", 7, 23, 2, 24, 2, 10, 2000, 14, 2
|
||||
"Staff of Light", 1, 102, 40, 255, 19, 20, 1500, 8, 3
|
||||
"Cold glaive ", 135, 92, 40, 255, 21, 20, 2500, 10, 3
|
||||
"Curing staff ", 121, 100, 30, 255, 5, 12, 2500, 8, 3
|
||||
"Minotaur's axe", 7, 255, 0, 0, 0, 0, 2000, 3, 0
|
||||
"Thunder hammer", 59, 94, 40, 255, 29, 15, 3500, 12, 4
|
||||
"Great axe +3 ", 7, 23, 4, 30, 3, 10, 3500, 12, 3
|
||||
"Flamberge +3 ", 7, 23, 4, 30, 3, 10, 5000, 14, 3
|
||||
"Sorcerer staff", 61, 21, 4, 255, 91, 10, 8000, 8, 5
|
||||
"Staff of Magic", 1, 88, 25, 255, 87, 10, 5000, 8, 4
|
||||
"Demon's glaive", 215, 96, 50, 255, 71, 40, 10000, 10, 5
|
||||
"Devil's glaive", 215, 92, 50, 255, 72, 40, 10000, 10, 5
|
||||
"The flamberge ", 7, 23, 10, 255, 73, 10, 15000, 30, 6
|
||||
"Holy flamberge", 111, 88, 50, 255, 43, 15, 20000, 20, 6
|
||||
"Evil flamberge", 175, 88, 50, 255, 46, 15, 20000, 20, 6
|
||||
"Padded armor ", 0, 0, 0, 0, 0, 0, 10, 0, 1
|
||||
"Leather armor ", 2, 0, 0, 0, 0, 0, 20, 0, 2
|
||||
"Scale armor ", 2, 0, 0, 0, 0, 0, 50, 0, 3
|
||||
"Ring mail ", 2, 0, 0, 0, 0, 0, 100, 0, 4
|
||||
"Chain mail ", 3, 0, 0, 0, 0, 0, 200, 0, 5
|
||||
"Splint mail ", 15, 0, 0, 0, 0, 0, 400, 0, 6
|
||||
"Plate mail ", 15, 0, 0, 0, 0, 0, 1000, 0, 7
|
||||
"Padded +1 ", 0, 0, 0, 0, 0, 0, 25, 0, 2
|
||||
"Leather +1 ", 2, 0, 0, 0, 0, 0, 60, 0, 3
|
||||
"Scale +1 ", 2, 0, 0, 0, 0, 0, 120, 0, 4
|
||||
"Ring mail +1 ", 2, 90, 5, 0, 0, 0, 250, 0, 5
|
||||
"Chain mail +1 ", 3, 90, 5, 0, 0, 0, 500, 0, 6
|
||||
"Splint mail +1", 15, 90, 10, 0, 0, 0, 1000, 0, 7
|
||||
"Plate mail +1 ", 15, 90, 10, 0, 0, 0, 2500, 0, 8
|
||||
"Leather +2 ", 2, 94, 10, 0, 0, 0, 150, 0, 4
|
||||
"Scale +2 ", 2, 92, 10, 0, 0, 0, 300, 0, 5
|
||||
"Ring mail +2 ", 2, 90, 15, 0, 0, 0, 750, 0, 6
|
||||
"Chain mail +2 ", 3, 90, 15, 0, 0, 0, 1500, 0, 7
|
||||
"Splint mail +2", 15, 90, 20, 0, 0, 0, 2500, 0, 8
|
||||
"Plate mail +2 ", 15, 90, 20, 0, 0, 0, 7500, 0, 9
|
||||
"Bracers ac 4 ", 52, 0, 0, 0, 0, 0, 1000, 0, 4
|
||||
"Ring mail +3 ", 2, 29, 2, 0, 0, 0, 2000, 0, 7
|
||||
"Chain mail +3 ", 3, 33, 4, 0, 0, 0, 4500, 0, 8
|
||||
"Splint mail +3", 15, 23, 2, 0, 0, 0, 7500, 0, 9
|
||||
"Plate mail +3 ", 15, 90, 50, 0, 0, 0, 15000, 0, 10
|
||||
"Bracers AC 6 ", 52, 98, 20, 255, 77, 20, 2500, 0, 6
|
||||
"Chain mail +3 ", 3, 255, 0, 0, 0, 0, 4500, 0, 0
|
||||
"Bracers AC 8 ", 0, 255, 0, 0, 0, 0, 7500, 0, 0
|
||||
"Blue ring mail", 2, 94, 60, 255, 66, 30, 10000, 0, 9
|
||||
"Red chain mail", 3, 90, 60, 255, 63, 30, 15000, 0, 10
|
||||
"X!xx!x's Plate", 207, 33, 10, 34, 5, 10, 18000, 0, 11
|
||||
"Holy plate ", 111, 88, 40, 99, 50, 30, 25000, 0, 12
|
||||
"Un-holy plate ", 175, 88, 40, 99, 50, 30, 25000, 0, 12
|
||||
"Ultimate plate", 21, 88, 40, 255, 49, 30, 30000, 0, 13
|
||||
"Bracers AC 8 ", 52, 98, 60, 255, 77, 40, 7500, 0, 8
|
||||
"Small shield ", 10, 0, 0, 0, 0, 0, 10, 0, 1
|
||||
"Large shield ", 10, 0, 0, 0, 0, 0, 50, 0, 2
|
||||
"Silver shield ", 10, 102, 20, 0, 0, 0, 100, 0, 2
|
||||
"Small shield+1", 10, 0, 0, 0, 0, 0, 100, 0, 2
|
||||
"Large shield+1", 10, 0, 0, 0, 0, 0, 200, 0, 3
|
||||
"Large shield+1", 10, 255, 0, 0, 0, 0, 200, 0, 0
|
||||
"Small shield+2", 10, 0, 0, 0, 0, 0, 400, 0, 3
|
||||
"Large shield+2", 10, 0, 0, 0, 0, 0, 800, 0, 4
|
||||
"Large shield+2", 10, 255, 0, 0, 0, 0, 800, 0, 0
|
||||
"Fire shield ", 10, 90, 20, 0, 0, 0, 2500, 0, 5
|
||||
"Cold shield ", 10, 92, 20, 0, 0, 0, 2500, 0, 5
|
||||
"Elec shield ", 10, 94, 20, 0, 0, 0, 2500, 0, 5
|
||||
"Acid shield ", 10, 96, 20, 0, 0, 0, 2500, 0, 5
|
||||
"Magic shield ", 10, 88, 20, 255, 77, 20, 5000, 0, 6
|
||||
"Dragon shield ", 10, 88, 10, 255, 92, 20, 8000, 0, 7
|
||||
"Rope & Hooks ", 0, 1, 0, 255, 58, 30, 10, 0, 0
|
||||
"Torch ", 0, 1, 0, 255, 4, 1, 2, 0, 0
|
||||
"Lantern ", 0, 1, 0, 255, 4, 10, 20, 0, 0
|
||||
"10 Foot pole ", 0, 1, 0, 0, 0, 0, 10, 0, 0
|
||||
"Garlic ", 0, 1, 0, 0, 0, 0, 5, 0, 0
|
||||
"Wolfsbane ", 0, 1, 0, 0, 0, 0, 10, 0, 0
|
||||
"Belladonna ", 0, 1, 0, 0, 0, 0, 25, 0, 0
|
||||
"Magic herbs ", 0, 1, 0, 255, 3, 3, 50, 0, 0
|
||||
"Dried beef ", 0, 1, 0, 62, 6, 3, 40, 0, 0
|
||||
"Robber's tools", 62, 108, 20, 0, 0, 0, 150, 0, 0
|
||||
"Bag of Silver ", 0, 1, 0, 0, 0, 0, 300, 0, 0
|
||||
"Amber gem ", 0, 1, 0, 0, 0, 0, 500, 0, 0
|
||||
"Smelling salt ", 0, 1, 0, 255, 0, 3, 50, 0, 0
|
||||
"Bag of sand ", 0, 1, 0, 255, 54, 5, 100, 0, 0
|
||||
"Might potion ", 0, 1, 0, 24, 5, 3, 200, 0, 0
|
||||
"Speed potion ", 0, 1, 0, 30, 5, 3, 200, 0, 0
|
||||
"Sundial ", 0, 1, 0, 255, 53, 50, 500, 0, 0
|
||||
"Curing potion ", 0, 1, 0, 255, 8, 4, 350, 0, 0
|
||||
"Magic potion ", 0, 1, 0, 43, 10, 2, 500, 0, 0
|
||||
"Defense ring ", 0, 60, 1, 255, 57, 30, 500, 0, 0
|
||||
"Bag of garbage", 0, 255, 0, 0, 0, 0, 100, 0, 0
|
||||
"Scroll of fire", 0, 1, 0, 255, 63, 1, 300, 0, 0
|
||||
"Flying carpet ", 61, 60, 2, 255, 64, 10, 500, 0, 0
|
||||
"Jade amulet ", 255, 19, 5, 0, 0, 0, 600, 0, 0
|
||||
"Antidote brew ", 0, 1, 0, 255, 25, 2, 500, 0, 0
|
||||
"Skill potion ", 0, 1, 0, 36, 5, 5, 600, 0, 0
|
||||
"Boots of Speed", 0, 29, 5, 30, 10, 10, 800, 0, 0
|
||||
"Lucky charm ", 0, 33, 5, 34, 10, 20, 800, 0, 0
|
||||
"Wand of Fire ", 53, 90, 15, 255, 63, 10, 1000, 0, 0
|
||||
"Undead amulet ", 0, 98, 50, 255, 7, 20, 800, 0, 0
|
||||
"Silent chime ", 0, 1, 0, 255, 14, 20, 400, 0, 0
|
||||
"Belt of Power ", 14, 23, 5, 0, 0, 0, 600, 0, 0
|
||||
"Model boat ", 0, 1, 0, 255, 23, 15, 400, 0, 0
|
||||
"Defense cloak ", 0, 60, 2, 0, 0, 0, 700, 0, 0
|
||||
"Knowledge book", 33, 21, 2, 48, 1, 4, 1000, 0, 0
|
||||
"Ruby idol ", 0, 1, 0, 0, 0, 0, 3000, 0, 0
|
||||
"Sorcerer robe ", 61, 21, 5, 255, 65, 20, 2500, 0, 0
|
||||
"Power gauntlet", 2, 23, 5, 0, 0, 0, 3000, 0, 0
|
||||
"Cleric's beads", 59, 25, 5, 255, 8, 50, 3000, 0, 0
|
||||
"Horn of Death ", 0, 1, 0, 255, 81, 10, 2500, 0, 0
|
||||
"Potion of Life", 0, 1, 0, 255, 38, 2, 1500, 0, 0
|
||||
"Shiny pendant ", 0, 102, 30, 255, 56, 10, 2000, 0, 0
|
||||
"Lightning wand", 50, 94, 20, 255, 66, 10, 1500, 0, 0
|
||||
"Precision ring", 0, 31, 5, 0, 0, 0, 3000, 0, 0
|
||||
"Return scroll ", 0, 1, 0, 255, 41, 1, 2000, 0, 0
|
||||
"Teleport helm ", 0, 88, 10, 255, 83, 20, 5000, 0, 0
|
||||
"Youth potion ", 0, 1, 0, 255, 39, 2, 4000, 0, 0
|
||||
"Bells of Time ", 0, 1, 0, 37, 10, 50, 1000, 0, 0
|
||||
"Magic oil ", 0, 1, 0, 255, 88, 1, 3000, 0, 0
|
||||
"Magic vest ", 0, 88, 20, 255, 78, 10, 6000, 0, 0
|
||||
"Destroyer wand", 53, 88, 10, 255, 85, 10, 7000, 0, 0
|
||||
"Element scarab", 0, 25, 5, 255, 44, 20, 6000, 0, 0
|
||||
"Sun scroll ", 0, 1, 0, 255, 46, 1, 3000, 0, 0
|
||||
"Star ruby ", 0, 33, 10, 255, 49, 30, 6000, 0, 0
|
||||
"Star sapphire ", 0, 88, 30, 255, 87, 10, 6000, 0, 0
|
||||
"Wealth chest ", 0, 1, 0, 58, 20, 5, 6000, 0, 0
|
||||
"Gem sack ", 0, 1, 0, 49, 10, 10, 10000, 0, 0
|
||||
"Diamond collar", 0, 37, 80, 255, 93, 10, 10000, 0, 0
|
||||
"Fire opal ", 0, 37, 80, 255, 91, 10, 10000, 0, 0
|
||||
"Unobtainium ", 255, 16, 5, 0, 0, 0, 50000, 0, 0
|
||||
"Vellum scroll ", 0, 1, 0, 0, 0, 0, 10, 0, 0
|
||||
"Ruby whistle ", 0, 33, 2, 255, 0, 200, 500, 0, 0
|
||||
"Kings Pass ", 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||
"Merchants Pass", 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||
"Crystal key ", 0, 1, 0, 255, 93, 10, 1000, 0, 0
|
||||
"Coral key ", 0, 1, 0, 255, 23, 10, 300, 0, 0
|
||||
"Bronze key ", 0, 1, 0, 255, 48, 20, 500, 0, 0
|
||||
"Silver key ", 0, 1, 0, 255, 51, 30, 600, 0, 0
|
||||
"Gold key ", 0, 1, 0, 255, 65, 15, 800, 0, 0
|
||||
"Diamond key ", 0, 1, 0, 255, 83, 20, 2000, 0, 0
|
||||
"Cactus nectar ", 0, 1, 0, 255, 16, 10, 400, 0, 0
|
||||
"Map of Desert ", 0, 1, 0, 255, 53, 20, 400, 0, 0
|
||||
"Laser blaster ", 0, 31, 5, 255, 85, 10, 2000, 0, 0
|
||||
"Dragons tooth ", 0, 1, 0, 255, 39, 10, 1500, 0, 0
|
||||
"Wyvern eye ", 0, 1, 0, 255, 62, 20, 1000, 0, 0
|
||||
"Medusa head ", 0, 255, 0, 0, 0, 0, 0, 0, 0
|
||||
"Ring of Okrim ", 0, 33, 10, 255, 78, 20, 3000, 0, 0
|
||||
"B Queen Idol ", 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||
"W Queen Idol ", 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||
"Pirates Map A ", 0, 1, 0, 0, 0, 0, 1000, 0, 0
|
||||
"Pirates Map B ", 0, 1, 0, 0, 0, 0, 2000, 0, 0
|
||||
"Thundranium ", 0, 1, 0, 24, 15, 250, 10000, 0, 0
|
||||
"Key card ", 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||
"Eye of Goros ", 0, 1, 0, 255, 89, 20, 10000, 0, 0
|
||||
"(Useless Item)", 0, 1, 0, 0, 0, 0, 0, 0, 0
|
||||
| ||||