summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-09-20 17:59:41 +0200
committerLéo Lam <leo@leolam.fr>2020-09-22 18:43:03 +0200
commit8756ccdd07c690e61f9896830ca8bec12d4cfee1 (patch)
tree6c8ecf11d0a9792b655ead8d71a6db3cfef90178 /src
parent5ac991b0e05026b5ae25bfb7541d085f8d7000a2 (diff)
ksys: Start adding OverlayArenaSystem
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/CMakeLists.txt2
-rw-r--r--src/KingSystem/Resource/CMakeLists.txt4
-rw-r--r--src/KingSystem/Resource/resHandle.cpp7
-rw-r--r--src/KingSystem/Resource/resHandle.h39
-rw-r--r--src/KingSystem/Resource/resResourceMgrTask.cpp1
-rw-r--r--src/KingSystem/Resource/resResourceMgrTask.h21
-rw-r--r--src/KingSystem/Resource/resSystem.h13
-rw-r--r--src/KingSystem/Sound/CMakeLists.txt3
-rw-r--r--src/KingSystem/Sound/sndResource.h23
-rw-r--r--src/KingSystem/System/CMakeLists.txt11
-rw-r--r--src/KingSystem/System/OverlayArena.cpp62
-rw-r--r--src/KingSystem/System/OverlayArena.h89
-rw-r--r--src/KingSystem/System/OverlayArenaSystem.cpp330
-rw-r--r--src/KingSystem/System/OverlayArenaSystem.h102
-rw-r--r--src/KingSystem/System/OverlayArenaSystemS1.h39
-rw-r--r--src/KingSystem/System/OverlayArenaSystemS2.h33
-rw-r--r--src/KingSystem/System/StringBoard.h14
-rw-r--r--src/KingSystem/System/SystemPauseMgr.cpp9
-rw-r--r--src/KingSystem/System/SystemPauseMgr.h33
-rw-r--r--src/KingSystem/Terrain/teraSystem.h7
-rw-r--r--src/KingSystem/Utils/Thread/Task.h4
-rw-r--r--src/KingSystem/Utils/Thread/TaskQueueBase.cpp6
-rw-r--r--src/KingSystem/Utils/Thread/TaskQueueBase.h4
23 files changed, 847 insertions, 9 deletions
diff --git a/src/KingSystem/CMakeLists.txt b/src/KingSystem/CMakeLists.txt
index 9d78cb77..86d6d781 100644
--- a/src/KingSystem/CMakeLists.txt
+++ b/src/KingSystem/CMakeLists.txt
@@ -2,3 +2,5 @@ add_subdirectory(ActorSystem)
add_subdirectory(Map)
add_subdirectory(MessageSystem)
add_subdirectory(Resource)
+add_subdirectory(Sound)
+add_subdirectory(System)
diff --git a/src/KingSystem/Resource/CMakeLists.txt b/src/KingSystem/Resource/CMakeLists.txt
index a018382f..645a074c 100644
--- a/src/KingSystem/Resource/CMakeLists.txt
+++ b/src/KingSystem/Resource/CMakeLists.txt
@@ -86,6 +86,8 @@ target_sources(uking PRIVATE
resCurrentResNameMgr.h
resEntryFactory.cpp
resEntryFactory.h
+ resHandle.cpp
+ resHandle.h
resResource.cpp
resResource.h
@@ -105,4 +107,6 @@ target_sources(uking PRIVATE
resResourceLod.h
resResourceRecipe.cpp
resResourceRecipe.h
+
+ resSystem.h
)
diff --git a/src/KingSystem/Resource/resHandle.cpp b/src/KingSystem/Resource/resHandle.cpp
new file mode 100644
index 00000000..67024b14
--- /dev/null
+++ b/src/KingSystem/Resource/resHandle.cpp
@@ -0,0 +1,7 @@
+#include "KingSystem/Resource/resHandle.h"
+
+namespace ksys::res {
+
+Handle::Handle() = default;
+
+} // namespace ksys::res
diff --git a/src/KingSystem/Resource/resHandle.h b/src/KingSystem/Resource/resHandle.h
new file mode 100644
index 00000000..186cb4ab
--- /dev/null
+++ b/src/KingSystem/Resource/resHandle.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <prim/seadRuntimeTypeInfo.h>
+#include <prim/seadTypedBitFlag.h>
+#include "KingSystem/Utils/Thread/ManagedTaskHandle.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys::res {
+
+class ResourceUnit;
+
+// FIXME: incomplete
+class Handle {
+ SEAD_RTTI_BASE(Handle)
+public:
+ enum class Status {
+ _0 = 0,
+ };
+
+ Handle();
+ virtual ~Handle();
+
+ Status getStatus() const;
+
+private:
+ enum class Flag : u8 {
+ _1 = 0x1,
+ };
+
+ sead::TypedBitFlag<Flag> mFlags = Flag::_1;
+ Status mStatus = Status::_0;
+ ResourceUnit* mUnit = nullptr;
+ util::ManagedTaskHandle mTaskHandle;
+ void* _40 = nullptr;
+ void* _48 = nullptr;
+};
+KSYS_CHECK_SIZE_NX150(Handle, 0x50);
+
+} // namespace ksys::res
diff --git a/src/KingSystem/Resource/resResourceMgrTask.cpp b/src/KingSystem/Resource/resResourceMgrTask.cpp
new file mode 100644
index 00000000..c5b53de1
--- /dev/null
+++ b/src/KingSystem/Resource/resResourceMgrTask.cpp
@@ -0,0 +1 @@
+#include "KingSystem/Resource/resResourceMgrTask.h"
diff --git a/src/KingSystem/Resource/resResourceMgrTask.h b/src/KingSystem/Resource/resResourceMgrTask.h
new file mode 100644
index 00000000..e9bdd2db
--- /dev/null
+++ b/src/KingSystem/Resource/resResourceMgrTask.h
@@ -0,0 +1,21 @@
+#pragma once
+
+namespace ksys {
+class OverlayArena;
+}
+
+namespace ksys::res {
+
+// FIXME: very, very incomplete.
+class ResourceMgrTask {
+public:
+ static ResourceMgrTask* instance() { return sInstance; }
+
+ void insertOverlayArena(OverlayArena* arena);
+ OverlayArena* getSomeArena() const;
+
+private:
+ static ResourceMgrTask* sInstance;
+};
+
+} // namespace ksys::res
diff --git a/src/KingSystem/Resource/resSystem.h b/src/KingSystem/Resource/resSystem.h
new file mode 100644
index 00000000..4c27f2b4
--- /dev/null
+++ b/src/KingSystem/Resource/resSystem.h
@@ -0,0 +1,13 @@
+#pragma once
+
+namespace ksys::res {
+
+// In release builds, the only thing this function does is return 1.
+// TODO: figure out what this is used for. Stubbed log function?
+bool stubbedLogFunction();
+
+// In release builds, the only thing this function does is return 0.
+// TODO: figure out what this is used for. Stubbed log function?
+bool returnFalse();
+
+} // namespace ksys::res
diff --git a/src/KingSystem/Sound/CMakeLists.txt b/src/KingSystem/Sound/CMakeLists.txt
new file mode 100644
index 00000000..fb85aff9
--- /dev/null
+++ b/src/KingSystem/Sound/CMakeLists.txt
@@ -0,0 +1,3 @@
+target_sources(uking PRIVATE
+ sndResource.h
+)
diff --git a/src/KingSystem/Sound/sndResource.h b/src/KingSystem/Sound/sndResource.h
new file mode 100644
index 00000000..c17e570a
--- /dev/null
+++ b/src/KingSystem/Sound/sndResource.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <heap/seadDisposer.h>
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys::snd {
+
+// FIXME: incomplete
+class SoundResource {
+ SEAD_SINGLETON_DISPOSER(SoundResource)
+ virtual ~SoundResource();
+
+public:
+ sead::Heap* getSoundDebugHeap() const { return mSoundDebugHeap; }
+
+private:
+ sead::Heap* mSoundResourceHeap;
+ void* _30;
+ sead::Heap* mSoundDebugHeap;
+};
+KSYS_CHECK_SIZE_NX150(SoundResource, 0x40);
+
+} // namespace ksys::snd
diff --git a/src/KingSystem/System/CMakeLists.txt b/src/KingSystem/System/CMakeLists.txt
new file mode 100644
index 00000000..f2a045ba
--- /dev/null
+++ b/src/KingSystem/System/CMakeLists.txt
@@ -0,0 +1,11 @@
+target_sources(uking PRIVATE
+ OverlayArena.cpp
+ OverlayArena.h
+ OverlayArenaSystem.cpp
+ OverlayArenaSystem.h
+ OverlayArenaSystemS1.h
+ OverlayArenaSystemS2.h
+ StringBoard.h
+ SystemPauseMgr.cpp
+ SystemPauseMgr.h
+)
diff --git a/src/KingSystem/System/OverlayArena.cpp b/src/KingSystem/System/OverlayArena.cpp
new file mode 100644
index 00000000..3e612cbf
--- /dev/null
+++ b/src/KingSystem/System/OverlayArena.cpp
@@ -0,0 +1,62 @@
+#include "KingSystem/System/OverlayArena.h"
+#include <heap/seadExpHeap.h>
+#include "KingSystem/Resource/resResourceMgrTask.h"
+#include "KingSystem/Resource/resSystem.h"
+
+namespace ksys {
+
+OverlayArena::OverlayArena() {
+ // FIXME: these should use offsetof()
+ mUnits.initOffset(0xc0);
+ mOffsetList2.initOffset(0xd0);
+}
+
+OverlayArena::~OverlayArena() {
+ destroy();
+}
+
+// NON_MATCHING: branching at the end (csel instead of a branch)
+bool OverlayArena::init(const OverlayArena::InitArg& arg) {
+ if (!arg.heap) {
+ res::stubbedLogFunction();
+ return false;
+ }
+
+ if (arg.size == 0)
+ res::stubbedLogFunction();
+
+ mFlags.change(Flag::_1, arg.set_flag_1);
+
+ mHeap = sead::ExpHeap::create(arg.size, arg.name, arg.heap, arg.alignment,
+ sead::Heap::cHeapDirection_Forward, true);
+
+ if (arg.use_best_fit_alloc_mode)
+ mHeap->setAllocMode(sead::ExpHeap::AllocMode::BestFit);
+
+ mHeapSize = mHeap->getSize();
+ _cc = 0;
+ mHeapFreeSize = mHeap->getFreeSize();
+ mHeapName = mHeap->getName();
+ mUsagePercentage = 0.0;
+ _c8 = 0;
+ mMinFreePercentage = arg.min_free_percentage;
+
+ if (res::ResourceMgrTask::instance())
+ res::ResourceMgrTask::instance()->insertOverlayArena(this);
+
+ mFlags.change(Flag::_20, arg.set_flag_20);
+ mFlags.change(Flag::_10, arg.set_flag_10);
+
+ struct UnusedTemp {
+ sead::SafeString str;
+ void* _10 = nullptr;
+ };
+ [[maybe_unused]] UnusedTemp temp;
+ temp.str = arg.name;
+
+ mFlags.change(Flag::_8, arg.set_flag_8);
+
+ return true;
+}
+
+} // namespace ksys
diff --git a/src/KingSystem/System/OverlayArena.h b/src/KingSystem/System/OverlayArena.h
new file mode 100644
index 00000000..ef64b723
--- /dev/null
+++ b/src/KingSystem/System/OverlayArena.h
@@ -0,0 +1,89 @@
+#pragma once
+
+#include <basis/seadTypes.h>
+#include <container/seadListImpl.h>
+#include <container/seadOffsetList.h>
+#include <prim/seadSafeString.h>
+#include <prim/seadTypedBitFlag.h>
+#include <thread/seadCriticalSection.h>
+#include "KingSystem/System/StringBoard.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace sead {
+class ExpHeap;
+class Heap;
+} // namespace sead
+
+namespace ksys {
+
+namespace res {
+class ResourceUnit;
+}
+
+class OverlayArena {
+public:
+ struct InitArg {
+ bool set_flag_1 = false;
+ bool set_flag_8 = false;
+ bool use_best_fit_alloc_mode = false;
+ u8 _3 = false;
+ bool set_flag_10 = true;
+ bool set_flag_20 = false;
+ u8 _6 = 1;
+ u32 alignment = 8;
+ u32 size = 0;
+ f32 min_free_percentage = 0.0;
+ sead::Heap* heap = nullptr;
+ sead::Heap* heap2 = nullptr;
+ sead::SafeString name;
+ };
+ KSYS_CHECK_SIZE_NX150(InitArg, 0x38);
+
+ OverlayArena();
+ virtual ~OverlayArena();
+
+ bool init(const InitArg& arg);
+ void destroy();
+
+private:
+ friend class OverlayArenaSystem;
+
+ enum class Flag : u8 {
+ _1 = 0x1,
+ _2 = 0x2,
+ _4 = 0x4,
+ _8 = 0x8,
+ _10 = 0x10,
+ _20 = 0x20,
+ };
+
+ sead::ListNode mListNode;
+ sead::TypedBitFlag<Flag> mFlags = [] {
+ decltype(mFlags) flags;
+ flags.set(Flag::_2);
+ flags.set(Flag::_4);
+ return flags;
+ }();
+ sead::ExpHeap* mHeap = nullptr;
+ f32 mMinFreePercentage = 0.0;
+ sead::Heap* mHeap2 = nullptr;
+ sead::OffsetList<res::ResourceUnit> mUnits;
+ sead::OffsetList<void*> mOffsetList2; // FIXME: type
+ sead::CriticalSection mCS;
+ void* mUsage2 = nullptr;
+ void* _b0 = nullptr;
+ u32 _b8 = 0;
+ u32 mUsage1 = 0;
+ u32 mHeapFreeSize = 0;
+ u32 _c4 = 0;
+ u32 _c8 = 0;
+ u32 _cc = 0;
+ u32 mHeapSize = 0;
+ sead::SafeString mHeapName;
+ f32 mUsagePercentage = 0.0;
+ StringBoard mStringBoard;
+ u8 _f8 = 0;
+};
+KSYS_CHECK_SIZE_NX150(OverlayArena, 0x100);
+
+} // namespace ksys
diff --git a/src/KingSystem/System/OverlayArenaSystem.cpp b/src/KingSystem/System/OverlayArenaSystem.cpp
new file mode 100644
index 00000000..0dd00733
--- /dev/null
+++ b/src/KingSystem/System/OverlayArenaSystem.cpp
@@ -0,0 +1,330 @@
+#include "KingSystem/System/OverlayArenaSystem.h"
+#include <KingSystem/Resource/resResourceMgrTask.h>
+#include <heap/seadExpHeap.h>
+#include <heap/seadHeap.h>
+#include <thread/seadThreadUtil.h>
+#include "KingSystem/Resource/resSystem.h"
+#include "KingSystem/Sound/sndResource.h"
+#include "KingSystem/System/OverlayArena.h"
+#include "KingSystem/System/SystemPauseMgr.h"
+#include "KingSystem/Terrain/teraSystem.h"
+#include "KingSystem/Utils/Thread/Task.h"
+#include "KingSystem/Utils/Thread/TaskThread.h"
+
+namespace ksys {
+
+SEAD_SINGLETON_DISPOSER_IMPL(OverlayArenaSystem)
+
+OverlayArenaSystem::OverlayArenaSystem()
+ : mEvent(nullptr, sead::IDisposer::HeapNullOption::DoNotAppendDisposerIfNoHeapSpecified, true) {
+ mEvent.resetSignal();
+}
+
+OverlayArenaSystem::~OverlayArenaSystem() {
+ destroyHeaps();
+
+ if (mSzsDecompressorInstHeap)
+ mSzsDecompressorInstHeap->destroy();
+
+ if (mTask)
+ delete mTask;
+ mTask = nullptr;
+
+ if (mPrepareThread) {
+ mPrepareThread->quitAndWaitDoneSingleThread(false);
+ if (mPrepareThread)
+ delete mPrepareThread;
+ mPrepareThread = nullptr;
+ }
+}
+
+void OverlayArenaSystem::destroyHeaps() {
+ res::stubbedLogFunction();
+ if (mGameDataWorkHeap) {
+ mGameDataWorkHeap->destroy();
+ mGameDataWorkHeap = nullptr;
+ }
+ res::stubbedLogFunction();
+
+ res::stubbedLogFunction();
+ if (mFixedHeap) {
+ mFixedHeap->destroy();
+ mFixedHeap = nullptr;
+ }
+ res::stubbedLogFunction();
+
+ res::stubbedLogFunction();
+ if (mMovableMemoryHeap) {
+ mMovableMemoryHeap->destroy();
+ mMovableMemoryHeap = nullptr;
+ }
+ res::stubbedLogFunction();
+
+ mFlags.set(Flag::_2);
+}
+
+// NON_MATCHING: reordering for TaskThread::InitArg
+bool OverlayArenaSystem::init(const InitArg& arg, sead::Heap* heap) {
+ mSystemPauseMgr = arg.system_pause_mgr;
+
+ mPrepareThread = new (heap) util::TaskThread(
+ "OverlayArena Prepare", heap, sead::ThreadUtil::ConvertPrioritySeadToPlatform(17),
+ sead::MessageQueue::BlockType::Blocking, 0x7fffffff, 0x14000, 32);
+
+ {
+ util::TaskThread::InitArg arg_;
+ arg_.batch_size = 0;
+ arg_.queue = nullptr;
+ arg_.num_lanes = 1;
+ arg_.heap = heap;
+ mPrepareThread->init(arg_);
+ mPrepareThread->setAffinity(sead::CoreIdMask(sead::CoreId::cMain));
+ mPrepareThread->start();
+ }
+
+ mDelegate = {this, &OverlayArenaSystem::delegatedFunction};
+
+ {
+ mTask = new (heap) util::Task(heap);
+ util::TaskDelegateSetter setter;
+ mTask->setDelegate(setter);
+ }
+
+ {
+ OverlayArenaSystemS2::InitArg arg_;
+ arg_.s1 = &mS1;
+ arg_.system_pause_mgr = mSystemPauseMgr;
+ mS2.init(arg_);
+ }
+
+ mSzsDecompressorInstHeap = sead::ExpHeap::create(
+ sead::ExpHeap::getManagementAreaSize(8) + 0x1e20, "SZSDecompressorInst", heap,
+ sizeof(void*), sead::Heap::cHeapDirection_Forward, true);
+
+ if (heap) {
+ mFlags.reset(Flag::_2);
+ mFixedHeap = sead::ExpHeap::tryCreate(0x17600000, "FixedHeap", heap, sizeof(void*),
+ sead::Heap::cHeapDirection_Forward, false);
+ if (mFixedHeap) {
+ createHeaps();
+ mMovableMemoryHeap =
+ sead::ExpHeap::tryCreate(0x100000, "MovableMemoryHeap", heap, sizeof(void*),
+ sead::Heap::cHeapDirection_Forward, false);
+ }
+ }
+
+ res::stubbedLogFunction();
+ mS1.init();
+ res::stubbedLogFunction();
+
+ if (mSystemPauseMgr) {
+ res::stubbedLogFunction();
+ mSystemPauseMgr->m2();
+ res::stubbedLogFunction();
+ }
+
+ return true;
+}
+
+void OverlayArenaSystem::getSzsDecompressor(sead::SZSDecompressor** decompressor) const {
+ if (decompressor)
+ *decompressor = mSzsDecompressor;
+}
+
+OverlayArena* OverlayArenaSystem::getArena() const {
+ return mArena;
+}
+
+OverlayArena* OverlayArenaSystem::getTeraSzsWorkArena() const {
+ return mTeraSzsWorkArena;
+}
+
+OverlayArena* OverlayArenaSystem::getAudioArena() const {
+ return mAudioArena;
+}
+
+OverlayArena* OverlayArenaSystem::getUnknownArena() const {
+ return mUnknownArena;
+}
+
+void OverlayArenaSystem::createHeaps() {
+ res::stubbedLogFunction();
+
+ res::stubbedLogFunction();
+ mGameDataWorkHeap =
+ sead::ExpHeap::tryCreate(0x400000, "GameDataWork", mFixedHeap, sizeof(void*),
+ sead::Heap::cHeapDirection_Forward, true);
+ if (!mGameDataWorkHeap)
+ return;
+
+ res::stubbedLogFunction();
+
+ createSzsDecompressor();
+ createTexArcWorkHeap();
+ createArena();
+ createTeraSzsWorkArena();
+ createAudioArena();
+ createJpegHeap();
+ createTeraWorkHeap();
+ createPlacementTreeHeap();
+
+ res::stubbedLogFunction();
+}
+
+void OverlayArenaSystem::createTexArcWorkHeap() {
+ res::stubbedLogFunction();
+
+ if (mTexArcWorkHeap)
+ return;
+
+ if (!mFixedHeap)
+ return;
+
+ mTexArcWorkHeap = sead::ExpHeap::tryCreate(0xc000000, "TexArcWork", mFixedHeap, sizeof(void*),
+ sead::Heap::cHeapDirection_Forward, true);
+ if (mTexArcWorkHeap)
+ res::stubbedLogFunction();
+}
+
+void OverlayArenaSystem::createArena() {
+ res::stubbedLogFunction();
+
+ if (mArena)
+ return;
+
+ if (!mFixedHeap)
+ return;
+
+ mArena = new (mFixedHeap, std::nothrow) OverlayArena;
+ if (!mArena) {
+ mArena = nullptr;
+ return;
+ }
+
+ OverlayArena::InitArg arg;
+ arg.size = 0x3affee0;
+ arg.set_flag_1 = true;
+ arg.set_flag_8 = true;
+ arg.use_best_fit_alloc_mode = false;
+ arg.name = "ForOverlayArena";
+ arg.heap = mFixedHeap;
+ arg.heap2 = nullptr;
+ arg._6 = false;
+ arg.set_flag_10 = false;
+ if (mArena->init(arg))
+ res::stubbedLogFunction();
+}
+
+void OverlayArenaSystem::createTeraSzsWorkArena() {
+ res::stubbedLogFunction();
+
+ if (mTeraSzsWorkArena)
+ return;
+
+ if (!mFixedHeap)
+ return;
+
+ mTeraSzsWorkArena = new (mFixedHeap, std::nothrow) OverlayArena;
+ if (!mTeraSzsWorkArena) {
+ mTeraSzsWorkArena = nullptr;
+ return;
+ }
+
+ OverlayArena::InitArg arg;
+ arg.size = 0x9ffee0;
+ arg.set_flag_1 = true;
+ arg.set_flag_8 = true;
+ arg.use_best_fit_alloc_mode = false;
+ arg.name = "TeraSZSWork";
+ arg.heap = mFixedHeap;
+ arg.heap2 = nullptr;
+ arg._6 = false;
+ arg.set_flag_10 = false;
+ if (mTeraSzsWorkArena->init(arg))
+ res::stubbedLogFunction();
+}
+
+void OverlayArenaSystem::createAudioArena() {
+ res::stubbedLogFunction();
+
+ if (mAudioArena)
+ return;
+
+ if (!mFixedHeap)
+ return;
+
+ mAudioArena = new (mFixedHeap, std::nothrow) OverlayArena;
+ if (!mAudioArena) {
+ mAudioArena = nullptr;
+ return;
+ }
+
+ OverlayArena::InitArg arg;
+ arg.size = 0x2e00000;
+ arg.set_flag_8 = true;
+ arg.use_best_fit_alloc_mode = false;
+ arg.name = "Audio(OverlayArena)";
+ arg.heap = mFixedHeap;
+ arg.heap2 = snd::SoundResource::instance()->getSoundDebugHeap();
+ arg.alignment = 0x1000;
+ if (mAudioArena->init(arg))
+ res::stubbedLogFunction();
+}
+
+void OverlayArenaSystem::createJpegHeap() {
+ res::stubbedLogFunction();
+
+ if (mJpegHeap)
+ return;
+
+ if (!mFixedHeap)
+ return;
+
+ mJpegHeap = sead::ExpHeap::tryCreate(0x900000, "JPEG", mFixedHeap, sizeof(void*),
+ sead::Heap::cHeapDirection_Forward, true);
+ if (mJpegHeap)
+ res::stubbedLogFunction();
+}
+
+void OverlayArenaSystem::createTeraWorkHeap() {
+ res::stubbedLogFunction();
+
+ if (tera::System::instance()) {
+ if (mTeraWorkHeap)
+ return;
+
+ mTeraWorkHeap = sead::ExpHeap::tryCreate(0, "TeraWork", mFixedHeap, sizeof(void*),
+ sead::Heap::cHeapDirection_Forward, false);
+ if (mTeraWorkHeap) {
+ tera::System::instance()->allocateApertureMapsCollectorImage(mTeraWorkHeap);
+ mTeraWorkHeap->adjust();
+ res::stubbedLogFunction();
+ }
+ } else {
+ res::stubbedLogFunction();
+ }
+}
+
+void OverlayArenaSystem::createPlacementTreeHeap() {
+ res::stubbedLogFunction();
+
+ if (mPlacementTreeHeap)
+ return;
+
+ mPlacementTreeHeap =
+ sead::ExpHeap::tryCreate(0x700000, "PlacementTree", mFixedHeap, sizeof(void*),
+ sead::Heap::cHeapDirection_Forward, false);
+ res::stubbedLogFunction();
+}
+
+void OverlayArenaSystem::createStubbed() {}
+
+void OverlayArenaSystem::createMovieHeap() {
+ res::stubbedLogFunction();
+ mMovieHeap = sead::ExpHeap::tryCreate(0x8c00000, "MovieHeap",
+ res::ResourceMgrTask::instance()->getSomeArena()->mHeap,
+ sizeof(void*), sead::Heap::cHeapDirection_Forward, false);
+ res::stubbedLogFunction();
+}
+
+} // namespace ksys
diff --git a/src/KingSystem/System/OverlayArenaSystem.h b/src/KingSystem/System/OverlayArenaSystem.h
new file mode 100644
index 00000000..46dc9b88
--- /dev/null
+++ b/src/KingSystem/System/OverlayArenaSystem.h
@@ -0,0 +1,102 @@
+#pragma once
+
+#include <heap/seadDisposer.h>
+#include <prim/seadDelegate.h>
+#include <prim/seadTypedBitFlag.h>
+#include <thread/seadAtomic.h>
+#include "KingSystem/Resource/resHandle.h"
+#include "KingSystem/System/OverlayArenaSystemS1.h"
+#include "KingSystem/System/OverlayArenaSystemS2.h"
+#include "KingSystem/Utils/Thread/Event.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace sead {
+class Heap;
+class SZSDecompressor;
+} // namespace sead
+
+namespace ksys {
+
+namespace util {
+class Task;
+class TaskThread;
+} // namespace util
+
+class OverlayArena;
+class SystemPauseMgr;
+
+// FIXME: incomplete
+class OverlayArenaSystem {
+ SEAD_SINGLETON_DISPOSER(OverlayArenaSystem)
+
+ OverlayArenaSystem();
+ virtual ~OverlayArenaSystem();
+
+public:
+ struct InitArg {
+ SystemPauseMgr* system_pause_mgr;
+ };
+
+ bool init(const InitArg& arg, sead::Heap* heap);
+
+ void getSzsDecompressor(sead::SZSDecompressor** decompressor) const;
+ OverlayArena* getArena() const;
+ OverlayArena* getTeraSzsWorkArena() const;
+ OverlayArena* getAudioArena() const;
+ OverlayArena* getUnknownArena() const;
+
+ void createTeraWorkHeap();
+ void createStubbed();
+ void createMovieHeap();
+
+private:
+ enum class Flag {
+ _1 = 0x1,
+ _2 = 0x2,
+ };
+
+ void createHeaps();
+ void destroyHeaps();
+
+ void createSzsDecompressor();
+ void createTexArcWorkHeap();
+ void createArena();
+ void createTeraSzsWorkArena();
+ void createAudioArena();
+ void createJpegHeap();
+ void createPlacementTreeHeap();
+
+ bool delegatedFunction();
+
+ sead::TypedBitFlag<Flag, u8> mFlags;
+ u32 _2c = 0;
+ sead::Heap* mFixedHeap = nullptr;
+ sead::Heap* mMovableMemoryHeap = nullptr;
+ sead::Heap* mGameDataWorkHeap = nullptr;
+ sead::Heap* mMovieHeap = nullptr;
+ sead::Heap* mPlacementTreeHeap = nullptr;
+ sead::Heap* mTeraWorkHeap = nullptr;
+ sead::Heap* mSzsDecompressorInstHeap = nullptr;
+ sead::Heap* mSzsHeap = nullptr;
+ sead::SZSDecompressor* mSzsDecompressor = nullptr;
+ sead::Heap* mTexArcWorkHeap = nullptr;
+ OverlayArena* mArena = nullptr;
+ OverlayArena* mTeraSzsWorkArena = nullptr;
+ OverlayArena* mAudioArena = nullptr;
+ OverlayArena* mUnknownArena = nullptr;
+ sead::Heap* mJpegHeap = nullptr;
+ SystemPauseMgr* mSystemPauseMgr = nullptr;
+ OverlayArenaSystemS1 mS1;
+ u32 _b8 = 0;
+ util::TaskThread* mPrepareThread = nullptr;
+ util::Task* mTask = nullptr;
+ sead::DelegateR<OverlayArenaSystem, bool> mDelegate;
+ OverlayArenaSystemS2 mS2;
+ sead::Atomic<u32> _130 = 0;
+ sead::Atomic<u32> _134 = 0;
+ res::Handle mResHandle;
+ util::Event mEvent;
+};
+KSYS_CHECK_SIZE_NX150(OverlayArenaSystem, 0x1c8);
+
+} // namespace ksys
diff --git a/src/KingSystem/System/OverlayArenaSystemS1.h b/src/KingSystem/System/OverlayArenaSystemS1.h
new file mode 100644
index 00000000..f2adce58
--- /dev/null
+++ b/src/KingSystem/System/OverlayArenaSystemS1.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys {
+
+// FIXME: incomplete
+// Unknown struct seen in OverlayArenaSystem.
+class OverlayArenaSystemS1 final {
+public:
+ OverlayArenaSystemS1();
+ virtual ~OverlayArenaSystemS1();
+
+ // TODO: figure out if this is the same interface as SystemPauseMgr.
+ // Both have the exact same number of virtual functions and some of the functions
+ // look somewhat similar (suspending threads, looping while waiting for their status to change).
+
+ virtual void init();
+ // Resume resource compaction
+ virtual void m3();
+ virtual void m4();
+ // Resume resource compaction + EventMgr
+ virtual void m5();
+ // Stop threads, clear cache, etc.
+ virtual void m6();
+ virtual bool m7();
+ virtual void m8();
+ virtual void m9();
+ // Does nothing
+ virtual void m10();
+ virtual bool m11();
+ virtual void m12();
+ virtual void m13();
+ // Does nothing
+ virtual void m14();
+};
+KSYS_CHECK_SIZE_NX150(OverlayArenaSystemS1, 0x8);
+
+} // namespace ksys
diff --git a/src/KingSystem/System/OverlayArenaSystemS2.h b/src/KingSystem/System/OverlayArenaSystemS2.h
new file mode 100644
index 00000000..2a43c72a
--- /dev/null
+++ b/src/KingSystem/System/OverlayArenaSystemS2.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <basis/seadTypes.h>
+#include <prim/seadDelegate.h>
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys {
+
+class OverlayArenaSystemS1;
+class SystemPauseMgr;
+
+// FIXME: incomplete
+class OverlayArenaSystemS2 {
+public:
+ struct InitArg {
+ OverlayArenaSystemS1* s1;
+ SystemPauseMgr* system_pause_mgr;
+ };
+
+ OverlayArenaSystemS2();
+
+ void init(const InitArg& arg);
+
+private:
+ u32 _0 = 0;
+ sead::Delegate1<OverlayArenaSystemS2, void*> mDelegate;
+ u32 _28 = 1;
+ void* _30 = nullptr;
+ void* _38 = nullptr;
+};
+KSYS_CHECK_SIZE_NX150(OverlayArenaSystemS2, 0x40);
+
+} // namespace ksys
diff --git a/src/KingSystem/System/StringBoard.h b/src/KingSystem/System/StringBoard.h
new file mode 100644
index 00000000..df275ab2
--- /dev/null
+++ b/src/KingSystem/System/StringBoard.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys {
+
+// Stubbed in release builds
+class StringBoard {
+public:
+ virtual ~StringBoard() = default;
+};
+KSYS_CHECK_SIZE_NX150(StringBoard, 0x8);
+
+} // namespace ksys
diff --git a/src/KingSystem/System/SystemPauseMgr.cpp b/src/KingSystem/System/SystemPauseMgr.cpp
new file mode 100644
index 00000000..ce8ddbdf
--- /dev/null
+++ b/src/KingSystem/System/SystemPauseMgr.cpp
@@ -0,0 +1,9 @@
+#include "KingSystem/System/SystemPauseMgr.h"
+
+namespace ksys {
+
+SystemPauseMgr::SystemPauseMgr() = default;
+
+SystemPauseMgr::~SystemPauseMgr() = default;
+
+} // namespace ksys
diff --git a/src/KingSystem/System/SystemPauseMgr.h b/src/KingSystem/System/SystemPauseMgr.h
new file mode 100644
index 00000000..43ca4efc
--- /dev/null
+++ b/src/KingSystem/System/SystemPauseMgr.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys {
+
+class SystemPauseMgr {
+public:
+ SystemPauseMgr();
+ virtual ~SystemPauseMgr();
+
+ virtual void m2();
+ virtual void m3();
+ virtual void m4();
+ virtual void m5();
+ virtual void m6();
+ virtual bool m7();
+ virtual void m8();
+ virtual void m9();
+ virtual void m10();
+ virtual bool m11();
+ virtual void m12();
+ virtual void m13();
+ virtual void m14();
+
+ bool get8() const { return _8; }
+
+private:
+ bool _8 = true;
+};
+KSYS_CHECK_SIZE_NX150(SystemPauseMgr, 0x10);
+
+} // namespace ksys
diff --git a/src/KingSystem/Terrain/teraSystem.h b/src/KingSystem/Terrain/teraSystem.h
index a3aab5d2..e940fe00 100644
--- a/src/KingSystem/Terrain/teraSystem.h
+++ b/src/KingSystem/Terrain/teraSystem.h
@@ -1,5 +1,9 @@
#pragma once
+namespace sead {
+class Heap;
+}
+
namespace ksys::tera {
// TODO:
@@ -23,6 +27,9 @@ class Scene {
void exportFileBinary();
};
class System {
+public:
+ static System* instance();
+ void allocateApertureMapsCollectorImage(sead::Heap* heap);
void loadScene();
};
class Water {
diff --git a/src/KingSystem/Utils/Thread/Task.h b/src/KingSystem/Utils/Thread/Task.h
index df54db8e..3f076d0b 100644
--- a/src/KingSystem/Utils/Thread/Task.h
+++ b/src/KingSystem/Utils/Thread/Task.h
@@ -131,7 +131,7 @@ protected:
friend class TaskQueueBase;
friend class TaskThread;
- enum class Flag {
+ enum class Flag : u8 {
DeleteDelegate = 0x1,
DoNotDeleteDelegate = 0x2,
NeedsToSignalEvent = 0x4,
@@ -173,7 +173,7 @@ protected:
}
u8 mLaneId = 0;
- sead::TypedBitFlag<Flag, u8> mFlags = Flag::DoNotDeleteDelegate;
+ sead::TypedBitFlag<Flag> mFlags = Flag::DoNotDeleteDelegate;
bool mDelegateResult = false;
TaskDelegate* mDelegate = nullptr;
void* mUserData = nullptr;
diff --git a/src/KingSystem/Utils/Thread/TaskQueueBase.cpp b/src/KingSystem/Utils/Thread/TaskQueueBase.cpp
index 430fdbf2..b6303ccb 100644
--- a/src/KingSystem/Utils/Thread/TaskQueueBase.cpp
+++ b/src/KingSystem/Utils/Thread/TaskQueueBase.cpp
@@ -57,7 +57,6 @@ void TaskQueueBase::clear() {
mQueueEmptyEvent.wait();
}
-// NON_MATCHING: swapped operands for a csel. The arg.set_flag1 check looks suspicious.
bool TaskQueueBase::init(const InitArg& arg) {
if (arg.max_num_threads == 0)
return false;
@@ -65,10 +64,7 @@ bool TaskQueueBase::init(const InitArg& arg) {
if (!mThreads.tryAllocBuffer(arg.max_num_threads, arg.heap))
return false;
- if (!arg.enable_locks)
- mFlags.reset(Flag::Lock);
- else
- mFlags.set(Flag::Lock);
+ mFlags.change(Flag::Lock, arg.enable_locks);
if (arg.num_lanes <= 0 || arg.num_lanes > 0x100)
return false;
diff --git a/src/KingSystem/Utils/Thread/TaskQueueBase.h b/src/KingSystem/Utils/Thread/TaskQueueBase.h
index 3d4b44cf..bdc7503f 100644
--- a/src/KingSystem/Utils/Thread/TaskQueueBase.h
+++ b/src/KingSystem/Utils/Thread/TaskQueueBase.h
@@ -88,7 +88,7 @@ public:
void fetchTask(Task** out_task);
protected:
- enum class Flag {
+ enum class Flag : u8 {
Lock = 0x1,
PreventThreadPoolChanges = 0x2,
};
@@ -145,7 +145,7 @@ protected:
void notifyThreadsForNewTasks();
- sead::TypedBitFlag<Flag, u8> mFlags;
+ sead::TypedBitFlag<Flag> mFlags;
sead::OffsetList<Task> mActiveTasks;
sead::Buffer<Lane> mLanes;
Event mQueueEmptyEvent;