summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-10-28 20:48:35 +0200
committerLéo Lam <leo@leolam.fr>2021-10-30 12:17:26 +0200
commit70aaa429fe82098d954d0945bfb1b8253a7fa45a (patch)
tree7a7d8e94b3a905831c6f06c4e6449cf08ad32245 /src
parent5580b4934565823844a7fa02ad0eb62cc7e3ab55 (diff)
ksys/phys: Start adding SystemData
- SystemData (WIP) - MaterialTable (should be complete)
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/Physics/CMakeLists.txt4
-rw-r--r--src/KingSystem/Physics/System/physMaterialTable.cpp124
-rw-r--r--src/KingSystem/Physics/System/physMaterialTable.h67
-rw-r--r--src/KingSystem/Physics/System/physSystemData.cpp152
-rw-r--r--src/KingSystem/Physics/System/physSystemData.h101
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