diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 049c5f10..4d91f223 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -74404,12 +74404,12 @@ 0x0000007100d68e54,sub_7100D68E54,188, 0x0000007100d68f10,nullsub_5545,4, 0x0000007100d68f14,sub_7100D68F14,412, -0x0000007100d690b0,aocManager::disposer::dtor,92, -0x0000007100d6910c,aocManager::disposer::dtorDelete,100, -0x0000007100d69170,aocManager::createInstance,128, -0x0000007100d691f0,aocManager::ctor,1560, +0x0000007100d690b0,aocManager::disposer::dtor,92,_ZN5uking3aoc7Manager18SingletonDisposer_D2Ev +0x0000007100d6910c,aocManager::disposer::dtorDelete,100,_ZN5uking3aoc7Manager18SingletonDisposer_D0Ev +0x0000007100d69170,aocManager::createInstance,128,_ZN5uking3aoc7Manager14createInstanceEPN4sead4HeapE +0x0000007100d691f0,aocManager::ctor,1560,_ZN5uking3aoc7ManagerC1Ev 0x0000007100d69808,aocManagerInitFlagsFuncPtr,4, -0x0000007100d6980c,aocManager::dtor,380, +0x0000007100d6980c,aocManager::dtor,380,_ZN5uking3aoc7ManagerD1Ev 0x0000007100d69988,aocManager::init,256, 0x0000007100d69a88,aocManager::loadVersionFile,204, 0x0000007100d69b54,sub_7100D69B54,180, @@ -74441,8 +74441,8 @@ 0x0000007100d6c8c4,getAocFlagString,428, 0x0000007100d6ca70,j__ZdlPv_858,4, 0x0000007100d6ca74,_ZN4sead19FixedSafeStringBaseIcLi107EEaSERKNS_14SafeStringBaseIcEE,240, -0x0000007100d6cb64,sub_7100D6CB64,48, -0x0000007100d6cb94,sub_7100D6CB94,92, +0x0000007100d6cb64,sub_7100D6CB64,48,_ZN4sead9Delegate1IN5uking3aoc7ManagerEPN4ksys3gdt7Manager11ReinitEventEE6invokeES8_ +0x0000007100d6cb94,sub_7100D6CB94,92,_ZNK4sead9Delegate1IN5uking3aoc7ManagerEPN4ksys3gdt7Manager11ReinitEventEE5cloneEPNS_4HeapE 0x0000007100d6cbf0,j__ZdlPv_859,4, 0x0000007100d6cbf4,_ZN4sead15FixedSafeStringILi153EEaSERKNS_14SafeStringBaseIcEE,240, 0x0000007100d6cce4,aoc2::Instance::dtor,92,_ZN5uking4aoc218SingletonDisposer_D2Ev @@ -76026,7 +76026,7 @@ 0x0000007100dd0970,nullsub_3856,4, 0x0000007100dd0974,GameDataMgr::calc1,240, 0x0000007100dd0a64,GameDataMgr::setCallback_stubbed,4,_ZN4ksys3gdt7Manager17addReinitCallbackERN4sead13DelegateEventIPNS1_11ReinitEventEE4SlotE -0x0000007100dd0a68,nullsub_3858,4, +0x0000007100dd0a68,nullsub_3858,4,_ZN4ksys3gdt7Manager20removeReinitCallbackERN4sead13DelegateEventIPNS1_11ReinitEventEE4SlotE 0x0000007100dd0a6c,GameDataMgr::setCurrentRupeeFlagName,12, 0x0000007100dd0a78,GameDataMgr::requestResetAllToInitial,16, 0x0000007100dd0a88,GameDataMgr::getAndSetShrineQuestAndKassFlags,3628, diff --git a/lib/sead b/lib/sead index 0295cef7..161a4d01 160000 --- a/lib/sead +++ b/lib/sead @@ -1 +1 @@ -Subproject commit 0295cef7a2f87eef8c7b75b6a21d8b3a9bd1572d +Subproject commit 161a4d014b9de8c41b44ba08b716b3b45e656de4 diff --git a/src/Game/DLC/aocManager.cpp b/src/Game/DLC/aocManager.cpp index 80d2711a..947bbba4 100644 --- a/src/Game/DLC/aocManager.cpp +++ b/src/Game/DLC/aocManager.cpp @@ -1 +1,46 @@ #include "Game/DLC/aocManager.h" +#include +#include "KingSystem/Utils/SafeDelete.h" + +#ifdef NNSDK +#include +#endif + +namespace uking::aoc { + +SEAD_SINGLETON_DISPOSER_IMPL(Manager) + +Manager::Manager() : mGdtReinitSlot{this, &Manager::onGdtReinit} { + resetFlags(); +} + +Manager::~Manager() { + if (auto* gdm = ksys::gdt::Manager::instance()) + gdm->removeReinitCallback(mGdtReinitSlot); + + mFileDevicePrefix.deregister(); + mFileDevicePrefix2.deregister(); + mVersionFileDevPrefix.deregister(); + + if (mFileDevice) { + sead::FileDeviceMgr::instance()->unmount("aoc"); + ksys::util::safeDelete(mFileDevice); + } + +#ifdef NNSDK + if (mAocFsCache) { + nn::fs::Unmount("aoc"); + ksys::util::safeDelete(mAocFsCache); + } +#endif +} + +void Manager::resetFlags() { + mFlagAocVerAtLastPlay = ksys::gdt::InvalidHandle; + mFlagLatestAocVerPlayed = ksys::gdt::InvalidHandle; + mFlagHasAocVer1 = ksys::gdt::InvalidHandle; + mFlagHasAocVer2 = ksys::gdt::InvalidHandle; + mFlagHasAocVer3 = ksys::gdt::InvalidHandle; +} + +} // namespace uking::aoc diff --git a/src/Game/DLC/aocManager.h b/src/Game/DLC/aocManager.h index db3c39f4..bb201944 100644 --- a/src/Game/DLC/aocManager.h +++ b/src/Game/DLC/aocManager.h @@ -1,9 +1,15 @@ #pragma once +#include #include +#include #include +#include +#include +#include "KingSystem/GameData/gdtManager.h" #include "KingSystem/Resource/resHandle.h" #include "KingSystem/Resource/resResourceMgrTask.h" +#include "KingSystem/Utils/Types.h" namespace sead { class FileDevice; @@ -27,13 +33,53 @@ public: bool hasAoc3() const { return mVersion >= 0x300; } private: - sead::FileDevice* mFileDevice{}; - ksys::res::FileDevicePrefix mFileDevicePrefix; + enum class Flag : u8 { - ksys::res::Handle mVersionResHandle; - sead::FixedSafeString<16> mVersionString; + }; + + struct DLCPosition { + sead::Vector3f translate = sead::Vector3f::zero; + sead::Vector3f rotate = sead::Vector3f::zero; + sead::Vector3f translate2 = sead::Vector3f::zero; + float scale = 0.0; + ksys::gdt::FlagHandle flag_handle = ksys::gdt::InvalidHandle; + }; + KSYS_CHECK_SIZE_NX150(DLCPosition, 0x2c); + + struct VersionFile { + ksys::res::Handle file_handle; + sead::FixedSafeString<16> string; + }; + KSYS_CHECK_SIZE_NX150(VersionFile, 0x78); + + void resetFlags(); + void onGdtReinit(ksys::gdt::Manager::ReinitEvent* event); + + sead::FileDevice* mFileDevice{}; + + ksys::res::FileDevicePrefix mVersionFileDevPrefix; + sead::StorageFor mVersionFile{sead::ZeroInitializeTag{}}; u32 mVersion{}; - // TODO: more fields + + ksys::res::Handle mAocMapMainFieldPack; + ksys::res::FileDevicePrefix mFileDevicePrefix; + ksys::res::Handle* mAocArchive{}; + ksys::res::FileDevicePrefix mFileDevicePrefix2; + + sead::SafeArray mDLCPositions; + + ksys::gdt::FlagHandle mFlagAocVerAtLastPlay{}; + ksys::gdt::FlagHandle mFlagLatestAocVerPlayed{}; + ksys::gdt::FlagHandle mFlagHasAocVer1{}; + ksys::gdt::FlagHandle mFlagHasAocVer2{}; + ksys::gdt::FlagHandle mFlagHasAocVer3{}; + ksys::gdt::Manager::ReinitSignal::Slot mGdtReinitSlot; + + sead::TypedBitFlag mFlags{}; +#ifdef NNSDK + u8* mAocFsCache{}; +#endif }; +KSYS_CHECK_SIZE_NX150(Manager, 0x598); } // namespace uking::aoc diff --git a/src/KingSystem/GameData/gdtManager.cpp b/src/KingSystem/GameData/gdtManager.cpp index 7c063df8..c3cd8c6d 100644 --- a/src/KingSystem/GameData/gdtManager.cpp +++ b/src/KingSystem/GameData/gdtManager.cpp @@ -137,6 +137,10 @@ void Manager::addReinitCallback(sead::DelegateEvent::Slot&) { // Stubbed in release builds. } +void Manager::removeReinitCallback(sead::DelegateEvent::Slot& slot) { + // Stubbed in release builds. +} + void Manager::IncreaseLogger::addRecord(s32 value, const sead::SafeString& name, s32 sub_idx, bool debug) { const u32 name_hash = sead::HashCRC32::calcStringHash(name); diff --git a/src/KingSystem/GameData/gdtManager.h b/src/KingSystem/GameData/gdtManager.h index a374e219..24f9841e 100644 --- a/src/KingSystem/GameData/gdtManager.h +++ b/src/KingSystem/GameData/gdtManager.h @@ -478,6 +478,7 @@ public: void init(sead::Heap* heap, sead::Framework* framework); void addReinitCallback(ReinitSignal::Slot& slot); + void removeReinitCallback(ReinitSignal::Slot& slot); private: enum class BitFlag { diff --git a/src/KingSystem/Resource/resResourceMgrTask.h b/src/KingSystem/Resource/resResourceMgrTask.h index d8c1d042..774ab55c 100644 --- a/src/KingSystem/Resource/resResourceMgrTask.h +++ b/src/KingSystem/Resource/resResourceMgrTask.h @@ -66,6 +66,8 @@ public: bool getField28() const { return _28; } void setField28(bool value) { _28 = value; } + void deregister(); + static constexpr size_t getListNodeOffset() { return offsetof(FileDevicePrefix, mListNode); } private: @@ -404,4 +406,9 @@ KSYS_CHECK_SIZE_NX150(sead::TaskBase, 0xd0); KSYS_CHECK_SIZE_NX150(sead::MethodTreeNode, 0x98); KSYS_CHECK_SIZE_NX150(ResourceMgrTask, 0x9c0eb8); +inline void FileDevicePrefix::deregister() { + if (mListNode.isLinked()) + ResourceMgrTask::instance()->deregisterFileDevicePrefix(*this); +} + } // namespace ksys::res