ksys/phys: Start adding SystemData

- SystemData (WIP)
- MaterialTable (should be complete)
This commit is contained in:
Léo Lam
2021-10-28 20:48:35 +02:00
parent 5580b49345
commit 70aaa429fe
7 changed files with 489 additions and 40 deletions
+4
View File
@@ -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
)
@@ -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
@@ -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
@@ -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
@@ -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