Split InfoString classes into multiple files depending on loading and writing code

This commit is contained in:
Jan 2021-03-24 13:51:21 +01:00
parent 9e00ad60e7
commit abcce11b00
36 changed files with 579 additions and 549 deletions

View File

@ -1,171 +0,0 @@
#include "InfoStringIW4.h"
#include <cassert>
using namespace IW4;
void InfoStringToStructConverter::FillStructure()
{
}
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
const cspField_t* fields, const size_t fieldCount)
: InfoStringToStructConverterBase(infoString, structure),
m_fields(fields),
m_field_count(fieldCount)
{
}
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
{
switch (static_cast<csParseFieldType_t>(field.iFieldType))
{
case CSPFT_STRING:
FillFromString(std::string(field.szName), field.iOffset);
break;
case CSPFT_STRING_MAX_STRING_CHARS:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
break;
case CSPFT_STRING_MAX_QPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
break;
case CSPFT_STRING_MAX_OSPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
break;
case CSPFT_INT:
FillFromInt(std::string(field.szName), field.iOffset);
break;
case CSPFT_QBOOLEAN:
FillFromQBoolean(std::string(field.szName), field.iOffset);
break;
case CSPFT_BOOL:
FillFromBool(std::string(field.szName), field.iOffset);
break;
case CSPFT_FLOAT:
FillFromFloat(std::string(field.szName), field.iOffset);
break;
case CSPFT_MPH_TO_INCHES_PER_SEC:
{
const auto* num = reinterpret_cast<float*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
m_info_string.SetValueForKey(std::string(field.szName), std::to_string(*num / 17.6f));
break;
}
case CSPFT_MILLISECONDS:
FillFromMilliseconds(std::string(field.szName), field.iOffset);
break;
case CSPFT_FX:
{
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (fx)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_XMODEL:
{
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (model)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_MATERIAL:
{
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (material)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_PHYS_COLLMAP:
{
const auto* physCollMap = *reinterpret_cast<PhysCollmap**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (physCollMap)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SOUND:
{
const auto* sndAlias = reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (sndAlias->name)
m_info_string.SetValueForKey(std::string(field.szName), std::string(sndAlias->name->soundName));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_TRACER:
{
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (tracer)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_NUM_BASE_FIELD_TYPES:
default:
assert(false);
break;
}
}
void InfoStringFromStructConverter::FillInfoString()
{
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
{
const auto& field = m_fields[fieldIndex];
assert(field.iFieldType >= 0);
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
FillFromBaseField(field);
else
FillFromExtensionField(field);
}
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
const size_t fieldCount)
: InfoStringFromStructConverterBase(structure),
m_fields(fields),
m_field_count(fieldCount)
{
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
m_fields(fields),
m_field_count(fieldCount)
{
}

View File

@ -1,168 +0,0 @@
#include "InfoStringT6.h"
#include <cassert>
using namespace T6;
void InfoStringToStructConverter::FillStructure()
{
}
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
const cspField_t* fields, const size_t fieldCount)
: InfoStringToStructConverterBase(infoString, structure),
m_fields(fields),
m_field_count(fieldCount)
{
}
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
{
switch (static_cast<csParseFieldType_t>(field.iFieldType))
{
case CSPFT_STRING:
FillFromString(std::string(field.szName), field.iOffset);
break;
case CSPFT_STRING_MAX_STRING_CHARS:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
break;
case CSPFT_STRING_MAX_QPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
break;
case CSPFT_STRING_MAX_OSPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
break;
case CSPFT_INT:
FillFromInt(std::string(field.szName), field.iOffset);
break;
case CSPFT_UINT:
FillFromUint(std::string(field.szName), field.iOffset);
break;
case CSPFT_BOOL:
FillFromBool(std::string(field.szName), field.iOffset);
break;
case CSPFT_QBOOLEAN:
FillFromQBoolean(std::string(field.szName), field.iOffset);
break;
case CSPFT_FLOAT:
FillFromFloat(std::string(field.szName), field.iOffset);
break;
case CSPFT_MILLISECONDS:
FillFromMilliseconds(std::string(field.szName), field.iOffset);
break;
case CSPFT_FX:
{
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (fx)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_XMODEL:
{
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (model)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_MATERIAL:
case CSPFT_MATERIAL_STREAM:
{
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (material)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_PHYS_PRESET:
{
const auto* physPreset = *reinterpret_cast<PhysPreset**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (physPreset)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physPreset->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SCRIPT_STRING:
FillFromScriptString(std::string(field.szName), field.iOffset);
break;
case CSPFT_TRACER:
{
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (tracer)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SOUND_ALIAS_ID:
{
// TODO: Search sound files for files matching the hash
const auto* hash = reinterpret_cast<unsigned*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
m_info_string.SetValueForKey(std::string(field.szName), "@" + std::to_string(*hash));
break;
}
case CSPFT_NUM_BASE_FIELD_TYPES:
default:
assert(false);
break;
}
}
void InfoStringFromStructConverter::FillInfoString()
{
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
{
const auto& field = m_fields[fieldIndex];
assert(field.iFieldType >= 0);
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
FillFromBaseField(field);
else
FillFromExtensionField(field);
}
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
const size_t fieldCount)
: InfoStringFromStructConverterBase(structure),
m_fields(fields),
m_field_count(fieldCount)
{
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
m_fields(fields),
m_field_count(fieldCount)
{
}

View File

@ -0,0 +1,105 @@
#include "InfoString.h"
#include <sstream>
#include <cstring>
const std::string InfoString::EMPTY_VALUE;
bool InfoString::HasKey(const std::string& key) const
{
return m_values.find(key) != m_values.end();
}
const std::string& InfoString::GetValueForKey(const std::string& key) const
{
const auto& value = m_values.find(key);
if (value == m_values.end())
return EMPTY_VALUE;
return value->second;
}
const std::string& InfoString::GetValueForKey(const std::string& key, bool* foundValue) const
{
const auto& value = m_values.find(key);
if (value == m_values.end())
{
if (foundValue)
*foundValue = false;
return EMPTY_VALUE;
}
if (foundValue)
*foundValue = true;
return value->second;
}
void InfoString::SetValueForKey(const std::string& key, std::string value)
{
if (!HasKey(key))
m_keys_by_insertion.push_back(key);
m_values[key] = std::move(value);
}
void InfoString::RemoveKey(const std::string& key)
{
const auto& value = m_values.find(key);
if (value != m_values.end())
m_values.erase(value);
}
std::string InfoString::ToString() const
{
std::stringstream ss;
bool first = true;
for (const auto& key : m_keys_by_insertion)
{
const auto value = m_values.find(key);
if (!first)
ss << '\\';
else
first = false;
ss << key << '\\' << value->second;
}
return ss.str();
}
std::string InfoString::ToString(const std::string& prefix) const
{
std::stringstream ss;
ss << prefix;
for (const auto& key : m_keys_by_insertion)
{
const auto value = m_values.find(key);
ss << '\\' << key << '\\' << value->second;
}
return ss.str();
}
void InfoString::ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const
{
for (const auto& key : m_keys_by_insertion)
{
const auto value = m_values.find(key);
gdtEntry.m_properties[key] = value->second;
}
gdtEntry.m_properties["configstringFileType"] = prefix;
}
void InfoString::FromString()
{
}
void InfoString::FromString(const std::string& prefix)
{
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <unordered_map>
#include <string>
#include <vector>
#include "Utils/ClassUtils.h"
#include "Obj/Gdt/GdtEntry.h"
class InfoString
{
static const std::string EMPTY_VALUE;
std::unordered_map<std::string, std::string> m_values;
std::vector<std::string> m_keys_by_insertion;
public:
_NODISCARD bool HasKey(const std::string& key) const;
_NODISCARD const std::string& GetValueForKey(const std::string& key) const;
const std::string& GetValueForKey(const std::string& key, bool* foundValue) const;
void SetValueForKey(const std::string& key, std::string value);
void RemoveKey(const std::string& key);
_NODISCARD std::string ToString() const;
_NODISCARD std::string ToString(const std::string& prefix) const;
void ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const;
void FromString();
void FromString(const std::string& prefix);
};

View File

@ -0,0 +1,15 @@
#include "InfoStringToStructConverter.h"
using namespace IW4;
void InfoStringToStructConverter::FillStructure()
{
}
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
const cspField_t* fields, const size_t fieldCount)
: InfoStringToStructConverterBase(infoString, structure),
m_fields(fields),
m_field_count(fieldCount)
{
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "InfoString/InfoStringToStructConverterBase.h"
#include "Game/IW4/IW4.h"
namespace IW4
{
class InfoStringToStructConverter : public InfoStringToStructConverterBase
{
const cspField_t* m_fields;
size_t m_field_count;
protected:
void FillStructure() override;
public:
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
};
}

View File

@ -0,0 +1,17 @@
#include "InfoStringToStructConverter.h"
#include <cassert>
using namespace T6;
void InfoStringToStructConverter::FillStructure()
{
}
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
const cspField_t* fields, const size_t fieldCount)
: InfoStringToStructConverterBase(infoString, structure),
m_fields(fields),
m_field_count(fieldCount)
{
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "InfoString/InfoStringToStructConverterBase.h"
#include "Game/T6/T6.h"
namespace T6
{
class InfoStringToStructConverter : public InfoStringToStructConverterBase
{
const cspField_t* m_fields;
size_t m_field_count;
protected:
void FillStructure() override;
public:
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
};
}

View File

@ -0,0 +1,15 @@
#include "InfoStringToStructConverterBase.h"
InfoStringToStructConverterBase::InfoStringToStructConverterBase(const InfoString& infoString, void* structure)
: m_info_string(infoString),
m_structure(structure)
{
}
InfoStringToStructConverterBase::~InfoStringToStructConverterBase()
= default;
void InfoStringToStructConverterBase::Convert()
{
FillStructure();
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "InfoString/InfoString.h"
class InfoStringToStructConverterBase
{
protected:
const InfoString& m_info_string;
void* m_structure;
virtual void FillStructure() = 0;
public:
InfoStringToStructConverterBase(const InfoString& infoString, void* structure);
virtual ~InfoStringToStructConverterBase();
InfoStringToStructConverterBase(const InfoStringToStructConverterBase& other) = delete;
InfoStringToStructConverterBase(InfoStringToStructConverterBase&& other) noexcept = delete;
InfoStringToStructConverterBase& operator=(const InfoStringToStructConverterBase& other) = delete;
InfoStringToStructConverterBase& operator=(InfoStringToStructConverterBase&& other) noexcept = delete;
void Convert();
};

View File

@ -5,7 +5,7 @@
#include <type_traits> #include <type_traits>
#include "Game/IW4/CommonIW4.h" #include "Game/IW4/CommonIW4.h"
#include "Game/IW4/InfoStringIW4.h" #include "Game/IW4/InfoString/InfoStringFromStructConverter.h"
using namespace IW4; using namespace IW4;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace IW4 namespace IW4
{ {

View File

@ -6,7 +6,7 @@
#include <type_traits> #include <type_traits>
#include "Game/IW4/CommonIW4.h" #include "Game/IW4/CommonIW4.h"
#include "Game/IW4/InfoStringIW4.h" #include "Game/IW4/InfoString/InfoStringFromStructConverter.h"
using namespace IW4; using namespace IW4;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace IW4 namespace IW4
{ {

View File

@ -0,0 +1,159 @@
#include "InfoStringFromStructConverter.h"
#include <cassert>
using namespace IW4;
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
{
switch (static_cast<csParseFieldType_t>(field.iFieldType))
{
case CSPFT_STRING:
FillFromString(std::string(field.szName), field.iOffset);
break;
case CSPFT_STRING_MAX_STRING_CHARS:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
break;
case CSPFT_STRING_MAX_QPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
break;
case CSPFT_STRING_MAX_OSPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
break;
case CSPFT_INT:
FillFromInt(std::string(field.szName), field.iOffset);
break;
case CSPFT_QBOOLEAN:
FillFromQBoolean(std::string(field.szName), field.iOffset);
break;
case CSPFT_BOOL:
FillFromBool(std::string(field.szName), field.iOffset);
break;
case CSPFT_FLOAT:
FillFromFloat(std::string(field.szName), field.iOffset);
break;
case CSPFT_MPH_TO_INCHES_PER_SEC:
{
const auto* num = reinterpret_cast<float*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
m_info_string.SetValueForKey(std::string(field.szName), std::to_string(*num / 17.6f));
break;
}
case CSPFT_MILLISECONDS:
FillFromMilliseconds(std::string(field.szName), field.iOffset);
break;
case CSPFT_FX:
{
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (fx)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_XMODEL:
{
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (model)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_MATERIAL:
{
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (material)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_PHYS_COLLMAP:
{
const auto* physCollMap = *reinterpret_cast<PhysCollmap**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (physCollMap)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SOUND:
{
const auto* sndAlias = reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (sndAlias->name)
m_info_string.SetValueForKey(std::string(field.szName), std::string(sndAlias->name->soundName));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_TRACER:
{
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (tracer)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_NUM_BASE_FIELD_TYPES:
default:
assert(false);
break;
}
}
void InfoStringFromStructConverter::FillInfoString()
{
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
{
const auto& field = m_fields[fieldIndex];
assert(field.iFieldType >= 0);
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
FillFromBaseField(field);
else
FillFromExtensionField(field);
}
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
const size_t fieldCount)
: InfoStringFromStructConverterBase(structure),
m_fields(fields),
m_field_count(fieldCount)
{
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
m_fields(fields),
m_field_count(fieldCount)
{
}

View File

@ -1,21 +1,9 @@
#pragma once #pragma once
#include "Utils/InfoString.h" #include "InfoString/InfoStringFromStructConverterBase.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
namespace IW4 namespace IW4
{ {
class InfoStringToStructConverter : public InfoStringToStructConverterBase
{
const cspField_t* m_fields;
size_t m_field_count;
protected:
void FillStructure() override;
public:
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
};
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
{ {
protected: protected:
@ -30,4 +18,4 @@ namespace IW4
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount); InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback); InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback);
}; };
} }

View File

@ -5,7 +5,7 @@
#include "Game/T6/CommonT6.h" #include "Game/T6/CommonT6.h"
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -5,7 +5,7 @@
#include <cmath> #include <cmath>
#include <type_traits> #include <type_traits>
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -4,7 +4,7 @@
#include <type_traits> #include <type_traits>
#include "Game/T6/CommonT6.h" #include "Game/T6/CommonT6.h"
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -5,7 +5,7 @@
#include "Game/T6/CommonT6.h" #include "Game/T6/CommonT6.h"
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -6,7 +6,7 @@
#include <cstring> #include <cstring>
#include "Game/T6/CommonT6.h" #include "Game/T6/CommonT6.h"
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -6,7 +6,7 @@
#include <cstring> #include <cstring>
#include "Game/T6/CommonT6.h" #include "Game/T6/CommonT6.h"
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -6,7 +6,7 @@
#include <cstring> #include <cstring>
#include "Game/T6/CommonT6.h" #include "Game/T6/CommonT6.h"
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -3,7 +3,7 @@
#include <cassert> #include <cassert>
#include <type_traits> #include <type_traits>
#include "Game/T6/InfoStringT6.h" #include "Game/T6/InfoString/InfoStringFromStructConverter.h"
using namespace T6; using namespace T6;

View File

@ -2,7 +2,7 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Utils/InfoString.h" #include "InfoString/InfoString.h"
namespace T6 namespace T6
{ {

View File

@ -0,0 +1,156 @@
#include "InfoStringFromStructConverter.h"
#include <cassert>
using namespace T6;
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
{
switch (static_cast<csParseFieldType_t>(field.iFieldType))
{
case CSPFT_STRING:
FillFromString(std::string(field.szName), field.iOffset);
break;
case CSPFT_STRING_MAX_STRING_CHARS:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
break;
case CSPFT_STRING_MAX_QPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
break;
case CSPFT_STRING_MAX_OSPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
break;
case CSPFT_INT:
FillFromInt(std::string(field.szName), field.iOffset);
break;
case CSPFT_UINT:
FillFromUint(std::string(field.szName), field.iOffset);
break;
case CSPFT_BOOL:
FillFromBool(std::string(field.szName), field.iOffset);
break;
case CSPFT_QBOOLEAN:
FillFromQBoolean(std::string(field.szName), field.iOffset);
break;
case CSPFT_FLOAT:
FillFromFloat(std::string(field.szName), field.iOffset);
break;
case CSPFT_MILLISECONDS:
FillFromMilliseconds(std::string(field.szName), field.iOffset);
break;
case CSPFT_FX:
{
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (fx)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_XMODEL:
{
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (model)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_MATERIAL:
case CSPFT_MATERIAL_STREAM:
{
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (material)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_PHYS_PRESET:
{
const auto* physPreset = *reinterpret_cast<PhysPreset**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (physPreset)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physPreset->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SCRIPT_STRING:
FillFromScriptString(std::string(field.szName), field.iOffset);
break;
case CSPFT_TRACER:
{
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (tracer)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SOUND_ALIAS_ID:
{
// TODO: Search sound files for files matching the hash
const auto* hash = reinterpret_cast<unsigned*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
m_info_string.SetValueForKey(std::string(field.szName), "@" + std::to_string(*hash));
break;
}
case CSPFT_NUM_BASE_FIELD_TYPES:
default:
assert(false);
break;
}
}
void InfoStringFromStructConverter::FillInfoString()
{
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
{
const auto& field = m_fields[fieldIndex];
assert(field.iFieldType >= 0);
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
FillFromBaseField(field);
else
FillFromExtensionField(field);
}
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
const size_t fieldCount)
: InfoStringFromStructConverterBase(structure),
m_fields(fields),
m_field_count(fieldCount)
{
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
m_fields(fields),
m_field_count(fieldCount)
{
}

View File

@ -1,21 +1,9 @@
#pragma once #pragma once
#include "Utils/InfoString.h" #include "InfoString/InfoStringFromStructConverterBase.h"
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
namespace T6 namespace T6
{ {
class InfoStringToStructConverter : public InfoStringToStructConverterBase
{
const cspField_t* m_fields;
size_t m_field_count;
protected:
void FillStructure() override;
public:
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
};
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
{ {
protected: protected:
@ -30,4 +18,4 @@ namespace T6
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount); InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback); InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback);
}; };
} }

View File

@ -1,123 +1,6 @@
#include "InfoString.h" #include "InfoStringFromStructConverterBase.h"
#include <cassert> #include <cassert>
#include <sstream>
#include <cstring>
const std::string InfoString::EMPTY_VALUE;
bool InfoString::HasKey(const std::string& key) const
{
return m_values.find(key) != m_values.end();
}
const std::string& InfoString::GetValueForKey(const std::string& key) const
{
const auto& value = m_values.find(key);
if (value == m_values.end())
return EMPTY_VALUE;
return value->second;
}
const std::string& InfoString::GetValueForKey(const std::string& key, bool* foundValue) const
{
const auto& value = m_values.find(key);
if (value == m_values.end())
{
if (foundValue)
*foundValue = false;
return EMPTY_VALUE;
}
if (foundValue)
*foundValue = true;
return value->second;
}
void InfoString::SetValueForKey(const std::string& key, std::string value)
{
if (!HasKey(key))
m_keys_by_insertion.push_back(key);
m_values[key] = std::move(value);
}
void InfoString::RemoveKey(const std::string& key)
{
const auto& value = m_values.find(key);
if (value != m_values.end())
m_values.erase(value);
}
std::string InfoString::ToString() const
{
std::stringstream ss;
bool first = true;
for (const auto& key : m_keys_by_insertion)
{
const auto value = m_values.find(key);
if (!first)
ss << '\\';
else
first = false;
ss << key << '\\' << value->second;
}
return ss.str();
}
std::string InfoString::ToString(const std::string& prefix) const
{
std::stringstream ss;
ss << prefix;
for (const auto& key : m_keys_by_insertion)
{
const auto value = m_values.find(key);
ss << '\\' << key << '\\' << value->second;
}
return ss.str();
}
void InfoString::ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const
{
for (const auto& key : m_keys_by_insertion)
{
const auto value = m_values.find(key);
gdtEntry.m_properties[key] = value->second;
}
gdtEntry.m_properties["configstringFileType"] = prefix;
}
void InfoString::FromString()
{
}
void InfoString::FromString(const std::string& prefix)
{
}
InfoStringToStructConverterBase::InfoStringToStructConverterBase(const InfoString& infoString, void* structure)
: m_info_string(infoString),
m_structure(structure)
{
}
InfoStringToStructConverterBase::~InfoStringToStructConverterBase()
= default;
void InfoStringToStructConverterBase::Convert()
{
FillStructure();
}
InfoStringFromStructConverterBase::InfoStringFromStructConverterBase(const void* structure) InfoStringFromStructConverterBase::InfoStringFromStructConverterBase(const void* structure)
: m_structure(structure), : m_structure(structure),

View File

@ -1,52 +1,9 @@
#pragma once #pragma once
#include <functional> #include <functional>
#include <unordered_map>
#include <string>
#include <vector>
#include "Obj/Gdt/GdtEntry.h" #include "InfoString/InfoString.h"
#include "Zone/ZoneTypes.h" #include "Zone/ZoneTypes.h"
class InfoString
{
static const std::string EMPTY_VALUE;
std::unordered_map<std::string, std::string> m_values;
std::vector<std::string> m_keys_by_insertion;
public:
bool HasKey(const std::string& key) const;
const std::string& GetValueForKey(const std::string& key) const;
const std::string& GetValueForKey(const std::string& key, bool* foundValue) const;
void SetValueForKey(const std::string& key, std::string value);
void RemoveKey(const std::string& key);
std::string ToString() const;
std::string ToString(const std::string& prefix) const;
void ToGdtProperties(const std::string& prefix, GdtEntry& gdtEntry) const;
void FromString();
void FromString(const std::string& prefix);
};
class InfoStringToStructConverterBase
{
protected:
const InfoString& m_info_string;
void* m_structure;
virtual void FillStructure() = 0;
public:
InfoStringToStructConverterBase(const InfoString& infoString, void* structure);
virtual ~InfoStringToStructConverterBase();
InfoStringToStructConverterBase(const InfoStringToStructConverterBase& other) = delete;
InfoStringToStructConverterBase(InfoStringToStructConverterBase&& other) noexcept = delete;
InfoStringToStructConverterBase& operator=(const InfoStringToStructConverterBase& other) = delete;
InfoStringToStructConverterBase& operator=(InfoStringToStructConverterBase&& other) noexcept = delete;
void Convert();
};
class InfoStringFromStructConverterBase class InfoStringFromStructConverterBase
{ {
protected: protected: