mirror of
https://github.com/zeldaret/botw
synced 2026-06-03 02:28:49 -04:00
ksys/phys: Start adding SystemData
- SystemData (WIP) - MaterialTable (should be complete)
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user