diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 87541b9f..d90076e4 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -83719,14 +83719,14 @@ Address,Quality,Size,Name 0x0000007100fb2098,U,000092, 0x0000007100fb20f4,U,000004,nullsub_4241 0x0000007100fb20f8,U,000004,j__ZdlPv_1003 -0x0000007100fb20fc,U,000308, +0x0000007100fb20fc,O,000308,_ZN4ksys4phys10ContactMgrC1Ev 0x0000007100fb2230,U,000180, 0x0000007100fb22e4,U,000036, 0x0000007100fb2308,U,000212, 0x0000007100fb23dc,U,000152, 0x0000007100fb2474,U,000116, -0x0000007100fb24e8,U,000316,ContactInfoTable -0x0000007100fb2624,U,000688, +0x0000007100fb24e8,O,000316,_ZN4ksys4phys10ContactMgr20loadContactInfoTableEPN4sead4HeapEN3agl3utl19ResParameterArchiveENS0_16ContactLayerTypeE +0x0000007100fb2624,O,000688,_ZN4ksys4phys10ContactMgr22doLoadContactInfoTableEN3agl3utl19ResParameterArchiveENS0_16ContactLayerTypeEb 0x0000007100fb28d4,U,000136, 0x0000007100fb295c,U,000220, 0x0000007100fb2a38,U,000100, @@ -83752,19 +83752,19 @@ Address,Quality,Size,Name 0x0000007100fb3b50,U,000100, 0x0000007100fb3bb4,U,000652, 0x0000007100fb3e40,U,000644, -0x0000007100fb40c4,U,000356, +0x0000007100fb40c4,O,000356,_ZNK4ksys4phys10ContactMgr18getSensorLayerMaskEPNS0_12ReceiverMaskERKN4sead14SafeStringBaseIcEE 0x0000007100fb4228,U,000204, 0x0000007100fb42f4,U,001092, 0x0000007100fb4738,U,000668, 0x0000007100fb49d4,U,000188, 0x0000007100fb4a90,U,000184, -0x0000007100fb4b48,U,000104, -0x0000007100fb4bb0,U,000160, -0x0000007100fb4c50,U,000004,j__ZdlPv_1004 +0x0000007100fb4b48,O,000104,_ZN4ksys4phys16ContactInfoTable8Receiver9postRead_Ev +0x0000007100fb4bb0,O,000160,_ZN4ksys4phys16ContactInfoTable8ReceiverD2Ev +0x0000007100fb4c50,O,000004,_ZN4ksys4phys16ContactInfoTable8ReceiverD0Ev 0x0000007100fb4c54,O,000432,_ZN4sead9SafeArrayIN3agl3utl9ParameterIiEELi32EEC2Ev -0x0000007100fb4e04,U,000056, -0x0000007100fb4e3c,U,000036, -0x0000007100fb4e60,U,000016, +0x0000007100fb4e04,O,000056,_ZN4ksys4phys23receiverMaskEnableLayerEPNS0_12ReceiverMaskENS0_12ContactLayerE +0x0000007100fb4e3c,O,000036,_ZN4ksys4phys37receiverMaskGetSensorLayerMaskForTypeEPNS0_12ReceiverMaskERKN4sead14SafeStringBaseIcEE +0x0000007100fb4e60,O,000016,_ZN4ksys4phys30receiverMaskSetSensorLayerMaskEPNS0_12ReceiverMaskEj 0x0000007100fb4e70,O,000144,_ZN4ksys4phys17EntityGroupFilter4makeENS0_12ContactLayer9ValueTypeES3_PN4sead4HeapE 0x0000007100fb4f00,O,000004,_ZN4ksys4phys17EntityGroupFilterD1Ev 0x0000007100fb4f04,O,000008,_ZThn16_N4ksys4phys17EntityGroupFilterD1Ev @@ -95439,7 +95439,7 @@ Address,Quality,Size,Name 0x00000071012b2134,O,000864,_ZN4ksys4phys10SystemDataD1Ev 0x00000071012b2494,O,000404,_ZN4sead9SafeArrayIN4ksys4phys10SystemData6TablesINS2_10LayerTableELi32EEELi2EED2Ev 0x00000071012b2628,O,000036,_ZN4ksys4phys10SystemDataD0Ev -0x00000071012b264c,O,000368,_ZN4ksys4phys10SystemData4loadEPN4sead4HeapEPNS0_11GroupFilterES6_PNS0_13MaterialTableEPNS0_16ContactInfoTableE +0x00000071012b264c,O,000368,_ZN4ksys4phys10SystemData4loadEPN4sead4HeapEPNS0_11GroupFilterES6_PNS0_13MaterialTableEPNS0_10ContactMgrE 0x00000071012b27bc,O,000544,_ZN4ksys4phys10SystemData14loadLayerTableEPN4sead4HeapEPNS0_11GroupFilterENS0_16ContactLayerTypeE 0x00000071012b29dc,O,000316,_ZN4ksys4phys10SystemData22loadCharacterCtrlTableEPN4sead4HeapE 0x00000071012b2b18,O,000292,_ZN4ksys4phys10SystemData22loadRagdollCtrlKeyListEPN4sead4HeapE diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index 928e58bd..5ef03722 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -38,8 +38,8 @@ target_sources(uking PRIVATE System/physConstraint.h System/physContactInfoParam.cpp System/physContactInfoParam.h - System/physContactInfoTable.cpp - System/physContactInfoTable.h + System/physContactMgr.cpp + System/physContactMgr.h System/physDefines.cpp System/physDefines.h System/physEntityGroupFilter.cpp diff --git a/src/KingSystem/Physics/RigidBody/physRigidBody.cpp b/src/KingSystem/Physics/RigidBody/physRigidBody.cpp index 3fe1bbe9..002c0aef 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBody.cpp +++ b/src/KingSystem/Physics/RigidBody/physRigidBody.cpp @@ -33,7 +33,8 @@ void RigidBody::setMotionFlag(MotionFlag flag) { if (mFlags.isOff(Flag1::_20) && mFlags.isOff(Flag1::_2)) { mFlags.set(Flag1::_2); - MemSystem::instance()->_160->sub_7100FA6C8C(mFlags.isOn(Flag1::MassScaling), this); + MemSystem::instance()->getRigidBodyRequestMgr()->sub_7100FA6C8C( + mFlags.isOn(Flag1::MassScaling), this); } } diff --git a/src/KingSystem/Physics/System/physContactInfoTable.cpp b/src/KingSystem/Physics/System/physContactInfoTable.cpp deleted file mode 100644 index 637cf21f..00000000 --- a/src/KingSystem/Physics/System/physContactInfoTable.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "KingSystem/Physics/System/physContactInfoTable.h" diff --git a/src/KingSystem/Physics/System/physContactInfoTable.h b/src/KingSystem/Physics/System/physContactInfoTable.h deleted file mode 100644 index 84fc8b0a..00000000 --- a/src/KingSystem/Physics/System/physContactInfoTable.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include "KingSystem/Physics/System/physDefines.h" - -namespace sead { -class Heap; -} - -namespace ksys::phys { - -// FIXME -class ContactInfoTable { -public: - ContactInfoTable(); - virtual ~ContactInfoTable(); - - void init(sead::Heap* heap); - - void load(sead::Heap* heap, agl::utl::ResParameterArchive archive, ContactLayerType type); -}; - -} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physContactMgr.cpp b/src/KingSystem/Physics/System/physContactMgr.cpp new file mode 100644 index 00000000..d87462d4 --- /dev/null +++ b/src/KingSystem/Physics/System/physContactMgr.cpp @@ -0,0 +1,91 @@ +#include "KingSystem/Physics/System/physContactMgr.h" +#include "KingSystem/Physics/System/physEntityGroupFilter.h" +#include "KingSystem/Physics/System/physGroupFilter.h" +#include "KingSystem/Physics/System/physMemSystem.h" + +namespace ksys::phys { + +ContactMgr::ContactMgr() { + // FIXME: figure out what these offsets are + mList1.initOffset(0x38); + mList2.initOffset(0x78); + mList3.initOffset(0x40); + mList0.initOffset(0x10); + mList4.initOffset(0x48); + mList5.initOffset(0x48); +} + +void ContactMgr::loadContactInfoTable(sead::Heap* heap, agl::utl::ResParameterArchive archive, + ContactLayerType type) { + auto& table = mContactInfoTables[int(type)]; + + table.param_io.addList(&table.contact_info_table_plist, "ContactInfoTable"); + + const auto root = archive.getRootList(); + const auto num_receivers = root.getResParameterObj(0).getNum(); + + if (num_receivers != 0) + table.receivers.allocBufferAssert(num_receivers, heap); + + doLoadContactInfoTable(archive, type, false); +} + +void ContactMgr::doLoadContactInfoTable(agl::utl::ResParameterArchive archive, + ContactLayerType type, bool skip_params) { + auto& table = mContactInfoTables[int(type)]; + + table.contact_info_table_plist.clearObj(); + + const auto root = archive.getRootList(); + const auto names = root.getResParameterObj(0); + + const auto* filter = MemSystem::instance()->getGroupFilter(type); + const auto layer_base = static_cast(getContactLayerBase(type)); + + for (int i = 0; i < table.receivers.size(); ++i) { + auto& receiver = table.receivers[i]; + + auto* receiver_name = names.getParameterData(i); + receiver.name = receiver_name; + + table.contact_info_table_plist.addObj(&receiver, receiver_name); + receiver.num_layers = filter->getNumLayers(); + + if (!skip_params) { + for (int idx = 0; idx < filter->getNumLayers(); ++idx) { + const char* layer_name = contactLayerToText(layer_base + idx); + receiver.layer_values[idx].init(0, layer_name, layer_name, &receiver); + } + } + } + + table.param_io.applyResParameterArchive(archive); +} + +bool ContactMgr::getSensorLayerMask(ReceiverMask* mask, + const sead::SafeString& receiver_type) const { + const auto& receivers = mContactInfoTables[int(ContactLayerType::Sensor)].receivers; + for (int i = 0; i < receivers.size(); ++i) { + const auto& receiver = receivers[i]; + if (receiver_type == receiver.name) { + receiverMaskSetSensorLayerMask(mask, receiver.layer_mask); + return true; + } + } + return false; +} + +void ContactInfoTable::Receiver::postRead_() { + layer_mask = 0; + layer_mask2 = 0; + + for (int i = 0; i < num_layers; ++i) { + const auto value = layer_values[i].ref(); + if (value & 1) + layer_mask |= 1 << i; + if (value & 2) + layer_mask2 |= 1 << i; + } +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physContactMgr.h b/src/KingSystem/Physics/System/physContactMgr.h new file mode 100644 index 00000000..e46d9997 --- /dev/null +++ b/src/KingSystem/Physics/System/physContactMgr.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "KingSystem/Physics/System/physDefines.h" + +namespace sead { +class Heap; +} + +namespace ksys::phys { + +struct ContactInfoTable { + struct Receiver : agl::utl::ParameterObj { + const char* name = nullptr; + // TODO: figure out what these masks are + u32 layer_mask = 0; + u32 layer_mask2 = 0; + int num_layers = 0; + sead::SafeArray, MaxNumLayersPerType> layer_values; + + protected: + void postRead_() override; + }; + + agl::utl::IParameterIO param_io; + agl::utl::ParameterList contact_info_table_plist; + sead::Buffer receivers; +}; + +class ContactMgr : public sead::hostio::Node { +public: + ContactMgr(); + virtual ~ContactMgr(); + + void init(sead::Heap* heap); + + void loadContactInfoTable(sead::Heap* heap, agl::utl::ResParameterArchive archive, + ContactLayerType type); + + bool getSensorLayerMask(ReceiverMask* mask, const sead::SafeString& receiver_type) const; + +private: + void doLoadContactInfoTable(agl::utl::ResParameterArchive archive, ContactLayerType type, + bool skip_params); + + // FIXME: type, name + sead::Buffer mBuffer; + sead::OffsetList mList0; + int mList0Size = 0; + sead::Atomic _34 = 0; + sead::OffsetList mList1; + sead::OffsetList mList2; + sead::OffsetList mList3; + sead::OffsetList mList4; + sead::OffsetList mList5; + sead::Mutex mMutex1; + sead::Mutex mMutex2; + sead::Mutex mMutex3; + sead::Mutex mMutex4; + sead::Mutex mMutex5; + sead::SafeArray mContactInfoTables{}; +}; + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physDefines.h b/src/KingSystem/Physics/System/physDefines.h index c40db48c..419ca0ba 100644 --- a/src/KingSystem/Physics/System/physDefines.h +++ b/src/KingSystem/Physics/System/physDefines.h @@ -1,7 +1,9 @@ #pragma once +#include #include #include +#include "KingSystem/Utils/BitField.h" namespace ksys::phys { @@ -69,6 +71,8 @@ SensorReserve20,\ SensorCustomReceiver,\ SensorEnd) +constexpr int MaxNumLayersPerType = 32; + SEAD_ENUM(Material, Undefined,\ Soil,\ @@ -164,6 +168,21 @@ enum class MotionType { Unknown = 3, }; +union ReceiverMask { + constexpr ReceiverMask() : raw(0) { unk_flag = true; } + constexpr explicit ReceiverMask(u32 raw_) : raw(raw_) {} + constexpr ReceiverMask& operator=(const ReceiverMask& m) { + raw = m.raw; + return *this; + } + + u32 raw; + // FIXME: is this a sensor layer mask? + util::BitField<0, 21, u32> layer_mask; + // FIXME: is sensor layer? is layer mask? + util::BitField<31, 1, u32> unk_flag; +}; + ContactLayerType getContactLayerType(ContactLayer layer); u32 makeContactLayerMask(ContactLayer layer); u32 getContactLayerBase(ContactLayerType type); diff --git a/src/KingSystem/Physics/System/physEntityGroupFilter.cpp b/src/KingSystem/Physics/System/physEntityGroupFilter.cpp index c67b0855..63e65733 100644 --- a/src/KingSystem/Physics/System/physEntityGroupFilter.cpp +++ b/src/KingSystem/Physics/System/physEntityGroupFilter.cpp @@ -7,6 +7,8 @@ #include #include #include +#include "KingSystem/Physics/System/physContactMgr.h" +#include "KingSystem/Physics/System/physMemSystem.h" #include "KingSystem/Utils/BitField.h" #include "KingSystem/Utils/HeapUtil.h" @@ -51,6 +53,21 @@ static_assert(sizeof(EntityCollisionFilterInfo) == sizeof(u32)); } // namespace +void receiverMaskEnableLayer(ReceiverMask* mask, ContactLayer layer) { + mask->raw |= 1 << getContactLayerBaseRelativeValue(layer); +} + +bool receiverMaskGetSensorLayerMaskForType(ReceiverMask* mask, + const sead::SafeString& receiver_type) { + return MemSystem::instance()->getContactMgr()->getSensorLayerMask(mask, receiver_type); +} + +void receiverMaskSetSensorLayerMask(ReceiverMask* mask, u32 layer_mask) { + *mask = {}; + mask->layer_mask = layer_mask; + mask->unk_flag = true; +} + EntityGroupFilter* EntityGroupFilter::make(ContactLayer::ValueType first, ContactLayer::ValueType last, sead::Heap* heap) { auto* filter = util::alloc(heap, first, last); diff --git a/src/KingSystem/Physics/System/physEntityGroupFilter.h b/src/KingSystem/Physics/System/physEntityGroupFilter.h index 9350a7fc..ca31a640 100644 --- a/src/KingSystem/Physics/System/physEntityGroupFilter.h +++ b/src/KingSystem/Physics/System/physEntityGroupFilter.h @@ -2,6 +2,7 @@ #include #include +#include #include "KingSystem/Physics/System/physDefines.h" #include "KingSystem/Physics/System/physGroupFilter.h" @@ -64,6 +65,11 @@ private: sead::SafeArray mMasks; }; +void receiverMaskEnableLayer(ReceiverMask* mask, ContactLayer layer); +bool receiverMaskGetSensorLayerMaskForType(ReceiverMask* mask, + const sead::SafeString& receiver_type); +void receiverMaskSetSensorLayerMask(ReceiverMask* mask, u32 layer_mask); + u32 orEntityGroundHitMask(u32 mask, GroundHit type); u32 orEntityGroundHitMask(u32 mask, const sead::SafeString& type); diff --git a/src/KingSystem/Physics/System/physGroupFilter.h b/src/KingSystem/Physics/System/physGroupFilter.h index ddf4b327..b139c386 100644 --- a/src/KingSystem/Physics/System/physGroupFilter.h +++ b/src/KingSystem/Physics/System/physGroupFilter.h @@ -60,6 +60,7 @@ public: ContactLayer::ValueType getLayerFirst() const { return mLayerFirst; } ContactLayer::ValueType getLayerLast() const { return mLayerLast; } + int getNumLayers() const { return getLayerLast() - getLayerFirst() + 1; } ContactLayerType getLayerType() const { return mLayerType; } void initFilter(sead::Heap* heap); diff --git a/src/KingSystem/Physics/System/physMemSystem.h b/src/KingSystem/Physics/System/physMemSystem.h index 3bd26cab..a5829227 100644 --- a/src/KingSystem/Physics/System/physMemSystem.h +++ b/src/KingSystem/Physics/System/physMemSystem.h @@ -2,23 +2,38 @@ #include #include +#include "KingSystem/Physics/System/physDefines.h" +#include "KingSystem/Utils/Types.h" namespace ksys::phys { +class ContactMgr; +class GroupFilter; class RigidBody; class SystemGroupHandler; +// FIXME: obviously incomplete. Also this should be moved to its own header +struct RigidBodyRequestMgr { + void sub_7100FA6C8C(bool, RigidBody*); +}; + class MemSystem { SEAD_SINGLETON_DISPOSER(MemSystem) public: - struct Struct160 { - void sub_7100FA6C8C(bool, RigidBody*); - }; + GroupFilter* getGroupFilter(ContactLayerType type) const; + ContactMgr* getContactMgr() const { return mContactMgr; } + RigidBodyRequestMgr* getRigidBodyRequestMgr() const { return mRigidBodyRequestMgr; } void removeSystemGroupHandler(SystemGroupHandler* handler); - u8 _20[0x140]; - Struct160* _160; +private: + u8 _20[0x148 - 0x20]; + ContactMgr* mContactMgr; + void* _150; + void* _158; + RigidBodyRequestMgr* mRigidBodyRequestMgr; + u8 _168[0x480 - 0x168]; }; +KSYS_CHECK_SIZE_NX150(MemSystem, 0x480); } // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physSystemData.cpp b/src/KingSystem/Physics/System/physSystemData.cpp index 319bb98e..d21af924 100644 --- a/src/KingSystem/Physics/System/physSystemData.cpp +++ b/src/KingSystem/Physics/System/physSystemData.cpp @@ -1,5 +1,5 @@ #include "KingSystem/Physics/System/physSystemData.h" -#include "KingSystem/Physics/System/physContactInfoTable.h" +#include "KingSystem/Physics/System/physContactMgr.h" #include "KingSystem/Physics/System/physGroupFilter.h" #include "KingSystem/Physics/System/physMaterialTable.h" #include "KingSystem/Physics/System/physRagdollControllerKeyList.h" @@ -39,7 +39,7 @@ SystemData::~SystemData() { void SystemData::load(sead::Heap* heap, GroupFilter* entity_group_filter, GroupFilter* sensor_group_filter, MaterialTable* material_table, - ContactInfoTable* contact_info_table) { + ContactMgr* contact_info_table) { loadLayerTable(heap, entity_group_filter, ContactLayerType::Entity); loadLayerTable(heap, sensor_group_filter, ContactLayerType::Sensor); loadMaterialTable(heap, material_table); @@ -90,11 +90,10 @@ void SystemData::loadSubMaterialTable(sead::Heap* heap, MaterialTable* table) { table->loadSubMaterialTable(heap, res); } -void SystemData::loadContactInfoTable(sead::Heap* heap, ContactInfoTable* table, - ContactLayerType type) { +void SystemData::loadContactInfoTable(sead::Heap* heap, ContactMgr* table, ContactLayerType type) { mContactInfoTableHandles[int(type)] = new (heap) res::Handle; const auto res = loadContactInfoTableRes(type); - table->load(heap, res, type); + table->loadContactInfoTable(heap, res, type); } void SystemData::loadCharacterCtrlTable(sead::Heap* heap) { diff --git a/src/KingSystem/Physics/System/physSystemData.h b/src/KingSystem/Physics/System/physSystemData.h index 4ee13ef7..9ed3b6f1 100644 --- a/src/KingSystem/Physics/System/physSystemData.h +++ b/src/KingSystem/Physics/System/physSystemData.h @@ -16,15 +16,13 @@ class Handle; namespace ksys::phys { -class ContactInfoTable; +class ContactMgr; class GroupFilter; class MaterialTable; class RagdollControllerKeyList; -constexpr int NumLayers = 32; - struct LayerTable : agl::utl::IParameterObj { - sead::SafeArray, NumLayers> layer_values; + sead::SafeArray, MaxNumLayersPerType> layer_values; GroupFilter* filter; ContactLayer layer; int num_layers; @@ -64,15 +62,15 @@ public: virtual ~SystemData(); void load(sead::Heap* heap, GroupFilter* entity_group_filter, GroupFilter* sensor_group_filter, - MaterialTable* material_table, ContactInfoTable* contact_info_table); + MaterialTable* material_table, ContactMgr* contact_info_table); private: - using LayerMatrix = Tables; + using LayerMatrix = Tables; void loadLayerTable(sead::Heap* heap, GroupFilter* filter, ContactLayerType type); void loadMaterialTable(sead::Heap* heap, MaterialTable* table); void loadSubMaterialTable(sead::Heap* heap, MaterialTable* table); - void loadContactInfoTable(sead::Heap* heap, ContactInfoTable* table, ContactLayerType type); + void loadContactInfoTable(sead::Heap* heap, ContactMgr* table, ContactLayerType type); void loadCharacterCtrlTable(sead::Heap* heap); void loadRagdollCtrlKeyList(sead::Heap* heap);