diff --git a/data/uking_functions.csv b/data/uking_functions.csv index bcf91c2d..9923d7f3 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -90956,60 +90956,60 @@ 0x000000710116a0c4,ActorParam::prepareLoad,404,_ZN4ksys3act13ActorParamMgr9loadParamEPKcPNS_3res6HandleEPvj 0x000000710116a258,ActorParam::loadActorFiles,492,_ZN4ksys3act13ActorParamMgr9loadFilesEPNS0_10ActorParamEPN4sead4HeapEPNS_3res6HandleEPvj 0x000000710116a444,ActorParam::loadActorPack,284,_ZN4ksys3act13ActorParamMgr20requestLoadActorPackEPNS_3res6HandleERKN4sead14SafeStringBaseIcEEj -0x000000710116a560,sub_710116A560,224, -0x000000710116a640,sub_710116A640,548, -0x000000710116a864,ActorParam::__auto0,144, -0x000000710116a8f4,ActorParam::x,828, -0x000000710116ac30,sub_710116AC30,1852, -0x000000710116b36c,sub_710116B36C,548, -0x000000710116b590,sub_710116B590,548, -0x000000710116b7b4,sub_710116B7B4,548, -0x000000710116b9d8,sub_710116B9D8,548, -0x000000710116bbfc,sub_710116BBFC,548, -0x000000710116be20,sub_710116BE20,548, -0x000000710116c044,sub_710116C044,548, -0x000000710116c268,sub_710116C268,548, -0x000000710116c48c,sub_710116C48C,548, -0x000000710116c6b0,sub_710116C6B0,548, -0x000000710116c8d4,sub_710116C8D4,548, -0x000000710116caf8,sub_710116CAF8,548, -0x000000710116cd1c,sub_710116CD1C,548, -0x000000710116cf40,sub_710116CF40,548, -0x000000710116d164,sub_710116D164,548, -0x000000710116d388,sub_710116D388,548, -0x000000710116d5ac,sub_710116D5AC,548, -0x000000710116d7d0,sub_710116D7D0,548, -0x000000710116d9f4,sub_710116D9F4,548, -0x000000710116dc18,sub_710116DC18,548, -0x000000710116de3c,ActorParam::__auto1,608, -0x000000710116e09c,sub_710116E09C,828, -0x000000710116e3d8,sub_710116E3D8,828, -0x000000710116e714,sub_710116E714,828, -0x000000710116ea50,sub_710116EA50,828, -0x000000710116ed8c,sub_710116ED8C,828, -0x000000710116f0c8,sub_710116F0C8,828, -0x000000710116f404,sub_710116F404,828, -0x000000710116f740,sub_710116F740,828, -0x000000710116fa7c,sub_710116FA7C,828, -0x000000710116fdb8,sub_710116FDB8,828, -0x00000071011700f4,sub_71011700F4,828, -0x0000007101170430,sub_7101170430,828, -0x000000710117076c,sub_710117076C,828, -0x0000007101170aa8,sub_7101170AA8,828, -0x0000007101170de4,sub_7101170DE4,828, -0x0000007101171120,sub_7101171120,828, -0x000000710117145c,sub_710117145C,828, -0x0000007101171798,sub_7101171798,828, -0x0000007101171ad4,sub_7101171AD4,828, -0x0000007101171e10,sub_7101171E10,828, -0x000000710117214c,sub_710117214C,732, -0x0000007101172428,sub_7101172428,548, -0x000000710117264c,sub_710117264C,548, -0x0000007101172870,sub_7101172870,548, -0x0000007101172a94,ActorParam::__auto2,1664, -0x0000007101173114,sub_7101173114,828, -0x0000007101173450,sub_7101173450,828, -0x000000710117378c,sub_710117378C,828, +0x000000710116a560,sub_710116A560,224,_ZN4ksys3act13ActorParamMgr14loadParamAsyncEPKcPNS_3res6HandleEPbPvj +0x000000710116a640,sub_710116A640,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res9ActorLinkEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116a864,ActorParam::__auto0,144,_ZN4ksys3act13ActorParamMgr22finishLoadingActorLinkEPNS0_10ActorParamEPv +0x000000710116a8f4,ActorParam::x,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res9ActorLinkEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116ac30,sub_710116AC30,1852,_ZN4ksys3act13ActorParamMgr19loadParamAsyncStep2EPNS0_10ActorParamEPNS_3res6HandleEPvj +0x000000710116b36c,sub_710116B36C,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res9ModelListEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116b590,sub_710116B590,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res4UMiiEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116b7b4,sub_710116B7B4,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res6ASListEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116b9d8,sub_710116B9D8,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res13AttClientListEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116bbfc,sub_710116BBFC,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res17RagdollConfigListEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116be20,sub_710116BE20,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res9AIProgramEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116c044,sub_710116C044,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res10GParamListEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116c268,sub_710116C268,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res7PhysicsEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116c48c,sub_710116C48C,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res8ChemicalEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116c6b0,sub_710116C6B0,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res11DamageParamEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116c8d4,sub_710116C8D4,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res18RagdollBlendWeightEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116caf8,sub_710116CAF8,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res9AwarenessEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116cd1c,sub_710116CD1C,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res4DropEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116cf40,sub_710116CF40,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res4ShopEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116d164,sub_710116D164,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res6RecipeEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116d388,sub_710116D388,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res3LodEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116d5ac,sub_710116D5AC,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res10AIScheduleEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116d7d0,sub_710116D7D0,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res11BoneControlEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116d9f4,sub_710116D9F4,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res13LifeConditionEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116dc18,sub_710116DC18,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res8AnimInfoEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710116de3c,ActorParam::__auto1,608,_ZN4ksys3act13ActorParamMgr18finishLoadingStep2EPNS0_10ActorParamEPv +0x000000710116e09c,sub_710116E09C,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res9ModelListEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116e3d8,sub_710116E3D8,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res4UMiiEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116e714,sub_710116E714,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res6ASListEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116ea50,sub_710116EA50,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res13AttClientListEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116ed8c,sub_710116ED8C,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res17RagdollConfigListEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116f0c8,sub_710116F0C8,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res9AIProgramEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116f404,sub_710116F404,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res10GParamListEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116f740,sub_710116F740,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res7PhysicsEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116fa7c,sub_710116FA7C,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res8ChemicalEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710116fdb8,sub_710116FDB8,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res11DamageParamEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x00000071011700f4,sub_71011700F4,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res18RagdollBlendWeightEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101170430,sub_7101170430,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res9AwarenessEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710117076c,sub_710117076C,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res4DropEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101170aa8,sub_7101170AA8,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res4ShopEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101170de4,sub_7101170DE4,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res6RecipeEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101171120,sub_7101171120,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res3LodEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710117145c,sub_710117145C,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res10AIScheduleEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101171798,sub_7101171798,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res11BoneControlEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101171ad4,sub_7101171AD4,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res13LifeConditionEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101171e10,sub_7101171E10,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res8AnimInfoEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710117214c,sub_710117214C,732,_ZN4ksys3act13ActorParamMgr17loadExtraResAsyncEPNS0_10ActorParamEPNS_3res6HandleEPvj +0x0000007101172428,sub_7101172428,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res2ASEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x000000710117264c,sub_710117264C,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res9AttClientEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x0000007101172870,sub_7101172870,548,_ZN4ksys3act13ActorParamMgr13loadFileAsyncINS_3res13RagdollConfigEEEbPNS0_10ActorParamENS5_12ResourceTypeERKN4sead14SafeStringBaseIcEESC_SC_PNS3_6HandleEPvj +0x0000007101172a94,ActorParam::__auto2,1664,_ZN4ksys3act13ActorParamMgr21finishLoadingExtraResEPNS0_10ActorParamEPv +0x0000007101173114,sub_7101173114,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res2ASEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x0000007101173450,sub_7101173450,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res9AttClientEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? +0x000000710117378c,sub_710117378C,828,_ZN4ksys3act13ActorParamMgr19handleAsyncFileLoadINS_3res13RagdollConfigEEEPT_PNS0_10ActorParamEPiNS7_12ResourceTypeEPv? 0x0000007101173ac8,sub_7101173AC8,1788,_ZN4ksys3act13ActorParamMgr14loadFilesStep2EPNS0_10ActorParamEPN4sead4HeapEPNS_3res6HandleEPvj 0x00000071011741c4,ActorParam::lockCsAndUnload,52,_ZN4ksys3act13ActorParamMgr11unloadParamEPNS0_10ActorParamE 0x00000071011741f8,act::checkResourceIsInPackAndSetPackRes2,420,_ZN4ksys3act13ActorParamMgr24prepareLoadFromActorPackEPN4sead22BufferedSafeStringBaseIcEEPNS_3res11LoadRequestEPvRKNS2_14SafeStringBaseIcEESD_SD_PNS6_6HandleEjSD_ diff --git a/src/KingSystem/ActorSystem/actActorParam.h b/src/KingSystem/ActorSystem/actActorParam.h index fe93b944..1186e244 100644 --- a/src/KingSystem/ActorSystem/actActorParam.h +++ b/src/KingSystem/ActorSystem/actActorParam.h @@ -75,6 +75,7 @@ public: AttClient = 26, RagdollConfig = 27, }; + static constexpr s32 NumResourceTypes = 28; static constexpr bool isValidType(ResourceType type) { return type <= ResourceType::AnimationInfo; diff --git a/src/KingSystem/ActorSystem/actActorParamMgr.cpp b/src/KingSystem/ActorSystem/actActorParamMgr.cpp index 17c6404d..e75eb43f 100644 --- a/src/KingSystem/ActorSystem/actActorParamMgr.cpp +++ b/src/KingSystem/ActorSystem/actActorParamMgr.cpp @@ -38,6 +38,9 @@ namespace ksys::act { SEAD_SINGLETON_DISPOSER_IMPL(ActorParamMgr) +using Type = ActorParam::ResourceType; +using User = res::ActorLink::User; + ActorParamMgr::ActorParamMgr() = default; ActorParamMgr::~ActorParamMgr() { @@ -84,13 +87,13 @@ ActorParam* ActorParamMgr::getParam(const char* actor_name, ActorParam** out_fre return nullptr; } -ActorParam* ActorParamMgr::loadParam(const char* actor_name, res::Handle* handle, void* x, +ActorParam* ActorParamMgr::loadParam(const char* actor_name, res::Handle* pack_handle, void* x, u32 load_req_c) { bool allocated_new = false; ActorParam* param = allocParam(actor_name, &allocated_new); if (allocated_new) { - loadFiles(param, mTmpActorParamMgrHeap, handle, x, load_req_c); + loadFiles(param, mTmpActorParamMgrHeap, pack_handle, x, load_req_c); param->setEventSignal(); } else { param->waitForEvent(); @@ -102,12 +105,9 @@ ActorParam* ActorParamMgr::loadParam(const char* actor_name, res::Handle* handle void ActorParamMgr::loadFiles(ActorParam* param, sead::Heap* heap, res::Handle* pack_handle, void* x, u32 load_req_c) { param->deleteResHandles(); - param->allocResHandles(heap, 0, 29); + param->allocResHandles(heap, 0, ActorParam::NumResourceTypes + 1); param->mActiveBufferIdx = 0; - using Type = ActorParam::ResourceType; - using User = res::ActorLink::User; - const auto* link = loadFile(param, Type::ActorLink, "Actor/ActorLink", "xml", param->getActorName().cstr(), pack_handle, x, load_req_c); @@ -150,14 +150,384 @@ bool ActorParamMgr::requestLoadActorPack(res::Handle* handle, const sead::SafeSt return handle->requestLoad(path, &req); } +ActorParam* ActorParamMgr::loadParamAsync(const char* actor_name, res::Handle* pack_handle, + bool* allocated_new, void* x, u32 load_req_c) { + auto* param = allocParam(actor_name, allocated_new); + if (!*allocated_new) + return param; + + param->deleteResHandles(); + param->allocResHandles(mTmpActorParamMgrHeap, 0, ActorParam::NumResourceTypes + 1); + param->mActiveBufferIdx = 0; + + loadFileAsync(param, Type::ActorLink, "Actor/ActorLink", "xml", + param->getActorName().cstr(), pack_handle, x, load_req_c); + return param; +} + +template +bool ActorParamMgr::loadFileAsync(ActorParam* param, ActorParam::ResourceType type, + const sead::SafeString& dir_name, + const sead::SafeString& extension, const sead::SafeString& name, + res::Handle* pack_handle, void* x, u32 load_req_c) { + auto* handle = param->allocHandle(); + + if (name != "Dummy" && !name.isEmpty()) { + sead::FixedSafeString<128> path; + res::LoadRequest req; + prepareLoadFromActorPack(&path, &req, x, dir_name, extension, name, pack_handle, load_req_c, + param->getActorName()); + return handle->requestLoad(path, &req); + } + + if (ActorParam::isValidType(type)) { + auto* res = sead::DynamicCast(mDummyResources[u32(type)].getResource()); + param->setResource(type, res); + } + + return true; +} + +// NON_MATCHING: different address calculation for static_cast(res)->getPath() +template +T* ActorParamMgr::handleAsyncFileLoad(ActorParam* param, s32* idx, ActorParam::ResourceType type, + void*) { + const s32 current_idx = *idx; + auto& handle = param->mHandles[param->mActiveBufferIdx][current_idx]; + *idx = current_idx + 1; + + if (ActorParam::isValidType(type)) { + if (auto* res = static_cast(param->getRes().mArray[u32(type)])) + return res; + } + + if (handle.isFlag8Set()) + return sead::DynamicCast(handle.getResource()); + + if (!handle.isReadyOrNeedsParse()) + return nullptr; + + handle.parseResource(nullptr); + + if (handle.checkLoadStatus() && type != Type::EventFlow) + param->_a = 1; + + auto* res = sead::DynamicCast(handle.getResource()); + if (res) { + auto* unit = handle.getUnit(); + if (unit) + static_cast(res)->getPath().copy(unit->getPath()); + } else { + res = sead::DynamicCast(mDummyResources[s32(type)].getResource()); + } + + if (ActorParam::isValidType(type) && res) + param->setResource(type, res); + + return res; +} + +bool ActorParamMgr::finishLoadingActorLink(ActorParam* param, void* x) { + s32 idx = 0; + if (!handleAsyncFileLoad(param, &idx, Type::ActorLink, x)) + return param->_a != 0; + + const auto* link = param->getRes().mActorLink; + if (!link) + return true; + + param->setProfileAndPriority(link->getUsers().getProfile(), link->getPriority().cstr()); + return true; +} + +void ActorParamMgr::loadParamAsyncStep2(ActorParam* param, res::Handle* pack_handle, void* x, + u32 load_req_c) { + const auto* link = param->getRes().mActorLink; + + loadFileAsync(param, Type::ModelList, "Actor/ModelList", "modellist", + link->getUsers().getModel(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::UMii, "Actor/UMii", "umii", link->getUsers().getUMii(), + pack_handle, x, load_req_c); + + loadFileAsync(param, Type::ASList, "Actor/ASList", "aslist", + link->getUsers().getAS(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::AttClientList, "Actor/AttClientList", "atcllist", + link->getUserName(User::Attention), pack_handle, x, + load_req_c); + + loadFileAsync(param, Type::RagdollConfigList, "Actor/RagdollConfigList", + "rgconfiglist", link->getUserName(User::RgConfigList), + pack_handle, x, load_req_c); + + loadFileAsync(param, Type::AIProgram, "Actor/AIProgram", "aiprog", + link->getUsers().getAIProgram(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::GParamList, "Actor/GeneralParamList", "gparamlist", + link->getUsers().getGParam(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::Physics, "Actor/Physics", "physics", + link->getUsers().getPhysics(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::Chemical, "Actor/Chemical", "chemical", + link->getUsers().getChemical(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::DamageParam, "Actor/DamageParam", "dmgparam", + link->getUsers().getDamageParam(), pack_handle, x, load_req_c); + + loadFileAsync( + param, Type::RagdollBlendWeight, "Actor/RagdollBlendWeight", "rgbw", + link->getUsers().getRgBlendWeight(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::Awareness, "Actor/Awareness", "awareness", + link->getUsers().getAwareness(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::DropTable, "Actor/DropTable", "drop", + link->getUsers().getDropTable(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::ShopData, "Actor/ShopData", "shop", + link->getUsers().getShopData(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::Recipe, "Actor/Recipe", "recipe", + link->getUsers().getRecipe(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::Lod, "Actor/LOD", "lod", link->getUsers().getLOD(), + pack_handle, x, load_req_c); + + loadFileAsync(param, Type::AISchedule, "Actor/AISchedule", "aischedule", + link->getUsers().getAISchedule(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::BoneControl, "Actor/BoneControl", "bonectrl", + link->getUsers().getBoneControl(), pack_handle, x, load_req_c); + + loadFileAsync(param, Type::LifeCondition, "Actor/LifeCondition", + "lifecondition", link->getUsers().getLifeCondition(), + pack_handle, x, load_req_c); + + loadFileAsync(param, Type::AnimationInfo, "Actor/AnimationInfo", "animinfo", + link->getUsers().getAnimationInfo(), pack_handle, x, load_req_c); +} + +bool ActorParamMgr::finishLoadingStep2(ActorParam* param, void* x) { + s32 idx = 1; + + if (!handleAsyncFileLoad(param, &idx, Type::ModelList, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::UMii, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::ASList, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::AttClientList, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::RagdollConfigList, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::AIProgram, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::GParamList, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::Physics, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::Chemical, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::DamageParam, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::RagdollBlendWeight, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::Awareness, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::DropTable, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::ShopData, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::Recipe, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::Lod, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::AISchedule, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::BoneControl, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::LifeCondition, x)) + return false; + + if (!handleAsyncFileLoad(param, &idx, Type::AnimationInfo, x)) + return false; + + return true; +} + +void ActorParamMgr::loadExtraResAsync(ActorParam* param, res::Handle* pack_handle, void* x, + u32 load_req_c) { + const auto* aslist = param->getRes().mASList; + const auto* atcllist = param->getRes().mAttClientList; + const auto* rgconfiglist = param->getRes().mRagdollConfigList; + + const auto num_as = aslist ? aslist->getASDefines().size() : 0; + const auto num_att = atcllist ? atcllist->getClients().size() : 0; + const auto num_rg = rgconfiglist ? rgconfiglist->getImpulseParams().size() : 0; + + param->allocResHandles(mTmpActorParamMgrHeap, 1, num_as + num_att + num_rg); + param->mActiveBufferIdx = 1; + + if (aslist) { + for (s32 i = 0; i < num_as; ++i) { + loadFileAsync(param, Type::AS, "Actor/AS", "as", + aslist->getASDefines()[i].getFileName(), pack_handle, x, + load_req_c); + } + } + + if (atcllist) { + for (s32 i = 0; i < num_att; ++i) { + loadFileAsync(param, Type::AttClient, "Actor/AttClient", "atcl", + atcllist->getClients()[i].getFileName(), pack_handle, x, + load_req_c); + } + } + + if (rgconfiglist) { + for (s32 i = 0; i < num_rg; ++i) { + loadFileAsync( + param, Type::RagdollConfig, "Actor/RagdollConfig", "rgconfig", + rgconfiglist->getImpulseParams()[i].getFileName(), pack_handle, x, load_req_c); + } + } +} + +bool ActorParamMgr::finishLoadingExtraRes(ActorParam* param, void* x) { + s32 idx = 0; + + auto* aslist = param->getRes().mASList; + if (aslist) { + for (s32 i = 0, n = aslist->getASDefines().size(); i < n; ++i) { + const sead::SafeString file_name = aslist->getASDefines()[i].getFileName(); + if (file_name == "Dummy" || file_name.isEmpty()) { + auto* as = sead::DynamicCast(mDummyResources[u32(Type::AS)].getResource()); + as->setIndex(u32(Type::AS)); + aslist->addAS_(i, as); + ++idx; + } else { + const res::Handle& handle = param->mHandles[1][idx]; + if (handle.isFlag8Set()) { + ++idx; + continue; + } + + auto* as = handleAsyncFileLoad(param, &idx, Type::AS, x); + if (!as) + return false; + + as->setIndex(u32(Type::AS)); + aslist->addAS_(i, as); + } + } + } + + auto* atcllist = param->getRes().mAttClientList; + if (atcllist) { + for (s32 i = 0, n = atcllist->getClients().size(); i < n; ++i) { + const sead::SafeString file_name = atcllist->getClients()[i].getFileName(); + if (file_name == "Dummy" || file_name.isEmpty()) { + auto* res = sead::DynamicCast( + mDummyResources[u32(Type::AttClient)].getResource()); + /// @bug This should be Type::AttClient. Copy paste error? + res->setIndex(u32(Type::AS)); + atcllist->addClient_(i, res); + ++idx; + } else { + const res::Handle& handle = param->mHandles[1][idx]; + if (handle.isFlag8Set()) { + ++idx; + continue; + } + + auto* res = handleAsyncFileLoad(param, &idx, Type::AttClient, x); + if (!res) + return false; + + res->setIndex(u32(Type::AttClient)); + atcllist->addClient_(i, res); + } + } + } + + auto* rgconfiglist = param->getRes().mRagdollConfigList; + if (rgconfiglist) { + for (s32 i = 0, n = rgconfiglist->getImpulseParams().size(); i < n; ++i) { + const sead::SafeString file_name = rgconfiglist->getImpulseParams()[i].getFileName(); + if (file_name == "Dummy" || file_name.isEmpty()) { + auto* res = sead::DynamicCast( + mDummyResources[u32(Type::RagdollConfig)].getResource()); + res->setIndex(u32(Type::RagdollConfig)); + rgconfiglist->addImpulseParamConfig_(i, res); + ++idx; + } else { + const res::Handle& handle = param->mHandles[1][idx]; + if (handle.isFlag8Set()) { + ++idx; + continue; + } + + auto* res = + handleAsyncFileLoad(param, &idx, Type::RagdollConfig, x); + if (!res) + return false; + + res->setIndex(u32(Type::RagdollConfig)); + rgconfiglist->addImpulseParamConfig_(i, res); + } + } + } + + param->_9 = 0; + param->onLoadFinished(this); + param->setEventSignal(); + return true; +} + +void ActorParamMgr::allocExtraResHandles(ActorParam* param, sead::Heap* heap) const { + s32 num_extra_handles = 0; + + auto* aslist = param->getRes().mASList; + auto* atcllist = param->getRes().mAttClientList; + auto* rgconfiglist = param->getRes().mRagdollConfigList; + + if (aslist) + num_extra_handles += aslist->getASDefines().size(); + + if (atcllist) + num_extra_handles += atcllist->getClients().size(); + + if (rgconfiglist) + num_extra_handles += rgconfiglist->getImpulseParams().size(); + + param->allocResHandles(heap, 1, num_extra_handles); +} + void ActorParamMgr::loadFilesStep2(ActorParam* param, sead::Heap* heap, res::Handle* pack_handle, void* x, u32 load_req_c) { const auto* link = param->getRes().mActorLink; param->mActiveBufferIdx = 0; - using Type = ActorParam::ResourceType; - using User = res::ActorLink::User; - loadFile(param, Type::AttClientList, "Actor/AttClientList", "atcllist", link->getUserName(User::Attention), pack_handle, x, load_req_c); @@ -165,29 +535,15 @@ void ActorParamMgr::loadFilesStep2(ActorParam* param, sead::Heap* heap, res::Han "rgconfiglist", link->getUserName(User::RgConfigList), pack_handle, x, load_req_c); - { - s32 num_extra_handles = 0; - auto* aslist = param->getRes().mASList; - auto* atcllist = param->getRes().mAttClientList; - auto* rgconfiglist = param->getRes().mRagdollConfigList; - if (aslist) - num_extra_handles += aslist->getBuffers().as_defines.size(); - if (atcllist) - num_extra_handles += atcllist->getClients().size(); - if (rgconfiglist) - num_extra_handles += rgconfiglist->getImpulseParams().size(); - - param->allocResHandles(heap, 1, num_extra_handles); - } - // Start loading the extra ActorParam files. + allocExtraResHandles(param, heap); param->mActiveBufferIdx = 1; if (auto* aslist = param->getRes().mASList) { - for (s32 i = 0; i < aslist->getBuffers().as_defines.size(); ++i) { + for (s32 i = 0; i < aslist->getASDefines().size(); ++i) { auto* as = loadFile(param, Type::AS, "Actor/AS", "as", - aslist->getBuffers().as_defines[i].file_name.ref().cstr(), - pack_handle, x, load_req_c); + aslist->getASDefines()[i].getFileName(), pack_handle, x, + load_req_c); if (as) { as->setIndex(u32(Type::AS)); aslist->addAS_(i, as); @@ -197,9 +553,9 @@ void ActorParamMgr::loadFilesStep2(ActorParam* param, sead::Heap* heap, res::Han if (auto* list = param->getRes().mAttClientList) { for (s32 i = 0; i < list->getClients().size(); ++i) { - auto* client = loadFile( - param, Type::AttClient, "Actor/AttClient", "atcl", - list->getClients()[i].file_name.ref().cstr(), pack_handle, x, load_req_c); + auto* client = loadFile(param, Type::AttClient, "Actor/AttClient", + "atcl", list->getClients()[i].getFileName(), + pack_handle, x, load_req_c); if (client) { client->setIndex(u32(Type::AttClient)); list->addClient_(i, client); @@ -211,7 +567,7 @@ void ActorParamMgr::loadFilesStep2(ActorParam* param, sead::Heap* heap, res::Han for (s32 i = 0; i < list->getImpulseParams().size(); ++i) { auto* config = loadFile( param, Type::RagdollConfig, "Actor/RagdollConfig", "rgconfig", - list->getImpulseParams()[i].file_name.ref().cstr(), pack_handle, x, load_req_c); + list->getImpulseParams()[i].getFileName(), pack_handle, x, load_req_c); if (config) { config->setIndex(u32(Type::RagdollConfig)); list->addImpulseParamConfig_(i, config); @@ -396,7 +752,7 @@ T* ActorParamMgr::loadFile(ActorParam* param, ActorParam::ResourceType type, con } else { path.format("%s/%s.b%s", dir_name_c, name_c, extension_c); - res = sead::DynamicCast(mResHandles[s32(type)].getResource()); + res = sead::DynamicCast(mDummyResources[s32(type)].getResource()); } if (res) { @@ -412,7 +768,7 @@ T* ActorParamMgr::loadFile(ActorParam* param, ActorParam::ResourceType type, con param->_a = 1; // Fall back to using the dummy resource. - res = sead::DynamicCast(mResHandles[s32(type)].getResource()); + res = sead::DynamicCast(mDummyResources[s32(type)].getResource()); sead::FixedSafeString<128> dummy_path; dummy_path.format("%s/Dummy.b%s", dir_name_c, extension_c); if (res) { @@ -425,7 +781,7 @@ T* ActorParamMgr::loadFile(ActorParam* param, ActorParam::ResourceType type, con res::GParamList* ActorParamMgr::getDummyGParamList() const { return static_cast( - mResHandles[u32(ActorParam::ResourceType::GParamList)].getResourceUnchecked()); + mDummyResources[u32(ActorParam::ResourceType::GParamList)].getResourceUnchecked()); } } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actActorParamMgr.h b/src/KingSystem/ActorSystem/actActorParamMgr.h index 67e60427..461ca4a6 100644 --- a/src/KingSystem/ActorSystem/actActorParamMgr.h +++ b/src/KingSystem/ActorSystem/actActorParamMgr.h @@ -42,9 +42,17 @@ public: ActorParam* allocParam(const char* actor_name, bool* allocated_new); ActorParam* getParam(const char* actor_name, ActorParam** out_free_param) const; - ActorParam* loadParam(const char* actor_name, res::Handle* handle, void* x, u32 load_req_c); + ActorParam* loadParam(const char* actor_name, res::Handle* pack_handle, void* x, + u32 load_req_c); void unloadParam(ActorParam* param); + ActorParam* loadParamAsync(const char* actor_name, res::Handle* pack_handle, + bool* allocated_new, void* x, u32 load_req_c); + bool finishLoadingActorLink(ActorParam* param, void* x); + void loadParamAsyncStep2(ActorParam* param, res::Handle* pack_handle, void* x, u32 load_req_c); + bool finishLoadingStep2(ActorParam* param, void* x); + void loadExtraResAsync(ActorParam* param, res::Handle* pack_handle, void* x, u32 load_req_c); + bool finishLoadingExtraRes(ActorParam* param, void* x); res::GParamList* getDummyGParamList() const; private: @@ -72,9 +80,20 @@ private: const char* extension_c, const char* name_c, res::Handle* pack_handle, void* x, u32 load_req_c); + template + bool loadFileAsync(ActorParam* param, ActorParam::ResourceType type, + const sead::SafeString& dir_name, const sead::SafeString& extension, + const sead::SafeString& name, res::Handle* pack_handle, void* x, + u32 load_req_c); + + template + T* handleAsyncFileLoad(ActorParam* param, s32* idx, ActorParam::ResourceType type, void* x); + void loadFilesStep2(ActorParam* param, sead::Heap* heap, res::Handle* pack_handle, void* x, u32 load_req_c); + void allocExtraResHandles(ActorParam* param, sead::Heap* heap) const; + static constexpr s32 NumParams = 0x400; sead::TypedBitFlag mFlags{}; @@ -84,7 +103,7 @@ private: void* _e8 = nullptr; sead::Heap* mDebugHeap = nullptr; sead::Heap* mTmpActorParamMgrHeap = nullptr; - sead::SafeArray mResHandles; + sead::SafeArray mDummyResources; mutable sead::CriticalSection mCS; }; KSYS_CHECK_SIZE_NX150(ActorParamMgr, 0xa00); diff --git a/src/KingSystem/Resource/resResourceASList.h b/src/KingSystem/Resource/resResourceASList.h index 3f3b5366..34795aa4 100644 --- a/src/KingSystem/Resource/resResourceASList.h +++ b/src/KingSystem/Resource/resResourceASList.h @@ -16,6 +16,8 @@ class ASList : public ParamIO, public Resource { SEAD_RTTI_OVERRIDE(ASList, Resource) public: struct ASDefine { + const char* getFileName() const { return file_name.ref().cstr(); } + agl::utl::Parameter name; agl::utl::Parameter file_name; agl::utl::ParameterObj obj; @@ -64,7 +66,9 @@ public: bool needsParse() const override { return true; } bool parse_(u8* data, size_t size, sead::Heap* heap) override; - const Buffers& getBuffers() const { return mBuffers; } + const sead::Buffer& getASDefines() const { return mBuffers.as_defines; } + const sead::Buffer& getCFDefines() const { return mBuffers.cf_defines; } + const sead::Buffer& getAddReses() const { return mBuffers.add_reses; } const Common& getCommon() const { return mCommon.ref(); } void addAS_(s32 index, AS* as); diff --git a/src/KingSystem/Resource/resResourceAttClientList.h b/src/KingSystem/Resource/resResourceAttClientList.h index 9cb018f4..aaf85966 100644 --- a/src/KingSystem/Resource/resResourceAttClientList.h +++ b/src/KingSystem/Resource/resResourceAttClientList.h @@ -24,6 +24,8 @@ public: KSYS_CHECK_SIZE_NX150(AttPos, 0x98); struct Client { + const char* getFileName() const { return file_name.ref().cstr(); } + agl::utl::Parameter name; agl::utl::Parameter file_name; agl::utl::Parameter is_valid; diff --git a/src/KingSystem/Resource/resResourceRagdollConfigList.h b/src/KingSystem/Resource/resResourceRagdollConfigList.h index c7787cb2..f5975628 100644 --- a/src/KingSystem/Resource/resResourceRagdollConfigList.h +++ b/src/KingSystem/Resource/resResourceRagdollConfigList.h @@ -16,6 +16,8 @@ class RagdollConfigList : public ParamIO, public Resource { SEAD_RTTI_OVERRIDE(RagdollConfigList, Resource) public: struct ImpulseParam { + const char* getFileName() const { return file_name.ref().cstr(); } + agl::utl::Parameter file_name; agl::utl::ParameterObj obj; RagdollConfig* config;