1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-25 21:39:42 +00:00
openmw/components/esm/esm4reader.cpp
cc9cii 6ec6b9bc2a OpenMW Integration.
Read the ESM/ESP records but do nothing with them for the moment.
2018-10-07 08:55:30 +11:00

94 lines
3.1 KiB
C++

#include "esm4reader.hpp"
ESM::ESM4Reader::ESM4Reader(bool oldHeader)
{
// TES4 header size is 4 bytes smaller than TES5 header
mReader.setRecHeaderSize(oldHeader ? sizeof(ESM4::RecordHeader)-4 : sizeof(ESM4::RecordHeader));
}
ESM::ESM4Reader::~ESM4Reader()
{
}
void ESM::ESM4Reader::openTes4File(const std::string &name)
{
mCtx.filename = name;
// WARNING: may throw
mCtx.leftFile = mReader.openTes4File(name);
mReader.registerForUpdates(this); // for updating mCtx.leftFile
mReader.getRecordHeader();
if (mReader.hdr().record.typeId == ESM4::REC_TES4)
{
mReader.loadHeader();
mCtx.leftFile -= mReader.hdr().record.dataSize;
// Hack: copy over values to TES3 header for getVer() and getRecordCount() to work
mHeader.mData.version = mReader.esmVersion();
mHeader.mData.records = mReader.numRecords();
mReader.buildLStringIndex(); // for localised strings in Skyrim
}
else
fail("Unknown file format");
}
ESM4::ReaderContext ESM::ESM4Reader::getESM4Context()
{
return mReader.getContext();
}
void ESM::ESM4Reader::restoreESM4Context(const ESM4::ReaderContext& ctx)
{
// Reopen the file if necessary
if (mCtx.filename != ctx.filename)
openTes4File(ctx.filename);
// mCtx.leftFile is the only thing used in the old context. Strictly speaking, updating it
// with the correct value is not really necessary since we're not going to load the rest of
// the file (most likely to load a CELL or LAND then be done with it).
mCtx.leftFile = mReader.getFileSize() - mReader.getFileOffset();
// restore group stack, load the header, etc.
mReader.restoreContext(ctx);
}
void ESM::ESM4Reader::restoreCellChildrenContext(const ESM4::ReaderContext& ctx)
{
// Reopen the file if necessary
if (mCtx.filename != ctx.filename)
openTes4File(ctx.filename);
mReader.restoreContext(ctx); // restore group stack, load the CELL header, etc.
if (mReader.hdr().record.typeId != ESM4::REC_CELL) // FIXME: testing only
fail("Restore Cell Children failed");
mReader.skipRecordData(); // skip the CELL record
mReader.getRecordHeader(); // load the header for cell child group (hopefully)
// this is a hack to load only the cell child group...
if (mReader.hdr().group.typeId == ESM4::REC_GRUP && mReader.hdr().group.type == ESM4::Grp_CellChild)
{
mCtx.leftFile = mReader.hdr().group.groupSize - ctx.recHeaderSize;
return;
}
// But some cells may have no child groups...
// Suspect "ICMarketDistrict" 7 18 is one, followed by cell record 00165F2C "ICMarketDistrict" 6 17
if (mReader.hdr().group.typeId != ESM4::REC_GRUP && mReader.hdr().record.typeId == ESM4::REC_CELL)
{
mCtx.leftFile = 0;
return;
}
// Maybe the group is completed
// See "ICMarketDistrict" 9 15 which is followed by a exterior sub-cell block
ESM4::ReaderContext tempCtx = mReader.getContext();
if (!tempCtx.groupStack.empty() && tempCtx.groupStack.back().second == 0)
{
mCtx.leftFile = 0;
return;
}
else
fail("Restore Cell Children failed");
}