mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
Dump StructuredDataDef struct member types
This commit is contained in:
parent
0a226652f2
commit
d82e876558
@ -1,5 +1,9 @@
|
||||
#include "CommonStructuredDataTypes.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "CommonStructuredDataDef.h"
|
||||
|
||||
CommonStructuredDataType::CommonStructuredDataType()
|
||||
: m_category(CommonStructuredDataTypeCategory::UNKNOWN),
|
||||
m_info({0})
|
||||
@ -18,6 +22,62 @@ CommonStructuredDataType::CommonStructuredDataType(const CommonStructuredDataTyp
|
||||
{
|
||||
}
|
||||
|
||||
size_t CommonStructuredDataType::GetAlignmentInBits() const
|
||||
{
|
||||
return m_category == CommonStructuredDataTypeCategory::BOOL ? 0u : 8u;
|
||||
}
|
||||
|
||||
size_t CommonStructuredDataType::GetSizeInBits(const CommonStructuredDataDef& def) const
|
||||
{
|
||||
switch (m_category)
|
||||
{
|
||||
case CommonStructuredDataTypeCategory::INT:
|
||||
case CommonStructuredDataTypeCategory::FLOAT:
|
||||
return 32u;
|
||||
case CommonStructuredDataTypeCategory::BYTE:
|
||||
return 8u;
|
||||
case CommonStructuredDataTypeCategory::BOOL:
|
||||
return 1u;
|
||||
case CommonStructuredDataTypeCategory::ENUM:
|
||||
case CommonStructuredDataTypeCategory::SHORT:
|
||||
return 16u;
|
||||
case CommonStructuredDataTypeCategory::STRING:
|
||||
return m_info.string_length * 8;
|
||||
case CommonStructuredDataTypeCategory::STRUCT:
|
||||
if (m_info.type_index >= def.m_structs.size())
|
||||
{
|
||||
assert(false);
|
||||
return 0u;
|
||||
}
|
||||
return def.m_structs[m_info.type_index]->m_size_in_byte * 8u;
|
||||
case CommonStructuredDataTypeCategory::INDEXED_ARRAY:
|
||||
{
|
||||
if (m_info.type_index >= def.m_indexed_arrays.size())
|
||||
{
|
||||
assert(false);
|
||||
return 0u;
|
||||
}
|
||||
const auto& indexedArray = def.m_indexed_arrays[m_info.type_index];
|
||||
return indexedArray.m_element_size_in_bits * indexedArray.m_element_count;
|
||||
}
|
||||
case CommonStructuredDataTypeCategory::ENUM_ARRAY:
|
||||
{
|
||||
if (m_info.type_index >= def.m_enumed_arrays.size())
|
||||
{
|
||||
assert(false);
|
||||
return 0u;
|
||||
}
|
||||
const auto& enumedArray = def.m_enumed_arrays[m_info.type_index];
|
||||
return enumedArray.m_element_size_in_bits * enumedArray.m_element_count;
|
||||
}
|
||||
|
||||
case CommonStructuredDataTypeCategory::UNKNOWN:
|
||||
default:
|
||||
assert(false);
|
||||
return 0u;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator<(const CommonStructuredDataType& lhs, const CommonStructuredDataType& rhs)
|
||||
{
|
||||
if (lhs.m_category < rhs.m_category)
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
|
||||
enum class CommonStructuredDataTypeCategory
|
||||
{
|
||||
UNKNOWN,
|
||||
@ -23,6 +25,7 @@ union CommonStructuredDataTypeExtraInfo
|
||||
size_t type_index;
|
||||
};
|
||||
|
||||
class CommonStructuredDataDef;
|
||||
struct CommonStructuredDataType
|
||||
{
|
||||
CommonStructuredDataTypeCategory m_category;
|
||||
@ -32,6 +35,9 @@ struct CommonStructuredDataType
|
||||
explicit CommonStructuredDataType(CommonStructuredDataTypeCategory category);
|
||||
CommonStructuredDataType(CommonStructuredDataTypeCategory category, size_t extraInfo);
|
||||
|
||||
_NODISCARD size_t GetAlignmentInBits() const;
|
||||
_NODISCARD size_t GetSizeInBits(const CommonStructuredDataDef& def) const;
|
||||
|
||||
friend bool operator<(const CommonStructuredDataType& lhs, const CommonStructuredDataType& rhs);
|
||||
friend bool operator<=(const CommonStructuredDataType& lhs, const CommonStructuredDataType& rhs);
|
||||
friend bool operator>(const CommonStructuredDataType& lhs, const CommonStructuredDataType& rhs);
|
||||
|
@ -420,14 +420,19 @@ void AssetDumperStructuredDataDefSet::ConvertEnum(CommonStructuredDataEnum* out,
|
||||
out->SortEntries();
|
||||
}
|
||||
|
||||
void AssetDumperStructuredDataDefSet::ConvertStruct(const CommonStructuredDataDef* def, CommonStructuredDataStruct* out, const StructuredDataStruct* in, const size_t structIndex, const size_t rootIndex)
|
||||
void AssetDumperStructuredDataDefSet::ConvertStruct(const CommonStructuredDataDef* def, const StructuredDataDef* gameDef, CommonStructuredDataStruct* out, const StructuredDataStruct* in, const size_t structIndex)
|
||||
{
|
||||
if (structIndex == rootIndex)
|
||||
if (gameDef->rootType.type == DATA_STRUCT && structIndex == static_cast<size_t>(gameDef->rootType.u.structIndex))
|
||||
{
|
||||
out->m_name = "root";
|
||||
out->m_size_in_byte = gameDef->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->m_name = "STRUCT_" + std::to_string(structIndex);
|
||||
out->m_size_in_byte = static_cast<size_t>(std::max(in->size, 0));
|
||||
}
|
||||
|
||||
out->m_size_in_byte = static_cast<size_t>(std::max(in->size, 0));
|
||||
out->m_bit_offset = in->bitOffset;
|
||||
|
||||
out->m_properties.resize(static_cast<size_t>(std::max(in->propertyCount, 0)));
|
||||
@ -463,7 +468,10 @@ void AssetDumperStructuredDataDefSet::ConvertEnumedArray(const CommonStructuredD
|
||||
out->m_enum_index = std::max(std::min(static_cast<size_t>(in->enumIndex), def->m_enums.size() - 1u), 0u);
|
||||
|
||||
if (def->m_enums.empty())
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
out->m_element_count = def->m_enums[out->m_enum_index]->ElementCount();
|
||||
}
|
||||
@ -490,7 +498,7 @@ std::unique_ptr<CommonStructuredDataDef> AssetDumperStructuredDataDefSet::Conver
|
||||
for (auto i = 0u; i < out->m_structs.size(); i++)
|
||||
{
|
||||
auto _struct = std::make_unique<CommonStructuredDataStruct>();
|
||||
ConvertStruct(out.get(), _struct.get(), &in->structs[i], i, static_cast<size_t>(in->rootType.u.structIndex));
|
||||
ConvertStruct(out.get(), in, _struct.get(), &in->structs[i], i);
|
||||
out->m_structs[i] = std::move(_struct);
|
||||
}
|
||||
for (auto i = 0u; i < out->m_indexed_arrays.size(); i++)
|
||||
|
@ -23,7 +23,7 @@ namespace IW4
|
||||
|
||||
static CommonStructuredDataType ConvertType(const CommonStructuredDataDef* def, const StructuredDataType in);
|
||||
static void ConvertEnum(CommonStructuredDataEnum* out, const StructuredDataEnum* in, size_t enumIndex);
|
||||
static void ConvertStruct(const CommonStructuredDataDef* def, CommonStructuredDataStruct* out, const StructuredDataStruct* in, const size_t structIndex, const size_t rootIndex);
|
||||
static void ConvertStruct(const CommonStructuredDataDef* def, const StructuredDataDef* gameDef, CommonStructuredDataStruct* out, const StructuredDataStruct* in, const size_t structIndex);
|
||||
static void ConvertIndexedArray(const CommonStructuredDataDef* def, CommonStructuredDataIndexedArray* out, const StructuredDataIndexedArray* in);
|
||||
static void ConvertEnumedArray(const CommonStructuredDataDef* def, CommonStructuredDataEnumedArray* out, const StructuredDataEnumedArray* in);
|
||||
static std::unique_ptr<CommonStructuredDataDef> ConvertDef(const StructuredDataDef* in);
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "StructuredDataDefDumper.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
StructuredDataDefDumperNew::StructuredDataDefDumperNew(std::ostream& stream)
|
||||
: AbstractTextDumper(stream),
|
||||
m_flags{}
|
||||
@ -44,32 +47,123 @@ void StructuredDataDefDumperNew::DumpEnum(const CommonStructuredDataEnum& _enum)
|
||||
m_stream << "};\n"; // end enum
|
||||
}
|
||||
|
||||
void StructuredDataDefDumperNew::DumpType(const CommonStructuredDataDef& def, CommonStructuredDataType type, std::string& typeName, std::vector<std::string>& arraySpecifiersInReverseOrder)
|
||||
void StructuredDataDefDumperNew::DumpType(const CommonStructuredDataDef& def, CommonStructuredDataType type, std::string& typeName, std::vector<std::string>& arraySpecifiers) const
|
||||
{
|
||||
typeName = "unknown";
|
||||
while (type.m_category != CommonStructuredDataTypeCategory::UNKNOWN)
|
||||
{
|
||||
switch (type.m_category)
|
||||
{
|
||||
case CommonStructuredDataTypeCategory::INT:
|
||||
typeName = "int";
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::BYTE:
|
||||
typeName = "byte";
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::BOOL:
|
||||
typeName = "bool";
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::FLOAT:
|
||||
typeName = "float";
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::SHORT:
|
||||
typeName = "short";
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::STRING:
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "string(" << type.m_info.string_length << ')';
|
||||
typeName = ss.str();
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
}
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::ENUM:
|
||||
assert(type.m_info.type_index < def.m_enums.size());
|
||||
if (type.m_info.type_index < def.m_enums.size())
|
||||
typeName = def.m_enums[type.m_info.type_index]->m_name;
|
||||
else
|
||||
typeName = "unknown";
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::STRUCT:
|
||||
assert(type.m_info.type_index < def.m_structs.size());
|
||||
if (type.m_info.type_index < def.m_structs.size())
|
||||
typeName = def.m_structs[type.m_info.type_index]->m_name;
|
||||
else
|
||||
typeName = "unknown";
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::INDEXED_ARRAY:
|
||||
assert(type.m_info.type_index < def.m_indexed_arrays.size());
|
||||
if (type.m_info.type_index < def.m_indexed_arrays.size())
|
||||
{
|
||||
const auto& indexArray = def.m_indexed_arrays[type.m_info.type_index];
|
||||
arraySpecifiers.push_back(std::to_string(indexArray.m_element_count));
|
||||
type = indexArray.m_array_type;
|
||||
}
|
||||
else
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::ENUM_ARRAY:
|
||||
assert(type.m_info.type_index < def.m_enumed_arrays.size());
|
||||
if (type.m_info.type_index < def.m_enumed_arrays.size())
|
||||
{
|
||||
const auto& enumedArray = def.m_enumed_arrays[type.m_info.type_index];
|
||||
|
||||
assert(enumedArray.m_enum_index < def.m_enums.size());
|
||||
if (enumedArray.m_enum_index < def.m_enums.size())
|
||||
arraySpecifiers.push_back(def.m_enums[enumedArray.m_enum_index]->m_name);
|
||||
type = enumedArray.m_array_type;
|
||||
}
|
||||
else
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
default:
|
||||
type = CommonStructuredDataType(CommonStructuredDataTypeCategory::UNKNOWN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StructuredDataDefDumperNew::DumpProperty(const CommonStructuredDataDef& def, const CommonStructuredDataStructProperty& property, unsigned& currentOffsetInBit)
|
||||
void StructuredDataDefDumperNew::DumpProperty(const CommonStructuredDataDef& def, const CommonStructuredDataStructProperty& property, unsigned& currentOffsetInBit) const
|
||||
{
|
||||
std::string typeName;
|
||||
std::vector<std::string> arraySpecifiersInReverseOrder;
|
||||
std::vector<std::string> arraySpecifiers;
|
||||
|
||||
DumpType(def, property.m_type, typeName, arraySpecifiersInReverseOrder);
|
||||
DumpType(def, property.m_type, typeName, arraySpecifiers);
|
||||
|
||||
Indent();
|
||||
m_stream << typeName << ' ' << property.m_name;
|
||||
|
||||
for (auto ri = arraySpecifiersInReverseOrder.rbegin(); ri != arraySpecifiersInReverseOrder.rend(); ++ri)
|
||||
for (auto ri = arraySpecifiers.begin(); ri != arraySpecifiers.end(); ++ri)
|
||||
m_stream << '[' << *ri << ']';
|
||||
|
||||
|
||||
#ifdef STRUCTUREDDATADEF_DEBUG
|
||||
m_stream << " /* Offset: " << (property.m_offset_in_bits / 8) << " byte";
|
||||
m_stream << "; // Offset: " << (property.m_offset_in_bits / 8) << " byte";
|
||||
if (property.m_offset_in_bits % 8 > 0)
|
||||
m_stream << " + " << (property.m_offset_in_bits % 8) << " bit";
|
||||
m_stream << " */";
|
||||
#endif
|
||||
|
||||
const auto sizeInBits = property.m_type.GetSizeInBits(def);
|
||||
m_stream << " | Size: ";
|
||||
|
||||
if (sizeInBits % 8 == 0)
|
||||
m_stream << (sizeInBits / 8) << " byte";
|
||||
else if (sizeInBits > 8)
|
||||
m_stream << (sizeInBits / 8) << " byte + " << (sizeInBits % 8) << " bit";
|
||||
else
|
||||
m_stream << sizeInBits << " bit";
|
||||
|
||||
m_stream << " | Alignment: " << property.m_type.GetAlignmentInBits() << " bit";
|
||||
m_stream << '\n';
|
||||
#else
|
||||
m_stream << ";\n";
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void StructuredDataDefDumperNew::DumpStruct(const CommonStructuredDataDef& def, const CommonStructuredDataStruct& _struct, const size_t structIndex)
|
||||
|
@ -16,8 +16,8 @@ class StructuredDataDefDumperNew : AbstractTextDumper
|
||||
void WriteLineComment(const std::string& comment) const;
|
||||
|
||||
void DumpEnum(const CommonStructuredDataEnum& _enum);
|
||||
void DumpType(const CommonStructuredDataDef& def, CommonStructuredDataType type, std::string& typeName, std::vector<std::string>& arraySpecifiersInReverseOrder);
|
||||
void DumpProperty(const CommonStructuredDataDef& def, const CommonStructuredDataStructProperty& property, unsigned& currentOffsetInBit);
|
||||
void DumpType(const CommonStructuredDataDef& def, CommonStructuredDataType type, std::string& typeName, std::vector<std::string>& arraySpecifiers) const;
|
||||
void DumpProperty(const CommonStructuredDataDef& def, const CommonStructuredDataStructProperty& property, unsigned& currentOffsetInBit) const;
|
||||
void DumpStruct(const CommonStructuredDataDef& def, const CommonStructuredDataStruct& _struct, size_t structIndex);
|
||||
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user