restructuring tes3 record structs

pull/16/head
Marc Zinnschlag 12 years ago
parent b085c4f749
commit 9e68a420ae

@ -23,7 +23,7 @@ struct ESMData
std::string author; std::string author;
std::string description; std::string description;
int version; int version;
ESM::ESMReader::MasterList masters; std::vector<ESM::Header::MasterData> masters;
std::deque<EsmTool::RecordBase *> mRecords; std::deque<EsmTool::RecordBase *> mRecords;
std::map<ESM::Cell *, std::deque<ESM::CellRef> > mCellRefs; std::map<ESM::Cell *, std::deque<ESM::CellRef> > mCellRefs;
@ -289,7 +289,7 @@ int load(Arguments& info)
std::cout << "Author: " << esm.getAuthor() << std::endl std::cout << "Author: " << esm.getAuthor() << std::endl
<< "Description: " << esm.getDesc() << std::endl << "Description: " << esm.getDesc() << std::endl
<< "File format version: " << esm.getFVer() << std::endl; << "File format version: " << esm.getFVer() << std::endl;
ESM::ESMReader::MasterList m = esm.getMasters(); std::vector<ESM::Header::MasterData> m = esm.getMasters();
if (!m.empty()) if (!m.empty())
{ {
std::cout << "Masters:" << std::endl; std::cout << "Masters:" << std::endl;
@ -427,7 +427,7 @@ int clone(Arguments& info)
esm.setDescription(info.data.description); esm.setDescription(info.data.description);
esm.setVersion(info.data.version); esm.setVersion(info.data.version);
for (ESM::ESMReader::MasterList::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it) for (std::vector<ESM::Header::MasterData>::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it)
esm.addMaster(it->name, it->size); esm.addMaster(it->name, it->size);
std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary); std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary);

@ -27,14 +27,15 @@ void ESMStore::load(ESM::ESMReader &esm)
ESM::Dialogue *dialogue = 0; ESM::Dialogue *dialogue = 0;
/// \todo Move this to somewhere else. ESMReader?
// Cache parent esX files by tracking their indices in the global list of // Cache parent esX files by tracking their indices in the global list of
// all files/readers used by the engine. This will greaty accelerate // all files/readers used by the engine. This will greaty accelerate
// refnumber mangling, as required for handling moved references. // refnumber mangling, as required for handling moved references.
int index = ~0; int index = ~0;
const ESM::ESMReader::MasterList &masters = esm.getMasters(); const std::vector<ESM::Header::MasterData> &masters = esm.getMasters();
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList(); std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
for (size_t j = 0; j < masters.size(); j++) { for (size_t j = 0; j < masters.size(); j++) {
ESM::MasterData &mast = const_cast<ESM::MasterData&>(masters[j]); ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
std::string fname = mast.name; std::string fname = mast.name;
for (int i = 0; i < esm.getIndex(); i++) { for (int i = 0; i < esm.getIndex(); i++) {
const std::string &candidate = allPlugins->at(i).getContext().filename; const std::string &candidate = allPlugins->at(i).getContext().filename;

@ -2,6 +2,8 @@
#define OPENMW_ESM_COMMON_H #define OPENMW_ESM_COMMON_H
#include <string> #include <string>
#include <vector>
#include <cstring>
#include <libs/platform/stdint.h> #include <libs/platform/stdint.h>
#include <libs/platform/string.h> #include <libs/platform/string.h>
@ -43,6 +45,8 @@ union NAME_T
bool operator!=(int v) const { return v != val; } bool operator!=(int v) const { return v != val; }
std::string toString() const { return std::string(name, strnlen(name, LEN)); } std::string toString() const { return std::string(name, strnlen(name, LEN)); }
void assign (const std::string& value) { std::strncpy (name, value.c_str(), LEN); }
}; };
typedef NAME_T<4> NAME; typedef NAME_T<4> NAME;
@ -53,27 +57,37 @@ typedef NAME_T<256> NAME256;
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)
/// File header data for all ES files /// File header data for all ES files
struct HEDRstruct struct Header
{ {
/* File format version. This is actually a float, the supported struct Data
versions are 1.2 and 1.3. These correspond to: {
1.2 = 0x3f99999a and 1.3 = 0x3fa66666 /* File format version. This is actually a float, the supported
*/ versions are 1.2 and 1.3. These correspond to:
int version; 1.2 = 0x3f99999a and 1.3 = 0x3fa66666
int type; // 0=esp, 1=esm, 32=ess (unused) */
NAME32 author; // Author's name int version;
NAME256 desc; // File description int type; // 0=esp, 1=esm, 32=ess (unused)
int records; // Number of records? Not used. NAME32 author; // Author's name
NAME256 desc; // File description
int records; // Number of records? Not used.
};
// Defines another files (esm or esp) that this file depends upon.
struct MasterData
{
std::string name;
uint64_t size;
int index; // Position of the parent file in the global list of loaded files
};
Data mData;
std::vector<MasterData> mMaster;
}; };
#pragma pack(pop)
// Defines another files (esm or esp) that this file depends upon.
struct MasterData
{
std::string name;
uint64_t size;
int index; // Position of the parent file in the global list of loaded files
};
#pragma pack(push)
#pragma pack(1)
// Data that is only present in save game files // Data that is only present in save game files
struct SaveData struct SaveData
{ {
@ -95,7 +109,7 @@ struct ESM_Context
uint32_t leftRec, leftSub; uint32_t leftRec, leftSub;
size_t leftFile; size_t leftFile;
NAME recName, subName; NAME recName, subName;
HEDRstruct header; Header::Data header;
// When working with multiple esX files, we will generate lists of all files that // When working with multiple esX files, we will generate lists of all files that
// actually contribute to a specific cell. Therefore, we need to store the index // actually contribute to a specific cell. Therefore, we need to store the index
// of the file belonging to this contest. See CellStore::(list/load)refs for details. // of the file belonging to this contest. See CellStore::(list/load)refs for details.

@ -63,16 +63,17 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
getRecHeader(); getRecHeader();
// Get the header // Get the header
getHNT(mCtx.header, "HEDR", 300); getHNT (mHeader.mData, "HEDR", 300);
mCtx.header = mHeader.mData;
// Some mods abuse the header.version field for the version of the mod instead of the version of the file format, so we can only ignore it. // Some mods abuse the header.version field for the version of the mod instead of the version of the file format, so we can only ignore it.
while (isNextSub("MAST")) while (isNextSub("MAST"))
{ {
MasterData m; Header::MasterData m;
m.name = getHString(); m.name = getHString();
m.size = getHNLong("DATA"); m.size = getHNLong("DATA");
mMasters.push_back(m); mHeader.mMaster.push_back(m);
} }
} }

