ksys/res: Add GameData

This commit is contained in:
Léo Lam 2020-10-17 17:05:41 +02:00
parent eb222dc784
commit 27da317935
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
9 changed files with 609 additions and 7 deletions

View File

@ -74760,12 +74760,12 @@
0x0000007100df67b8,sub_7100DF67B8,268,
0x0000007100df68c4,sub_7100DF68C4,268,
0x0000007100df69d0,sub_7100DF69D0,268,
0x0000007100df6adc,ResourceBgdata::ctor,136,
0x0000007100df6b64,ResourceBgdata::dtor,20,
0x0000007100df6b78,ResourceBgdata::dtorDelete,52,
0x0000007100df6bac,ResourceBgdata::doCreate,32556,
0x0000007100dfead8,GameDataFlag::DebugData::load,308,
0x0000007100dfec0c,GameDataFlag::Properties::ctor,256,
0x0000007100df6adc,ResourceBgdata::ctor,136,_ZN4ksys3res8GameDataC1Ev
0x0000007100df6b64,ResourceBgdata::dtor,20,_ZN4ksys3res8GameDataD1Ev
0x0000007100df6b78,ResourceBgdata::dtorDelete,52,_ZN4ksys3res8GameDataD0Ev
0x0000007100df6bac,ResourceBgdata::doCreate,32556,_ZN4ksys3res8GameData9doCreate_EPhjPN4sead4HeapE!
0x0000007100dfead8,GameDataFlag::DebugData::load,308,_ZN4ksys3res8GameData13loadDebugDataEPNS_3gdt13FlagDebugDataERKN2al9ByamlIterE
0x0000007100dfec0c,GameDataFlag::Properties::ctor,256,_ZN4ksys3res8GameData18loadFlagPropertiesEPNS_3gdt14FlagPropertiesERKN2al9ByamlIterE
0x0000007100dfed0c,GameDataFlagBool::m0,20,_ZN4ksys3gdt4FlagIbED2Ev
0x0000007100dfed20,GameDataFlagBool::m1,52,_ZN4ksys3gdt4FlagIbED0Ev
0x0000007100dfed54,GameDataFlagBool::getHash,8,_ZNK4ksys3gdt4FlagIbE7getHashEv

Can't render this file because it is too large.

@ -1 +1 @@
Subproject commit 03809dcc60116923222b5e6ff066c14d6ba88da3
Subproject commit 5c347c3ee762eba5595c107c448b527513dbb3e3

View File

@ -1,4 +1,6 @@
target_sources(uking PRIVATE
gdtFlag.cpp
gdtFlag.h
gdtManager.cpp
gdtManager.h
)

View File

@ -186,6 +186,7 @@ public:
virtual bool setValue(T value);
virtual FlagDebugData* getDebugData() const;
void setDebugData(FlagDebugData* data);
private:
sead::SizedEnum<typename FlagType::ValueType, u8> mType = FlagType::Invalid;
@ -381,4 +382,9 @@ inline FlagDebugData* Flag<T>::getDebugData() const {
return mDebugData;
}
template <typename T>
inline void Flag<T>::setDebugData(FlagDebugData* data) {
mDebugData = data;
}
} // namespace ksys::gdt

View File

@ -0,0 +1,7 @@
#include "KingSystem/GameData/gdtManager.h"
namespace ksys::gdt {
SEAD_SINGLETON_DISPOSER_IMPL(Manager)
}

View File

@ -0,0 +1,49 @@
#pragma once
#include <container/seadSafeArray.h>
#include <heap/seadDisposer.h>
#include "KingSystem/Resource/resHandle.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::gdt {
class IManager {
public:
virtual ~IManager() = 0;
};
inline IManager::~IManager() = default;
/// GameDataMgr communication.
class ManagerCom {
public:
virtual const char* getName() const { return "GameData"; }
virtual void syncData();
void* _8 = nullptr;
void* _10 = nullptr;
};
KSYS_CHECK_SIZE_NX150(ManagerCom, 0x18);
// FIXME: very incomplete. This is only here because res::GameData needs to use the Manager's heaps
class Manager : public IManager, public ManagerCom {
SEAD_SINGLETON_DISPOSER(Manager)
Manager();
virtual ~Manager();
public:
sead::Heap* getGameDataHeap() const { return mGameDataHeap; }
sead::Heap* getSaveAreaHeap() const { return mSaveAreaHeap; }
sead::Heap* getGameDataComHeap() const { return mGameDataComHeap; }
private:
sead::Heap* mGameDataHeap = nullptr;
sead::Heap* mSaveAreaHeap = nullptr;
sead::Heap* mGameDataComHeap = nullptr;
res::Handle mGameDataArcHandle;
sead::SafeArray<res::Handle, 31> mBgdataHandles;
};
// FIXME: the size should be 0xDC8
KSYS_CHECK_SIZE_NX150(Manager, 0xa58);
} // namespace ksys::gdt

