diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index f417d5c60..ea9a388a5 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -1,8 +1,10 @@ #include +#include #include #include +#include #include #define ESMTOOL_VERSION 1.1 @@ -16,19 +18,33 @@ namespace bpo = boost::program_options; void printRaw(ESMReader &esm); void loadCell(Cell &cell, ESMReader &esm, bool quiet); +struct ESMData +{ + std::string author; + std::string description; + ESMReader::MasterList masters; + + std::list records; +}; + // Based on the legacy struct struct Arguments { unsigned int raw_given; unsigned int quiet_given; unsigned int loadcells_given; + + std::string mode; std::string encoding; std::string filename; + std::string outname; + + ESMData data; }; bool parseOptions (int argc, char** argv, Arguments &info) { - bpo::options_description desc("Inspect and extract from Morrowind ES files (ESM, ESP, ESS)\nSyntax: esmtool [options] file \nAllowed options"); + bpo::options_description desc("Inspect and extract from Morrowind ES files (ESM, ESP, ESS)\nSyntax: esmtool [options] mode infile [outfile]\nAllowed options"); desc.add_options() ("help,h", "print help message.") @@ -38,11 +54,11 @@ bool parseOptions (int argc, char** argv, Arguments &info) ("loadcells,C", "Browse through contents of all cells.") ( "encoding,e", bpo::value(&(info.encoding))-> - default_value("win1252"), - "Character encoding used in ESMTool:\n" - "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" - "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" - "\n\twin1252 - Western European (Latin) alphabet, used by default") + default_value("win1252"), + "Character encoding used in ESMTool:\n" + "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" + "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" + "\n\twin1252 - Western European (Latin) alphabet, used by default") ; std::string finalText = "\nIf no option is given, the default action is to parse all records in the archive\nand display diagnostic information."; @@ -51,11 +67,12 @@ bool parseOptions (int argc, char** argv, Arguments &info) bpo::options_description hidden("Hidden Options"); hidden.add_options() + ( "mode,m", bpo::value(), "esmtool mode") ( "input-file,i", bpo::value< vector >(), "input file") ; bpo::positional_options_description p; - p.add("input-file", -1); + p.add("mode", 1).add("input-file", 2); // there might be a better way to do this bpo::options_description all; @@ -77,6 +94,12 @@ bool parseOptions (int argc, char** argv, Arguments &info) std::cout << "ESMTool version " << ESMTOOL_VERSION << std::endl; return false; } + if (!variables.count("mode")) + { + std::cout << "No mode specified!" << std::endl << std::endl + << desc << finalText << std::endl; + return false; + } if ( !variables.count("input-file") ) { @@ -86,14 +109,18 @@ bool parseOptions (int argc, char** argv, Arguments &info) } // handling gracefully the user adding multiple files - if (variables["input-file"].as< vector >().size() > 1) - { - std::cout << "\nERROR: more than one ES file specified\n\n"; - std::cout << desc << finalText << std::endl; - return false; - } +/* if (variables["input-file"].as< vector >().size() > 1) + { + std::cout << "\nERROR: more than one ES file specified\n\n"; + std::cout << desc << finalText << std::endl; + return false; + }*/ + + info.mode = variables["mode"].as(); info.filename = variables["input-file"].as< vector >()[0]; + if (variables["input-file"].as< vector >().size() > 1) + info.outname = variables["input-file"].as< vector >()[1]; info.raw_given = variables.count ("raw"); info.quiet_given = variables.count ("quiet"); @@ -122,288 +149,612 @@ bool parseOptions (int argc, char** argv, Arguments &info) return true; } +int load(Arguments& info); +int clone(Arguments& info); int main(int argc, char**argv) { - Arguments info; - if(!parseOptions (argc, argv, info)) - return 1; + Arguments info; + if(!parseOptions (argc, argv, info)) + return 1; + + if (info.mode == "dump") + return load(info); + else if (info.mode == "clone") + return clone(info); + else + { + cout << "Invalid or no mode specified, dying horribly. Have a nice day." << endl; + return 1; + } + + return 0; +} - ESMReader esm; - esm.setEncoding(info.encoding); +void loadCell(Cell &cell, ESMReader &esm, bool quiet) +{ + // Skip back to the beginning of the reference list + cell.restore(esm); - string filename = info.filename; - cout << "\nFile: " << filename << endl; + // Loop through all the references + CellRef ref; + if(!quiet) cout << " References:\n"; + while(cell.getNextRef(esm, ref)) + { + if(quiet) continue; - try { + cout << " Refnum: " << ref.refnum << endl; + cout << " ID: '" << ref.refID << "'\n"; + cout << " Owner: '" << ref.owner << "'\n"; + cout << " INTV: " << ref.intv << " NAM9: " << ref.intv << endl; + } +} - if(info.raw_given) +void printRaw(ESMReader &esm) +{ + while(esm.hasMoreRecs()) { - cout << "RAW file listing:\n"; + NAME n = esm.getRecName(); + cout << "Record: " << n.toString() << endl; + esm.getRecHeader(); + while(esm.hasMoreSubs()) + { + uint64_t offs = esm.getOffset(); + esm.getSubName(); + esm.skipHSub(); + n = esm.retSubName(); + cout << " " << n.toString() << " - " << esm.getSubSize() + << " bytes @ 0x" << hex << offs << "\n"; + } + } +} - esm.openRaw(filename); +int load(Arguments& info) +{ + ESMReader esm; + esm.setEncoding(info.encoding); - printRaw(esm); + string filename = info.filename; + cout << "\nFile: " << filename << endl; - return 0; - } + std::list skipped; - bool quiet = info.quiet_given; - bool loadCells = info.loadcells_given; + try { - esm.open(filename); + if(info.raw_given) + { + cout << "RAW file listing:\n"; - cout << "Author: " << esm.getAuthor() << endl; - cout << "Description: " << esm.getDesc() << endl; - cout << "File format version: " << esm.getFVer() << endl; - cout << "Special flag: " << esm.getSpecial() << endl; - cout << "Masters:\n"; - ESMReader::MasterList m = esm.getMasters(); - for(unsigned int i=0;i::iterator it = info.data.records.begin(); it != info.data.records.end();) + { + delete *it; + info.data.records.erase(it++); + } + return 1; } - return 0; + return 0; } -void loadCell(Cell &cell, ESMReader &esm, bool quiet) +#include + +int clone(Arguments& info) { - // Skip back to the beginning of the reference list - cell.restore(esm); + if (info.outname.empty()) + { + cout << "You need to specify an output name" << endl; + return 1; + } + + if (load(info) != 0) + { + cout << "Failed to load, aborting." << endl; + return 1; + } - // Loop through all the references - CellRef ref; - if(!quiet) cout << " References:\n"; - while(cell.getNextRef(esm, ref)) + cout << "Loaded " << info.data.records.size() << " records:" << endl; + + std::map records; + + for (std::list::iterator it = info.data.records.begin(); it != info.data.records.end();) { - if(quiet) continue; + Record* rec = *it; + NAME n; + n.val = rec->getName(); + records[n.toString()]++; - cout << " Refnum: " << ref.refnum << endl; - cout << " ID: '" << ref.refID << "'\n"; - cout << " Owner: '" << ref.owner << "'\n"; - cout << " INTV: " << ref.intv << " NAM9: " << ref.intv << endl; + delete rec; + info.data.records.erase(it++); } -} -void printRaw(ESMReader &esm) -{ - while(esm.hasMoreRecs()) + for (std::map::iterator it = records.begin(); it != records.end(); ++it) { - NAME n = esm.getRecName(); - cout << "Record: " << n.toString() << endl; - esm.getRecHeader(); - while(esm.hasMoreSubs()) - { - uint64_t offs = esm.getOffset(); - esm.getSubName(); - esm.skipHSub(); - n = esm.retSubName(); - cout << " " << n.toString() << " - " << esm.getSubSize() - << " bytes @ 0x" << hex << offs << "\n"; - } + std::string n = it->first; + cout << n << ": " << it->second << " records." << endl; } + + return 0; } diff --git a/components/esm/esm_writer.cpp b/components/esm/esm_writer.cpp index 1875ae330..57517b0f5 100644 --- a/components/esm/esm_writer.cpp +++ b/components/esm/esm_writer.cpp @@ -1,4 +1,6 @@ #include "esm_writer.hpp" +#include +#include namespace ESM { @@ -15,22 +17,31 @@ void ESMWriter::setType(FileType type) void ESMWriter::setAuthor(const std::string& auth) { - strcpy(auth.c_str(), m_header.author, 32); + strncpy((char*)&m_header.author, auth.c_str(), 32); } void ESMWriter::setDescription(const std::string& desc) { - strcpy(desc.c_str(), m_header.desc, 256); + strncpy((char*)&m_header.desc, desc.c_str(), 256); } void ESMWriter::save(const std::string& file) { - std::ostream os(file, "wb"); - save(os); + std::ofstream fs(file.c_str(), std::ios_base::out | std::ios_base::trunc); + save(fs); + fs.close(); } void ESMWriter::save(std::ostream& file) { + m_stream = &file; + + startRecord("TES3"); + writeT(0); + writeT(0); + + endRecord(); + // TODO: Saving } @@ -39,6 +50,28 @@ void ESMWriter::close() // TODO: Saving } +void ESMWriter::startRecord(const std::string& name) +{ + writeName(name); + RecordData rec; + rec.position = m_stream->tellp(); + rec.size = 0; + m_records.push_back(rec); + writeT(0); +} + +void ESMWriter::endRecord() +{ + std::streampos cur = m_stream->tellp(); + RecordData rec = m_records.back(); + m_records.pop_back(); + + m_stream->seekp(rec.position); + m_stream->write((char*)&rec.size, sizeof(int)); + + m_stream->seekp(cur); +} + void ESMWriter::writeHNString(const std::string& name, const std::string& data) { writeName(name); @@ -59,7 +92,10 @@ void ESMWriter::writeName(const std::string& name) void ESMWriter::write(const char* data, int size) { - m_stream.write(data, size); + if (!m_records.empty()) + m_records.back().size += size; + + m_stream->write(data, size); } } diff --git a/components/esm/esm_writer.hpp b/components/esm/esm_writer.hpp index 21cb42de9..3999e987d 100644 --- a/components/esm/esm_writer.hpp +++ b/components/esm/esm_writer.hpp @@ -2,6 +2,7 @@ #define _ESM_WRITER_H #include +#include #include #include "esm_common.hpp" @@ -10,6 +11,12 @@ namespace ESM { class ESMWriter { + struct RecordData + { + std::streampos position; + int size; + }; + public: void setVersion(Version ver); void setType(FileType type); @@ -68,13 +75,16 @@ public: assert(sizeof(T) == size); writeT(data); } - + + void startRecord(const std::string& name); + void endRecord(); void writeHString(const std::string& data); void writeName(const std::string& data); void write(const char* data, int size); private: - std::ostream m_stream; + std::vector m_records; + std::ostream* m_stream; HEDRstruct m_header; SaveData m_saveData; diff --git a/components/esm/loadacti.hpp b/components/esm/loadacti.hpp index 3f968bc7c..083c8fc67 100644 --- a/components/esm/loadacti.hpp +++ b/components/esm/loadacti.hpp @@ -1,18 +1,21 @@ #ifndef _ESM_ACTI_H #define _ESM_ACTI_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" namespace ESM { -struct Activator +struct Activator : public Record { std::string name, script, model; void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_ACTI; } }; } #endif diff --git a/components/esm/loadalch.hpp b/components/esm/loadalch.hpp index b447fe50c..5adc44ee2 100644 --- a/components/esm/loadalch.hpp +++ b/components/esm/loadalch.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_ALCH_H #define _ESM_ALCH_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -12,7 +13,7 @@ namespace ESM * Alchemy item (potions) */ -struct Potion +struct Potion : public Record { struct ALDTstruct { @@ -27,6 +28,8 @@ struct Potion void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_ALCH; } }; } #endif diff --git a/components/esm/loadappa.hpp b/components/esm/loadappa.hpp index ff105a307..8321778db 100644 --- a/components/esm/loadappa.hpp +++ b/components/esm/loadappa.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_APPA_H #define _ESM_APPA_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -11,7 +12,7 @@ namespace ESM * Alchemist apparatus */ -struct Apparatus +struct Apparatus : public Record { enum AppaType { @@ -34,6 +35,8 @@ struct Apparatus void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_APPA; } }; } #endif diff --git a/components/esm/loadarmo.hpp b/components/esm/loadarmo.hpp index 5026696c2..1b2cb8653 100644 --- a/components/esm/loadarmo.hpp +++ b/components/esm/loadarmo.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_ARMO_H #define _ESM_ARMO_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -54,7 +55,7 @@ struct PartReferenceList void save(ESMWriter &esm); }; -struct Armor +struct Armor : public Record { enum Type { @@ -85,6 +86,8 @@ struct Armor void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_ARMO; } }; } #endif diff --git a/components/esm/loadbody.hpp b/components/esm/loadbody.hpp index 46cb1d899..90605e39d 100644 --- a/components/esm/loadbody.hpp +++ b/components/esm/loadbody.hpp @@ -1,13 +1,14 @@ #ifndef _ESM_BODY_H #define _ESM_BODY_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" namespace ESM { -struct BodyPart +struct BodyPart : public Record { enum MeshPart { @@ -54,6 +55,8 @@ struct BodyPart void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_BODY; } }; } #endif diff --git a/components/esm/loadbook.hpp b/components/esm/loadbook.hpp index a46135cc0..a5a891a58 100644 --- a/components/esm/loadbook.hpp +++ b/components/esm/loadbook.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_BOOK_H #define _ESM_BOOK_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -11,7 +12,7 @@ namespace ESM * Books, magic scrolls, notes and so on */ -struct Book +struct Book : public Record { struct BKDTstruct { @@ -24,6 +25,8 @@ struct Book void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_BOOK; } }; } #endif diff --git a/components/esm/loadbsgn.hpp b/components/esm/loadbsgn.hpp index d00664bff..b094b2e49 100644 --- a/components/esm/loadbsgn.hpp +++ b/components/esm/loadbsgn.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_BSGN_H #define _ESM_BSGN_H +#include "record.hpp" #include "defs.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -8,7 +9,7 @@ namespace ESM { -struct BirthSign +struct BirthSign : public Record { std::string name, description, texture; @@ -17,6 +18,8 @@ struct BirthSign void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_BSGN; } }; } #endif diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index 8d461369c..f03c541b7 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_CELL_H #define _ESM_CELL_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -84,7 +85,7 @@ public: (using ESMReader::getContext()) and jumping back into place whenever we need to load a given cell. */ -struct Cell +struct Cell : public Record { enum Flags { @@ -123,6 +124,8 @@ struct Cell void load(ESMReader &esm); void save(ESMWriter &esm); + int getName() { return REC_CELL; } + bool isExterior() const { return !(data.flags & Interior); diff --git a/components/esm/loadclas.hpp b/components/esm/loadclas.hpp index a89481a7a..084f1edb1 100644 --- a/components/esm/loadclas.hpp +++ b/components/esm/loadclas.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_CLAS_H #define _ESM_CLAS_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -13,7 +14,7 @@ namespace ESM // These flags tells us which items should be auto-calculated for this // class -struct Class +struct Class : public Record { enum AutoCalc { @@ -63,6 +64,8 @@ struct Class void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_CLAS; } }; } #endif diff --git a/components/esm/loadclot.hpp b/components/esm/loadclot.hpp index 77ef3786a..4d0ec06cd 100644 --- a/components/esm/loadclot.hpp +++ b/components/esm/loadclot.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_CLOT_H #define _ESM_CLOT_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "loadarmo.hpp" @@ -12,7 +13,7 @@ namespace ESM * Clothing */ -struct Clothing +struct Clothing : public Record { enum Type { @@ -43,6 +44,8 @@ struct Clothing void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_CLOT; } }; } #endif diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index bf6994f9a..7d8952e38 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_CONT_H #define _ESM_CONT_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -25,7 +26,7 @@ struct InventoryList void save(ESMWriter &esm); }; -struct Container +struct Container : public Record { enum Flags { @@ -42,6 +43,8 @@ struct Container void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_CONT; } }; } #endif diff --git a/components/esm/loadcrea.cpp b/components/esm/loadcrea.cpp index f5ffb694f..7b84a7f29 100644 --- a/components/esm/loadcrea.cpp +++ b/components/esm/loadcrea.cpp @@ -2,10 +2,13 @@ namespace ESM { -void Creature::load(ESMReader &esm, const std::string& id) +void Creature::setID(const std::string& id) { mId = id; +} +void Creature::load(ESMReader &esm) +{ model = esm.getHNString("MODL"); original = esm.getHNOString("CNAM"); name = esm.getHNOString("FNAM"); diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 2f5f4061d..3035003cf 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_CREA_H #define _ESM_CREA_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "loadcont.hpp" @@ -13,7 +14,7 @@ namespace ESM * */ -struct Creature +struct Creature : public Record { // Default is 0x48? enum Flags @@ -64,8 +65,11 @@ struct Creature std::string mId; - void load(ESMReader &esm, const std::string& id); + void setID(const std::string& id); + void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_CREA; } }; } #endif diff --git a/components/esm/loadcrec.hpp b/components/esm/loadcrec.hpp index 056f572ae..0a575921a 100644 --- a/components/esm/loadcrec.hpp +++ b/components/esm/loadcrec.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_CREC_H #define _ESM_CREC_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -10,29 +11,33 @@ namespace ESM { */ /// Changes a creature -struct LoadCREC +struct LoadCREC : public Record { - void load(ESMReader &esm) + void load(ESMReader &esm) { esm.skipRecord(); } - void save(ESMWriter &esm) + void save(ESMWriter &esm) { } + + int getName() { return REC_CREC; } }; /// Changes an item list / container -struct LoadCNTC +struct LoadCNTC : public Record { - void load(ESMReader &esm) + void load(ESMReader &esm) { esm.skipRecord(); } - void save(ESMWriter &esm) + void save(ESMWriter &esm) { } + + int getName() { return REC_CNTC; } }; } #endif diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index a19b0c7ad..92818598e 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -3,6 +3,7 @@ #include +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "loadinfo.hpp" @@ -15,7 +16,7 @@ namespace ESM * the INFO records following the DIAL. */ -struct Dialogue +struct Dialogue : public Record { enum Type { @@ -32,6 +33,8 @@ struct Dialogue void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_DIAL; } }; } #endif diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index 1234ac7f9..e8b3be970 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -1,18 +1,21 @@ #ifndef _ESM_DOOR_H #define _ESM_DOOR_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" namespace ESM { -struct Door +struct Door : public Record { std::string name, model, script, openSound, closeSound; void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_DOOR; } }; } #endif diff --git a/components/esm/loadench.hpp b/components/esm/loadench.hpp index 609166983..1cb417c9f 100644 --- a/components/esm/loadench.hpp +++ b/components/esm/loadench.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_ENCH_H #define _ESM_ENCH_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -12,7 +13,7 @@ namespace ESM * Enchantments */ -struct Enchantment +struct Enchantment : public Record { enum Type { @@ -36,6 +37,8 @@ struct Enchantment void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_ENCH; } }; } #endif diff --git a/components/esm/loadfact.hpp b/components/esm/loadfact.hpp index 686554da3..f62c92e19 100644 --- a/components/esm/loadfact.hpp +++ b/components/esm/loadfact.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_FACT_H #define _ESM_FACT_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -24,7 +25,7 @@ struct RankData int factReaction; // Reaction from faction members }; -struct Faction +struct Faction : public Record { std::string id, name; @@ -55,6 +56,8 @@ struct Faction void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_FACT; } }; } #endif diff --git a/components/esm/loadglob.hpp b/components/esm/loadglob.hpp index 669475fe7..8a6991490 100644 --- a/components/esm/loadglob.hpp +++ b/components/esm/loadglob.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_GLOB_H #define _ESM_GLOB_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -12,13 +13,15 @@ namespace ESM * Global script variables */ -struct Global +struct Global : public Record { unsigned value; VarType type; void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_GLOB; } }; } #endif diff --git a/components/esm/loadgmst.hpp b/components/esm/loadgmst.hpp index dc0400a4e..0854ea2aa 100644 --- a/components/esm/loadgmst.hpp +++ b/components/esm/loadgmst.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_GMST_H #define _ESM_GMST_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -13,7 +14,7 @@ namespace ESM * */ -struct GameSetting +struct GameSetting : public Record { std::string id; @@ -85,6 +86,8 @@ struct GameSetting void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_GMST; } }; } #endif diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index 6f2d5ab25..36c31a422 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_INFO_H #define _ESM_INFO_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -15,7 +16,7 @@ namespace ESM * and form a linked list of dialogue items. */ -struct DialInfo +struct DialInfo : public Record { enum Gender { @@ -100,6 +101,8 @@ struct DialInfo void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_INFO; } }; /* diff --git a/components/esm/loadingr.hpp b/components/esm/loadingr.hpp index 040118bbf..8536d5b02 100644 --- a/components/esm/loadingr.hpp +++ b/components/esm/loadingr.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_INGR_H #define _ESM_INGR_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -11,7 +12,7 @@ namespace ESM * Alchemy ingredient */ -struct Ingredient +struct Ingredient : public Record { struct IRDTstruct { @@ -27,6 +28,8 @@ struct Ingredient void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_INGR; } }; } #endif diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index ba506b63b..6a14891f1 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_LAND_H #define _ESM_LAND_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -10,7 +11,7 @@ namespace ESM * Landscape data. */ -struct Land +struct Land : public Record { Land(); ~Land(); @@ -75,6 +76,8 @@ struct Land void load(ESMReader &esm); void save(ESMWriter &esm); + int getName() { return REC_LAND; } + /** * Actually loads data */ diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index ff20ce9d1..c8591d7d2 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_LEVLISTS_H #define _ESM_LEVLISTS_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -15,7 +16,7 @@ namespace ESM * several files. */ -struct LeveledListBase +struct LeveledListBase : public Record { enum Flags { @@ -45,6 +46,14 @@ struct LeveledListBase void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() + { + if (recName[0] == 'C') + return REC_LEVC; + + return REC_LEVI; + } }; struct CreatureLevList: LeveledListBase diff --git a/components/esm/loadligh.hpp b/components/esm/loadligh.hpp index aecd8b99b..75a78ae5f 100644 --- a/components/esm/loadligh.hpp +++ b/components/esm/loadligh.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_LIGH_H #define _ESM_LIGH_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -12,7 +13,7 @@ namespace ESM * and torches. */ -struct Light +struct Light : public Record { enum Flags { @@ -43,6 +44,8 @@ struct Light void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_LIGH; } }; } #endif diff --git a/components/esm/loadlocks.hpp b/components/esm/loadlocks.hpp index 1c2a709f1..c92a56ea7 100644 --- a/components/esm/loadlocks.hpp +++ b/components/esm/loadlocks.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_LOCKS_H #define _ESM_LOCKS_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -12,7 +13,7 @@ namespace ESM * items (REPA). These have nearly identical data structures. */ -struct Tool +struct Tool : public Record { enum Type { @@ -38,16 +39,26 @@ struct Tool void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() + { + if (type == Type_Probe) + return REC_PROB; + else if (type == Type_Repair) + return REC_REPA; + else + return REC_LOCK; + } }; struct Probe: Tool { - + Probe() { type = Type_Probe; } }; struct Repair: Tool { - + Repair() { type = Type_Repair; } }; } diff --git a/components/esm/loadltex.hpp b/components/esm/loadltex.hpp index d171c8e11..994e12024 100644 --- a/components/esm/loadltex.hpp +++ b/components/esm/loadltex.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_LTEX_H #define _ESM_LTEX_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -23,13 +24,15 @@ namespace ESM * texture, and see if it affects the game. */ -struct LandTexture +struct LandTexture : public Record { std::string id, texture; int index; void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_LTEX; } }; } #endif diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index ed0b03d0b..1c95be2bc 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -1,13 +1,14 @@ #ifndef _ESM_MGEF_H #define _ESM_MGEF_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" namespace ESM { -struct MagicEffect +struct MagicEffect : public Record { enum Flags { @@ -48,6 +49,8 @@ struct MagicEffect void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_MGEF; } }; } #endif diff --git a/components/esm/loadmisc.hpp b/components/esm/loadmisc.hpp index 9aaa3c1be..3d6cdb526 100644 --- a/components/esm/loadmisc.hpp +++ b/components/esm/loadmisc.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_MISC_H #define _ESM_MISC_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -12,7 +13,7 @@ namespace ESM * carried, bought and sold. It also includes keys. */ -struct Miscellaneous +struct Miscellaneous : public Record { struct MCDTstruct { @@ -28,6 +29,8 @@ struct Miscellaneous void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_MISC; } }; } #endif diff --git a/components/esm/loadnpc.cpp b/components/esm/loadnpc.cpp index 6cb6b64c7..34b5e69ed 100644 --- a/components/esm/loadnpc.cpp +++ b/components/esm/loadnpc.cpp @@ -3,10 +3,13 @@ namespace ESM { -void NPC::load(ESMReader &esm, const std::string& id) +void NPC::setID(const std::string& id) { mId = id; +} +void NPC::load(ESMReader &esm) +{ npdt52.gold = -10; model = esm.getHNOString("MODL"); diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index 3e094a197..3f8a60304 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_NPC_H #define _ESM_NPC_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "loadcont.hpp" @@ -12,7 +13,7 @@ namespace ESM { * NPC definition */ -struct NPC +struct NPC : public Record { // Services enum Services @@ -102,8 +103,11 @@ struct NPC std::string mId; // Implementation moved to load_impl.cpp - void load(ESMReader &esm, const std::string& id); + void setID(const std::string& id); + void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_NPC_; } }; } #endif diff --git a/components/esm/loadnpcc.hpp b/components/esm/loadnpcc.hpp index a65f6a6b3..46d1bf9d2 100644 --- a/components/esm/loadnpcc.hpp +++ b/components/esm/loadnpcc.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_NPCC_H #define _ESM_NPCC_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -71,7 +72,7 @@ namespace ESM { * will be harder than reading it. */ -struct LoadNPCC +struct LoadNPCC : public Record { void load(ESMReader &esm) { @@ -80,6 +81,8 @@ struct LoadNPCC void save(ESMWriter &esm) { } + + int getName() { return REC_NPCC; } }; } #endif diff --git a/components/esm/loadpgrd.hpp b/components/esm/loadpgrd.hpp index ec339240f..db423204c 100644 --- a/components/esm/loadpgrd.hpp +++ b/components/esm/loadpgrd.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_PGRD_H #define _ESM_PGRD_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -10,7 +11,7 @@ namespace ESM /* * Path grid. */ -struct Pathgrid +struct Pathgrid : public Record { struct DATAstruct { @@ -44,6 +45,8 @@ struct Pathgrid void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_PGRD; } }; } #endif diff --git a/components/esm/loadrace.hpp b/components/esm/loadrace.hpp index 15fa43984..5c0593786 100644 --- a/components/esm/loadrace.hpp +++ b/components/esm/loadrace.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_RACE_H #define _ESM_RACE_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -12,7 +13,7 @@ namespace ESM * Race definition */ -struct Race +struct Race : public Record { struct SkillBonus { @@ -60,6 +61,8 @@ struct Race void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_RACE; } }; } #endif diff --git a/components/esm/loadregn.hpp b/components/esm/loadregn.hpp index 81b8bc51d..90444b5ad 100644 --- a/components/esm/loadregn.hpp +++ b/components/esm/loadregn.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_REGN_H #define _ESM_REGN_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -11,7 +12,7 @@ namespace ESM * Region data */ -struct Region +struct Region : public Record { #pragma pack(push) #pragma pack(1) @@ -43,6 +44,8 @@ struct Region void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_REGN; } }; } #endif diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index 55cfb053a..bf6082704 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_SCPT_H #define _ESM_SCPT_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -11,7 +12,7 @@ namespace ESM * Script definitions */ -class Script +class Script : public Record { public: struct SCHDstruct @@ -52,6 +53,8 @@ public: void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_SCPT; } }; } #endif diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index 8cc90b063..68ada6020 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -3,6 +3,7 @@ #include +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -14,7 +15,7 @@ namespace ESM { * */ -struct Skill +struct Skill : public Record { struct SKDTstruct { @@ -69,6 +70,8 @@ struct Skill void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_SKIL; } }; } #endif diff --git a/components/esm/loadsndg.hpp b/components/esm/loadsndg.hpp index e9e20c212..33b89726f 100644 --- a/components/esm/loadsndg.hpp +++ b/components/esm/loadsndg.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_SNDG_H #define _ESM_SNDG_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -11,7 +12,7 @@ namespace ESM * Sound generator. This describes the sounds a creature make. */ -struct SoundGenerator +struct SoundGenerator : public Record { enum Type { @@ -32,6 +33,8 @@ struct SoundGenerator void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_SNDG; } }; } #endif diff --git a/components/esm/loadsoun.hpp b/components/esm/loadsoun.hpp index 9f0bdf509..05663ba22 100644 --- a/components/esm/loadsoun.hpp +++ b/components/esm/loadsoun.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_SOUN_H #define _ESM_SOUN_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -12,13 +13,15 @@ struct SOUNstruct unsigned char volume, minRange, maxRange; }; -struct Sound +struct Sound : public Record { SOUNstruct data; std::string sound; void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_SOUN; } }; } #endif diff --git a/components/esm/loadspel.hpp b/components/esm/loadspel.hpp index 971bf23a4..674f7e35d 100644 --- a/components/esm/loadspel.hpp +++ b/components/esm/loadspel.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_SPEL_H #define _ESM_SPEL_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" #include "defs.hpp" @@ -8,7 +9,7 @@ namespace ESM { -struct Spell +struct Spell : public Record { enum SpellType { @@ -40,6 +41,8 @@ struct Spell void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_SPEL; } }; } #endif diff --git a/components/esm/loadsscr.hpp b/components/esm/loadsscr.hpp index 2cc7eccf9..2249b08ee 100644 --- a/components/esm/loadsscr.hpp +++ b/components/esm/loadsscr.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_SSCR_H #define _ESM_SSCR_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -15,13 +16,15 @@ namespace ESM reference. */ -struct StartScript +struct StartScript : public Record { std::string script; // Load a record and add it to the list void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_SSCR; } }; } diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index a5b82c46d..3ebbd4813 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_STAT_H #define _ESM_STAT_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -18,12 +19,14 @@ namespace ESM { * you decode the CELL blocks, if you want to test this hypothesis. */ -struct Static +struct Static : public Record { std::string model; void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_STAT; } }; } #endif diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index 8e7947bf3..4d464a7ee 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_WEAP_H #define _ESM_WEAP_H +#include "record.hpp" #include "esm_reader.hpp" #include "esm_writer.hpp" @@ -11,7 +12,7 @@ namespace ESM * Weapon definition */ -struct Weapon +struct Weapon : public Record { enum Type { @@ -58,6 +59,8 @@ struct Weapon void load(ESMReader &esm); void save(ESMWriter &esm); + + int getName() { return REC_WEAP; } }; } #endif diff --git a/components/esm/record.hpp b/components/esm/record.hpp new file mode 100644 index 000000000..666a6c15b --- /dev/null +++ b/components/esm/record.hpp @@ -0,0 +1,70 @@ +#ifndef _ESM_RECORD_H +#define _ESM_RECORD_H + +namespace ESM +{ + +enum RecNameInts +{ + REC_ACTI = 0x49544341, + REC_ALCH = 0x48434c41, + REC_APPA = 0x41505041, + REC_ARMO = 0x4f4d5241, + REC_BODY = 0x59444f42, + REC_BOOK = 0x4b4f4f42, + REC_BSGN = 0x4e475342, + REC_CELL = 0x4c4c4543, + REC_CLAS = 0x53414c43, + REC_CLOT = 0x544f4c43, + REC_CNTC = 0x43544e43, + REC_CONT = 0x544e4f43, + REC_CREA = 0x41455243, + REC_CREC = 0x43455243, + REC_DIAL = 0x4c414944, + REC_DOOR = 0x524f4f44, + REC_ENCH = 0x48434e45, + REC_FACT = 0x54434146, + REC_GLOB = 0x424f4c47, + REC_GMST = 0x54534d47, + REC_INFO = 0x4f464e49, + REC_INGR = 0x52474e49, + REC_LAND = 0x444e414c, + REC_LEVC = 0x4356454c, + REC_LEVI = 0x4956454c, + REC_LIGH = 0x4847494c, + REC_LOCK = 0x4b434f4c, + REC_LTEX = 0x5845544c, + REC_MGEF = 0x4645474d, + REC_MISC = 0x4353494d, + REC_NPC_ = 0x5f43504e, + REC_NPCC = 0x4343504e, + REC_PGRD = 0x44524750, + REC_PROB = 0x424f5250, + REC_RACE = 0x45434152, + REC_REGN = 0x4e474552, + REC_REPA = 0x41504552, + REC_SCPT = 0x54504353, + REC_SKIL = 0x4c494b53, + REC_SNDG = 0x47444e53, + REC_SOUN = 0x4e554f53, + REC_SPEL = 0x4c455053, + REC_SSCR = 0x52435353, + REC_STAT = 0x54415453, + REC_WEAP = 0x50414557 +}; + +class ESMReader; +class ESMWriter; + +class Record +{ +public: + virtual void load(ESMReader& esm) = 0; + virtual void save(ESMWriter& esm) = 0; + + virtual int getName() = 0; +}; + +} + +#endif diff --git a/components/esm/records.hpp b/components/esm/records.hpp index 704a11609..e05f74f5d 100644 --- a/components/esm/records.hpp +++ b/components/esm/records.hpp @@ -1,6 +1,7 @@ #ifndef _ESM_RECORDS_H #define _ESM_RECORDS_H +#include "record.hpp" #include "loadacti.hpp" #include "loadalch.hpp" #include "loadappa.hpp" @@ -45,57 +46,4 @@ // Special records which are not loaded from ESM #include "attr.hpp" - -namespace ESM { - -// Integer versions of all the record names, used for faster lookup -enum RecNameInts - { - REC_ACTI = 0x49544341, - REC_ALCH = 0x48434c41, - REC_APPA = 0x41505041, - REC_ARMO = 0x4f4d5241, - REC_BODY = 0x59444f42, - REC_BOOK = 0x4b4f4f42, - REC_BSGN = 0x4e475342, - REC_CELL = 0x4c4c4543, - REC_CLAS = 0x53414c43, - REC_CLOT = 0x544f4c43, - REC_CNTC = 0x43544e43, - REC_CONT = 0x544e4f43, - REC_CREA = 0x41455243, - REC_CREC = 0x43455243, - REC_DIAL = 0x4c414944, - REC_DOOR = 0x524f4f44, - REC_ENCH = 0x48434e45, - REC_FACT = 0x54434146, - REC_GLOB = 0x424f4c47, - REC_GMST = 0x54534d47, - REC_INFO = 0x4f464e49, - REC_INGR = 0x52474e49, - REC_LAND = 0x444e414c, - REC_LEVC = 0x4356454c, - REC_LEVI = 0x4956454c, - REC_LIGH = 0x4847494c, - REC_LOCK = 0x4b434f4c, - REC_LTEX = 0x5845544c, - REC_MGEF = 0x4645474d, - REC_MISC = 0x4353494d, - REC_NPC_ = 0x5f43504e, - REC_NPCC = 0x4343504e, - REC_PGRD = 0x44524750, - REC_PROB = 0x424f5250, - REC_RACE = 0x45434152, - REC_REGN = 0x4e474552, - REC_REPA = 0x41504552, - REC_SCPT = 0x54504353, - REC_SKIL = 0x4c494b53, - REC_SNDG = 0x47444e53, - REC_SOUN = 0x4e554f53, - REC_SPEL = 0x4c455053, - REC_SSCR = 0x52435353, - REC_STAT = 0x54415453, - REC_WEAP = 0x50414557 - }; -} #endif diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index d7a4100aa..bc3b676a2 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -104,7 +104,8 @@ namespace ESMS void load(ESMReader &esm, const std::string &id) { std::string id2 = toLower (id); - list[id2].load(esm, id2); + list[id2].setID(id2); + list[id2].load(esm); } // Find the given object ID, or return NULL if not found.