diff options
| author | Léo Lam <leo@leolam.fr> | 2021-10-28 20:48:35 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-10-30 12:17:26 +0200 |
| commit | 70aaa429fe82098d954d0945bfb1b8253a7fa45a (patch) | |
| tree | 7a7d8e94b3a905831c6f06c4e6449cf08ad32245 /src | |
| parent | 5580b4934565823844a7fa02ad0eb62cc7e3ab55 (diff) | |
ksys/phys: Start adding SystemData
- SystemData (WIP)
- MaterialTable (should be complete)
Diffstat (limited to 'src')
| -rw-r--r-- | src/KingSystem/Physics/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physMaterialTable.cpp | 124 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physMaterialTable.h | 67 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physSystemData.cpp | 152 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physSystemData.h | 101 |
5 files changed, 448 insertions, 0 deletions
diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index b4f8d18b..f1f7e050 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -24,12 +24,16 @@ target_sources(uking PRIVATE System/physContactInfoParam.h System/physDefines.cpp System/physDefines.h + System/physMaterialTable.cpp + System/physMaterialTable.h System/physParamSet.cpp System/physParamSet.h System/physRagdollControllerKeyList.h System/physRagdollControllerKeyList.cpp System/physShapeParam.cpp System/physShapeParam.h + System/physSystemData.cpp + System/physSystemData.h System/physUserTag.cpp System/physUserTag.h ) diff --git a/src/KingSystem/Physics/System/physMaterialTable.cpp b/src/KingSystem/Physics/System/physMaterialTable.cpp new file mode 100644 index 00000000..50bfe70f --- /dev/null +++ b/src/KingSystem/Physics/System/physMaterialTable.cpp @@ -0,0 +1,124 @@ +#include "KingSystem/Physics/System/physMaterialTable.h" +#include <heap/seadFrameHeap.h> + +namespace ksys::phys { + +MaterialTable::MaterialTable() = default; + +MaterialTable::~MaterialTable() = default; + +void MaterialTable::loadMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive) { + addMaterialTableList("MaterialTable"); + + for (int i = 0; i < Material::size(); ++i) { + const char* material_name = materialToText(i); + auto& obj = mMaterialTable[i]; + mMaterialTablePList.addObj(&obj, material_name); + + for (int j = 0; j < Material::size(); ++j) { + const char* target_name = materialToText(j); + obj.values[j].init(sead::Vector2f::zero, target_name, target_name, &obj); + } + } + + mMaterialTablePIO.applyResParameterArchive(archive); +} + +void MaterialTable::loadSubMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive) { + addSubMaterialTableList("SubMaterialTable"); + + const auto SubMaterialTable = archive.getRootList().getResParameterList(0); + + auto* str_heap = sead::FrameHeap::create( + 0, "SubMaterialString", heap, 8, sead::Heap::HeapDirection::cHeapDirection_Forward, false); + + for (int i = 0; i < Material::size() && i < SubMaterialTable.getResParameterObjNum(); ++i) { + const char* material_name = materialToText(i); + auto& obj = mSubMaterialTable[i]; + mSubMaterialTablePList.addObj(&obj, material_name); + obj.num_values = SubMaterialTable.getResParameterObj(i).getNum(); + + for (int submat = 0; submat < obj.values.size(); ++submat) { + auto* key = new (str_heap) sead::FormatFixedSafeString<32>("submat_%d", submat); + obj.values[submat].init(sead::SafeString::cEmptyString, *key, *key, &obj); + } + } + + if (archive.getRootList().getResParameterListNum() >= 2) { + mSubMaterialTablePIO.addList(&mSoundSubMaterialTablePList, "SoundSubMaterialTable"); + for (int i = 0; i < Material::size() && i < SubMaterialTable.getResParameterObjNum(); ++i) { + const char* material_name = materialToText(i); + auto& obj = mSoundSubMaterialTable[i]; + mSoundSubMaterialTablePList.addObj(&obj, material_name); + obj.num_values = SubMaterialTable.getResParameterObj(i).getNum(); + + for (int submat = 0; submat < obj.values.size(); ++submat) { + auto* key = new (str_heap) sead::FormatFixedSafeString<32>("submat_%d", submat); + obj.values[submat].init(sead::SafeString::cEmptyString, *key, *key, &obj); + } + } + } + + if (archive.getRootList().getResParameterListNum() >= 3) { + mSubMaterialTablePIO.addList(&mSoundMatchingSubMaterialTablePList, + "SoundMatchingSubMaterialTable"); + const auto list = archive.getRootList().getResParameterList(2); + for (int i = 0; i < Material::size() && i < list.getResParameterObjNum(); ++i) { + const char* material_name = materialToText(i); + auto& obj = mSoundMatchingSubMaterialTable[i]; + mSoundMatchingSubMaterialTablePList.addObj(&obj, material_name); + obj.num_values = list.getResParameterObj(i).getNum(); + + for (int submat = 0; submat < obj.values.size(); ++submat) { + auto* key = new (str_heap) sead::FormatFixedSafeString<32>("submat_%d", submat); + obj.values[submat].init(sead::SafeString::cEmptyString, *key, *key, &obj); + } + } + } + + str_heap->adjust(); + mSubMaterialTablePIO.applyResParameterArchive(archive); +} + +const sead::SafeString& MaterialTable::getSubMaterial(Material material, int submat_idx) const { + return mSubMaterialTable[material].values[submat_idx].ref(); +} + +const sead::SafeString& MaterialTable::getSoundMatchingSubMaterial(Material material, + int submat_idx) const { + return mSoundMatchingSubMaterialTable[material].values[submat_idx].ref(); +} + +static int getSubMaterialIdx_(const MaterialTable::SubValues& table, Material material, + const sead::SafeString& submat_name) { + for (int i = 0; i < table.num_values; ++i) { + if (submat_name == table.values[i].ref()) + return i; + } + + if (submat_name == sead::SafeString::cEmptyString) + return 0; + + return -1; +} + +int MaterialTable::getSubMaterialIdx(Material material, const sead::SafeString& submat_name) const { + const auto& table = mSubMaterialTable[material]; + return getSubMaterialIdx_(table, material, submat_name); +} + +int MaterialTable::getSoundSubMaterialIdx(Material material, + const sead::SafeString& submat_name) const { + const auto& table = mSoundSubMaterialTable[material]; + return getSubMaterialIdx_(table, material, submat_name); +} + +int MaterialTable::getNumSubMaterials(Material material) const { + return mSubMaterialTable[material].num_values; +} + +bool MaterialTable::subMaterialHasSound(Material material, int submat_idx) const { + return getSoundSubMaterialIdx(material, getSubMaterial(material, submat_idx)) != -1; +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physMaterialTable.h b/src/KingSystem/Physics/System/physMaterialTable.h new file mode 100644 index 00000000..04240b0d --- /dev/null +++ b/src/KingSystem/Physics/System/physMaterialTable.h @@ -0,0 +1,67 @@ +#pragma once + +#include <agl/Utils/aglParameter.h> +#include <agl/Utils/aglParameterIO.h> +#include <agl/Utils/aglParameterList.h> +#include <agl/Utils/aglParameterObj.h> +#include <agl/Utils/aglResParameter.h> +#include <container/seadSafeArray.h> +#include "KingSystem/Physics/System/physDefines.h" +#include "KingSystem/Utils/Types.h" + +namespace ksys::phys { + +class MaterialTable { +public: + struct Values : agl::utl::IParameterObj { + sead::SafeArray<agl::utl::Parameter<sead::Vector2f>, Material::size()> values; + }; + KSYS_CHECK_SIZE_NX150(Values, 0x4b0); + + struct SubValues : agl::utl::IParameterObj { + sead::SafeArray<agl::utl::Parameter<sead::FixedSafeString<32>>, 12> values; + int num_values; + }; + KSYS_CHECK_SIZE_NX150(SubValues, 0x3f8); + + MaterialTable(); + virtual ~MaterialTable(); + + void loadMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive); + void loadSubMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive); + + const sead::SafeString& getSubMaterial(Material material, int submat_idx) const; + const sead::SafeString& getSoundMatchingSubMaterial(Material material, int submat_idx) const; + + int getSubMaterialIdx(Material material, const sead::SafeString& submat_name) const; + int getSoundSubMaterialIdx(Material material, const sead::SafeString& submat_name) const; + + int getNumSubMaterials(Material material) const; + bool subMaterialHasSound(Material material, int submat_idx) const; + +private: + void addMaterialTableList(const char* name) { + mMaterialTablePIO.addList(&mMaterialTablePList, name); + } + + void addSubMaterialTableList(const char* name) { + mSubMaterialTablePIO.addList(&mSubMaterialTablePList, name); + } + + agl::utl::IParameterIO mMaterialTablePIO; + agl::utl::ParameterList mMaterialTablePList; + sead::SafeArray<Values, Material::size()> mMaterialTable; + + agl::utl::IParameterIO mSubMaterialTablePIO; + agl::utl::ParameterList mSubMaterialTablePList; + sead::SafeArray<SubValues, Material::size()> mSubMaterialTable; + + agl::utl::ParameterList mSoundSubMaterialTablePList; + sead::SafeArray<SubValues, Material::size()> mSoundSubMaterialTable; + + agl::utl::ParameterList mSoundMatchingSubMaterialTablePList; + sead::SafeArray<SubValues, Material::size()> mSoundMatchingSubMaterialTable; +}; +KSYS_CHECK_SIZE_NX150(MaterialTable, 0x25a28); + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physSystemData.cpp b/src/KingSystem/Physics/System/physSystemData.cpp new file mode 100644 index 00000000..097b6a4b --- /dev/null +++ b/src/KingSystem/Physics/System/physSystemData.cpp @@ -0,0 +1,152 @@ +#include "KingSystem/Physics/System/physSystemData.h" +#include "KingSystem/Physics/System/physMaterialTable.h" +#include "KingSystem/Physics/System/physRagdollControllerKeyList.h" +#include "KingSystem/Resource/resHandle.h" +#include "KingSystem/Resource/resLoadRequest.h" + +namespace ksys::phys { + +SystemData::SystemData() = default; + +template <typename T> +static void deleteAndNull(T*& ptr) { + if (ptr) { + delete ptr; + ptr = nullptr; + } +} + +SystemData::~SystemData() { + deleteAndNull(mMaterialTableHandle); + deleteAndNull(mSubMaterialTableHandle); + + deleteAndNull(mLayerTableInfo[0].mResHandle); + deleteAndNull(mContactInfoTableHandles[0]); + + deleteAndNull(mLayerTableInfo[1].mResHandle); + deleteAndNull(mContactInfoTableHandles[1]); + + deleteAndNull(mCharacterCtrlTable.mResHandle); + + if (auto*& handle = mRagdollCtrlKeyListHandle) { + delete handle; + handle = nullptr; + mRagdollCtrlKeyList = nullptr; + } +} + +void SystemData::load(sead::Heap* heap, LayerTable* entity_layer_table, + LayerTable* sensor_layer_table, MaterialTable* material_table, + ContactInfoTable* contact_info_table) { + loadLayerTable(heap, entity_layer_table, LayerTableType::Entity); + loadLayerTable(heap, sensor_layer_table, LayerTableType::Sensor); + loadMaterialTable(heap, material_table); + loadSubMaterialTable(heap, material_table); + loadContactInfoTable(heap, contact_info_table, LayerTableType::Entity); + loadContactInfoTable(heap, contact_info_table, LayerTableType::Sensor); + loadCharacterCtrlTable(heap); + loadRagdollCtrlKeyList(heap); +} + +void SystemData::loadMaterialTable(sead::Heap* heap, MaterialTable* table) { + mMaterialTableHandle = new (heap) res::Handle; + const auto res = loadMaterialTableRes(); + table->loadMaterialTable(heap, res); +} + +void SystemData::loadCharacterCtrlTable(sead::Heap* heap) { + mCharacterCtrlTable.addList("CharacterControllerTable"); + + auto& obj = mCharacterCtrlTable.mTables[0]; + mCharacterCtrlTable.mParamList.addObj( + &obj, CharacterControllerTable::Type(CharacterControllerTable::Type::Default).text()); + + for (int i = 0; i < Material::size(); ++i) { + const char* material_text = materialToText(i); + obj.params[i].init(0.0, material_text, material_text, &obj); + } + + mCharacterCtrlTable.mResHandle = new (heap) res::Handle; + const auto res = loadCharacterCtrlTableRes(); + mCharacterCtrlTable.mParamIO.applyResParameterArchive(res); +} + +void SystemData::loadRagdollCtrlKeyList(sead::Heap* heap) { + mRagdollCtrlKeyListHandle = new (heap) res::Handle; + + res::LoadRequest request; + request.mRequester = "physSystemData"; + const char* path = "Physics/System/RagdollControllerKeyList.brgcon"; + auto* res = mRagdollCtrlKeyListHandle->load(path, &request); + mRagdollCtrlKeyList = sead::DynamicCast<RagdollControllerKeyList>(res); +} + +agl::utl::ResParameterArchive +SystemData::loadLayerTableRes(const SystemData::LayerTableInfoContainer& container, + SystemData::LayerTableType type) { + res::LoadRequest request; + request.mRequester = "physSystemData"; + const char* path{}; + switch (type) { + case LayerTableType::Entity: + path = "Physics/System/EntityLayerTable.bphyslayer"; + break; + case LayerTableType::Sensor: + path = "Physics/System/SensorLayerTable.bphyslayer"; + break; + } + const auto& resource = *container.mResHandle->load(path, &request); + auto* direct_resource = sead::DynamicCast<const sead::DirectResource>(&resource); + return agl::utl::ResParameterArchive{direct_resource->getRawData()}; +} + +agl::utl::ResParameterArchive SystemData::loadMaterialTableRes() { + res::LoadRequest request; + request.mRequester = "physSystemData"; + const char* path = "Physics/System/PhysicsMaterialTable.bphysmaterial"; + const auto& resource = *mMaterialTableHandle->load(path, &request); + auto* direct_resource = sead::DynamicCast<const sead::DirectResource>(&resource); + return agl::utl::ResParameterArchive{direct_resource->getRawData()}; +} + +agl::utl::ResParameterArchive SystemData::loadSubMaterialTableRes() { + res::LoadRequest request; + request.mRequester = "physSystemData"; + const char* path = "Physics/System/PhysicsSubMaterialTable.bphyssubmat"; + const auto& resource = *mSubMaterialTableHandle->load(path, &request); + auto* direct_resource = sead::DynamicCast<const sead::DirectResource>(&resource); + return agl::utl::ResParameterArchive{direct_resource->getRawData()}; +} + +agl::utl::ResParameterArchive SystemData::loadContactInfoTableRes(SystemData::LayerTableType type) { + res::LoadRequest request; + request.mRequester = "physSystemData"; + const char* path{}; + switch (type) { + case LayerTableType::Entity: + path = "Physics/System/EntityContactInfoTable.bphyscontact"; + break; + case LayerTableType::Sensor: + path = "Physics/System/SensorContactInfoTable.bphyscontact"; + break; + } + /// @bug Possible bug? The request is never used. + const auto& resource = *mContactInfoTableHandles[int(type)]->load(path, nullptr); + auto* direct_resource = sead::DynamicCast<const sead::DirectResource>(&resource); + return agl::utl::ResParameterArchive{direct_resource->getRawData()}; +} + +agl::utl::ResParameterArchive SystemData::loadCharacterCtrlTableRes() { + res::LoadRequest request; + request.mRequester = "physSystemData"; + const char* path = "Physics/System/CharacterControllerTable.bphyscharcon"; + const auto& resource = *mCharacterCtrlTable.mResHandle->load(path, &request); + auto* direct_resource = sead::DynamicCast<const sead::DirectResource>(&resource); + return agl::utl::ResParameterArchive{direct_resource->getRawData()}; +} + +void LayerTableInfo::postRead_() { + // FIXME +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physSystemData.h b/src/KingSystem/Physics/System/physSystemData.h new file mode 100644 index 00000000..9d119655 --- /dev/null +++ b/src/KingSystem/Physics/System/physSystemData.h @@ -0,0 +1,101 @@ +#pragma once + +#include <agl/Utils/aglParameter.h> +#include <agl/Utils/aglParameterIO.h> +#include <agl/Utils/aglParameterList.h> +#include <agl/Utils/aglParameterObj.h> +#include <agl/Utils/aglResParameter.h> +#include <container/seadSafeArray.h> +#include <prim/seadEnum.h> +#include "KingSystem/Physics/System/physDefines.h" +#include "KingSystem/Utils/Types.h" + +namespace ksys::res { +class Handle; +} + +namespace ksys::phys { + +class ContactInfoTable; +class LayerTable; +class MaterialTable; +class RagdollControllerKeyList; + +constexpr int NumLayers = 32; + +struct LayerTableInfo : agl::utl::IParameterObj { + sead::SafeArray<agl::utl::Parameter<int>, NumLayers> params; + void* table; + int idx = 0; + int count; + +protected: + void postRead_() override; +}; +KSYS_CHECK_SIZE_NX150(LayerTableInfo, 0x440); + +struct CharacterControllerTable : agl::utl::IParameterObj { + SEAD_ENUM(Type, Default) + + sead::SafeArray<agl::utl::Parameter<float>, Material::size()> params; +}; +KSYS_CHECK_SIZE_NX150(CharacterControllerTable, 0x4b0); + +class SystemData { +public: + template <typename Table, int Count> + class Tables { + public: + auto& Entries() { return mTables; } + const auto& Entries() const { return mTables; } + + private: + friend class SystemData; + + void addList(const char* name) { mParamIO.addList(&mParamList, name); } + + sead::SafeArray<Table, Count> mTables; + agl::utl::ParameterList mParamList; + agl::utl::IParameterIO mParamIO; + res::Handle* mResHandle = nullptr; + }; + + SystemData(); + virtual ~SystemData(); + + void load(sead::Heap* heap, LayerTable* entity_layer_table, LayerTable* sensor_layer_table, + MaterialTable* material_table, ContactInfoTable* contact_info_table); + +private: + enum class LayerTableType { + Entity, + Sensor, + }; + + using LayerTableInfoContainer = Tables<LayerTableInfo, NumLayers>; + + void loadLayerTable(sead::Heap* heap, LayerTable* table, LayerTableType type); + void loadMaterialTable(sead::Heap* heap, MaterialTable* table); + void loadSubMaterialTable(sead::Heap* heap, MaterialTable* table); + void loadContactInfoTable(sead::Heap* heap, ContactInfoTable* table, LayerTableType type); + void loadCharacterCtrlTable(sead::Heap* heap); + void loadRagdollCtrlKeyList(sead::Heap* heap); + + agl::utl::ResParameterArchive loadLayerTableRes(const LayerTableInfoContainer& container, + LayerTableType type); + agl::utl::ResParameterArchive loadMaterialTableRes(); + agl::utl::ResParameterArchive loadSubMaterialTableRes(); + agl::utl::ResParameterArchive loadContactInfoTableRes(LayerTableType type); + agl::utl::ResParameterArchive loadCharacterCtrlTableRes(); + + sead::SafeArray<LayerTableInfoContainer, 2> mLayerTableInfo{}; + res::Handle* mMaterialTableHandle{}; + res::Handle* mSubMaterialTableHandle{}; + sead::SafeArray<res::Handle*, 2> mContactInfoTableHandles{}; + Tables<CharacterControllerTable, 1> mCharacterCtrlTable; + RagdollControllerKeyList* mRagdollCtrlKeyList{}; + res::Handle* mRagdollCtrlKeyListHandle{}; +}; +KSYS_CHECK_SIZE_NX150(SystemData, 0x11b48); + +} // namespace ksys::phys |
