This commit is contained in:
GRAnimated 2026-04-23 03:41:05 +02:00 committed by GitHub
commit aa91174b27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 298 additions and 17 deletions

View file

@ -144653,75 +144653,75 @@ Sequence/E3ResourceLoader.o:
label:
- _ZN16E3ResourceLoaderC1Ev
- _ZN16E3ResourceLoaderC2Ev
status: NotDecompiled
status: Matching
- offset: 0x50a454
size: 452
label: _ZN16E3ResourceLoader21loadHomeStageResourceEv
status: NotDecompiled
status: Matching
- offset: 0x50a618
size: 348
label: _ZN16E3ResourceLoader17loadWorldResourceEv
status: NotDecompiled
status: Matching
- offset: 0x50a774
size: 332
label:
- _ZN16E3ResourceLoaderD1Ev
- _ZN16E3ResourceLoaderD2Ev
status: NotDecompiled
status: Matching
- offset: 0x50a8c0
size: 12
label: _ZN16E3ResourceLoader23cancelLoadWorldResourceEv
status: NotDecompiled
status: Matching
- offset: 0x50a8cc
size: 36
label: _ZN16E3ResourceLoaderD0Ev
status: NotDecompiled
status: Matching
- offset: 0x50a8f0
size: 104
label: _ZN16E3ResourceLoader33requestLoadWorldHomeStageResourceEv
status: NotDecompiled
status: Matching
- offset: 0x50a958
size: 8
label: _ZNK16E3ResourceLoader31isEndLoadWorldHomeStageResourceEv
status: NotDecompiled
status: Matching
- offset: 0x50a960
size: 112
label: _ZN16E3ResourceLoader24requestLoadWorldResourceEi
status: NotDecompiled
status: Matching
- offset: 0x50a9d0
size: 60
label: _ZNK16E3ResourceLoader12isEndLoadAnyEv
status: NotDecompiled
status: Matching
- offset: 0x50aa0c
size: 396
label: _ZN16E3ResourceLoader15tryCreateExHeapEi
status: NotDecompiled
status: Matching
- offset: 0x50ab98
size: 180
label: _ZN16E3ResourceLoader23tryDestroyWorldResourceEPN4sead4HeapE
status: NotDecompiled
status: Matching
- offset: 0x50ac4c
size: 4
label: _ZNK16E3ResourceLoader13printHeapInfoEv
status: NotDecompiled
status: Matching
- offset: 0x50ac50
size: 360
label: _ZN16E3ResourceLoader28loadHomeStageResourceByWorldEPKcPN4sead4HeapEii
status: NotDecompiled
status: Matching
- offset: 0x50adb8
size: 28
label: _ZNK2al10FunctorV0MIP16E3ResourceLoaderMS1_FvvEEclEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x50add4
size: 76
label: _ZNK2al10FunctorV0MIP16E3ResourceLoaderMS1_FvvEE5cloneEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x50ae20
size: 4
label: _ZN2al10FunctorV0MIP16E3ResourceLoaderMS1_FvvEED0Ev
status: NotDecompiled
status: Matching
lazy: true
- offset: 0x50ae24
size: 32

View file

