diff --git a/data/uking_functions.csv b/data/uking_functions.csv index d90076e4..d581e5b6 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -83727,12 +83727,12 @@ Address,Quality,Size,Name 0x0000007100fb2474,U,000116, 0x0000007100fb24e8,O,000316,_ZN4ksys4phys10ContactMgr20loadContactInfoTableEPN4sead4HeapEN3agl3utl19ResParameterArchiveENS0_16ContactLayerTypeE 0x0000007100fb2624,O,000688,_ZN4ksys4phys10ContactMgr22doLoadContactInfoTableEN3agl3utl19ResParameterArchiveENS0_16ContactLayerTypeEb -0x0000007100fb28d4,U,000136, +0x0000007100fb28d4,O,000136,_ZN4ksys4phys10ContactMgr18allocContactPointsEPN4sead4HeapEiRKNS2_14SafeStringBaseIcEEiii 0x0000007100fb295c,U,000220, -0x0000007100fb2a38,U,000100, +0x0000007100fb2a38,O,000100,_ZN4ksys4phys10ContactMgr21registerContactPointsEPNS0_18RigidContactPointsE 0x0000007100fb2a9c,U,000056, 0x0000007100fb2ad4,U,000156, -0x0000007100fb2b70,U,000148, +0x0000007100fb2b70,O,000148,_ZN4ksys4phys10ContactMgr17freeContactPointsEPNS0_18RigidContactPointsE 0x0000007100fb2c04,U,000144, 0x0000007100fb2c94,U,000216, 0x0000007100fb2d6c,U,000136, @@ -84088,11 +84088,11 @@ Address,Quality,Size,Name 0x0000007100fc7608,U,000052, 0x0000007100fc763c,U,000064, 0x0000007100fc767c,U,000024, -0x0000007100fc7694,U,000076, -0x0000007100fc76e0,U,000004,nullsub_4247 -0x0000007100fc76e4,U,000004,j__ZdlPv_1009 -0x0000007100fc76e8,U,000092, -0x0000007100fc7744,U,000048, +0x0000007100fc7694,O,000076,_ZN4ksys4phys18RigidContactPointsC1ERKN4sead14SafeStringBaseIcEEiii +0x0000007100fc76e0,O,000004,_ZN4ksys4phys18RigidContactPointsD1Ev +0x0000007100fc76e4,O,000004,_ZN4ksys4phys18RigidContactPointsD0Ev +0x0000007100fc76e8,O,000092,_ZN4ksys4phys18RigidContactPoints11allocPointsEPN4sead4HeapEi +0x0000007100fc7744,O,000048,_ZN4ksys4phys18RigidContactPoints10freePointsEv 0x0000007100fc7774,U,000084, 0x0000007100fc77c8,U,000044, 0x0000007100fc77f4,U,000260, @@ -84301,13 +84301,13 @@ Address,Quality,Size,Name 0x0000007100fcf8b0,U,000004,nullsub_4257 0x0000007100fcf8b4,U,000008, 0x0000007100fcf8bc,U,000072, -0x0000007100fcf904,U,000348, +0x0000007100fcf904,O,000348,_ZN4ksys4phys20RigidContactPointsEx17registerLayerPairENS0_12ContactLayerES2_b 0x0000007100fcfa60,U,000024, -0x0000007100fcfa78,U,000096, -0x0000007100fcfad8,U,000004,nullsub_4258 -0x0000007100fcfadc,U,000004,j__ZdlPv_1013 -0x0000007100fcfae0,U,000300, -0x0000007100fcfc0c,U,000168, +0x0000007100fcfa78,O,000096,_ZN4ksys4phys20RigidContactPointsExC1ERKN4sead14SafeStringBaseIcEEiii +0x0000007100fcfad8,O,000004,_ZN4ksys4phys20RigidContactPointsExD1Ev +0x0000007100fcfadc,O,000004,_ZN4ksys4phys20RigidContactPointsExD0Ev +0x0000007100fcfae0,O,000300,_ZN4ksys4phys20RigidContactPointsEx11allocPointsEPN4sead4HeapEii +0x0000007100fcfc0c,O,000168,_ZN4ksys4phys20RigidContactPointsEx10freePointsEv 0x0000007100fcfcb4,U,000260, 0x0000007100fcfdb8,U,000048, 0x0000007100fcfde8,U,000068, @@ -93425,11 +93425,11 @@ Address,Quality,Size,Name 0x000000710121686c,U,000040,PhysicsMemSys::__auto15 0x0000007101216894,U,000052, 0x00000071012168c8,U,000052, -0x00000071012168fc,U,000008, -0x0000007101216904,U,000008, +0x00000071012168fc,O,000008,_ZNK4ksys4phys9MemSystem18allocContactPointsEPN4sead4HeapEiRKNS2_14SafeStringBaseIcEEiii +0x0000007101216904,O,000008,_ZNK4ksys4phys9MemSystem17freeContactPointsEPNS0_18RigidContactPointsE 0x000000710121690c,U,000008, 0x0000007101216914,U,000080, -0x0000007101216964,U,000008, +0x0000007101216964,O,000008,_ZNK4ksys4phys9MemSystem21registerContactPointsEPNS0_18RigidContactPointsE 0x000000710121696c,U,000008, 0x0000007101216974,U,000048, 0x00000071012169a4,U,000008, diff --git a/lib/sead b/lib/sead index d19d8107..c2ffe0c2 160000 --- a/lib/sead +++ b/lib/sead @@ -1 +1 @@ -Subproject commit d19d810793cbd4d92d45793b1956a71ea71f9dd0 +Subproject commit c2ffe0c2d03a2ffa2a8b2a679810e08ebd16d45d diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index 5ef03722..7936a9f4 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -56,6 +56,10 @@ target_sources(uking PRIVATE System/physParamSet.h System/physRagdollControllerKeyList.h System/physRagdollControllerKeyList.cpp + System/physRigidContactPoints.cpp + System/physRigidContactPoints.h + System/physRigidContactPointsEx.cpp + System/physRigidContactPointsEx.h System/physShapeParam.cpp System/physShapeParam.h System/physSystemData.cpp diff --git a/src/KingSystem/Physics/System/physContactMgr.cpp b/src/KingSystem/Physics/System/physContactMgr.cpp index d87462d4..dfbf294e 100644 --- a/src/KingSystem/Physics/System/physContactMgr.cpp +++ b/src/KingSystem/Physics/System/physContactMgr.cpp @@ -1,13 +1,15 @@ #include "KingSystem/Physics/System/physContactMgr.h" +#include #include "KingSystem/Physics/System/physEntityGroupFilter.h" #include "KingSystem/Physics/System/physGroupFilter.h" #include "KingSystem/Physics/System/physMemSystem.h" +#include "KingSystem/Physics/System/physRigidContactPoints.h" namespace ksys::phys { ContactMgr::ContactMgr() { + mRigidContactPoints.initOffset(RigidContactPoints::getListNodeOffset()); // FIXME: figure out what these offsets are - mList1.initOffset(0x38); mList2.initOffset(0x78); mList3.initOffset(0x40); mList0.initOffset(0x10); @@ -62,6 +64,33 @@ void ContactMgr::doLoadContactInfoTable(agl::utl::ResParameterArchive archive, table.param_io.applyResParameterArchive(archive); } +RigidContactPoints* ContactMgr::allocContactPoints(sead::Heap* heap, int num, + const sead::SafeString& name, int a, int b, + int c) { + auto* points = new (heap) RigidContactPoints(name, a, b, c); + points->allocPoints(heap, num); + return points; +} + +void ContactMgr::registerContactPoints(RigidContactPoints* points) { + auto lock = sead::makeScopedLock(mMutex1); + if (!points->isLinked()) + mRigidContactPoints.pushBack(points); +} + +void ContactMgr::freeContactPoints(RigidContactPoints* points) { + if (!points) + return; + + { + auto lock = sead::makeScopedLock(mMutex1); + if (points->isLinked()) + mRigidContactPoints.erase(points); + } + points->freePoints(); + delete points; +} + bool ContactMgr::getSensorLayerMask(ReceiverMask* mask, const sead::SafeString& receiver_type) const { const auto& receivers = mContactInfoTables[int(ContactLayerType::Sensor)].receivers; diff --git a/src/KingSystem/Physics/System/physContactMgr.h b/src/KingSystem/Physics/System/physContactMgr.h index e46d9997..4eb5f4ff 100644 --- a/src/KingSystem/Physics/System/physContactMgr.h +++ b/src/KingSystem/Physics/System/physContactMgr.h @@ -20,6 +20,8 @@ class Heap; namespace ksys::phys { +class RigidContactPoints; + struct ContactInfoTable { struct Receiver : agl::utl::ParameterObj { const char* name = nullptr; @@ -50,6 +52,11 @@ public: bool getSensorLayerMask(ReceiverMask* mask, const sead::SafeString& receiver_type) const; + RigidContactPoints* allocContactPoints(sead::Heap* heap, int num, const sead::SafeString& name, + int a, int b, int c); + void registerContactPoints(RigidContactPoints* points); + void freeContactPoints(RigidContactPoints* points); + private: void doLoadContactInfoTable(agl::utl::ResParameterArchive archive, ContactLayerType type, bool skip_params); @@ -59,7 +66,7 @@ private: sead::OffsetList mList0; int mList0Size = 0; sead::Atomic _34 = 0; - sead::OffsetList mList1; + sead::OffsetList mRigidContactPoints; sead::OffsetList mList2; sead::OffsetList mList3; sead::OffsetList mList4; diff --git a/src/KingSystem/Physics/System/physDefines.h b/src/KingSystem/Physics/System/physDefines.h index 419ca0ba..6ea54cda 100644 --- a/src/KingSystem/Physics/System/physDefines.h +++ b/src/KingSystem/Physics/System/physDefines.h @@ -10,6 +10,7 @@ namespace ksys::phys { enum class ContactLayerType { Entity, Sensor, + Invalid, }; SEAD_ENUM(ContactLayer, diff --git a/src/KingSystem/Physics/System/physMemSystem.cpp b/src/KingSystem/Physics/System/physMemSystem.cpp index e69de29b..a8193a33 100644 --- a/src/KingSystem/Physics/System/physMemSystem.cpp +++ b/src/KingSystem/Physics/System/physMemSystem.cpp @@ -0,0 +1,22 @@ +#include "KingSystem/Physics/System/physMemSystem.h" +#include "KingSystem/Physics/System/physContactMgr.h" + +namespace ksys::phys { + +SEAD_SINGLETON_DISPOSER_IMPL(MemSystem) + +RigidContactPoints* MemSystem::allocContactPoints(sead::Heap* heap, int num, + const sead::SafeString& name, int a, int b, + int c) const { + return mContactMgr->allocContactPoints(heap, num, name, a, b, c); +} + +void MemSystem::freeContactPoints(RigidContactPoints* points) const { + mContactMgr->freeContactPoints(points); +} + +void MemSystem::registerContactPoints(RigidContactPoints* points) const { + mContactMgr->registerContactPoints(points); +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physMemSystem.h b/src/KingSystem/Physics/System/physMemSystem.h index a5829227..92eec883 100644 --- a/src/KingSystem/Physics/System/physMemSystem.h +++ b/src/KingSystem/Physics/System/physMemSystem.h @@ -10,6 +10,8 @@ namespace ksys::phys { class ContactMgr; class GroupFilter; class RigidBody; +class RigidContactPoints; +class RigidContactPointsEx; class SystemGroupHandler; // FIXME: obviously incomplete. Also this should be moved to its own header @@ -19,15 +21,25 @@ struct RigidBodyRequestMgr { class MemSystem { SEAD_SINGLETON_DISPOSER(MemSystem) + MemSystem(); + virtual ~MemSystem(); + public: GroupFilter* getGroupFilter(ContactLayerType type) const; ContactMgr* getContactMgr() const { return mContactMgr; } RigidBodyRequestMgr* getRigidBodyRequestMgr() const { return mRigidBodyRequestMgr; } + RigidContactPoints* allocContactPoints(sead::Heap* heap, int num, const sead::SafeString& name, + int a, int b, int c) const; + void freeContactPoints(RigidContactPoints* points) const; + void registerContactPoints(RigidContactPoints* points) const; + void registerContactPointLayerPair(RigidContactPointsEx* points, ContactLayer layer1, + ContactLayer layer2, bool enabled); + void removeSystemGroupHandler(SystemGroupHandler* handler); private: - u8 _20[0x148 - 0x20]; + u8 _28[0x148 - 0x28]; ContactMgr* mContactMgr; void* _150; void* _158; diff --git a/src/KingSystem/Physics/System/physRigidContactPoints.cpp b/src/KingSystem/Physics/System/physRigidContactPoints.cpp new file mode 100644 index 00000000..2e1c6ed9 --- /dev/null +++ b/src/KingSystem/Physics/System/physRigidContactPoints.cpp @@ -0,0 +1,18 @@ +#include "KingSystem/Physics/System/physRigidContactPoints.h" + +namespace ksys::phys { + +RigidContactPoints::RigidContactPoints(const sead::SafeString& name, int a, int b, int c) + : IRigidContactPoints(name, a, b, c) {} + +RigidContactPoints::~RigidContactPoints() = default; + +void RigidContactPoints::allocPoints(sead::Heap* heap, int num) { + mPoints.allocBufferAssert(num, heap); +} + +void RigidContactPoints::freePoints() { + mPoints.freeBuffer(); +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physRigidContactPoints.h b/src/KingSystem/Physics/System/physRigidContactPoints.h new file mode 100644 index 00000000..21165243 --- /dev/null +++ b/src/KingSystem/Physics/System/physRigidContactPoints.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "KingSystem/Utils/Types.h" + +namespace ksys::phys { + +class IRigidContactPoints : public sead::INamable { +public: + // FIXME: parameter names + IRigidContactPoints(const sead::SafeString& name, int a, int b, int c) + : sead::INamable(name), _2c(a), _30(b), _34(c) {} + virtual ~IRigidContactPoints() = default; + + bool isLinked() const { return mListNode.isLinked(); } + static constexpr size_t getListNodeOffset() { return offsetof(IRigidContactPoints, mListNode); } + +protected: + sead::Atomic _18; + sead::SafeArray mLayerMask; + sead::SafeArray mLayerMask2; + u32 _2c{}; + u32 _30{}; + u32 _34{}; + sead::ListNode mListNode{}; +}; + +class RigidContactPoints : public IRigidContactPoints { +public: + static RigidContactPoints* make(sead::Heap* heap, int num, const sead::SafeString& name, int a, + int b, int c); + static void free(RigidContactPoints* instance); + + RigidContactPoints(const sead::SafeString& name, int a, int b, int c); + ~RigidContactPoints() override; + virtual void freePoints(); + virtual void allocPoints(sead::Heap* heap, int num); + +private: + sead::Buffer mPoints{}; + void* _58{}; +}; +KSYS_CHECK_SIZE_NX150(RigidContactPoints, 0x60); + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physRigidContactPointsEx.cpp b/src/KingSystem/Physics/System/physRigidContactPointsEx.cpp new file mode 100644 index 00000000..ac836364 --- /dev/null +++ b/src/KingSystem/Physics/System/physRigidContactPointsEx.cpp @@ -0,0 +1,52 @@ +#include "KingSystem/Physics/System/physRigidContactPointsEx.h" +#include "KingSystem/Physics/System/physMemSystem.h" + +namespace ksys::phys { + +bool RigidContactPointsEx::registerLayerPair(ContactLayer layer1, ContactLayer layer2, + bool enabled) { + if (mLayerType == ContactLayerType::Invalid) + mLayerType = getContactLayerType(layer1); + + if (!isPairUnknown(layer1, layer2)) + return false; + + // Add a new one. + auto* entry = mLayerEntries.emplaceBack(); + if (entry == nullptr) + return false; + + entry->layer1 = layer1; + entry->layer2 = layer2; + entry->enabled = enabled; + [&] { MemSystem::instance()->registerContactPointLayerPair(this, layer1, layer2, enabled); }(); + return true; +} + +bool RigidContactPointsEx::isPairUnknown(ContactLayer layer1, ContactLayer layer2) const { + for (int i = 0; i < mLayerEntries.size(); ++i) { + const auto* entry = mLayerEntries[i]; + if (int(layer1) == entry->layer1 && int(layer2) == entry->layer2) + return false; + if (int(layer1) == entry->layer2 && int(layer2) == entry->layer1) + return false; + } + return true; +} + +RigidContactPointsEx::RigidContactPointsEx(const sead::SafeString& name, int a, int b, int c) + : IRigidContactPoints(name, a, b, c) {} + +RigidContactPointsEx::~RigidContactPointsEx() = default; + +void RigidContactPointsEx::allocPoints(sead::Heap* heap, int num, int num2) { + mPoints.allocBufferAssert(num, heap); + mLayerEntries.allocBuffer(num2, heap); +} + +void RigidContactPointsEx::freePoints() { + mPoints.freeBuffer(); + mLayerEntries.freeBuffer(); +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physRigidContactPointsEx.h b/src/KingSystem/Physics/System/physRigidContactPointsEx.h new file mode 100644 index 00000000..69954ee1 --- /dev/null +++ b/src/KingSystem/Physics/System/physRigidContactPointsEx.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include "KingSystem/Physics/System/physDefines.h" +#include "KingSystem/Physics/System/physRigidContactPoints.h" + +namespace ksys::phys { + +// FIXME: rename. This should be below SensorGroupFilter and StaticCompound stuff +class RigidContactPointsEx : public IRigidContactPoints { +public: + static RigidContactPointsEx* make(); + static void free(RigidContactPointsEx* instance); + + RigidContactPointsEx(const sead::SafeString& name, int a, int b, int c); + ~RigidContactPointsEx() override; + virtual void freePoints(); + virtual void allocPoints(sead::Heap* heap, int num, int num2); + + bool registerLayerPair(ContactLayer layer1, ContactLayer layer2, bool enabled); + bool isPairUnknown(ContactLayer layer1, ContactLayer layer2) const; + +private: + struct LayerEntry { + ContactLayer layer1; + ContactLayer layer2; + bool enabled; + }; + + sead::Buffer mPoints{}; + sead::ObjArray mLayerEntries; + ContactLayerType mLayerType = ContactLayerType::Invalid; + void* _80 = nullptr; +}; +KSYS_CHECK_SIZE_NX150(RigidContactPointsEx, 0x88); + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physSystemData.cpp b/src/KingSystem/Physics/System/physSystemData.cpp index 9280e5f5..825edf69 100644 --- a/src/KingSystem/Physics/System/physSystemData.cpp +++ b/src/KingSystem/Physics/System/physSystemData.cpp @@ -135,6 +135,8 @@ agl::utl::ResParameterArchive SystemData::loadLayerTableRes(const SystemData::La case ContactLayerType::Sensor: path = "Physics/System/SensorLayerTable.bphyslayer"; break; + case ContactLayerType::Invalid: + break; } const auto& resource = *matrix.mResHandle->load(path, &request); auto* direct_resource = sead::DynamicCast(&resource); @@ -170,6 +172,8 @@ agl::utl::ResParameterArchive SystemData::loadContactInfoTableRes(ContactLayerTy case ContactLayerType::Sensor: path = "Physics/System/SensorContactInfoTable.bphyscontact"; break; + case ContactLayerType::Invalid: + break; } /// @bug Possible bug? The request is never used. const auto& resource = *mContactInfoTableHandles[int(type)]->load(path, nullptr);