From 3d371999a4a7223637aaf6bd4428a046574609d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Fri, 4 Sep 2020 22:01:52 +0200 Subject: [PATCH] ksys/res: Implement EntryFactory (base class and template) Also adds a heap-related function that's used by EntryFactory (and many other functions) --- CMakeLists.txt | 4 ++ data/uking_functions.csv | 31 ++++++------ lib/sead | 2 +- src/KingSystem/Resource/resEntryFactory.cpp | 20 ++++++++ src/KingSystem/Resource/resEntryFactory.h | 53 +++++++++++++++++++++ src/KingSystem/Resource/resResource.h | 2 + src/KingSystem/Utils/HeapUtil.cpp | 17 +++++++ src/KingSystem/Utils/HeapUtil.h | 14 ++++++ 8 files changed, 127 insertions(+), 16 deletions(-) create mode 100644 src/KingSystem/Resource/resEntryFactory.cpp create mode 100644 src/KingSystem/Resource/resEntryFactory.h create mode 100644 src/KingSystem/Utils/HeapUtil.cpp create mode 100644 src/KingSystem/Utils/HeapUtil.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bb7d6ea..3ceaf5d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,8 @@ add_executable(uking src/KingSystem/MessageSystem/mesTransceiver.h + src/KingSystem/Resource/resEntryFactory.cpp + src/KingSystem/Resource/resEntryFactory.h src/KingSystem/Resource/resResource.cpp src/KingSystem/Resource/resResource.h @@ -61,6 +63,8 @@ add_executable(uking src/KingSystem/Utils/ByamlLocal.h src/KingSystem/Utils/ByamlUtil.cpp src/KingSystem/Utils/Debug.h + src/KingSystem/Utils/HeapUtil.cpp + src/KingSystem/Utils/HeapUtil.h src/KingSystem/Utils/StrTreeMap.h src/KingSystem/Utils/Types.h ) diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 5912bbad..507d58af 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -51854,13 +51854,14 @@ 0x000000710089f510,EntryFactoryBactcapt::newResource_,156, 0x000000710089f5ac,sub_710089F5AC,8, 0x000000710089f5b4,sub_710089F5B4,8, -0x000000710089f5bc,EntryFactoryBase::dtor,20, -0x000000710089f5d0,EntryFactoryBase::dtorDelete,52, -0x000000710089f604,sub_710089F604,8, -0x000000710089f60c,sub_710089F60C,92, -0x000000710089f668,EntryFactoryBase::getResourceSize,8, -0x000000710089f670,EntryFactoryBase::getLoadDataAlignment,8, -0x000000710089f798,sub_710089F798,140, +0x000000710089f5bc,EntryFactoryBase::dtor,20,_ZN4ksys3res16EntryFactoryBaseD2Ev +0x000000710089f5d0,EntryFactoryBase::dtorDelete,52,_ZN4ksys3res16EntryFactoryBaseD0Ev +0x000000710089f604,sub_710089F604,8,_ZNK4ksys3res16EntryFactoryBase27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x000000710089f60c,sub_710089F60C,92,_ZNK4ksys3res16EntryFactoryBase18getRuntimeTypeInfoEv +0x000000710089f668,EntryFactoryBase::getResourceSize,8,_ZNK4ksys3res16EntryFactoryBase15getResourceSizeEv +0x000000710089f670,EntryFactoryBase::getLoadDataAlignment,8,_ZNK4ksys3res16EntryFactoryBase20getLoadDataAlignmentEv +0x000000710089f678,EntryFactoryBase::rtti1_impl,0x120,_ZN4ksys3res16EntryFactoryBase33checkDerivedRuntimeTypeInfoStaticEPKN4sead15RuntimeTypeInfo9InterfaceE +0x000000710089f798,sub_710089F798,140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys3res16EntryFactoryBaseEE9isDerivedEPKNS0_9InterfaceE 0x000000710089f824,_ZNK3agl3utl13IParameterObj9preWrite_Ev,8,_ZNK3agl3utl13IParameterObj9preWrite_Ev 0x000000710089f82c,_ZNK3agl3utl13IParameterObj10postWrite_Ev,4,_ZNK3agl3utl13IParameterObj10postWrite_Ev 0x000000710089f830,_ZN3agl3utl13IParameterObj8preRead_Ev,8,_ZN3agl3utl13IParameterObj8preRead_Ev @@ -79862,13 +79863,13 @@ 0x0000007100f41e1c,EntryFactoryBFRES::newResource_,152, 0x0000007100f41eb4,EntryFactoryBFRES::getResourceSize,8, 0x0000007100f41ebc,EntryFactoryBFRES::getLoadDataAlignment,8, -0x0000007100f41ec4,EntryFactoryResBase::dtor,68, -0x0000007100f41f08,EntryFactoryResBase::dtorDelete,76, -0x0000007100f41f54,EntryFactoryResBase::rtti1,132, -0x0000007100f41fd8,EntryFactoryResBase::rtti2,92, -0x0000007100f42034,EntryFactoryResBase::newResource_,152, -0x0000007100f420cc,EntryFactoryResBase::getResourceSize,8, -0x0000007100f420d4,EntryFactoryResBase::getLoadDataAlignment,8, +0x0000007100f41ec4,EntryFactoryResBase::dtor,68,_ZN4ksys3res12EntryFactoryINS0_8ResourceEED2Ev +0x0000007100f41f08,EntryFactoryResBase::dtorDelete,76,_ZN4ksys3res12EntryFactoryINS0_8ResourceEED0Ev +0x0000007100f41f54,EntryFactoryResBase::rtti1,132,_ZNK4ksys3res12EntryFactoryINS0_8ResourceEE27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x0000007100f41fd8,EntryFactoryResBase::rtti2,92,_ZNK4ksys3res12EntryFactoryINS0_8ResourceEE18getRuntimeTypeInfoEv +0x0000007100f42034,EntryFactoryResBase::newResource_,152,_ZN4ksys3res12EntryFactoryINS0_8ResourceEE12newResource_EPN4sead4HeapEi +0x0000007100f420cc,EntryFactoryResBase::getResourceSize,8,_ZNK4ksys3res12EntryFactoryINS0_8ResourceEE15getResourceSizeEv +0x0000007100f420d4,EntryFactoryResBase::getLoadDataAlignment,8,_ZNK4ksys3res12EntryFactoryINS0_8ResourceEE20getLoadDataAlignmentEv 0x0000007100f420dc,sub_7100F420DC,68, 0x0000007100f42120,sub_7100F42120,76, 0x0000007100f4216c,sub_7100F4216C,132, @@ -82778,7 +82779,7 @@ 0x0000007100fe8a14,sub_7100FE8A14,92, 0x0000007100fe8a70,j__ZdlPv_1027,4, 0x0000007100fe8a74,sub_7100FE8A74,24, -0x0000007100fe8a8c,sinitCreateEntryFactoryResBase,200, +0x0000007100fe8a8c,sinitCreateEntryFactoryResBase,200,_GLOBAL__sub_I_resEntryFactory.cpp 0x0000007100fe8b54,sub_7100FE8B54,60, 0x0000007100fe8b90,sub_7100FE8B90,400, 0x0000007100fe8d20,sub_7100FE8D20,20, diff --git a/lib/sead b/lib/sead index e2e9cffa..d823497e 160000 --- a/lib/sead +++ b/lib/sead @@ -1 +1 @@ -Subproject commit e2e9cffaab4f82b1840e9f1c352670bae8168aea +Subproject commit d823497e44528cf8d9127b1e38ddc38e9616d789 diff --git a/src/KingSystem/Resource/resEntryFactory.cpp b/src/KingSystem/Resource/resEntryFactory.cpp new file mode 100644 index 00000000..ac3a1a7e --- /dev/null +++ b/src/KingSystem/Resource/resEntryFactory.cpp @@ -0,0 +1,20 @@ +#include "KingSystem/Resource/resEntryFactory.h" + +namespace ksys::res { + +static EntryFactory sDefaultEntryFactory; + +u32 EntryFactoryBase::getResourceSize() const { + KSYS_CHECK_SIZE_NX150(sead::DirectResource, 0x20); + return sizeof(sead::DirectResource); +} + +u32 EntryFactoryBase::getLoadDataAlignment() const { + return sizeof(void*); +} + +EntryFactory& getDefaultResourceFactory() { + return sDefaultEntryFactory; +} + +} // namespace ksys::res diff --git a/src/KingSystem/Resource/resEntryFactory.h b/src/KingSystem/Resource/resEntryFactory.h new file mode 100644 index 00000000..3b065d77 --- /dev/null +++ b/src/KingSystem/Resource/resEntryFactory.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include "KingSystem/Resource/resResource.h" +#include "KingSystem/Utils/HeapUtil.h" +#include "KingSystem/Utils/Types.h" + +namespace ksys::res { + +class EntryFactoryBase : public sead::DirectResourceFactoryBase { + SEAD_RTTI_OVERRIDE(EntryFactoryBase, sead::DirectResourceFactoryBase) +public: + explicit EntryFactoryBase(f32 size_multiplier = 1.0, u32 size_constant = 0) + : mSizeMultiplier(size_multiplier), mSizeConstant(size_constant) {} + ~EntryFactoryBase() override { ; } + + virtual u32 getResourceSize() const; + virtual u32 getLoadDataAlignment() const; + + f32 getSizeMultiplier() const { return mSizeMultiplier; } + u32 getSizeConstant() const { return mSizeConstant; } + +protected: + f32 mSizeMultiplier; + u32 mSizeConstant; +}; +KSYS_CHECK_SIZE_NX150(EntryFactoryBase, 0x80); + +template +class EntryFactory : public EntryFactoryBase { + SEAD_RTTI_OVERRIDE(EntryFactory, EntryFactoryBase) +public: + using EntryFactoryBase::EntryFactoryBase; + + u32 getResourceSize() const override { return sizeof(T); } + u32 getLoadDataAlignment() const override { return T::cLoadDataAlignment; } + + T* newResource_(sead::Heap* heap_, s32 alignment) override { + sead::Heap* heap = util::getHeapOrCurrentHeap(heap_); + sead::ScopedCurrentHeapSetter setter{heap}; + return new (heap, alignment, std::nothrow_t{}) T{}; + } + +protected: + // XXX: What is this used for? + T mResource; +}; + +EntryFactory& getDefaultResourceFactory(); + +} // namespace ksys::res diff --git a/src/KingSystem/Resource/resResource.h b/src/KingSystem/Resource/resResource.h index a678166b..2bd96642 100644 --- a/src/KingSystem/Resource/resResource.h +++ b/src/KingSystem/Resource/resResource.h @@ -34,6 +34,8 @@ public: bool finishParsing(); bool m7(); + static constexpr size_t cLoadDataAlignment = 4; + protected: virtual void onDestroy_() {} virtual bool parse_(u8* data, size_t size, sead::Heap* heap); diff --git a/src/KingSystem/Utils/HeapUtil.cpp b/src/KingSystem/Utils/HeapUtil.cpp new file mode 100644 index 00000000..fb06c48f --- /dev/null +++ b/src/KingSystem/Utils/HeapUtil.cpp @@ -0,0 +1,17 @@ +#include "KingSystem/Utils/HeapUtil.h" +#include +#include + +namespace ksys::util { + +sead::Heap* getHeapOrCurrentHeap(sead::Heap* heap) { + if (heap) + return heap; + + if (!sead::ThreadMgr::instance()) + return nullptr; + + return sead::HeapMgr::instance()->getCurrentHeap(); +} + +} // namespace ksys::util diff --git a/src/KingSystem/Utils/HeapUtil.h b/src/KingSystem/Utils/HeapUtil.h new file mode 100644 index 00000000..0e6be692 --- /dev/null +++ b/src/KingSystem/Utils/HeapUtil.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace sead { +class Heap; +} + +namespace ksys::util { + +/// Returns the specified heap if it is not null. Otherwise, this returns the current heap. +sead::Heap* getHeapOrCurrentHeap(sead::Heap* heap); + +} // namespace ksys::util