diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 37d1b4f2..9091acbf 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -94511,13 +94511,13 @@ 0x00000071012733d8,sub_71012733D8,40, 0x0000007101273400,sub_7101273400,72, 0x0000007101273448,sub_7101273448,52, -0x000000710127347c,DemoASLoader::ctor,348, -0x00000071012735d8,sub_71012735D8,140, -0x0000007101273664,sub_7101273664,136, -0x00000071012736ec,DemoASLoader::load,1100, -0x0000007101273b38,sub_7101273B38,68, -0x0000007101273b7c,sub_7101273B7C,168, -0x0000007101273c24,DemoASLoader::finishLoad,212, +0x000000710127347c,DemoASLoader::ctor,348,_ZN4ksys3res12DemoASLoaderC1ERKN4sead14SafeStringBaseIcEEPNS2_4HeapE +0x00000071012735d8,sub_71012735D8,140,_ZN4ksys3res12DemoASLoaderD1Ev +0x0000007101273664,sub_7101273664,136,_ZN4ksys3res12DemoASLoaderD0Ev +0x00000071012736ec,DemoASLoader::load,1100,_ZN4ksys3res12DemoASLoader4loadERKN2al9ByamlIterEbPNS0_6HandleE +0x0000007101273b38,sub_7101273B38,68,_ZNK4ksys3res12DemoASLoader7getNameEi +0x0000007101273b7c,sub_7101273B7C,168,_ZNK4ksys3res12DemoASLoader5getASEi +0x0000007101273c24,DemoASLoader::finishLoad,212,_ZN4ksys3res12DemoASLoader10finishLoadEv 0x0000007101273cf8,registerBdemoResourceFactory,288,_ZN4ksys3res4Demo15registerFactoryEPN4sead4HeapE 0x0000007101273e18,ResourceBdemo::doCreate,6656,_ZN4ksys3res4Demo9doCreate_EPhjPN4sead4HeapE 0x0000007101275818,sub_7101275818,292,_ZN4ksys3res4DemoD2Ev diff --git a/src/KingSystem/Resource/CMakeLists.txt b/src/KingSystem/Resource/CMakeLists.txt index d6023a99..51b24dc7 100644 --- a/src/KingSystem/Resource/CMakeLists.txt +++ b/src/KingSystem/Resource/CMakeLists.txt @@ -194,6 +194,8 @@ target_sources(uking PRIVATE Actor/resResourceUMii.cpp Actor/resResourceUMii.h + Event/resDemoASLoader.cpp + Event/resDemoASLoader.h Event/resResourceDemo.cpp Event/resResourceDemo.h Event/resResourceEventFlow.cpp diff --git a/src/KingSystem/Resource/Event/resDemoASLoader.cpp b/src/KingSystem/Resource/Event/resDemoASLoader.cpp new file mode 100644 index 00000000..a29bc570 --- /dev/null +++ b/src/KingSystem/Resource/Event/resDemoASLoader.cpp @@ -0,0 +1,96 @@ +#include "KingSystem/Resource/Event/resDemoASLoader.h" +#include "KingSystem/Resource/Actor/resResourceAS.h" +#include "KingSystem/Resource/resHandle.h" +#include "KingSystem/Resource/resLoadRequest.h" +#include "KingSystem/Utils/Byaml/Byaml.h" + +namespace ksys::res { + +DemoASLoader::DemoASLoader(const sead::SafeString& event_name, sead::Heap* heap) + : mHeap(heap), mEventName(event_name) {} + +DemoASLoader::~DemoASLoader() { + mHandles.freeBuffer(); + mNames.freeBuffer(); +} + +void DemoASLoader::load(const al::ByamlIter& iter, bool synchronous, Handle* pack_handle) { + al::ByamlIter as_list; + if (!iter.tryGetIterByKey(&as_list, "as")) + return; + + const int num_as = as_list.getSize(); + if (num_as <= 0) { + mNumAS = 0; + } else { + mHandles.allocBufferAssert(num_as, mHeap); + mNames.allocBufferAssert(num_as, mHeap); + mNumAS = 0; + + for (int i = 0; i < num_as; ++i) { + al::ByamlIter entry; + as_list.tryGetIterByIndex(&entry, i); + + const char* file_c; + entry.tryGetStringByKey(&file_c, "file"); + const sead::SafeString file = file_c; + + sead::FixedSafeString<256> path; + path.format("Actor/AS/%s/%s.bas", mEventName.cstr(), file.cstr()); + + mNames[mNumAS].copy(file); + + LoadRequest request; + request.mRequester = "DemoASLoader"; + request.mPackHandle = pack_handle; + request._22 = true; + Handle::Status status = Handle::Status::Unknown; + if (synchronous) + mHandles[mNumAS].load(path, &request, &status); + else + mHandles[mNumAS].requestLoad(path, &request, &status); + + ++mNumAS; + } + } + + mStatus = synchronous ? Status::Succeeded : Status::Loading; +} + +const char* DemoASLoader::getName(int idx) const { + return mNames[idx].cstr(); +} + +AS* DemoASLoader::getAS(int idx) const { + return sead::DynamicCast(mHandles[idx].getResource()); +} + +bool DemoASLoader::finishLoad() { + if (mStatus == Status::Loading) { + bool ready = true; + + for (int i = 0; i < mNumAS; ++i) { + auto& handle = mHandles[i]; + + if (handle.isReadyOrNeedsParse()) + handle.parseResource(nullptr); + + if (handle.isReady()) { + if (handle.checkLoadStatus()) { + mStatus = Status::Failed; + ready = false; + break; + } + } else { + ready = false; + } + } + + if (ready) + mStatus = Status::Succeeded; + } + + return mStatus != Status::Loading; +} + +} // namespace ksys::res diff --git a/src/KingSystem/Resource/Event/resDemoASLoader.h b/src/KingSystem/Resource/Event/resDemoASLoader.h new file mode 100644 index 00000000..3c203bd9 --- /dev/null +++ b/src/KingSystem/Resource/Event/resDemoASLoader.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include "KingSystem/Utils/Types.h" + +namespace al { +class ByamlIter; +} + +namespace sead { +class Heap; +} + +namespace ksys::res { + +class AS; +class Handle; + +class DemoASLoader { +public: + DemoASLoader(const sead::SafeString& event_name, sead::Heap* heap); + virtual ~DemoASLoader(); + + void load(const al::ByamlIter& iter, bool synchronous, Handle* pack_handle); + + const char* getName(int idx) const; + AS* getAS(int idx) const; + + /// @return whether the load has finished (succeeded or failed). + bool finishLoad(); + +private: + enum class Status { + Uninitialized = 0, + Loading = 1, + Succeeded = 2, + Failed = 3, + }; + + sead::Heap* mHeap = nullptr; + sead::Buffer mHandles; + sead::Buffer> mNames; + sead::FixedSafeString<64> mEventName; + int mNumAS = 0; + Status mStatus = Status::Uninitialized; +}; +KSYS_CHECK_SIZE_NX150(DemoASLoader, 0x90); + +} // namespace ksys::res diff --git a/src/KingSystem/Resource/resHandle.h b/src/KingSystem/Resource/resHandle.h index 02fc311c..aacad690 100644 --- a/src/KingSystem/Resource/resHandle.h +++ b/src/KingSystem/Resource/resHandle.h @@ -44,6 +44,8 @@ public: FileDeviceError = 13, /// "Canceled" (16) Cancelled = 14, + /// Unknown + Unknown = 15, }; Handle();