diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 912ad0d683..b83c711476 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -896,9 +896,6 @@ namespace EsmTool if (const ESM::Land::LandData* data = mData.getLandData(mData.mDataTypes)) { std::cout << " Height Offset: " << data->mHeightOffset << std::endl; - // Lots of missing members. - std::cout << " Unknown1: " << data->mUnk1 << std::endl; - std::cout << " Unknown2: " << static_cast(data->mUnk2) << std::endl; } mData.unloadData(); std::cout << " Deleted: " << mIsDeleted << std::endl; diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp index 4c4bd1e438..ebb0c9d281 100644 --- a/apps/essimporter/converter.cpp +++ b/apps/essimporter/converter.cpp @@ -232,7 +232,7 @@ namespace ESSImport esm.skip(4); } - esm.getExact(nam8, 32); + esm.getT(nam8); newcell.mFogOfWar.reserve(16 * 16); for (int x = 0; x < 16; ++x) diff --git a/apps/essimporter/importcellref.cpp b/apps/essimporter/importcellref.cpp index 56e888d3f6..9e8e9a6948 100644 --- a/apps/essimporter/importcellref.cpp +++ b/apps/essimporter/importcellref.cpp @@ -1,10 +1,30 @@ #include "importcellref.hpp" #include +#include + #include namespace ESSImport { + template T> + void decompose(T&& v, const auto& f) + { + f(v.mUnknown, v.mFlags, v.mBreathMeter, v.mUnknown2, v.mDynamic, v.mUnknown3, v.mAttributes, v.mMagicEffects, + v.mUnknown4, v.mGoldPool, v.mCountDown, v.mUnknown5); + } + + template T> + void decompose(T&& v, const auto& f) + { + f(v.mUnknown1, v.mFlags, v.mUnknown2, v.mCorpseClearCountdown, v.mUnknown3); + } + + template T> + void decompose(T&& v, const auto& f) + { + f(v.mGroupIndex, v.mUnknown, v.mTime); + } void CellRef::load(ESM::ESMReader& esm) { @@ -45,14 +65,9 @@ namespace ESSImport bool isDeleted = false; ESM::CellRef::loadData(esm, isDeleted); - mActorData.mHasACDT - = esm.getHNOT("ACDT", mActorData.mACDT.mUnknown, mActorData.mACDT.mFlags, mActorData.mACDT.mBreathMeter, - mActorData.mACDT.mUnknown2, mActorData.mACDT.mDynamic, mActorData.mACDT.mUnknown3, - mActorData.mACDT.mAttributes, mActorData.mACDT.mMagicEffects, mActorData.mACDT.mUnknown4, - mActorData.mACDT.mGoldPool, mActorData.mACDT.mCountDown, mActorData.mACDT.mUnknown5); + mActorData.mHasACDT = esm.getOptionalComposite("ACDT", mActorData.mACDT); - mActorData.mHasACSC = esm.getHNOT("ACSC", mActorData.mACSC.mUnknown1, mActorData.mACSC.mFlags, - mActorData.mACSC.mUnknown2, mActorData.mACSC.mCorpseClearCountdown, mActorData.mACSC.mUnknown3); + mActorData.mHasACSC = esm.getOptionalComposite("ACSC", mActorData.mACSC); if (esm.isNextSub("ACSL")) esm.skipHSubSize(112); @@ -127,8 +142,7 @@ namespace ESSImport if (esm.isNextSub("ND3D")) esm.skipHSub(); - mActorData.mHasANIS - = esm.getHNOT("ANIS", mActorData.mANIS.mGroupIndex, mActorData.mANIS.mUnknown, mActorData.mANIS.mTime); + mActorData.mHasANIS = esm.getOptionalComposite("ANIS", mActorData.mANIS); if (esm.isNextSub("LVCR")) { @@ -146,7 +160,7 @@ namespace ESSImport // I've seen DATA *twice* on a creature record, and with the exact same content too! weird // alarmvoi0000.ess for (int i = 0; i < 2; ++i) - esm.getHNOT("DATA", mPos.pos, mPos.rot); + esm.getOptionalComposite("DATA", mPos); mDeleted = 0; if (esm.isNextSub("DELE")) diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index 76b685c8a3..5cc9a8259b 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -135,7 +135,7 @@ namespace ESSImport sub.mFileOffset = esm.getFileOffset(); sub.mName = esm.retSubName().toString(); sub.mData.resize(esm.getSubSize()); - esm.getExact(&sub.mData[0], sub.mData.size()); + esm.getExact(sub.mData.data(), sub.mData.size()); rec.mSubrecords.push_back(sub); } file.mRecords.push_back(rec); diff --git a/components/esm/luascripts.cpp b/components/esm/luascripts.cpp index 8f2048d8a7..71e2ce6dc1 100644 --- a/components/esm/luascripts.cpp +++ b/components/esm/luascripts.cpp @@ -38,7 +38,7 @@ std::string ESM::loadLuaBinaryData(ESMReader& esm) { esm.getSubHeader(); data.resize(esm.getSubSize()); - esm.getExact(data.data(), static_cast(data.size())); + esm.getExact(data.data(), data.size()); } return data; } diff --git a/components/esm3/esmreader.cpp b/components/esm3/esmreader.cpp index c52e739f5f..4f69b8edef 100644 --- a/components/esm3/esmreader.cpp +++ b/components/esm3/esmreader.cpp @@ -153,7 +153,7 @@ namespace ESM { if (isNextSub(name)) return getHString(); - return ""; + return {}; } ESM::RefId ESMReader::getHNORefId(NAME name) @@ -244,21 +244,6 @@ namespace ESM skipHString(); } - void ESMReader::getHExact(void* p, std::size_t size) - { - getSubHeader(); - if (size != mCtx.leftSub) - reportSubSizeMismatch(size, mCtx.leftSub); - getExact(p, size); - } - - // Read the given number of bytes from a named subrecord - void ESMReader::getHNExact(void* p, std::size_t size, NAME name) - { - getSubNameIs(name); - getHExact(p, size); - } - FormId ESMReader::getFormId(bool wide, NAME tag) { FormId res; @@ -316,7 +301,7 @@ namespace ESM // reading the subrecord data anyway. const std::size_t subNameSize = decltype(mCtx.subName)::sCapacity; - getExact(mCtx.subName.mData, static_cast(subNameSize)); + getExact(mCtx.subName.mData, subNameSize); mCtx.leftRec -= static_cast(subNameSize); } @@ -506,7 +491,7 @@ namespace ESM case RefIdType::Generated: { std::uint64_t generated{}; - getExact(&generated, sizeof(std::uint64_t)); + getT(generated); return RefId::generated(generated); } case RefIdType::Index: @@ -514,14 +499,14 @@ namespace ESM RecNameInts recordType{}; getExact(&recordType, sizeof(std::uint32_t)); std::uint32_t index{}; - getExact(&index, sizeof(std::uint32_t)); + getT(index); return RefId::index(recordType, index); } case RefIdType::ESM3ExteriorCell: { int32_t x, y; - getExact(&x, sizeof(std::int32_t)); - getExact(&y, sizeof(std::int32_t)); + getT(x); + getT(y); return RefId::esm3ExteriorCell(x, y); } } @@ -529,7 +514,7 @@ namespace ESM fail("Unsupported RefIdType: " + std::to_string(static_cast(refIdType))); } - [[noreturn]] void ESMReader::fail(const std::string& msg) + [[noreturn]] void ESMReader::fail(std::string_view msg) { std::stringstream ss; diff --git a/components/esm3/esmreader.hpp b/components/esm3/esmreader.hpp index b67cc0f8bb..5af5e75573 100644 --- a/components/esm3/esmreader.hpp +++ b/components/esm3/esmreader.hpp @@ -237,12 +237,6 @@ namespace ESM void skipHRefId(); - // Read the given number of bytes from a subrecord - void getHExact(void* p, std::size_t size); - - // Read the given number of bytes from a named subrecord - void getHNExact(void* p, std::size_t size, NAME name); - ESM::FormId getFormId(bool wide = false, NAME tag = "FRMR"); /************************************************************************* @@ -354,7 +348,7 @@ namespace ESM } /// Used for error handling - [[noreturn]] void fail(const std::string& msg); + [[noreturn]] void fail(std::string_view msg); /// Sets font encoder for ESM strings void setEncoder(ToUTF8::Utf8Encoder* encoder) { mEncoder = encoder; } diff --git a/components/esm3/esmwriter.cpp b/components/esm3/esmwriter.cpp index ad64ced0a4..47c861e3ca 100644 --- a/components/esm3/esmwriter.cpp +++ b/components/esm3/esmwriter.cpp @@ -97,14 +97,14 @@ namespace ESM mHeader.mData.type = type; } - void ESMWriter::setAuthor(const std::string& auth) + void ESMWriter::setAuthor(std::string_view auth) { - mHeader.mData.author.assign(auth); + mHeader.mData.author = auth; } - void ESMWriter::setDescription(const std::string& desc) + void ESMWriter::setDescription(std::string_view desc) { - mHeader.mData.desc.assign(desc); + mHeader.mData.desc = desc; } void ESMWriter::setRecordCount(int count) @@ -122,7 +122,7 @@ namespace ESM mHeader.mMaster.clear(); } - void ESMWriter::addMaster(const std::string& name, uint64_t size) + void ESMWriter::addMaster(std::string_view name, uint64_t size) { Header::MasterData d; d.name = name; @@ -208,14 +208,14 @@ namespace ESM endRecord(NAME(name)); } - void ESMWriter::writeHNString(NAME name, const std::string& data) + void ESMWriter::writeHNString(NAME name, std::string_view data) { startSubRecord(name); writeHString(data); endRecord(name); } - void ESMWriter::writeHNString(NAME name, const std::string& data, size_t size) + void ESMWriter::writeHNString(NAME name, std::string_view data, size_t size) { assert(data.size() <= size); startSubRecord(name); @@ -278,9 +278,9 @@ namespace ESM write(string.c_str(), string.size()); } - void ESMWriter::writeHString(const std::string& data) + void ESMWriter::writeHString(std::string_view data) { - if (data.size() == 0) + if (data.empty()) write("\0", 1); else { @@ -291,7 +291,7 @@ namespace ESM } } - void ESMWriter::writeHCString(const std::string& data) + void ESMWriter::writeHCString(std::string_view data) { writeHString(data); if (data.size() > 0 && data[data.size() - 1] != '\0') diff --git a/components/esm3/esmwriter.hpp b/components/esm3/esmwriter.hpp index 101246fe43..96445bcdae 100644 --- a/components/esm3/esmwriter.hpp +++ b/components/esm3/esmwriter.hpp @@ -38,8 +38,8 @@ namespace ESM void setVersion(unsigned int ver = 0x3fa66666); void setType(int type); void setEncoder(ToUTF8::Utf8Encoder* encoding); - void setAuthor(const std::string& author); - void setDescription(const std::string& desc); + void setAuthor(std::string_view author); + void setDescription(std::string_view desc); void setHeader(const Header& value) { mHeader = value; } // Set the record count for writing it in the file header @@ -54,7 +54,7 @@ namespace ESM void clearMaster(); - void addMaster(const std::string& name, uint64_t size); + void addMaster(std::string_view name, uint64_t size); void save(std::ostream& file); ///< Start saving a file by writing the TES3 header. @@ -62,20 +62,20 @@ namespace ESM void close(); ///< \note Does not close the stream. - void writeHNString(NAME name, const std::string& data); - void writeHNString(NAME name, const std::string& data, size_t size); - void writeHNCString(NAME name, const std::string& data) + void writeHNString(NAME name, std::string_view data); + void writeHNString(NAME name, std::string_view data, size_t size); + void writeHNCString(NAME name, std::string_view data) { startSubRecord(name); writeHCString(data); endRecord(name); } - void writeHNOString(NAME name, const std::string& data) + void writeHNOString(NAME name, std::string_view data) { if (!data.empty()) writeHNString(name, data); } - void writeHNOCString(NAME name, const std::string& data) + void writeHNOCString(NAME name, std::string_view data) { if (!data.empty()) writeHNCString(name, data); @@ -140,6 +140,7 @@ namespace ESM // state being discarded without any error on writing or reading it. :( // writeHNString and friends must be used instead. void writeHNT(NAME name, const std::string& data) = delete; + void writeHNT(NAME name, std::string_view data) = delete; void writeT(NAME data) = delete; @@ -181,8 +182,8 @@ namespace ESM void endRecord(NAME name); void endRecord(uint32_t name); void writeMaybeFixedSizeString(const std::string& data, std::size_t size); - void writeHString(const std::string& data); - void writeHCString(const std::string& data); + void writeHString(std::string_view data); + void writeHCString(std::string_view data); void writeMaybeFixedSizeRefId(RefId value, std::size_t size); diff --git a/components/esm3/landrecorddata.hpp b/components/esm3/landrecorddata.hpp index e7db0d9f3a..ca2a2b74ad 100644 --- a/components/esm3/landrecorddata.hpp +++ b/components/esm3/landrecorddata.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_COMPONENTS_ESM3_LANDRECORDDATA_H #define OPENMW_COMPONENTS_ESM3_LANDRECORDDATA_H +#include #include namespace ESM @@ -22,24 +23,20 @@ namespace ESM // Initial reference height for the first vertex, only needed for filling mHeights float mHeightOffset = 0; // Height in world space for each vertex - float mHeights[sLandNumVerts]; + std::array mHeights; float mMinHeight = 0; float mMaxHeight = 0; // 24-bit normals, these aren't always correct though. Edge and corner normals may be garbage. - std::int8_t mNormals[sLandNumVerts * 3]; + std::array mNormals; // 2D array of texture indices. An index can be used to look up an LandTexture, // but to do so you must subtract 1 from the index first! // An index of 0 indicates the default texture. - std::uint16_t mTextures[sLandNumTextures]; + std::array mTextures; // 24-bit RGB color for each vertex - std::uint8_t mColours[3 * sLandNumVerts]; - - // ??? - std::uint16_t mUnk1 = 0; - std::uint8_t mUnk2 = 0; + std::array mColours; int mDataLoaded = 0; }; diff --git a/components/esm3/loadland.cpp b/components/esm3/loadland.cpp index 8b8a8f90fa..74edf30498 100644 --- a/components/esm3/loadland.cpp +++ b/components/esm3/loadland.cpp @@ -5,7 +5,9 @@ #include #include -#include "components/esm/defs.hpp" +#include +#include + #include "esmreader.hpp" #include "esmwriter.hpp" @@ -13,27 +15,43 @@ namespace ESM { namespace { + struct VHGT + { + float mHeightOffset; + std::int8_t mHeightData[LandRecordData::sLandNumVerts]; + }; + + template T> + void decompose(T&& v, const auto& f) + { + char padding[3] = { 0, 0, 0 }; + f(v.mHeightOffset, v.mHeightData, padding); + } + void transposeTextureData(const std::uint16_t* in, std::uint16_t* out) { - int readPos = 0; // bit ugly, but it works - for (int y1 = 0; y1 < 4; y1++) - for (int x1 = 0; x1 < 4; x1++) - for (int y2 = 0; y2 < 4; y2++) - for (int x2 = 0; x2 < 4; x2++) + size_t readPos = 0; // bit ugly, but it works + for (size_t y1 = 0; y1 < 4; y1++) + for (size_t x1 = 0; x1 < 4; x1++) + for (size_t y2 = 0; y2 < 4; y2++) + for (size_t x2 = 0; x2 < 4; x2++) out[(y1 * 4 + y2) * 16 + (x1 * 4 + x2)] = in[readPos++]; } // Loads data and marks it as loaded. Return true if data is actually loaded from reader, false otherwise // including the case when data is already loaded. - bool condLoad(ESMReader& reader, int flags, int& targetFlags, int dataFlag, void* ptr, std::size_t size) + bool condLoad(ESMReader& reader, int flags, int& targetFlags, int dataFlag, auto& in) { if ((targetFlags & dataFlag) == 0 && (flags & dataFlag) != 0) { - reader.getHExact(ptr, size); + if constexpr (std::is_same_v, VHGT>) + reader.getSubComposite(in); + else + reader.getHT(in); targetFlags |= dataFlag; return true; } - reader.skipHSubSize(size); + reader.skipHSub(); return false; } } @@ -50,11 +68,7 @@ namespace ESM switch (esm.retSubName().toInt()) { case fourCC("INTV"): - esm.getSubHeader(); - if (esm.getSubSize() != 8) - esm.fail("Subrecord size is not equal to 8"); - esm.getT(mX); - esm.getT(mY); + esm.getHT(mX, mY); hasLocation = true; break; case fourCC("DATA"): @@ -94,7 +108,7 @@ namespace ESM mDataTypes |= DATA_VHGT; break; case fourCC("WNAM"): - esm.getHExact(mWnam.data(), mWnam.size()); + esm.getHT(mWnam); mDataTypes |= DATA_WNAM; break; case fourCC("VCLR"): @@ -137,12 +151,10 @@ namespace ESM { VHGT offsets; offsets.mHeightOffset = mLandData->mHeights[0] / HEIGHT_SCALE; - offsets.mUnk1 = mLandData->mUnk1; - offsets.mUnk2 = mLandData->mUnk2; float prevY = mLandData->mHeights[0]; - int number = 0; // avoid multiplication - for (int i = 0; i < LAND_SIZE; ++i) + size_t number = 0; // avoid multiplication + for (unsigned i = 0; i < LandRecordData::sLandSize; ++i) { float diff = (mLandData->mHeights[number] - prevY) / HEIGHT_SCALE; offsets.mHeightData[number] @@ -151,7 +163,7 @@ namespace ESM float prevX = prevY = mLandData->mHeights[number]; ++number; - for (int j = 1; j < LAND_SIZE; ++j) + for (unsigned j = 1; j < LandRecordData::sLandSize; ++j) { diff = (mLandData->mHeights[number] - prevX) / HEIGHT_SCALE; offsets.mHeightData[number] @@ -161,7 +173,7 @@ namespace ESM ++number; } } - esm.writeHNT("VHGT", offsets, sizeof(VHGT)); + esm.writeNamedComposite("VHGT", offsets); } if (mDataTypes & Land::DATA_WNAM) { @@ -169,13 +181,15 @@ namespace ESM std::int8_t wnam[LAND_GLOBAL_MAP_LOD_SIZE]; constexpr float max = std::numeric_limits::max(); constexpr float min = std::numeric_limits::min(); - constexpr float vertMult = static_cast(Land::LAND_SIZE - 1) / LAND_GLOBAL_MAP_LOD_SIZE_SQRT; - for (int row = 0; row < LAND_GLOBAL_MAP_LOD_SIZE_SQRT; ++row) + constexpr float vertMult + = static_cast(LandRecordData::sLandSize - 1) / LAND_GLOBAL_MAP_LOD_SIZE_SQRT; + for (unsigned row = 0; row < LAND_GLOBAL_MAP_LOD_SIZE_SQRT; ++row) { - for (int col = 0; col < LAND_GLOBAL_MAP_LOD_SIZE_SQRT; ++col) + for (unsigned col = 0; col < LAND_GLOBAL_MAP_LOD_SIZE_SQRT; ++col) { - float height = mLandData->mHeights[static_cast(row * vertMult) * Land::LAND_SIZE - + static_cast(col * vertMult)]; + float height + = mLandData->mHeights[static_cast(row * vertMult) * LandRecordData::sLandSize + + static_cast(col * vertMult)]; height /= height > 0 ? 128.f : 16.f; height = std::clamp(height, min, max); wnam[row * LAND_GLOBAL_MAP_LOD_SIZE_SQRT + col] = static_cast(height); @@ -189,8 +203,8 @@ namespace ESM } if (mDataTypes & Land::DATA_VTEX) { - uint16_t vtex[LAND_NUM_TEXTURES]; - transposeTextureData(mLandData->mTextures, vtex); + uint16_t vtex[LandRecordData::sLandNumTextures]; + transposeTextureData(mLandData->mTextures.data(), vtex); esm.writeHNT("VTEX", vtex); } } @@ -200,25 +214,23 @@ namespace ESM { setPlugin(0); - std::fill(std::begin(mWnam), std::end(mWnam), 0); + mWnam.fill(0); if (mLandData == nullptr) mLandData = std::make_unique(); mLandData->mHeightOffset = 0; - std::fill(std::begin(mLandData->mHeights), std::end(mLandData->mHeights), 0.0f); + mLandData->mHeights.fill(0); mLandData->mMinHeight = 0; mLandData->mMaxHeight = 0; - for (int i = 0; i < LAND_NUM_VERTS; ++i) + for (size_t i = 0; i < LandRecordData::sLandNumVerts; ++i) { mLandData->mNormals[i * 3 + 0] = 0; mLandData->mNormals[i * 3 + 1] = 0; mLandData->mNormals[i * 3 + 2] = 127; } - std::fill(std::begin(mLandData->mTextures), std::end(mLandData->mTextures), 0); - std::fill(std::begin(mLandData->mColours), std::end(mLandData->mColours), 255); - mLandData->mUnk1 = 0; - mLandData->mUnk2 = 0; + mLandData->mTextures.fill(0); + mLandData->mColours.fill(255); mLandData->mDataLoaded = Land::DATA_VNML | Land::DATA_VHGT | Land::DATA_WNAM | Land::DATA_VCLR | Land::DATA_VTEX; mDataTypes = mLandData->mDataLoaded; @@ -259,32 +271,32 @@ namespace ESM if (reader.isNextSub("VNML")) { - condLoad(reader, flags, data.mDataLoaded, DATA_VNML, data.mNormals, sizeof(data.mNormals)); + condLoad(reader, flags, data.mDataLoaded, DATA_VNML, data.mNormals); } if (reader.isNextSub("VHGT")) { VHGT vhgt; - if (condLoad(reader, flags, data.mDataLoaded, DATA_VHGT, &vhgt, sizeof(vhgt))) + if (condLoad(reader, flags, data.mDataLoaded, DATA_VHGT, vhgt)) { data.mMinHeight = std::numeric_limits::max(); data.mMaxHeight = -std::numeric_limits::max(); float rowOffset = vhgt.mHeightOffset; - for (int y = 0; y < LAND_SIZE; y++) + for (unsigned y = 0; y < LandRecordData::sLandSize; y++) { - rowOffset += vhgt.mHeightData[y * LAND_SIZE]; + rowOffset += vhgt.mHeightData[y * LandRecordData::sLandSize]; - data.mHeights[y * LAND_SIZE] = rowOffset * HEIGHT_SCALE; + data.mHeights[y * LandRecordData::sLandSize] = rowOffset * HEIGHT_SCALE; if (rowOffset * HEIGHT_SCALE > data.mMaxHeight) data.mMaxHeight = rowOffset * HEIGHT_SCALE; if (rowOffset * HEIGHT_SCALE < data.mMinHeight) data.mMinHeight = rowOffset * HEIGHT_SCALE; float colOffset = rowOffset; - for (int x = 1; x < LAND_SIZE; x++) + for (unsigned x = 1; x < LandRecordData::sLandSize; x++) { - colOffset += vhgt.mHeightData[y * LAND_SIZE + x]; - data.mHeights[x + y * LAND_SIZE] = colOffset * HEIGHT_SCALE; + colOffset += vhgt.mHeightData[y * LandRecordData::sLandSize + x]; + data.mHeights[x + y * LandRecordData::sLandSize] = colOffset * HEIGHT_SCALE; if (colOffset * HEIGHT_SCALE > data.mMaxHeight) data.mMaxHeight = colOffset * HEIGHT_SCALE; @@ -292,8 +304,6 @@ namespace ESM data.mMinHeight = colOffset * HEIGHT_SCALE; } } - data.mUnk1 = vhgt.mUnk1; - data.mUnk2 = vhgt.mUnk2; } } @@ -301,13 +311,13 @@ namespace ESM reader.skipHSub(); if (reader.isNextSub("VCLR")) - condLoad(reader, flags, data.mDataLoaded, DATA_VCLR, data.mColours, 3 * LAND_NUM_VERTS); + condLoad(reader, flags, data.mDataLoaded, DATA_VCLR, data.mColours); if (reader.isNextSub("VTEX")) { - uint16_t vtex[LAND_NUM_TEXTURES]; - if (condLoad(reader, flags, data.mDataLoaded, DATA_VTEX, vtex, sizeof(vtex))) + uint16_t vtex[LandRecordData::sLandNumTextures]; + if (condLoad(reader, flags, data.mDataLoaded, DATA_VTEX, vtex)) { - transposeTextureData(vtex, data.mTextures); + transposeTextureData(vtex, data.mTextures.data()); } } } diff --git a/components/esm3/loadland.hpp b/components/esm3/loadland.hpp index 0d32407a5d..510f1790a8 100644 --- a/components/esm3/loadland.hpp +++ b/components/esm3/loadland.hpp @@ -86,19 +86,9 @@ namespace ESM // total number of textures per land static constexpr int LAND_NUM_TEXTURES = LandRecordData::sLandNumTextures; - static constexpr int LAND_GLOBAL_MAP_LOD_SIZE = 81; + static constexpr unsigned LAND_GLOBAL_MAP_LOD_SIZE = 81; - static constexpr int LAND_GLOBAL_MAP_LOD_SIZE_SQRT = 9; - -#pragma pack(push, 1) - struct VHGT - { - float mHeightOffset; - std::int8_t mHeightData[LAND_NUM_VERTS]; - std::uint16_t mUnk1; - std::uint8_t mUnk2; - }; -#pragma pack(pop) + static constexpr unsigned LAND_GLOBAL_MAP_LOD_SIZE_SQRT = 9; using LandData = ESM::LandRecordData; @@ -128,16 +118,10 @@ namespace ESM const LandData* getLandData(int flags) const; /// Return land data without loading first anything. Can return a 0-pointer. - const LandData* getLandData() const - { - return mLandData.get(); - } + const LandData* getLandData() const { return mLandData.get(); } /// Return land data without loading first anything. Can return a 0-pointer. - LandData* getLandData() - { - return mLandData.get(); - } + LandData* getLandData() { return mLandData.get(); } /// \attention Must not be called on objects that aren't fully loaded. ///