diff --git a/esm/esm_reader.hpp b/esm/esm_reader.hpp index c552cd102a..d608079a6a 100644 --- a/esm/esm_reader.hpp +++ b/esm/esm_reader.hpp @@ -174,7 +174,7 @@ public: getRecHeader(); // Get the header - getHNT(header, "HEDR"); + getHNT(header, "HEDR", 300); if(header.version != VER_12 && header.version != VER_13) @@ -193,7 +193,7 @@ public: // Savegame-related data // Player position etc - getHNT(saveData, "GMDT"); + getHNT(saveData, "GMDT", 124); /* Image properties, five ints. Is always: Red-mask: 0xff0000 @@ -233,6 +233,16 @@ public: getHT(x); } + // Version with extra size checking, to make sure the compiler + // doesn't mess up our struct padding. + template + void getHNT(X &x, const char* name, int size) + { + assert(sizeof(X) == size); + getSubNameIs(name); + getHT(x); + } + int64_t getHNLong(const char *name) { int64_t val; @@ -250,12 +260,22 @@ public: getT(x); } + // Read a string by the given name if it is the next record. + std::string getHNOString(const char* name) + { + if(isNextSub(name)) + return getHString(); + return ""; + } + + // Read a string with the given sub-record name std::string getHNString(const char* name) { getSubNameIs(name); return getHString(); } + // Read a string, including the sub-record header (but not the name) std::string getHString() { getSubHeader(); @@ -431,10 +451,12 @@ public: *************************************************************************/ template - void getT(X &x) + void getT(X &x) { getExact(&x, sizeof(X)); } + + void getExact(void*x, int size) { - int t = esm->read(&x, sizeof(X)); - if(t != sizeof(X)) + int t = esm->read(x, size); + if(t != size) fail("Read error"); } void getName(NAME &name) { getT(name); } diff --git a/esm/loadarmo.hpp b/esm/loadarmo.hpp new file mode 100644 index 0000000000..1e065f3e8f --- /dev/null +++ b/esm/loadarmo.hpp @@ -0,0 +1,102 @@ +#ifndef _ESM_ARMO_H +#define _ESM_ARMO_H + +#include "esm_reader.hpp" + +enum PartReferenceType + { + PRT_Head = 0, + PRT_Hair = 1, + PRT_Neck = 2, + PRT_Cuirass = 3, + PRT_Groin = 4, + PRT_Skirt = 5, + PRT_RHand = 6, + PRT_LHand = 7, + PRT_RWrist = 8, + PRT_LWrist = 9, + PRT_Shield = 10, + PRT_RForearm = 11, + PRT_LForearm = 12, + PRT_RUpperarm = 13, + PRT_LUpperarm = 14, + PRT_RFoot = 15, + PRT_LFoot = 16, + PRT_RAnkle = 17, + PRT_LAnkle = 18, + PRT_RKnee = 19, + PRT_LKnee = 20, + PRT_RLeg = 21, + PRT_LLeg = 22, + PRT_RPauldron = 23, + PRT_LPauldron = 24, + PRT_Weapon = 25, + PRT_Tail = 26 + }; + +// Reference to body parts +struct PartReference +{ + char part; + std::string male, female; +}; + +// A list of references to body parts +struct PartReferenceList +{ + std::vector parts; + + void load(ESMReader &esm) + { + while(esm.isNextSub("INDX")) + { + PartReference pr; + esm.getHT(pr.part); // The INDX byte + pr.male = esm.getHNOString("BNAM"); + pr.female = esm.getHNOString("CNAM"); + } + } +}; + +struct Armor +{ + enum Type + { + Helmet = 0, + Cuirass = 1, + LPauldron = 2, + RPauldron = 3, + Greaves = 4, + Boots = 5, + LGauntlet = 6, + RGauntlet = 7, + Shield = 8, + LBracer = 9, + RBracer = 10 + }; + + struct AODTstruct + { + int type; + float weight; + int value, health, enchant, armor; + }; + + AODTstruct data; + PartReferenceList parts; + + std::string name, model, icon, script, enchant; + + void load(ESMReader &esm) + { + model = esm.getHNString("MODL"); + name = esm.getHNString("FNAM"); + script = esm.getHNOString("SCRI"); + esm.getHNT(data, "AODT", 24); + icon = esm.getHNOString("ITEX"); + parts.load(esm); + enchant = esm.getHNOString("ENAM"); + } +}; + +#endif diff --git a/esm/loadbody.hpp b/esm/loadbody.hpp index 5417f5c707..8b6a1e6ab7 100644 --- a/esm/loadbody.hpp +++ b/esm/loadbody.hpp @@ -52,7 +52,7 @@ struct BodyPart { model = esm.getHNString("MODL"); name = esm.getHNString("FNAM"); - esm.getHNT(data, "BYDT"); + esm.getHNT(data, "BYDT", 4); } }; diff --git a/esm/loadbsgn.hpp b/esm/loadbsgn.hpp new file mode 100644 index 0000000000..e8771b536a --- /dev/null +++ b/esm/loadbsgn.hpp @@ -0,0 +1,24 @@ +#ifndef _ESM_SOUN_H +#define _ESM_SOUN_H + +#include "esm_reader.hpp" +//#include "loadspel.hpp" + +struct BirthSign +{ + std::string name, description, texture; + + // List of powers and abilities that come with this birth sign. + //SpellList powers; + + void load(ESMReader &esm) + { + name = esm.getHNString("FNAM"); + texture = esm.getHNOString("TNAM"); + description = esm.getHNOString("DESC"); + + //powers.load(esm); + }; +}; + +#endif diff --git a/esm/loadsoun.hpp b/esm/loadsoun.hpp new file mode 100644 index 0000000000..355a8685e2 --- /dev/null +++ b/esm/loadsoun.hpp @@ -0,0 +1,22 @@ +#ifndef _ESM_SOUN_H +#define _ESM_SOUN_H + +#include "esm_reader.hpp" + +struct SOUNstruct +{ + unsigned char volume, minRange, maxRange; +}; + +struct Sound +{ + SOUNstruct data; + std::string sound; + + void load(ESMReader &esm) + { + sound = esm.getHNString("FNAM"); + esm.getHNT(data, "DATA", 3); + } +}; +#endif diff --git a/esm/records.hpp b/esm/records.hpp index d395bcd922..6fa56d937b 100644 --- a/esm/records.hpp +++ b/esm/records.hpp @@ -1,8 +1,10 @@ #ifndef _ESM_RECORDS_H #define _ESM_RECORDS_H -//#include "loadarmo.hpp" +#include "loadarmo.hpp" #include "loadbody.hpp" +#include "loadbsgn.hpp" +#include "loadsoun.hpp" // Integer versions of all the record names, used for faster lookup enum RecNameInts diff --git a/esm/tests/esmtool.cpp b/esm/tests/esmtool.cpp index ac8a4880bb..155a708bfc 100644 --- a/esm/tests/esmtool.cpp +++ b/esm/tests/esmtool.cpp @@ -1,10 +1,9 @@ -#include "../esm_reader.hpp" -#include "../records.hpp" - #include - using namespace std; +#include "../esm_reader.hpp" +#include "../records.hpp" + int main(int argc, char**argv) { if(argc != 2) @@ -36,6 +35,19 @@ int main(int argc, char**argv) switch(n.val) { + case REC_ARMO: + { + Armor am; + am.load(esm); + cout << " Name: " << am.name << endl; + cout << " Mesh: " << am.model << endl; + cout << " Icon: " << am.icon << endl; + cout << " Script: " << am.script << endl; + cout << " Enchantment: " << am.enchant << endl; + cout << " Type: " << am.data.type << endl; + cout << " Weight: " << am.data.weight << endl; + break; + } case REC_BODY: { BodyPart bp; diff --git a/old_d_version/esm/loadarmo.d b/old_d_version/esm/loadarmo.d deleted file mode 100644 index 670b539d26..0000000000 --- a/old_d_version/esm/loadarmo.d +++ /dev/null @@ -1,149 +0,0 @@ -/* - OpenMW - The completely unofficial reimplementation of Morrowind - Copyright (C) 2008 Nicolay Korslund - Email: < korslund@gmail.com > - WWW: http://openmw.snaptoad.com/ - - This file (loadarmo.d) is part of the OpenMW package. - - OpenMW is distributed as free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License - version 3, as published by the Free Software Foundation. - - 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 - version 3 along with this program. If not, see - http://www.gnu.org/licenses/ . - - */ - -module esm.loadarmo; -import esm.imports; - -import esm.loadbody, esm.loadench; - -/* - * Armor - */ - -// Reference to body parts -struct PartReference -{ - enum Index - { - Head = 0, - Hair = 1, - Neck = 2, - Cuirass = 3, - Groin = 4, - Skirt = 5, - RHand = 6, - LHand = 7, - RWrist = 8, - LWrist = 9, - Shield = 10, - RForearm = 11, - LForearm = 12, - RUpperarm = 13, - LUpperarm = 14, - RFoot = 15, - LFoot = 16, - RAnkle = 17, - LAnkle = 18, - RKnee = 19, - LKnee = 20, - RLeg = 21, - LLeg = 22, - RPauldron = 23, - LPauldron = 24, - Weapon = 25, - Tail = 26 - } - Index part; - - BodyPart* male, female; -} - -struct PartReferenceList -{ - RegionBuffer!(PartReference) parts; - - void load() - {with(esFile){ - parts = getRegion().getBuffer!(PartReference)(0,1); - while(isNextSub("INDX")) - { - parts.length = parts.length + 1; - with(parts.array[$-1]) - { - part = cast(PartReference.Index) getHByte; - male = getHNOPtr!(BodyPart)("BNAM", bodyParts); - female = getHNOPtr!(BodyPart)("CNAM", bodyParts); - } - } - }} -} - -struct Armor -{ - enum Type : int - { - Helmet = 0, - Cuirass = 1, - LPauldron = 2, - RPauldron = 3, - Greaves = 4, - Boots = 5, - LGauntlet = 6, - RGauntlet = 7, - Shield = 8, - LBracer = 9, - RBracer = 10 - } - - align(1) struct AODTstruct - { - Type type; - float weight; - int value, health, enchant, armor; - - static assert(AODTstruct.sizeof==24); - } - - AODTstruct data; - - mixin LoadT!(); - - PartReferenceList parts; - - MeshIndex model; - IconIndex icon; - - Script *script; - Enchantment *enchant; - - void load() - {with(esFile){ - model = getMesh(); - name = getHNString("FNAM"); - script = getHNOPtr!(Script)("SCRI", scripts); - readHNExact(&data, data.sizeof, "AODT"); - icon = getOIcon(); - - parts.load(); - - enchant = getHNOPtr!(Enchantment)("ENAM", enchants); - - makeProto(); - - proto.setInt("type", data.type); - proto.setInt("armor", data.armor); - - proto.setInt("health", data.health); - }} -} -ListID!(Armor) armors;