@ -0,0 +1,243 @@
#include "Sequence/E3ResourceLoader.h"
#include <heap/seadFrameHeap.h>
#include <thread/seadThread.h>
#include "Library/Base/StringUtil.h"
#include "Library/File/FileUtil.h"
#include "Library/Memory/HeapUtil.h"
#include "Library/Resource/ResourceFunction.h"
#include "Library/Thread/AsyncFunctorThread.h"
#include "Library/Yaml/ByamlIter.h"
#include "Library/Yaml/ByamlUtil.h"
#include "System/GameDataFunction.h"
static s32 cPriority = sead::Thread::cDefaultPriority + 6;
static s32 _cDefaultPriority = sead::Thread::cDefaultPriority;
E3ResourceLoader::E3ResourceLoader() {
using E3ResourceLoaderFunctor = al::FunctorV0M<E3ResourceLoader*, void (E3ResourceLoader::*)()>;
mLoadHomeStageResourceThread = new al::AsyncFunctorThread(
"LoadHomeStageResourceThread",
E3ResourceLoaderFunctor(this, &E3ResourceLoader::loadHomeStageResource), cPriority,
0x100000, sead::CoreId::cMain);
mWorldResourceThread = new al::AsyncFunctorThread(
"WolrdResourceThread", E3ResourceLoaderFunctor(this, &E3ResourceLoader::loadWorldResource),
cPriority, 0x100000, sead::CoreId::cMain);
al::createWorldResourceHeap(false);
mWorldResourceHeap = al::getWorldResourceHeap();
}
E3ResourceLoader::~E3ResourceLoader() {
cancelLoadWorldResource();
if (mLoadHomeStageResourceThread) {
delete mLoadHomeStageResourceThread;
mLoadHomeStageResourceThread = nullptr;
}
if (mWorldResourceThread) {
delete mWorldResourceThread;
mWorldResourceThread = nullptr;
}
al::removeResourceCategory("E3常駐");
if (mSandWorldHomeStageResource) {
al::removeResourceCategory("砂ワールドホーム");
mSandWorldHomeStageResource->destroy();
mSandWorldHomeStageResource = nullptr;
}
if (mCityWorldHomeStageResource) {
al::removeResourceCategory("都市ワールドホーム");
mCityWorldHomeStageResource->destroy();
mCityWorldHomeStageResource = nullptr;
}
if (mWorldExResource) {
al::removeResourceCategory("ワールド常駐");
mWorldExResource->destroy();
mWorldExResource = nullptr;
}
if (mWorldResourceHeap) {
al::destroyWorldResourceHeap(false);
mWorldResourceHeap = nullptr;
}
al::resetCurrentCategoryName();
}
void E3ResourceLoader::loadHomeStageResource() {
if (!mHasCreatedResourceCategory) {
al::createCategoryResourceAll("プレイヤーモデル");
al::addResourceCategory("E3常駐", 0x400, mWorldResourceHeap);
al::createCategoryResourceAll("E3常駐");
mHasCreatedResourceCategory = true;
}
if (mWorldExResource) {
al::removeResourceCategory("ワールド常駐");
mWorldExResource->destroy();
mWorldExResource = nullptr;
}
if (!mSandWorldHomeStageResource) {
// 280 MB
sead::FrameHeap* heap = sead::FrameHeap::create(
280 * 1024 * 1024, "SandWorldHomeStageResource", mWorldResourceHeap, 8,
sead::Heap::cHeapDirection_Forward, false);
mSandWorldHomeStageResource = heap;
al::addResourceCategory("砂ワールドホーム", 1024, heap);
s32 worldIndexSand = GameDataFunction::getWorldIndexSand();
loadHomeStageResourceByWorld("砂ワールドホーム", mWorldResourceHeap, worldIndexSand, 8);
}
if (!mCityWorldHomeStageResource) {
// 290 MB
sead::FrameHeap* heap = sead::FrameHeap::create(
290 * 1024 * 1024, "CityWorldHomeStageResource", mWorldResourceHeap, 8,
sead::Heap::cHeapDirection_Reverse, false);
mCityWorldHomeStageResource = heap;
al::addResourceCategory("都市ワールドホーム", 1024, heap);
s32 worldIndexCity = GameDataFunction::getWorldIndexCity();
loadHomeStageResourceByWorld("都市ワールドホーム", heap, worldIndexCity, 12);
}
}
void E3ResourceLoader::loadWorldResource() {
al::setCurrentCategoryNameDefault();
const u8* byml = al::tryGetBymlFromArcName("SystemData/WorldList", "WorldResource");
al::ByamlIter byamlIter = al::ByamlIter(byml);
al::ByamlIter worldIter;
al::getByamlIterByIndex(&worldIter, byamlIter, mLoadWorldId);
al::ByamlIter worldResourceIter;
al::getByamlIterByKey(&worldResourceIter, worldIter, "WorldResource");
s32 size = worldResourceIter.getSize();
for (s32 i = 0; i < size; i++) {
al::ByamlIter resourceIter;
worldResourceIter.tryGetIterByIndex(&resourceIter, i);
const char* name = nullptr;
const char* ext = nullptr;
resourceIter.tryGetStringByKey(&name, "Name");
resourceIter.tryGetStringByKey(&ext, "Ext");
if (!al::findResource(name))
al::findOrCreateResource(name, ext);
if (mHasLoadedWorldResource)
return;
}
mIsLoaded = true;
}
void E3ResourceLoader::cancelLoadWorldResource() {
mHasLoadedWorldResource = true;
}
bool E3ResourceLoader::requestLoadWorldHomeStageResource() {
if (mSandWorldHomeStageResource && mCityWorldHomeStageResource &&
isEndLoadWorldHomeStageResource())
return false;
if (isEndLoadWorldHomeStageResource()) {
mHasLoadedWorldResource = false;
mIsLoaded = false;
mLoadWorldId = -1;
al::clearFileLoaderEntry();
mLoadHomeStageResourceThread->start();
return true;
}
return false;
}
bool E3ResourceLoader::isEndLoadWorldHomeStageResource() const {
return mLoadHomeStageResourceThread->isDone();
}
bool E3ResourceLoader::requestLoadWorldResource(s32 loadWorldId) {
if (mLoadWorldId == loadWorldId && mIsLoaded)
return false;
if (isEndLoadAny()) {
mHasLoadedWorldResource = false;
al::clearFileLoaderEntry();
mIsLoaded = false;
mLoadWorldId = loadWorldId;
mWorldResourceThread->start();
return true;
}
return false;
}
bool E3ResourceLoader::isEndLoadAny() const {
return mWorldResourceThread->isDone() && isEndLoadWorldHomeStageResource();
}
void E3ResourceLoader::tryCreateExHeap(s32 loadWorldId) {
if (mWorldExResource)
return;
if (GameDataFunction::getWorldIndexSand() == loadWorldId)
tryDestroyWorldResource(mCityWorldHomeStageResource);
else if (GameDataFunction::getWorldIndexCity() == loadWorldId)
tryDestroyWorldResource(mSandWorldHomeStageResource);
mWorldExResource = sead::FrameHeap::create(0, "WorldExResource", mWorldResourceHeap, 8,
sead::Heap::cHeapDirection_Forward, false);
al::addResourceCategory("ワールド常駐", 1024, mWorldExResource);
}
void E3ResourceLoader::tryDestroyWorldResource(sead::Heap* heap) {
if (!heap)
return;
if (mSandWorldHomeStageResource == heap) {
al::removeResourceCategory("砂ワールドホーム");
mSandWorldHomeStageResource->destroy();
mSandWorldHomeStageResource = nullptr;
}
if (mCityWorldHomeStageResource == heap) {
al::removeResourceCategory("都市ワールドホーム");
mCityWorldHomeStageResource->destroy();
mCityWorldHomeStageResource = nullptr;
}
}
void E3ResourceLoader::printHeapInfo() const {}
void E3ResourceLoader::loadHomeStageResourceByWorld(const char* worldName, sead::Heap* _heap,
s32 loadWorldId, s32 scenarioId) {
const u8* byml = al::tryGetBymlFromArcName("SystemData/WorldList", "WorldResource");
al::ByamlIter byamlIter = al::ByamlIter(byml);
al::ByamlIter worldIter;
al::getByamlIterByIndex(&worldIter, byamlIter, loadWorldId);
al::ByamlIter worldResourceIter;
if (!al::tryGetByamlIterByKey(&worldResourceIter, worldIter,
al::StringTmp<32>{"Scenario%d", scenarioId}.cstr()))
return;
al::setCurrentCategoryName(worldName);
s32 size = worldResourceIter.getSize();
for (s32 i = 0; i < size; i++) {
al::ByamlIter iter;
worldResourceIter.tryGetIterByIndex(&iter, i);
const char* name = nullptr;
const char* ext = nullptr;
iter.tryGetStringByKey(&name, "Name");
iter.tryGetStringByKey(&ext, "Ext");
al::findOrCreateResource(name, ext);
if (mHasLoadedWorldResource)
return;
}
}

