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 description;
int version;
ESM::ESMReader::MasterList masters;
std::vector<ESM::Header::MasterData> masters;
std::deque<EsmTool::RecordBase *> mRecords;
std::map<ESM::Cell *, std::deque<ESM::CellRef> > mCellRefs;
@ -289,7 +289,7 @@ int load(Arguments& info)
std::cout << "Author: " << esm.getAuthor() << std::endl
<< "Description: " << esm.getDesc() << 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())
{
std::cout << "Masters:" << std::endl;
@ -427,7 +427,7 @@ int clone(Arguments& info)
esm.setDescription(info.data.description);
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);
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;
/// \todo Move this to somewhere else. ESMReader?
// Cache parent esX files by tracking their indices in the global list of
// all files/readers used by the engine. This will greaty accelerate
// refnumber mangling, as required for handling moved references.
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();
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;
for (int i = 0; i < esm.getIndex(); i++) {
const std::string &candidate = allPlugins->at(i).getContext().filename;

@ -2,6 +2,8 @@
#define OPENMW_ESM_COMMON_H
#include <string>
#include <vector>
#include <cstring>
#include <libs/platform/stdint.h>
#include <libs/platform/string.h>
@ -43,6 +45,8 @@ union NAME_T
bool operator!=(int v) const { return v != val; }
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;
@ -53,27 +57,37 @@ typedef NAME_T<256> NAME256;
#pragma pack(push)
#pragma pack(1)
/// File header data for all ES files
struct HEDRstruct
struct Header
{
/* File format version. This is actually a float, the supported
versions are 1.2 and 1.3. These correspond to:
1.2 = 0x3f99999a and 1.3 = 0x3fa66666
*/
int version;
int type; // 0=esp, 1=esm, 32=ess (unused)
NAME32 author; // Author's name
NAME256 desc; // File description
int records; // Number of records? Not used.
struct Data
{
/* File format version. This is actually a float, the supported
versions are 1.2 and 1.3. These correspond to:
1.2 = 0x3f99999a and 1.3 = 0x3fa66666
*/
int version;
int type; // 0=esp, 1=esm, 32=ess (unused)
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
struct SaveData
{
@ -95,7 +109,7 @@ struct ESM_Context
uint32_t leftRec, leftSub;
size_t leftFile;
NAME recName, subName;
HEDRstruct header;
Header::Data header;
// 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
// 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();
// 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.
while (isNextSub("MAST"))
{
MasterData m;
Header::MasterData m;
m.name = getHString();
m.size = getHNLong("DATA");
mMasters.push_back(m);
mHeader.mMaster.push_back(m);
}
}

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

@ -1,6 +1,5 @@
#include "esmwriter.hpp"
#include <fstream>
#include <cstring>
bool count = true;
@ -9,30 +8,30 @@ namespace ESM
int ESMWriter::getVersion()
{
return m_header.version;
return mHeader.mData.version;
}
void ESMWriter::setVersion(int ver)
{
m_header.version = ver;
mHeader.mData.version = ver;
}
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)
{
strncpy((char*)&m_header.desc, desc.c_str(), 256);
mHeader.mData.desc.assign (desc);
}
void ESMWriter::addMaster(const std::string& name, uint64_t size)
{
MasterData d;
Header::MasterData d;
d.name = name;
d.size = size;
m_masters.push_back(d);
mHeader.mMaster.push_back(d);
}
void ESMWriter::save(const std::string& file)
@ -48,11 +47,12 @@ void ESMWriter::save(std::ostream& file)
startRecord("TES3", 0);
m_header.records = 0;
writeHNT("HEDR", m_header, 300);
mHeader.mData.records = 0;
writeHNT("HEDR", mHeader.mData, 300);
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);
writeHNT("DATA", it->size);

@ -88,14 +88,13 @@ public:
void write(const char* data, size_t size);
private:
std::list<MasterData> m_masters;
std::list<RecordData> m_records;
std::ostream* m_stream;
std::streampos m_headerPos;
ToUTF8::Utf8Encoder* m_encoder;
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.
// In this case, do not spawn a new reference, but overwrite the old one.
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;
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;
size_t global = esm.getIndex() + 1;
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;
mref.mRefnum |= global << 24; // insert global plugin ID

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

Loading…
Cancel
Save