mirror of https://github.com/zeldaret/botw.git
Implement most of aocManager
And fix FileDevicePrefix's userdata param type
This commit is contained in:
parent
96157129f8
commit
c3528b3911
|
@ -437,7 +437,7 @@
|
|||
0x000000710000ded8,sub_710000DED8,1412,
|
||||
0x000000710000e45c,Dragon::m78,164,
|
||||
0x000000710000e500,sub_710000E500,756,
|
||||
0x000000710000e7f4,_ZN4sead15FixedSafeStringILi128EEaSERKNS_14SafeStringBaseIcEE,240,
|
||||
0x000000710000e7f4,_ZN4sead15FixedSafeStringILi128EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead15FixedSafeStringILi16EEaSERKNS_14SafeStringBaseIcEE
|
||||
0x000000710000e8e4,sub_710000E8E4,420,
|
||||
0x000000710000ea88,sub_710000EA88,456,
|
||||
0x000000710000ec50,sub_710000EC50,84,
|
||||
|
@ -501,7 +501,7 @@
|
|||
0x0000007100012538,sub_7100012538,68,
|
||||
0x000000710001257c,nullsub_45,4,
|
||||
0x0000007100012580,_ZNK4sead15RuntimeTypeInfo6DeriveINS_13TaskParameterEE9isDerivedEPKNS0_9InterfaceE,140,
|
||||
0x000000710001260c,j__ZdlPv_6,4,
|
||||
0x000000710001260c,j__ZdlPv_6,4,_ZN4sead15FixedSafeStringILi16EED0Ev
|
||||
0x0000007100012610,_ZNK4sead14SafeStringBaseIcE9findIndexERKS1_,468,_ZNK4sead14SafeStringBaseIcE9findIndexERKS1_
|
||||
0x00000071000127e4,_ZN4sead18Matrix34CalcCommonIfE7inverseERNS_9BaseMtx34IfEERKS3_,336,
|
||||
0x0000007100012934,j__ZdlPv_7,4,
|
||||
|
@ -53187,8 +53187,8 @@
|
|||
0x00000071008af674,sub_71008AF674,204,
|
||||
0x00000071008af740,sub_71008AF740,92,
|
||||
0x00000071008af79c,nullsub_2626,4,
|
||||
0x00000071008af7a0,j__ZdlPv_394,4,
|
||||
0x00000071008af7a4,_ZN4sead19FixedSafeStringBaseIcLi93EEaSERKNS_14SafeStringBaseIcEE,240,
|
||||
0x00000071008af7a0,j__ZdlPv_394,4,_ZN4sead15FixedSafeStringILi73EED0Ev
|
||||
0x00000071008af7a4,_ZN4sead15FixedSafeStringILi73EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead15FixedSafeStringILi73EEaSERKNS_14SafeStringBaseIcEE
|
||||
0x00000071008af894,sub_71008AF894,140,
|
||||
0x00000071008af920,evt::S7EventFlow::ctor,536,
|
||||
0x00000071008afb38,evt::S7EventFlow::m4,244,
|
||||
|
@ -74403,48 +74403,48 @@
|
|||
0x0000007100d68d94,printLifeRecoverInfo,192,
|
||||
0x0000007100d68e54,sub_7100D68E54,188,
|
||||
0x0000007100d68f10,nullsub_5545,4,
|
||||
0x0000007100d68f14,sub_7100D68F14,412,
|
||||
0x0000007100d68f14,sub_7100D68F14,412,_GLOBAL__sub_I_aocManager.cpp
|
||||
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,
|
||||
0x0000007100d69808,aocManagerInitFlagsFuncPtr,4,_ZN5uking3aoc7Manager11onGdtReinitEPN4ksys3gdt7Manager11ReinitEventE
|
||||
0x0000007100d6980c,aocManager::dtor,380,_ZN5uking3aoc7ManagerD1Ev
|
||||
0x0000007100d69988,aocManager::init,256,
|
||||
0x0000007100d69a88,aocManager::loadVersionFile,204,
|
||||
0x0000007100d69b54,sub_7100D69B54,180,
|
||||
0x0000007100d69c08,aocManager::insertPrefixMap,152,
|
||||
0x0000007100d69ca0,aocManager::unloadAocMainFieldPack,68,
|
||||
0x0000007100d69ce4,aocManager::getFileDevForAocMap,324,
|
||||
0x0000007100d69e28,aocManager::archiveHasFile,292,
|
||||
0x0000007100d69f4c,isAoCMap,1064,
|
||||
0x0000007100d6a374,aocManager::getFileDevAndPackResForMubin,376,
|
||||
0x0000007100d6a4ec,aocManager::getFileDevForPhysicsStaticCompound,168,
|
||||
0x0000007100d6a594,aocManager::getFileDevForAocTeraMesh,104,
|
||||
0x0000007100d6a5fc,aocManager::getFileDevForAocNavMesh,168,
|
||||
0x0000007100d6a6a4,aocManager::getFileDevIfTerrain,104,
|
||||
0x0000007100d6a70c,aocManager::getFileDevIfGameAocField,104,
|
||||
0x0000007100d6a774,aocManager::getAocDevIfPathContainsUIStaffRollDLC,104,
|
||||
0x0000007100d6a7dc,aoc::isAocDungeon,516,
|
||||
0x0000007100d6a9e0,aoc::isAocMap,748,
|
||||
0x0000007100d6accc,stringIsAocField,140,
|
||||
0x0000007100d6ad58,aocManager::getAocFileDeviceIfIsNotNormalDungeon,448,
|
||||
0x0000007100d6af18,aocManager::addPrefixForArchiveFiles,172,
|
||||
0x0000007100d6afc4,aocManager::movieDemoPathStuff,660,
|
||||
0x0000007100d69988,aocManager::init,256,_ZN5uking3aoc7Manager4initEPN4sead4HeapE
|
||||
0x0000007100d69a88,aocManager::loadVersionFile,204,_ZN5uking3aoc7Manager15loadVersionFileEv
|
||||
0x0000007100d69b54,sub_7100D69B54,180,_ZN5uking3aoc7Manager20loadAocMainFieldPackEPN4ksys12OverlayArenaE
|
||||
0x0000007100d69c08,aocManager::insertPrefixMap,152,_ZN5uking3aoc7Manager24registerAocMainFieldPackEv
|
||||
0x0000007100d69ca0,aocManager::unloadAocMainFieldPack,68,_ZN5uking3aoc7Manager22unloadAocMainFieldPackEv
|
||||
0x0000007100d69ce4,aocManager::getFileDevForAocMap,324,_ZNK5uking3aoc7Manager23getFileDeviceForMapFileERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d69e28,aocManager::archiveHasFile,292,_ZNK5uking3aoc7Manager14aocPackHasFileERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d69f4c,isAoCMap,1064,_ZNK5uking3aoc7Manager9isAocFileERKN4sead14SafeStringBaseIcEES6_S6_S6_S6_
|
||||
0x0000007100d6a374,aocManager::getFileDevAndPackResForMubin,376,_ZN5uking3aoc7Manager19getFileDeviceForMapEPPN4sead10FileDeviceEPPN4ksys3res6HandleERKNS2_14SafeStringBaseIcEE
|
||||
0x0000007100d6a4ec,aocManager::getFileDevForPhysicsStaticCompound,168,_ZNK5uking3aoc7Manager30getFileDeviceForStaticCompoundERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6a594,aocManager::getFileDevForAocTeraMesh,104,_ZNK5uking3aoc7Manager24getFileDeviceForTeraMeshERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6a5fc,aocManager::getFileDevForAocNavMesh,168,_ZNK5uking3aoc7Manager23getFileDeviceForNavMeshERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6a6a4,aocManager::getFileDevIfTerrain,104,_ZNK5uking3aoc7Manager23getFileDeviceForTerrainERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6a70c,aocManager::getFileDevIfGameAocField,104,_ZNK5uking3aoc7Manager20getFileDeviceForGameERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6a774,aocManager::getAocDevIfPathContainsUIStaffRollDLC,104,_ZNK5uking3aoc7Manager18getFileDeviceForUIERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6a7dc,aoc::isAocDungeon,516,_ZN5uking3aoc7Manager12isAocDungeonERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6a9e0,aoc::isAocMap,748,_ZN5uking3aoc7Manager8isAocMapERKN4sead14SafeStringBaseIcEES6_
|
||||
0x0000007100d6accc,stringIsAocField,140,_ZN5uking3aoc7Manager10isAocFieldERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6ad58,aocManager::getAocFileDeviceIfIsNotNormalDungeon,448,_ZNK5uking3aoc7Manager27getFileDeviceForDungeonPackERKN4sead14SafeStringBaseIcEE
|
||||
0x0000007100d6af18,aocManager::addPrefixForArchiveFiles,172,_ZN5uking3aoc7Manager15registerAocPackEPN4ksys3res6HandleE
|
||||
0x0000007100d6afc4,aocManager::movieDemoPathStuff,660,_ZNK5uking3aoc7Manager15changeMoviePathERN4sead22BufferedSafeStringBaseIcEE
|
||||
0x0000007100d6b258,aocManager::parseMainFieldStaticForDlc,2488,
|
||||
0x0000007100d6bc10,aocManager::x,1224,
|
||||
0x0000007100d6c0d8,aocManager::parseVersionString,916,
|
||||
0x0000007100d6c46c,aocManager::Version::ready,384,
|
||||
0x0000007100d6c5ec,aocManager::initApp,48,
|
||||
0x0000007100d6c61c,aocManager::initFlags,460,
|
||||
0x0000007100d6c0d8,aocManager::parseVersionString,916,_ZN5uking3aoc7Manager12parseVersionEv?
|
||||
0x0000007100d6c46c,aocManager::Version::ready,384,_ZN5uking3aoc7Manager11VersionFile11readVersionEv
|
||||
0x0000007100d6c5ec,aocManager::initApp,48,_ZN5uking3aoc7Manager12initGameDataEv
|
||||
0x0000007100d6c61c,aocManager::initFlags,460,_ZN5uking3aoc7Manager11reinitFlagsEv
|
||||
0x0000007100d6c7e8,aocManager::setLatestPlayedGameDataFlags,220,
|
||||
0x0000007100d6c8c4,getAocFlagString,428,
|
||||
0x0000007100d6ca70,j__ZdlPv_858,4,
|
||||
0x0000007100d6ca74,_ZN4sead19FixedSafeStringBaseIcLi107EEaSERKNS_14SafeStringBaseIcEE,240,
|
||||
0x0000007100d6c8c4,getAocFlagString,428,_ZN5uking3aoc7Manager12GameDataFlag5text_Ei
|
||||
0x0000007100d6ca70,j__ZdlPv_858,4,_ZN4sead19FixedSafeStringBaseIcLi73EED0Ev
|
||||
0x0000007100d6ca74,_ZN4sead19FixedSafeStringBaseIcLi73EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead19FixedSafeStringBaseIcLi73EEaSERKNS_14SafeStringBaseIcEE
|
||||
0x0000007100d6cb64,sub_7100D6CB64,48,_ZN4sead9Delegate1IN5uking3aoc7ManagerEPN4ksys3gdt7Manager11ReinitEventEE6invokeES8_
|
||||
0x0000007100d6cb94,sub_7100D6CB94,92,_ZNK4sead9Delegate1IN5uking3aoc7ManagerEPN4ksys3gdt7Manager11ReinitEventEE5cloneEPNS_4HeapE
|
||||
0x0000007100d6cbf0,j__ZdlPv_859,4,
|
||||
0x0000007100d6cbf4,_ZN4sead15FixedSafeStringILi153EEaSERKNS_14SafeStringBaseIcEE,240,
|
||||
0x0000007100d6cbf0,j__ZdlPv_859,4,_ZN4sead15FixedSafeStringILi4EED0Ev
|
||||
0x0000007100d6cbf4,_ZN4sead15FixedSafeStringILi153EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead15FixedSafeStringILi4EEaSERKNS_14SafeStringBaseIcEE
|
||||
0x0000007100d6cce4,aoc2::Instance::dtor,92,_ZN5uking4aoc218SingletonDisposer_D2Ev
|
||||
0x0000007100d6cd40,aoc2::Instance::dtorDelete,100,_ZN5uking4aoc218SingletonDisposer_D0Ev
|
||||
0x0000007100d6cda4,aoc2::createInstance,136,_ZN5uking4aoc214createInstanceEPN4sead4HeapE
|
||||
|
@ -93189,7 +93189,7 @@
|
|||
0x000000710120a9ec,return_0_0,8,_ZNK4ksys3res15ResourceMgrTask10isHostPathERKN4sead14SafeStringBaseIcEE
|
||||
0x000000710120a9f4,res::ResourceMgrTask::dropSFromExtensionForBfevflBcamanimAndBarslist,756,_ZNK4ksys3res15ResourceMgrTask26dropSFromExtensionIfNeededERKN4sead14SafeStringBaseIcEERNS2_22BufferedSafeStringBaseIcEEiS6_
|
||||
0x000000710120ace8,res::ResourceMgrTask::unloadSeadResource,84,_ZN4ksys3res15ResourceMgrTask18unloadSeadResourceEPN4sead8ResourceE
|
||||
0x000000710120ad3c,res::ResourceMgrTask::getResourceSize,328,_ZNK4ksys3res15ResourceMgrTask15getResourceSizeERKN4sead14SafeStringBaseIcEEPNS2_10FileDeviceE
|
||||
0x000000710120ad3c,res::ResourceMgrTask::getResourceSize,328,_ZNK4ksys3res15ResourceMgrTask15getResourceSizeERKN4sead14SafeStringBaseIcEEPv
|
||||
0x000000710120ae84,res::ResourceMgrTask::insertIntoFileDeviceToPrefixMap,116,_ZN4ksys3res15ResourceMgrTask24registerFileDevicePrefixERNS0_16FileDevicePrefixE
|
||||
0x000000710120aef8,res::ResourceMgrTask::eraseFromFileDeviceToPrefixMap,104,_ZN4ksys3res15ResourceMgrTask26deregisterFileDevicePrefixERNS0_16FileDevicePrefixE
|
||||
0x000000710120af60,res::ResourceMgrTask::__auto3,164,_ZN4ksys3res15ResourceMgrTask27callStubbedFunctionOnArenasEv
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -1 +1 @@
|
|||
Subproject commit 9d3e4be6c4404efa6cf039bd8b93ad98609e3480
|
||||
Subproject commit 7ea03832ecf296f4ad2331094398ca07fa92b76a
|
2
lib/sead
2
lib/sead
|
@ -1 +1 @@
|
|||
Subproject commit 77a3f1521986cdbe957ee26339c2659400f9e304
|
||||
Subproject commit dfbcf903b8543c5f85fe166eaf8d4bc92c9c93ba
|
|
@ -1,13 +1,53 @@
|
|||
#include "Game/DLC/aocManager.h"
|
||||
#include <container/seadBuffer.h>
|
||||
#include <filedevice/seadFileDeviceMgr.h>
|
||||
#include <prim/seadStringBuilder.h>
|
||||
#include <resource/seadSharcArchiveRes.h>
|
||||
#include "KingSystem/Resource/resLoadRequest.h"
|
||||
#include "KingSystem/Resource/resResourceMgrTask.h"
|
||||
#include "KingSystem/Utils/InitTimeInfo.h"
|
||||
#include "KingSystem/Utils/SafeDelete.h"
|
||||
|
||||
#ifdef NNSDK
|
||||
#include <filedevice/nin/seadNinAocFileDeviceNin.h>
|
||||
#include <nn/aoc.h>
|
||||
#include <nn/fs.h>
|
||||
#include <prim/seadStringUtil.h>
|
||||
#endif
|
||||
|
||||
namespace uking::aoc {
|
||||
|
||||
namespace {
|
||||
|
||||
struct DungeonInfo {
|
||||
int number;
|
||||
sead::SafeString flag;
|
||||
};
|
||||
|
||||
ksys::util::InitConstants sInitConstants;
|
||||
DungeonInfo sDungeonInfoData[] = {
|
||||
{120, "Defeat_OneHitDungeon001"},
|
||||
{121, "BalladOfHeroGerudo_AppearDungeon03"},
|
||||
{122, "Defeat_OneHitDungeon002"},
|
||||
{123, "Defeat_OneHitDungeon003"},
|
||||
{124, "BalladOfHeroZora_AppearDungeon01"},
|
||||
{125, "BalladOfHeroZora_AppearDungeon02"},
|
||||
{126, "BalladOfHeroZora_AppearDungeon03"},
|
||||
{127, "BalladOfHeroRito_TargetHittingSuccess"},
|
||||
{128, "BalladOfHeroRito_AppearDungeon03"},
|
||||
{129, "BalladOfHeroRito_AppearDungeon02"},
|
||||
{130, "BalladOfHeroGoron_FirstKillGolemR"},
|
||||
{131, "BalladOfHeroGoron_AppearDungeon01"},
|
||||
{132, "BalladOfHeroGoron_AppearDungeon03"},
|
||||
{133, "BalladOfHeroGerudo_AppearDungeon02"},
|
||||
{134, "BalladOfHeroGerudo_AppearDungeon01"},
|
||||
{135, "Defeat_OneHitDungeon004"},
|
||||
};
|
||||
sead::Buffer<DungeonInfo> sDungeonInfo{sDungeonInfoData};
|
||||
constexpr int NumDungeons = 16;
|
||||
|
||||
} // namespace
|
||||
|
||||
SEAD_SINGLETON_DISPOSER_IMPL(Manager)
|
||||
|
||||
Manager::Manager() : mGdtReinitSlot{this, &Manager::onGdtReinit} {
|
||||
|
@ -18,8 +58,8 @@ Manager::~Manager() {
|
|||
if (auto* gdm = ksys::gdt::Manager::instance())
|
||||
gdm->removeReinitCallback(mGdtReinitSlot);
|
||||
|
||||
mFileDevicePrefix.deregister();
|
||||
mFileDevicePrefix2.deregister();
|
||||
mAocMainFieldPackPrefix.deregister();
|
||||
mAocPackPrefix.deregister();
|
||||
mVersionFileDevPrefix.deregister();
|
||||
|
||||
if (mFileDevice) {
|
||||
|
@ -43,4 +83,449 @@ void Manager::resetFlags() {
|
|||
mFlagHasAocVer3 = ksys::gdt::InvalidHandle;
|
||||
}
|
||||
|
||||
void Manager::init(sead::Heap* heap) {
|
||||
#ifdef NNSDK
|
||||
std::array<int, 2> dlc_info;
|
||||
if (nn::aoc::ListAddOnContent(dlc_info.data(), 0, dlc_info.size()) == dlc_info.size() &&
|
||||
(dlc_info[0] == 1 || dlc_info[1] == 1)) {
|
||||
size_t cache_size = 0;
|
||||
nn::fs::QueryMountAddOnContentCacheSize(&cache_size, 1);
|
||||
const size_t cache_size_ = cache_size;
|
||||
mAocFsCache = static_cast<u8*>(heap->tryAlloc(cache_size_, sizeof(void*)));
|
||||
|
||||
nn::fs::MountAddOnContent("aoc", 1, mAocFsCache, cache_size);
|
||||
|
||||
mFileDevice = new (heap) sead::NinAocFileDevice("aoc");
|
||||
sead::FileDeviceMgr::instance()->mount(mFileDevice, "aoc");
|
||||
loadVersionFile();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Manager::loadVersionFile() {
|
||||
if (!mFileDevice)
|
||||
return;
|
||||
|
||||
mVersionFileDevPrefix.registerPrefix("Aoc/0010/", mFileDevice, false);
|
||||
|
||||
ksys::res::LoadRequest req;
|
||||
req.mRequester = "aocManager";
|
||||
req._26 = false;
|
||||
req.mAocFileDevice = mFileDevice;
|
||||
const sead::SafeString path = "System/AocVersion.txt";
|
||||
mVersionFile->file_handle.requestLoad(path, &req);
|
||||
}
|
||||
|
||||
void Manager::loadAocMainFieldPack(ksys::OverlayArena* arena) {
|
||||
if (!hasAoc3())
|
||||
return;
|
||||
|
||||
auto* device = mFileDevice;
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
ksys::res::LoadRequest req;
|
||||
req.mRequester = "aocManager";
|
||||
req._8 = true;
|
||||
req._26 = false;
|
||||
req.mAocFileDevice = device;
|
||||
req.mArena = arena;
|
||||
mAocMainFieldPack.requestLoad("Pack/AocMainField.pack", &req);
|
||||
}
|
||||
|
||||
void Manager::registerAocMainFieldPack() {
|
||||
mAocMainFieldPack.waitForReady();
|
||||
mAocMainFieldPack.parseResource(nullptr);
|
||||
if (mAocMainFieldPack.isSuccess())
|
||||
mAocMainFieldPackPrefix.registerPrefix("Aoc/0010/", mAocMainFieldPack.getResource(), false);
|
||||
}
|
||||
|
||||
void Manager::unloadAocMainFieldPack() {
|
||||
mAocMainFieldPackPrefix.deregister();
|
||||
mAocMainFieldPack.requestUnload();
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForMapFile(const sead::SafeString& path) const {
|
||||
if (!hasAoc2())
|
||||
return nullptr;
|
||||
|
||||
auto* device = mFileDevice;
|
||||
|
||||
if (aocPackHasFile(path))
|
||||
return nullptr;
|
||||
|
||||
if (path.startsWith("Map/MainField/"))
|
||||
return device;
|
||||
|
||||
if (hasAoc3() && path.startsWith("Map/MainFieldDungeon/"))
|
||||
return device;
|
||||
|
||||
if (isAocFile(path, "Map/", "Map/AocField/", "Map/MainFieldDungeon/", "Map/CDungeon/"))
|
||||
return device;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Manager::getFileDeviceForMap(sead::FileDevice** p_file_device, ksys::res::Handle** p_handle,
|
||||
const sead::SafeString& path) {
|
||||
if (!hasAoc2())
|
||||
return false;
|
||||
|
||||
auto* device = mFileDevice;
|
||||
|
||||
if (path.startsWith("Map/MainField/")) {
|
||||
if (mAocMainFieldPack.isSuccess())
|
||||
*p_handle = &mAocMainFieldPack;
|
||||
else
|
||||
*p_file_device = device;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aocPackHasFile(path))
|
||||
return false;
|
||||
|
||||
if (hasAoc3() && path.startsWith("Map/MainFieldDungeon/")) {
|
||||
*p_file_device = device;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isAocFile(path, "Map/", "Map/AocField/", "Map/MainFieldDungeon/", "Map/CDungeon/")) {
|
||||
*p_file_device = device;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForStaticCompound(const sead::SafeString& path) const {
|
||||
if (!hasAoc2())
|
||||
return nullptr;
|
||||
|
||||
auto* device = mFileDevice;
|
||||
|
||||
if (aocPackHasFile(path))
|
||||
return nullptr;
|
||||
|
||||
if (isAocFile(path, "Physics/StaticCompound/", "Physics/StaticCompound/AocField/",
|
||||
"Physics/StaticCompound/MainFieldDungeon/", "Physics/StaticCompound/CDungeon/")) {
|
||||
return device;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForTeraMesh(const sead::SafeString& path) const {
|
||||
if (!hasAoc2())
|
||||
return nullptr;
|
||||
|
||||
if (path.startsWith("Physics/TeraMeshRigidBody/AocField/"))
|
||||
return mFileDevice;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForNavMesh(const sead::SafeString& path) const {
|
||||
if (!hasAoc2())
|
||||
return nullptr;
|
||||
|
||||
auto* device = mFileDevice;
|
||||
|
||||
if (aocPackHasFile(path))
|
||||
return nullptr;
|
||||
|
||||
if (isAocFile(path, "NavMesh/", "NavMesh/AocField/", "NavMesh/MainFieldDungeon/",
|
||||
"NavMesh/CDungeon/")) {
|
||||
return device;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForTerrain(const sead::SafeString& path) const {
|
||||
if (!hasAoc2())
|
||||
return nullptr;
|
||||
|
||||
if (path.startsWith("Terrain/A/AocField"))
|
||||
return mFileDevice;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForGame(const sead::SafeString& path) const {
|
||||
if (!hasAoc2())
|
||||
return nullptr;
|
||||
|
||||
if (path.startsWith("Game/AocField/"))
|
||||
return mFileDevice;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForUI(const sead::SafeString& path) const {
|
||||
if (!hasAoc3())
|
||||
return nullptr;
|
||||
|
||||
if (path.startsWith("UI/StaffRollDLC/"))
|
||||
return mFileDevice;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Manager::isAocFile(const sead::SafeString& path, const sead::SafeString& dir,
|
||||
const sead::SafeString& dir_aoc_field,
|
||||
const sead::SafeString& dir_main_field_dungeon,
|
||||
const sead::SafeString& dir_cdungeon) const {
|
||||
if (!path.startsWith(dir))
|
||||
return false;
|
||||
|
||||
if (path.startsWith(dir_aoc_field))
|
||||
return true;
|
||||
|
||||
if (path.startsWith(dir_main_field_dungeon)) {
|
||||
const auto rel_path = path.getPart(dir_main_field_dungeon.calcLength());
|
||||
if (rel_path.startsWith("RemainsElectric"))
|
||||
return false;
|
||||
if (rel_path.startsWith("RemainsFire"))
|
||||
return false;
|
||||
if (rel_path.startsWith("RemainsWater"))
|
||||
return false;
|
||||
if (rel_path.startsWith("RemainsWind"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (path.startsWith(dir_cdungeon)) {
|
||||
const auto rel_path = path.getPart(dir_cdungeon.calcLength());
|
||||
return isAocDungeon(rel_path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isAocDungeonNumber(const sead::SafeString& number) {
|
||||
int num;
|
||||
sead::FixedSafeString<4> buffer;
|
||||
buffer.copy(number, 3);
|
||||
return sead::StringUtil::tryParseS32(&num, buffer, sead::StringUtil::CardinalNumber::Base10) &&
|
||||
num >= 120;
|
||||
}
|
||||
|
||||
bool Manager::isAocDungeon(const sead::SafeString& map_name) {
|
||||
if (!map_name.startsWith("Dungeon"))
|
||||
return true;
|
||||
const auto number = map_name.getPart(sead::SafeString("Dungeon").calcLength());
|
||||
return isAocDungeonNumber(number);
|
||||
}
|
||||
|
||||
bool Manager::isAocMap(const sead::SafeString& map_type, const sead::SafeString& map_name) {
|
||||
if (isAocField(map_type))
|
||||
return true;
|
||||
|
||||
if (map_type == "MainFieldDungeon") {
|
||||
if (map_name == "RemainsElectric")
|
||||
return false;
|
||||
if (map_name == "RemainsFire")
|
||||
return false;
|
||||
if (map_name == "RemainsWater")
|
||||
return false;
|
||||
if (map_name == "RemainsWind")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (map_type == "CDungeon")
|
||||
return isAocDungeon(map_name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Manager::isAocField(const sead::SafeString& map_type) {
|
||||
return map_type == "AocField";
|
||||
}
|
||||
|
||||
sead::FileDevice* Manager::getFileDeviceForDungeonPack(const sead::SafeString& path) const {
|
||||
if (!hasAoc3())
|
||||
return nullptr;
|
||||
|
||||
auto* device = mFileDevice;
|
||||
|
||||
const sead::SafeString prefix = "Pack/";
|
||||
const auto prefix_len = prefix.calcLength();
|
||||
|
||||
if (!path.startsWith(prefix))
|
||||
return nullptr;
|
||||
|
||||
const auto rel_path = path.getPart(prefix_len);
|
||||
|
||||
if (rel_path.startsWith("Dungeon") && !isAocDungeon(rel_path))
|
||||
device = nullptr;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
void Manager::registerAocPack(ksys::res::Handle* pack) {
|
||||
mAocPack = pack;
|
||||
if (pack) {
|
||||
mAocPackPrefix.registerPrefix("Aoc/0010/", pack->getResource(), true);
|
||||
} else {
|
||||
mAocPackPrefix.deregister();
|
||||
}
|
||||
}
|
||||
|
||||
bool Manager::aocPackHasFile(const sead::SafeString& path) const {
|
||||
if (!mAocPack)
|
||||
return false;
|
||||
|
||||
const auto* res = sead::DynamicCast<sead::SharcArchiveRes>(mAocPack->getResource());
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
sead::FixedStringBuilder<0x81> builder;
|
||||
builder.copy(path.cstr());
|
||||
ksys::res::ResourceMgrTask::instance()->addSExtensionPrefix(builder);
|
||||
return res->isExistFile(builder);
|
||||
}
|
||||
|
||||
bool Manager::changeMoviePath(sead::BufferedSafeString& path) const {
|
||||
if (!hasAoc3())
|
||||
return false;
|
||||
|
||||
const sead::SafeString prefix = "Movie/";
|
||||
const auto prefix_len = prefix.calcLength();
|
||||
if (!path.startsWith(prefix))
|
||||
return false;
|
||||
|
||||
const auto rel_path = path.getPart(prefix_len);
|
||||
if (!rel_path.startsWith("Demo6"))
|
||||
return false;
|
||||
|
||||
path.prepend("aoc://");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Manager::parseVersion() {
|
||||
if (!mVersionFile->readVersion())
|
||||
return false;
|
||||
|
||||
if (mVersionFile->string.isEmpty()) {
|
||||
mVersion = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
const int dot_index = mVersionFile->string.findIndex(".");
|
||||
const int minor_index = dot_index + 1;
|
||||
if (dot_index <= 0 || minor_index >= mVersionFile->string.calcLength()) {
|
||||
mVersionFile->string.clear();
|
||||
mVersion = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 major, minor;
|
||||
const auto parse = [&] {
|
||||
sead::FixedSafeString<16> major_str;
|
||||
major_str.copy(mVersionFile->string, dot_index);
|
||||
|
||||
constexpr auto base = sead::StringUtil::CardinalNumber::Base10;
|
||||
if (!sead::StringUtil::tryParseU32(&major, major_str, base))
|
||||
return false;
|
||||
|
||||
const auto minor_str = mVersionFile->string.getPart(minor_index);
|
||||
if (!sead::StringUtil::tryParseU32(&minor, minor_str, base))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!parse()) {
|
||||
mVersionFile->string.clear();
|
||||
mVersion = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
mVersion = (major << 8) + minor;
|
||||
}
|
||||
|
||||
checkVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
// NON_MATCHING: stack and duplicated branch -- volatile variables are painful
|
||||
void Manager::checkVersion() {
|
||||
if (mVersion == 0)
|
||||
return;
|
||||
|
||||
const auto fail = [this](VersionError error) {
|
||||
mVersionFlags.setBit(error);
|
||||
mVersion = 0;
|
||||
};
|
||||
|
||||
if (mVersion < 0x300) {
|
||||
fail(VersionError::TooOld);
|
||||
} else if (mVersion >= 0x400) {
|
||||
fail(VersionError::TooNew);
|
||||
}
|
||||
|
||||
mVersionFlags.isOnBit(VersionError(VersionError::TooOld));
|
||||
mVersionFlags.isOnBit(VersionError(VersionError::TooNew));
|
||||
}
|
||||
|
||||
bool Manager::VersionFile::readVersion() {
|
||||
if (!file_handle.isFlag2Set())
|
||||
return true;
|
||||
|
||||
if (file_handle.isSuccess()) {
|
||||
auto* res = sead::DynamicCast<sead::DirectResource>(file_handle.getResource());
|
||||
string.copy(reinterpret_cast<const char*>(res->getRawData()), res->getRawSize());
|
||||
} else {
|
||||
if (!file_handle.checkLoadStatus())
|
||||
return false;
|
||||
string.clear();
|
||||
}
|
||||
|
||||
file_handle.requestUnload();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Manager::initGameData() {
|
||||
reinitFlags();
|
||||
ksys::gdt::Manager::instance()->addReinitCallback(mGdtReinitSlot);
|
||||
}
|
||||
|
||||
static const sead::SafeString& getDungeonFlag(int number) {
|
||||
for (auto it = sDungeonInfo.begin(); it != sDungeonInfo.end(); ++it) {
|
||||
if (it->number == number)
|
||||
return it->flag;
|
||||
}
|
||||
return sead::SafeString::cEmptyString;
|
||||
}
|
||||
|
||||
void Manager::reinitFlags() {
|
||||
mFlagAocVerAtLastPlay = ksys::gdt::Manager::instance()->getS32Handle("AoCVerAtLastPlay");
|
||||
mFlagLatestAocVerPlayed = ksys::gdt::Manager::instance()->getS32Handle("LatestAoCVerPlayed");
|
||||
mFlagHasAocVer1 =
|
||||
ksys::gdt::Manager::instance()->getBoolHandle(GameDataFlag::text(GameDataFlag::HasAoCVer1));
|
||||
mFlagHasAocVer2 =
|
||||
ksys::gdt::Manager::instance()->getBoolHandle(GameDataFlag::text(GameDataFlag::HasAoCVer2));
|
||||
mFlagHasAocVer3 =
|
||||
ksys::gdt::Manager::instance()->getBoolHandle(GameDataFlag::text(GameDataFlag::HasAoCVer3));
|
||||
|
||||
for (int i = 0; i < mDLCPositions.size(); ++i) {
|
||||
ksys::gdt::FlagHandle handle = ksys::gdt::InvalidHandle;
|
||||
|
||||
if (i < NumDungeons) {
|
||||
if (mDLCPositions[i].flag_handle == ksys::gdt::InvalidHandle)
|
||||
continue;
|
||||
|
||||
handle = ksys::gdt::Manager::instance()->getBoolHandle(getDungeonFlag(i + 120));
|
||||
}
|
||||
|
||||
mDLCPositions[i].flag_handle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::onGdtReinit(ksys::gdt::Manager::ReinitEvent* event) {
|
||||
reinitFlags();
|
||||
}
|
||||
|
||||
} // namespace uking::aoc
|
||||
|
|
|
@ -3,14 +3,19 @@
|
|||
#include <container/seadSafeArray.h>
|
||||
#include <heap/seadDisposer.h>
|
||||
#include <math/seadVector.h>
|
||||
#include <prim/seadEnum.h>
|
||||
#include <prim/seadSafeString.h>
|
||||
#include <prim/seadStorageFor.h>
|
||||
#include <prim/seadTypedBitFlag.h>
|
||||
#include <prim/seadBitFlag.h>
|
||||
#include "KingSystem/GameData/gdtManager.h"
|
||||
#include "KingSystem/Resource/resHandle.h"
|
||||
#include "KingSystem/Resource/resResourceMgrTask.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace ksys {
|
||||
class OverlayArena;
|
||||
}
|
||||
|
||||
namespace sead {
|
||||
class FileDevice;
|
||||
}
|
||||
|
@ -24,6 +29,8 @@ class Manager {
|
|||
~Manager();
|
||||
|
||||
public:
|
||||
void init(sead::Heap* heap);
|
||||
|
||||
u32 getVersion() const { return mVersion; }
|
||||
|
||||
/// @return Whether the Master Trials DLC is supported.
|
||||
|
@ -32,10 +39,44 @@ public:
|
|||
/// @return Whether the Champion's Ballad DLC is supported.
|
||||
bool hasAoc3() const { return mVersion >= 0x300; }
|
||||
|
||||
private:
|
||||
enum class Flag : u8 {
|
||||
void loadAocMainFieldPack(ksys::OverlayArena* arena);
|
||||
void registerAocMainFieldPack();
|
||||
void unloadAocMainFieldPack();
|
||||
|
||||
};
|
||||
sead::FileDevice* getFileDeviceForMapFile(const sead::SafeString& path) const;
|
||||
bool getFileDeviceForMap(sead::FileDevice** p_file_device, ksys::res::Handle** p_handle,
|
||||
const sead::SafeString& path);
|
||||
sead::FileDevice* getFileDeviceForStaticCompound(const sead::SafeString& path) const;
|
||||
sead::FileDevice* getFileDeviceForTeraMesh(const sead::SafeString& path) const;
|
||||
sead::FileDevice* getFileDeviceForNavMesh(const sead::SafeString& path) const;
|
||||
sead::FileDevice* getFileDeviceForTerrain(const sead::SafeString& path) const;
|
||||
sead::FileDevice* getFileDeviceForGame(const sead::SafeString& path) const;
|
||||
sead::FileDevice* getFileDeviceForUI(const sead::SafeString& path) const;
|
||||
|
||||
bool isAocFile(const sead::SafeString& path, const sead::SafeString& dir,
|
||||
const sead::SafeString& dir_aoc_field,
|
||||
const sead::SafeString& dir_main_field_dungeon,
|
||||
const sead::SafeString& dir_cdungeon) const;
|
||||
static bool isAocDungeon(const sead::SafeString& map_name);
|
||||
static bool isAocMap(const sead::SafeString& map_type, const sead::SafeString& map_name);
|
||||
static bool isAocField(const sead::SafeString& map_type);
|
||||
|
||||
sead::FileDevice* getFileDeviceForDungeonPack(const sead::SafeString& path) const;
|
||||
void registerAocPack(ksys::res::Handle* pack);
|
||||
bool aocPackHasFile(const sead::SafeString& path) const;
|
||||
|
||||
bool changeMoviePath(sead::BufferedSafeString & path) const;
|
||||
|
||||
void parseAocMainFieldStaticInfo(const al::ByamlIter& iter);
|
||||
// TODO: figure out what this does
|
||||
bool getSomePos(sead::Vector3f* translate, u32* p_mask, u32* mask);
|
||||
|
||||
bool parseVersion();
|
||||
void setGameDataFlags() const;
|
||||
|
||||
private:
|
||||
SEAD_ENUM(GameDataFlag, AoCVerAtLastPlay ,LatestAoCVerPlayed ,HasAoCVer1 ,HasAoCVer2 ,HasAoCVer3)
|
||||
SEAD_ENUM(VersionError, TooNew, TooOld)
|
||||
|
||||
struct DLCPosition {
|
||||
sead::Vector3f translate = sead::Vector3f::zero;
|
||||
|
@ -47,12 +88,19 @@ private:
|
|||
KSYS_CHECK_SIZE_NX150(DLCPosition, 0x2c);
|
||||
|
||||
struct VersionFile {
|
||||
bool readVersion();
|
||||
|
||||
ksys::res::Handle file_handle;
|
||||
sead::FixedSafeString<16> string;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(VersionFile, 0x78);
|
||||
|
||||
void loadVersionFile();
|
||||
void checkVersion();
|
||||
|
||||
void resetFlags();
|
||||
void initGameData();
|
||||
void reinitFlags();
|
||||
void onGdtReinit(ksys::gdt::Manager::ReinitEvent* event);
|
||||
|
||||
sead::FileDevice* mFileDevice{};
|
||||
|
@ -61,10 +109,10 @@ private:
|
|||
sead::StorageFor<VersionFile, true> mVersionFile{sead::ZeroInitializeTag{}};
|
||||
u32 mVersion{};
|
||||
|
||||
ksys::res::Handle mAocMapMainFieldPack;
|
||||
ksys::res::FileDevicePrefix mFileDevicePrefix;
|
||||
ksys::res::Handle* mAocArchive{};
|
||||
ksys::res::FileDevicePrefix mFileDevicePrefix2;
|
||||
ksys::res::Handle mAocMainFieldPack;
|
||||
ksys::res::FileDevicePrefix mAocMainFieldPackPrefix;
|
||||
ksys::res::Handle* mAocPack{};
|
||||
ksys::res::FileDevicePrefix mAocPackPrefix;
|
||||
|
||||
sead::SafeArray<DLCPosition, 20> mDLCPositions;
|
||||
|
||||
|
@ -75,7 +123,7 @@ private:
|
|||
ksys::gdt::FlagHandle mFlagHasAocVer3{};
|
||||
ksys::gdt::Manager::ReinitSignal::Slot mGdtReinitSlot;
|
||||
|
||||
sead::TypedBitFlag<Flag> mFlags{};
|
||||
sead::BitFlag8 mVersionFlags{};
|
||||
#ifdef NNSDK
|
||||
u8* mAocFsCache{};
|
||||
#endif
|
||||
|
|
|
@ -421,15 +421,14 @@ void ResourceMgrTask::unloadSeadResource(sead::Resource* resource) {
|
|||
stubbedLogFunction();
|
||||
}
|
||||
|
||||
u32 ResourceMgrTask::getResourceSize(const sead::SafeString& name,
|
||||
sead::FileDevice* file_device) const {
|
||||
if (!file_device)
|
||||
u32 ResourceMgrTask::getResourceSize(const sead::SafeString& name, void* userdata) const {
|
||||
if (!userdata)
|
||||
return mResourceInfoContainer.getResourceSize(name);
|
||||
|
||||
mFileDevicePrefixesLock.readLock();
|
||||
|
||||
for (const auto& entry : mFileDevicePrefixes) {
|
||||
if (entry.getFileDevice() == file_device) {
|
||||
if (entry.getUserData() == userdata) {
|
||||
const u32 size = mResourceInfoContainer.getResourceSize(entry.getPrefix(), name);
|
||||
if (size == 0 && entry.getField28())
|
||||
break;
|
||||
|
|
|
@ -57,8 +57,8 @@ class FileDevicePrefix {
|
|||
public:
|
||||
FileDevicePrefix() = default;
|
||||
|
||||
sead::FileDevice* getFileDevice() const { return mFileDevice; }
|
||||
void setFileDevice(sead::FileDevice* device) { mFileDevice = device; }
|
||||
void* getUserData() const { return mUserData; }
|
||||
void setUserData(void* userdata) { mUserData = userdata; }
|
||||
|
||||
const sead::SafeString& getPrefix() const { return mPrefix; }
|
||||
void setPrefix(const sead::SafeString& prefix) { mPrefix = prefix; }
|
||||
|
@ -66,13 +66,15 @@ public:
|
|||
bool getField28() const { return _28; }
|
||||
void setField28(bool value) { _28 = value; }
|
||||
|
||||
void registerPrefix(const sead::SafeString& prefix, void* userdata, bool set28);
|
||||
void registerPrefix(const char* prefix, void* userdata, bool set28);
|
||||
void deregister();
|
||||
|
||||
static constexpr size_t getListNodeOffset() { return offsetof(FileDevicePrefix, mListNode); }
|
||||
|
||||
private:
|
||||
sead::ListNode mListNode;
|
||||
sead::FileDevice* mFileDevice = nullptr;
|
||||
void* mUserData = nullptr;
|
||||
sead::SafeString mPrefix;
|
||||
bool _28 = false;
|
||||
};
|
||||
|
@ -173,7 +175,7 @@ public:
|
|||
|
||||
void unloadSeadResource(sead::Resource* resource);
|
||||
|
||||
u32 getResourceSize(const sead::SafeString& name, sead::FileDevice* file_device) const;
|
||||
u32 getResourceSize(const sead::SafeString& name, void* userdata) const;
|
||||
|
||||
void registerFileDevicePrefix(FileDevicePrefix& prefix);
|
||||
void deregisterFileDevicePrefix(FileDevicePrefix& prefix);
|
||||
|
@ -406,6 +408,19 @@ KSYS_CHECK_SIZE_NX150(sead::TaskBase, 0xd0);
|
|||
KSYS_CHECK_SIZE_NX150(sead::MethodTreeNode, 0x98);
|
||||
KSYS_CHECK_SIZE_NX150(ResourceMgrTask, 0x9c0eb8);
|
||||
|
||||
inline void FileDevicePrefix::registerPrefix(const sead::SafeString& prefix, void* userdata,
|
||||
bool set28) {
|
||||
setUserData(userdata);
|
||||
setPrefix(prefix);
|
||||
if (set28)
|
||||
setField28(true);
|
||||
ResourceMgrTask::instance()->registerFileDevicePrefix(*this);
|
||||
}
|
||||
|
||||
inline void FileDevicePrefix::registerPrefix(const char* prefix, void* userdata, bool set28) {
|
||||
registerPrefix(sead::SafeString(prefix), userdata, set28);
|
||||
}
|
||||
|
||||
inline void FileDevicePrefix::deregister() {
|
||||
if (mListNode.isLinked())
|
||||
ResourceMgrTask::instance()->deregisterFileDevicePrefix(*this);
|
||||
|
|
Loading…
Reference in New Issue