View file

@ -0,0 +1,38 @@
#pragma once
#include <heap/seadFrameHeap.h>
namespace al {
class AsyncFunctorThread;
}
class E3ResourceLoader {
public:
E3ResourceLoader();
virtual ~E3ResourceLoader();
void loadHomeStageResource();
void loadWorldResource();
void cancelLoadWorldResource();
bool requestLoadWorldHomeStageResource();
bool isEndLoadWorldHomeStageResource() const;
bool requestLoadWorldResource(s32 loadWorldId);
bool isEndLoadAny() const;
void tryCreateExHeap(s32 loadWorldId);
void tryDestroyWorldResource(sead::Heap* heap);
void printHeapInfo() const;
void loadHomeStageResourceByWorld(const char* worldName, sead::Heap* _heap, s32 loadWorldId,
s32 scenarioId);
private:
al::AsyncFunctorThread* mLoadHomeStageResourceThread = nullptr;
al::AsyncFunctorThread* mWorldResourceThread = nullptr;
sead::Heap* mWorldResourceHeap = nullptr;
sead::FrameHeap* mSandWorldHomeStageResource = nullptr;
sead::FrameHeap* mCityWorldHomeStageResource = nullptr;
sead::FrameHeap* mWorldExResource = nullptr;
bool mHasLoadedWorldResource = false;
bool mIsLoaded = false;
bool mHasCreatedResourceCategory = false;
s32 mLoadWorldId = -1;
};