From fd01b4cad7a31cf5870083dff8088b095b3b2b31 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 30 Jul 2023 17:41:23 +0200 Subject: [PATCH 1/2] Avoid casts to read cell flags --- components/esm4/loadcell.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/components/esm4/loadcell.cpp b/components/esm4/loadcell.cpp index 0170935c44..00954f4d9d 100644 --- a/components/esm4/loadcell.cpp +++ b/components/esm4/loadcell.cpp @@ -136,11 +136,15 @@ void ESM4::Cell::load(ESM4::Reader& reader) { if (subHdr.dataSize != 1) throw std::runtime_error("CELL unexpected DATA flag size"); - reader.get(&mCellFlags, sizeof(std::uint8_t)); + std::uint8_t value = 0; + reader.get(value); + mCellFlags = value; } else { - reader.get((std::uint8_t&)mCellFlags); // 8 bits in Obvlivion + std::uint8_t value = 0; + reader.get(value); // 8 bits in Obvlivion + mCellFlags = value; } #if 0 std::string padding; From 798f3cc3856103510f0764a186ce9df2cd770689 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 30 Jul 2023 15:45:12 +0200 Subject: [PATCH 2/2] Support ESM4 record FullName, CellFlags, X, Y fields by esmtool --- apps/esmtool/tes4.cpp | 33 ++++++++++++++++++ components/debug/writeflags.hpp | 37 ++++++++++++++++++++ components/detournavigator/debug.cpp | 45 +++++++++--------------- components/esm4/typetraits.hpp | 52 ++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 components/debug/writeflags.hpp diff --git a/apps/esmtool/tes4.cpp b/apps/esmtool/tes4.cpp index 11c3249d44..e601d85d7d 100644 --- a/apps/esmtool/tes4.cpp +++ b/apps/esmtool/tes4.cpp @@ -2,10 +2,12 @@ #include "arguments.hpp" #include "labels.hpp" +#include #include #include #include +#include #include #include #include @@ -108,6 +110,29 @@ namespace EsmTool return stream; } + struct WriteCellFlags + { + std::uint16_t mValue; + }; + + using CellFlagString = Debug::FlagString; + + constexpr std::array cellFlags{ + CellFlagString{ ESM4::CELL_Interior, "Interior" }, + CellFlagString{ ESM4::CELL_HasWater, "HasWater" }, + CellFlagString{ ESM4::CELL_NoTravel, "NoTravel" }, + CellFlagString{ ESM4::CELL_HideLand, "HideLand" }, + CellFlagString{ ESM4::CELL_Public, "Public" }, + CellFlagString{ ESM4::CELL_HandChgd, "HandChgd" }, + CellFlagString{ ESM4::CELL_QuasiExt, "QuasiExt" }, + CellFlagString{ ESM4::CELL_SkyLight, "SkyLight" }, + }; + + std::ostream& operator<<(std::ostream& stream, const WriteCellFlags& write) + { + return Debug::writeFlags(stream, write.mValue, cellFlags); + } + template void readTypedRecord(const Params& params, ESM4::Reader& reader) { @@ -137,6 +162,14 @@ namespace EsmTool std::cout << "\n Parent: " << value.mParent; if constexpr (ESM4::hasEditorId) std::cout << "\n EditorId: " << value.mEditorId; + if constexpr (ESM4::hasFullName) + std::cout << "\n FullName: " << value.mFullName; + if constexpr (ESM4::hasCellFlags) + std::cout << "\n CellFlags: " << WriteCellFlags{ value.mCellFlags }; + if constexpr (ESM4::hasX) + std::cout << "\n X: " << value.mX; + if constexpr (ESM4::hasY) + std::cout << "\n Y: " << value.mY; if constexpr (ESM::hasModel) std::cout << "\n Model: " << value.mModel; if constexpr (ESM4::hasNif) diff --git a/components/debug/writeflags.hpp b/components/debug/writeflags.hpp new file mode 100644 index 0000000000..bb9705f852 --- /dev/null +++ b/components/debug/writeflags.hpp @@ -0,0 +1,37 @@ +#ifndef OPENMW_COMPONENTS_DEBUG_WRITEFLAGS_H +#define OPENMW_COMPONENTS_DEBUG_WRITEFLAGS_H + +#include +#include +#include + +namespace Debug +{ + template + struct FlagString + { + T mValue; + std::string_view mString; + }; + + template + std::ostream& writeFlags(std::ostream& stream, const T& value, const FlagStrings& flagStrings) + { + bool first = true; + for (const auto& v : flagStrings) + { + if ((value & v.mValue) == 0) + continue; + if (first) + first = false; + else + stream << " | "; + stream << v.mString; + } + if (first) + stream << "[None]"; + return stream << " (0x" << std::hex << value << std::resetiosflags(std::ios_base::hex) << ')'; + } +} + +#endif diff --git a/components/detournavigator/debug.cpp b/components/detournavigator/debug.cpp index 1f6f104db5..835f37f999 100644 --- a/components/detournavigator/debug.cpp +++ b/components/detournavigator/debug.cpp @@ -6,6 +6,8 @@ #include "tilespositionsrange.hpp" #include "version.hpp" +#include + #include #include @@ -94,40 +96,25 @@ namespace DetourNavigator namespace { - struct StatusString - { - dtStatus mStatus; - std::string_view mString; + using StatusString = Debug::FlagString; + + constexpr std::array dtStatuses{ + StatusString{ DT_FAILURE, "DT_FAILURE" }, + StatusString{ DT_SUCCESS, "DT_SUCCESS" }, + StatusString{ DT_IN_PROGRESS, "DT_IN_PROGRESS" }, + StatusString{ DT_WRONG_MAGIC, "DT_WRONG_MAGIC" }, + StatusString{ DT_WRONG_VERSION, "DT_WRONG_VERSION" }, + StatusString{ DT_OUT_OF_MEMORY, "DT_OUT_OF_MEMORY" }, + StatusString{ DT_INVALID_PARAM, "DT_INVALID_PARAM" }, + StatusString{ DT_BUFFER_TOO_SMALL, "DT_BUFFER_TOO_SMALL" }, + StatusString{ DT_OUT_OF_NODES, "DT_OUT_OF_NODES" }, + StatusString{ DT_PARTIAL_RESULT, "DT_PARTIAL_RESULT" }, }; } - static constexpr std::array dtStatuses{ - StatusString{ DT_FAILURE, "DT_FAILURE" }, - StatusString{ DT_SUCCESS, "DT_SUCCESS" }, - StatusString{ DT_IN_PROGRESS, "DT_IN_PROGRESS" }, - StatusString{ DT_WRONG_MAGIC, "DT_WRONG_MAGIC" }, - StatusString{ DT_WRONG_VERSION, "DT_WRONG_VERSION" }, - StatusString{ DT_OUT_OF_MEMORY, "DT_OUT_OF_MEMORY" }, - StatusString{ DT_INVALID_PARAM, "DT_INVALID_PARAM" }, - StatusString{ DT_BUFFER_TOO_SMALL, "DT_BUFFER_TOO_SMALL" }, - StatusString{ DT_OUT_OF_NODES, "DT_OUT_OF_NODES" }, - StatusString{ DT_PARTIAL_RESULT, "DT_PARTIAL_RESULT" }, - }; - std::ostream& operator<<(std::ostream& stream, const WriteDtStatus& value) { - bool first = true; - for (const auto& v : dtStatuses) - { - if ((value.mStatus & v.mStatus) == 0) - continue; - if (first) - first = false; - else - stream << " | "; - stream << v.mString; - } - return stream; + return Debug::writeFlags(stream, value.mStatus, dtStatuses); } std::ostream& operator<<(std::ostream& stream, const Flag value) diff --git a/components/esm4/typetraits.hpp b/components/esm4/typetraits.hpp index bbac3a6ac1..2e04f2e70d 100644 --- a/components/esm4/typetraits.hpp +++ b/components/esm4/typetraits.hpp @@ -70,6 +70,58 @@ namespace ESM4 template inline constexpr bool hasEditorId = HasEditorId::value; + template > + struct HasFullName : std::false_type + { + }; + + template + struct HasFullName> : std::true_type + { + }; + + template + inline constexpr bool hasFullName = HasFullName::value; + + template > + struct HasCellFlags : std::false_type + { + }; + + template + struct HasCellFlags> : std::true_type + { + }; + + template + inline constexpr bool hasCellFlags = HasCellFlags::value; + + template > + struct HasX : std::false_type + { + }; + + template + struct HasX> : std::true_type + { + }; + + template + inline constexpr bool hasX = HasX::value; + + template > + struct HasY : std::false_type + { + }; + + template + struct HasY> : std::true_type + { + }; + + template + inline constexpr bool hasY = HasY::value; + template > struct HasNif : std::false_type {