@ -22,25 +22,17 @@ public:
ESMReader(void); ESMReader(void);
/*************************************************************************
*
* Public type definitions
*
*************************************************************************/
typedef std::vector<MasterData> MasterList;
/************************************************************************* /*************************************************************************
* *
* Information retrieval * Information retrieval
* *
*************************************************************************/ *************************************************************************/
int getVer() const { return mCtx.header.version; } int getVer() const { return mHeader.mData.version; }
float getFVer() const { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; } float getFVer() const { if(mHeader.mData.version == VER_12) return 1.2; else return 1.3; }
const std::string getAuthor() const { return mCtx.header.author.toString(); } const std::string getAuthor() const { return mHeader.mData.author.toString(); }
const std::string getDesc() const { return mCtx.header.desc.toString(); } const std::string getDesc() const { return mHeader.mData.desc.toString(); }
const MasterList &getMasters() const { return mMasters; } const std::vector<Header::MasterData> &getMasters() const { return mHeader.mMaster; }
const NAME &retSubName() const { return mCtx.subName; } const NAME &retSubName() const { return mCtx.subName; }
uint32_t getSubSize() const { return mCtx.leftSub; } uint32_t getSubSize() const { return mCtx.leftSub; }
@ -264,7 +256,8 @@ private:
// Buffer for ESM strings // Buffer for ESM strings
std::vector<char> mBuffer; std::vector<char> mBuffer;
MasterList mMasters; Header mHeader;
std::vector<ESMReader> *mGlobalReaderList; std::vector<ESMReader> *mGlobalReaderList;
ToUTF8::Utf8Encoder* mEncoder; ToUTF8::Utf8Encoder* mEncoder;
}; };

@ -1,6 +1,5 @@
#include "esmwriter.hpp" #include "esmwriter.hpp"
#include <fstream> #include <fstream>
#include <cstring>
bool count = true; bool count = true;
@ -9,30 +8,30 @@ namespace ESM
int ESMWriter::getVersion() int ESMWriter::getVersion()
{ {
return m_header.version; return mHeader.mData.version;
} }
void ESMWriter::setVersion(int ver) void ESMWriter::setVersion(int ver)
{ {
m_header.version = ver; mHeader.mData.version = ver;
} }
void ESMWriter::setAuthor(const std::string& auth) void ESMWriter::setAuthor(const std::string& auth)
{ {
strncpy((char*)&m_header.author, auth.c_str(), 32); mHeader.mData.author.assign (auth);
} }
void ESMWriter::setDescription(const std::string& desc) void ESMWriter::setDescription(const std::string& desc)
{ {
strncpy((char*)&m_header.desc, desc.c_str(), 256); mHeader.mData.desc.assign (desc);
} }
void ESMWriter::addMaster(const std::string& name, uint64_t size) void ESMWriter::addMaster(const std::string& name, uint64_t size)
{ {
MasterData d; Header::MasterData d;
d.name = name; d.name = name;
d.size = size; d.size = size;
m_masters.push_back(d); mHeader.mMaster.push_back(d);
} }
void ESMWriter::save(const std::string& file) void ESMWriter::save(const std::string& file)
@ -48,11 +47,12 @@ void ESMWriter::save(std::ostream& file)
startRecord("TES3", 0); startRecord("TES3", 0);
m_header.records = 0; mHeader.mData.records = 0;
writeHNT("HEDR", m_header, 300); writeHNT("HEDR", mHeader.mData, 300);
m_headerPos = m_stream->tellp() - (std::streampos)4; m_headerPos = m_stream->tellp() - (std::streampos)4;
for (std::list<MasterData>::iterator it = m_masters.begin(); it != m_masters.end(); ++it) for (std::vector<Header::MasterData>::iterator it = mHeader.mMaster.begin();
it != mHeader.mMaster.end(); ++it)
{ {
writeHNCString("MAST", it->name); writeHNCString("MAST", it->name);
writeHNT("DATA", it->size); writeHNT("DATA", it->size);

@ -88,14 +88,13 @@ public:
void write(const char* data, size_t size); void write(const char* data, size_t size);
private: private:
std::list<MasterData> m_masters;
std::list<RecordData> m_records; std::list<RecordData> m_records;
std::ostream* m_stream; std::ostream* m_stream;
std::streampos m_headerPos; std::streampos m_headerPos;
ToUTF8::Utf8Encoder* m_encoder; ToUTF8::Utf8Encoder* m_encoder;
int m_recordCount; int m_recordCount;
HEDRstruct m_header; Header mHeader;
}; };
} }