View File

@ -132,6 +132,8 @@ target_sources(uking PRIVATE
resResourceDemo.h
resResourceDrop.cpp
resResourceDrop.h
resResourceGameData.cpp
resResourceGameData.h
resResourceGParamList.cpp
resResourceGParamList.h
resResourceLifeCondition.cpp

View File

@ -0,0 +1,453 @@
#include "KingSystem/Resource/resResourceGameData.h"
#include <type_traits>
#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/HeapUtil.h"
namespace ksys::res {
GameData::GameData() = default;
GameData::~GameData() {
;
}
namespace {
template <typename FlagType, typename GetConfigFn>
KSYS_ALWAYS_INLINE inline void
loadFlags(const sead::SafeString& data_type, const al::ByamlIter& root_iter, sead::Heap* heap,
sead::Buffer<FlagType>& flags, const sead::SafeString& wanted_data_type,
gdt::FlagType flag_type, const GetConfigFn& get_config_fn) {
constexpr bool IsBoolFlag = std::is_same<FlagType, gdt::FlagBool>();
if (data_type != wanted_data_type)
return;
al::ByamlIter array_iter;
if (!root_iter.tryGetIterByIndex(&array_iter, 0))
return;
const auto num_flags = array_iter.getSize();
if (num_flags > 0)
flags.allocBufferAssert(num_flags, heap);
gdt::FlagProperties properties{};
typename FlagType::ConfigType config{};
for (s32 i = 0; i < num_flags; ++i) {
al::ByamlIter iter;
if (!array_iter.tryGetIterByIndex(&iter, i))
continue;
gdt::FlagDebugData* debug_data = nullptr;
if (util::getDebugHeap())
debug_data = new (util::getDebugHeap()) gdt::FlagDebugData();
GameData::loadDebugData(debug_data, iter);
s32 hash = 0;
iter.tryGetIntByKey(&hash, "HashValue");
const u32 hash_u = hash;
GameData::loadFlagProperties(&properties, iter);
get_config_fn(&config, iter);
flags[i].setDebugData(debug_data);
flags[i].setType(flag_type);
flags[i].setHash(hash_u);
flags[i].setConfig(config);
flags[i].resetToInitialValue();
flags[i].setProperties(properties);
if constexpr (IsBoolFlag) {
s32 category = 0;
iter.tryGetIntByKey(&category, "Category");
flags[i].setCategory(category);
}
}
}
template <typename FlagType, typename GetConfigFn, typename GetConfigForChildFlagFn>
KSYS_ALWAYS_INLINE inline void
loadArrayFlags(const sead::SafeString& data_type, const al::ByamlIter& root_iter, sead::Heap* heap,
sead::PtrArray<sead::Buffer<FlagType>>& flags,
const sead::SafeString& wanted_data_type, gdt::FlagType flag_type,
const GetConfigFn& get_config_fn,
const GetConfigForChildFlagFn& get_config_for_child_flag_fn) {
if (data_type != wanted_data_type)
return;
al::ByamlIter array_iter;
if (!root_iter.tryGetIterByIndex(&array_iter, 0))
return;
const auto num_flags = array_iter.getSize();
flags.allocBuffer(num_flags, heap);
gdt::FlagProperties properties{};
typename FlagType::ConfigType config{};
for (s32 i = 0; i < num_flags; ++i) {
al::ByamlIter iter;
if (!array_iter.tryGetIterByIndex(&iter, i))
continue;
gdt::FlagDebugData* debug_data = nullptr;
if (util::getDebugHeap())
debug_data = new (util::getDebugHeap()) gdt::FlagDebugData();
GameData::loadDebugData(debug_data, iter);
s32 hash = 0;
iter.tryGetIntByKey(&hash, "HashValue");
const u32 hash_u = hash;
GameData::loadFlagProperties(&properties, iter);
get_config_fn(&config, iter);
al::ByamlIter values_iter;
al::ByamlIter init_value_iter;
if (iter.tryGetIterByKey(&init_value_iter, "InitValue")) {
al::ByamlIter item;
if (init_value_iter.tryGetIterByIndex(&item, 0))
item.tryGetIterByKey(&values_iter, "Values");
}
const s32 num_items = values_iter.getSize();
auto& buffer = *(new (heap) sead::Buffer<FlagType>);
buffer.allocBufferAssert(u32(num_items > 1 ? num_items : 1u), heap);
for (s32 value_idx = 0; value_idx < num_items; ++value_idx) {
buffer[value_idx].setDebugData(debug_data);
buffer[value_idx].setType(flag_type);
buffer[value_idx].setHash(hash_u);
if (get_config_for_child_flag_fn(&config, values_iter, value_idx)) {
buffer[value_idx].setConfig(config);
buffer[value_idx].resetToInitialValue();
}
buffer[value_idx].setProperties(properties);
}
flags.pushBack(&buffer);
}
}
inline void tryGetFloatOrInt(const al::ByamlIter& iter, const char* key, f32* value) {
if (iter.tryGetFloatByKey(value, key))
return;
s32 int_value{};
iter.tryGetIntByKey(&int_value, key);
*value = int_value;
}
inline void tryGetFloatOrIntByIndex(const al::ByamlIter& iter, s32 index, f32* value) {
if (iter.tryGetFloatByIndex(value, index))
return;
s32 int_value{};
iter.tryGetIntByIndex(&int_value, index);
*value = int_value;
}
template <typename T>
KSYS_ALWAYS_INLINE inline bool tryGetVector(const al::ByamlIter& value_iter, T* vector) {
al::ByamlIter array_iter;
if (!value_iter.tryGetIterByIndex(&array_iter, 0))
return false;
for (size_t i = 0; i < vector->e.size(); ++i)
tryGetFloatOrIntByIndex(array_iter, i, &vector->e[i]);
return true;
}
} // namespace
// NON_MATCHING:
// * stack layout and reordering (possibly caused by the stack differences).
// * In init_string_array_flag_config, some calls to memcpy (for string copies) are replaced
// with memset and calcLength() is optimized out.
// * sead::Vector4<float>::operator= (the original code does 64-bit loads and stores)
void GameData::doCreate_(u8* data, u32, sead::Heap*) {
auto* heap = gdt::Manager::instance()->getSaveAreaHeap();
const al::ByamlIter root_iter{data};
const char* key = nullptr;
root_iter.getKeyName(&key, 0);
const sead::SafeString data_type = key;
loadFlags(data_type, root_iter, heap, mBoolFlags, "bool_data", gdt::FlagType::Bool,
[](gdt::FlagBool::ConfigType* config, const al::ByamlIter& iter) {
bool min_value{};
bool max_value{};
s32 init_value{};
iter.tryGetIntByKey(&init_value, "InitValue");
config->initial_value = init_value;
iter.tryGetBoolByKey(&min_value, "MinValue");
iter.tryGetBoolByKey(&max_value, "MaxValue");
});
loadFlags(data_type, root_iter, heap, mS32Flags, "s32_data", gdt::FlagType::S32,
[](gdt::FlagS32::ConfigType* config, const al::ByamlIter& iter) {
s32 init_value{};
s32 min_value{};
s32 max_value{};
iter.tryGetIntByKey(&init_value, "InitValue");
iter.tryGetIntByKey(&min_value, "MinValue");
iter.tryGetIntByKey(&max_value, "MaxValue");
config->initial_value = init_value;
config->min_value = min_value;
config->max_value = max_value;
});
loadFlags(data_type, root_iter, heap, mF32Flags, "f32_data", gdt::FlagType::F32,
[](gdt::FlagF32::ConfigType* config, const al::ByamlIter& iter) {
f32 init_value{};
f32 min_value{};
f32 max_value{};
tryGetFloatOrInt(iter, "InitValue", &init_value);
tryGetFloatOrInt(iter, "MinValue", &min_value);
tryGetFloatOrInt(iter, "MaxValue", &max_value);
config->initial_value = init_value;
config->min_value = min_value;
config->max_value = max_value;
});
const auto init_string_flag_config = [](auto* config, const al::ByamlIter& iter) {
using StringType = decltype(config->initial_value);
const char* init_value = "";
iter.tryGetStringByKey(&init_value, "InitValue");
auto* debug_heap = util::getDebugHeap();
if (debug_heap && !sead::SafeString(init_value).isEmpty()) {
auto* copy = new (debug_heap) StringType;
copy->copy(init_value);
init_value = copy->cstr();
}
config->initial_value = StringType(init_value);
config->min_value = StringType("");
config->max_value = StringType("");
};
loadFlags(data_type, root_iter, heap, mStringFlags, "string_data", gdt::FlagType::String,
init_string_flag_config);
loadFlags(data_type, root_iter, heap, mString64Flags, "string64_data", gdt::FlagType::String64,
init_string_flag_config);
loadFlags(data_type, root_iter, heap, mString256Flags, "string256_data",
gdt::FlagType::String256, init_string_flag_config);
const auto init_vector_flag_config = [](auto* config, const al::ByamlIter& iter) {
using VectorType = decltype(config->initial_value);
VectorType init_value;
al::ByamlIter init_value_iter;
if (iter.tryGetIterByKey(&init_value_iter, "InitValue"))
tryGetVector(init_value_iter, &init_value);
VectorType min_value;
al::ByamlIter min_value_iter;
if (iter.tryGetIterByKey(&min_value_iter, "MinValue"))
tryGetVector(min_value_iter, &min_value);
VectorType max_value;
al::ByamlIter max_value_iter;
if (iter.tryGetIterByKey(&max_value_iter, "MaxValue"))
tryGetVector(max_value_iter, &max_value);
config->initial_value = init_value;
config->min_value = min_value;
config->max_value = max_value;
};
loadFlags(data_type, root_iter, heap, mVector2fFlags, "vector2f_data", gdt::FlagType::Vector2f,
init_vector_flag_config);
loadFlags(data_type, root_iter, heap, mVector3fFlags, "vector3f_data", gdt::FlagType::Vector3f,
init_vector_flag_config);
loadFlags(data_type, root_iter, heap, mVector4fFlags, "vector4f_data", gdt::FlagType::Vector4f,
init_vector_flag_config);
loadArrayFlags(
data_type, root_iter, heap, mBoolArrayFlags, "bool_array_data", gdt::FlagType::BoolArray,
[](gdt::FlagBool::ConfigType*, const al::ByamlIter& iter) {
bool min_value;
bool max_value;
iter.tryGetBoolByKey(&min_value, "MinValue");
iter.tryGetBoolByKey(&max_value, "MaxValue");
},
[](gdt::FlagBool::ConfigType* config, const al::ByamlIter& values_iter, s32 value_idx) {
bool value;
s32 int_value{};
if (values_iter.tryGetIntByIndex(&int_value, value_idx))
value = int_value & 1;
else
values_iter.tryGetBoolByIndex(&value, value_idx);
config->initial_value = value;
return true;
});
loadArrayFlags(
data_type, root_iter, heap, mS32ArrayFlags, "s32_array_data", gdt::FlagType::S32Array,
[](gdt::FlagS32::ConfigType* config, const al::ByamlIter& iter) {
s32 min_value;
s32 max_value;
iter.tryGetIntByKey(&min_value, "MinValue");
iter.tryGetIntByKey(&max_value, "MaxValue");
config->min_value = min_value;
config->max_value = max_value;
},
[](gdt::FlagS32::ConfigType* config, const al::ByamlIter& values_iter, s32 value_idx) {
s32 value;
values_iter.tryGetIntByIndex(&value, value_idx);
config->initial_value = value;
return true;
});
loadArrayFlags(
data_type, root_iter, heap, mF32ArrayFlags, "f32_array_data", gdt::FlagType::F32Array,
[](gdt::FlagF32::ConfigType* config, const al::ByamlIter& iter) {
f32 min_value;
f32 max_value;
iter.tryGetFloatByKey(&min_value, "MinValue");
iter.tryGetFloatByKey(&max_value, "MaxValue");
config->min_value = min_value;
config->max_value = max_value;
},
[](gdt::FlagF32::ConfigType* config, const al::ByamlIter& values_iter, s32 value_idx) {
f32 value;
tryGetFloatOrIntByIndex(values_iter, value_idx, &value);
config->initial_value = value;
return true;
});
const auto init_string_array_flag_config = [](auto* config, const al::ByamlIter&) {
using StringType = decltype(config->initial_value);
config->min_value = StringType("");
config->max_value = StringType("");
};
const auto init_string_array_child_flag_config =
[heap](auto* config, const al::ByamlIter& values_iter, s32 value_idx) {
using StringType = decltype(config->initial_value);
const char* init_value = "";
values_iter.tryGetStringByIndex(&init_value, value_idx);
if (!sead::SafeString(init_value).isEmpty()) {
auto* copy = new (heap) StringType;
copy->copy(init_value);
init_value = copy->cstr();
}
config->initial_value = StringType(init_value);
return true;
};
loadArrayFlags(data_type, root_iter, heap, mStringArrayFlags, "string32_array_data",
gdt::FlagType::StringArray, init_string_array_flag_config,
init_string_array_child_flag_config);
loadArrayFlags(data_type, root_iter, heap, mString64ArrayFlags, "string64_array_data",
gdt::FlagType::String64Array, init_string_array_flag_config,
init_string_array_child_flag_config);
loadArrayFlags(data_type, root_iter, heap, mString256ArrayFlags, "string256_array_data",
gdt::FlagType::String256Array, init_string_array_flag_config,
init_string_array_child_flag_config);
const auto init_vector_array_flag_config = [](auto* config, const al::ByamlIter& iter) {
using VectorType = decltype(config->initial_value);
VectorType min_value;
al::ByamlIter min_value_iter;
if (iter.tryGetIterByKey(&min_value_iter, "MinValue"))
tryGetVector(min_value_iter, &min_value);
VectorType max_value;
al::ByamlIter max_value_iter;
if (iter.tryGetIterByKey(&max_value_iter, "MaxValue"))
tryGetVector(max_value_iter, &max_value);
config->min_value = min_value;
config->max_value = max_value;
};
const auto init_vector_array_child_flag_config =
[](auto* config, const al::ByamlIter& values_iter, s32 value_idx) {
using VectorType = decltype(config->initial_value);
VectorType value;
al::ByamlIter value_iter;
if (!values_iter.tryGetIterByIndex(&value_iter, value_idx))
return false;
if (!tryGetVector(value_iter, &value))
return false;
config->initial_value = value;
return true;
};
loadArrayFlags(data_type, root_iter, heap, mVector2fArrayFlags, "vector2f_array_data",
gdt::FlagType::Vector2fArray, init_vector_array_flag_config,
init_vector_array_child_flag_config);
loadArrayFlags(data_type, root_iter, heap, mVector3fArrayFlags, "vector3f_array_data",
gdt::FlagType::Vector3fArray, init_vector_array_flag_config,
init_vector_array_child_flag_config);
loadArrayFlags(data_type, root_iter, heap, mVector4fArrayFlags, "vector4f_array_data",
gdt::FlagType::Vector4fArray, init_vector_array_flag_config,
init_vector_array_child_flag_config);
}
void GameData::loadDebugData(gdt::FlagDebugData* data, const al::ByamlIter& iter) {
if (!data)
return;
const char* data_name = "";
s32 delete_rev = -1;
iter.tryGetStringByKey(&data_name, "DataName");
iter.tryGetIntByKey(&delete_rev, "DeleteRev");
data->name = "";
if (util::getDebugHeap() && !sead::SafeString(data_name).isEmpty()) {
const s32 len = sead::SafeString(data_name).calcLength();
auto* ptr = new (util::getDebugHeap()) char[len + 1];
std::strncpy(ptr, data_name, len);
ptr[len] = sead::SafeString::cNullChar;
data->name = ptr;
}
data->delete_rev = delete_rev;
}
void GameData::loadFlagProperties(gdt::FlagProperties* properties, const al::ByamlIter& iter) {
bool is_one_trigger = false;
bool is_program_readable = false;
bool is_program_writable = false;
bool is_save = false;
bool is_event_associated = false;
int reset_type = 0;
iter.tryGetBoolByKey(&is_one_trigger, "IsOneTrigger");
iter.tryGetBoolByKey(&is_program_readable, "IsProgramReadable");
iter.tryGetBoolByKey(&is_program_writable, "IsProgramWritable");
iter.tryGetBoolByKey(&is_save, "IsSave");
iter.tryGetBoolByKey(&is_event_associated, "IsEventAssociated");
iter.tryGetIntByKey(&reset_type, "ResetType");
properties->setIsOneTrigger(is_one_trigger);
properties->setIsProgramReadable(is_program_readable);
properties->setIsProgramWritable(is_program_writable);
properties->setIsSave(is_save);
properties->setIsEventAssociated(is_event_associated);
properties->setResetType(gdt::ResetType(reset_type));
}
} // namespace ksys::res

View File

@ -0,0 +1,83 @@
#pragma once
#include <container/seadBuffer.h>
#include <container/seadPtrArray.h>
#include <resource/seadResource.h>
#include "KingSystem/GameData/gdtFlag.h"
#include "KingSystem/Utils/Types.h"
namespace al {
class ByamlIter;
}
namespace ksys::res {
class GameData : public sead::DirectResource {
public:
static void loadDebugData(gdt::FlagDebugData* data, const al::ByamlIter& iter);
static void loadFlagProperties(gdt::FlagProperties* properties, const al::ByamlIter& iter);
GameData();
~GameData() override;
void doCreate_(u8* buffer, u32 values_iter, sead::Heap* heap) override;
s32 getField14() const { return _14; }
const sead::Buffer<gdt::FlagBool>& getBoolFlags() const { return mBoolFlags; }
const sead::Buffer<gdt::FlagS32>& getS32Flags() const { return mS32Flags; }
const sead::Buffer<gdt::FlagF32>& getF32Flags() const { return mF32Flags; }
const sead::Buffer<gdt::FlagString>& getStringFlags() const { return mStringFlags; }
const sead::Buffer<gdt::FlagString64>& getString64Flags() const { return mString64Flags; }
const sead::Buffer<gdt::FlagString256>& getString256Flags() const { return mString256Flags; }
const sead::Buffer<gdt::FlagVector2f>& getVector2fFlags() const { return mVector2fFlags; }
const sead::Buffer<gdt::FlagVector3f>& getVector3fFlags() const { return mVector3fFlags; }
const sead::Buffer<gdt::FlagVector4f>& getVector4fFlags() const { return mVector4fFlags; }
const sead::PtrArray<gdt::FlagBoolArray>& getBoolArrayFlags() const { return mBoolArrayFlags; }
const sead::PtrArray<gdt::FlagS32Array>& getS32ArrayFlags() const { return mS32ArrayFlags; }
const sead::PtrArray<gdt::FlagF32Array>& getF32ArrayFlags() const { return mF32ArrayFlags; }
const sead::PtrArray<gdt::FlagStringArray>& getStringArrayFlags() const {
return mStringArrayFlags;
}
const sead::PtrArray<gdt::FlagString64Array>& getString64ArrayFlags() const {
return mString64ArrayFlags;
}
const sead::PtrArray<gdt::FlagString256Array>& getString256ArrayFlags() const {
return mString256ArrayFlags;
}
const sead::PtrArray<gdt::FlagVector2fArray>& getVector2fArrayFlags() const {
return mVector2fArrayFlags;
}
const sead::PtrArray<gdt::FlagVector3fArray>& getVector3fArrayFlags() const {
return mVector3fArrayFlags;
}
const sead::PtrArray<gdt::FlagVector4fArray>& getVector4fArrayFlags() const {
return mVector4fArrayFlags;
}
private:
s32 _14 = -1;
sead::Buffer<gdt::FlagBool> mBoolFlags;
sead::Buffer<gdt::FlagS32> mS32Flags;
sead::Buffer<gdt::FlagF32> mF32Flags;
sead::Buffer<gdt::FlagString> mStringFlags;
sead::Buffer<gdt::FlagString64> mString64Flags;
sead::Buffer<gdt::FlagString256> mString256Flags;
sead::Buffer<gdt::FlagVector2f> mVector2fFlags;
sead::Buffer<gdt::FlagVector3f> mVector3fFlags;
sead::Buffer<gdt::FlagVector4f> mVector4fFlags;
sead::PtrArray<gdt::FlagBoolArray> mBoolArrayFlags;
sead::PtrArray<gdt::FlagS32Array> mS32ArrayFlags;
sead::PtrArray<gdt::FlagF32Array> mF32ArrayFlags;
sead::PtrArray<gdt::FlagStringArray> mStringArrayFlags;
sead::PtrArray<gdt::FlagString64Array> mString64ArrayFlags;
sead::PtrArray<gdt::FlagString256Array> mString256ArrayFlags;
sead::PtrArray<gdt::FlagVector2fArray> mVector2fArrayFlags;
sead::PtrArray<gdt::FlagVector3fArray> mVector3fArrayFlags;
sead::PtrArray<gdt::FlagVector4fArray> mVector4fArrayFlags;
};
KSYS_CHECK_SIZE_NX150(GameData, 0x140);
} // namespace ksys::res