@ -245,7 +245,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
// If the most significant 8 bits are used, then this reference already exists. // If the most significant 8 bits are used, then this reference already exists.
// In this case, do not spawn a new reference, but overwrite the old one. // In this case, do not spawn a new reference, but overwrite the old one.
ref.mRefnum &= 0x00ffffff; // delete old plugin ID ref.mRefnum &= 0x00ffffff; // delete old plugin ID
const ESM::ESMReader::MasterList &masters = esm.getMasters(); const std::vector<Header::MasterData> &masters = esm.getMasters();
global = masters[local-1].index + 1; global = masters[local-1].index + 1;
ref.mRefnum |= global << 24; // insert global plugin ID ref.mRefnum |= global << 24; // insert global plugin ID
} }
@ -348,7 +348,7 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref)
int local = (mref.mRefnum & 0xff000000) >> 24; int local = (mref.mRefnum & 0xff000000) >> 24;
size_t global = esm.getIndex() + 1; size_t global = esm.getIndex() + 1;
mref.mRefnum &= 0x00ffffff; // delete old plugin ID mref.mRefnum &= 0x00ffffff; // delete old plugin ID
const ESM::ESMReader::MasterList &masters = esm.getMasters(); const std::vector<Header::MasterData> &masters = esm.getMasters();
global = masters[local-1].index + 1; global = masters[local-1].index + 1;
mref.mRefnum |= global << 24; // insert global plugin ID mref.mRefnum |= global << 24; // insert global plugin ID

@ -157,7 +157,7 @@ Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const
if (!file) if (!file)
return Qt::NoItemFlags; return Qt::NoItemFlags;
if (canBeChecked(file)) { if (canBeChecked(file)) {
if (index.column() == 0) { if (index.column() == 0) {
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
} else { } else {
@ -226,7 +226,7 @@ bool lessThanEsmFile(const EsmFile *e1, const EsmFile *e2)
return true; return true;
if (!e1->fileName().endsWith(".esm") && e2->fileName().endsWith(".esm")) if (!e1->fileName().endsWith(".esm") && e2->fileName().endsWith(".esm"))
return false; return false;
return e1->fileName().toLower() < e2->fileName().toLower(); return e1->fileName().toLower() < e2->fileName().toLower();
} }
@ -281,7 +281,7 @@ void DataFilesModel::addFiles(const QString &path)
fileReader.setEncoder(&encoder); fileReader.setEncoder(&encoder);
fileReader.open(dir.absoluteFilePath(path).toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters(); std::vector<ESM::Header::MasterData> mlist = fileReader.getMasters();
QStringList masters; QStringList masters;
for (unsigned int i = 0; i < mlist.size(); ++i) { for (unsigned int i = 0; i < mlist.size(); ++i) {
@ -369,10 +369,10 @@ QStringList DataFilesModel::checkedItems()
QStringList DataFilesModel::checkedItemsPaths() QStringList DataFilesModel::checkedItemsPaths()
{ {
QStringList list; QStringList list;
QList<EsmFile *>::ConstIterator it; QList<EsmFile *>::ConstIterator it;
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd(); QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
int i = 0; int i = 0;
for (it = mFiles.constBegin(); it != itEnd; ++it) { for (it = mFiles.constBegin(); it != itEnd; ++it) {
EsmFile *file = item(i); EsmFile *file = item(i);
@ -381,7 +381,7 @@ QStringList DataFilesModel::checkedItemsPaths()
if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file))
list << file->path(); list << file->path();
} }
return list; return list;
} }

Loading…
Cancel
Save