summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/System/CMakeLists.txt5
-rw-r--r--src/KingSystem/System/UI/ArcResource.h33
-rw-r--r--src/KingSystem/System/UI/ArcResourceMgr.h34
-rw-r--r--src/KingSystem/System/UI/LayoutResourceMgr.cpp268
-rw-r--r--src/KingSystem/System/UI/LayoutResourceMgr.h97
-rw-r--r--src/KingSystem/ksys.cpp19
-rw-r--r--src/KingSystem/ksys.h7
7 files changed, 463 insertions, 0 deletions
diff --git a/src/KingSystem/System/CMakeLists.txt b/src/KingSystem/System/CMakeLists.txt
index 4f907b81..ee6b48f0 100644
--- a/src/KingSystem/System/CMakeLists.txt
+++ b/src/KingSystem/System/CMakeLists.txt
@@ -1,4 +1,9 @@
target_sources(uking PRIVATE
+ UI/ArcResource.h
+ UI/ArcResourceMgr.h
+ UI/LayoutResourceMgr.cpp
+ UI/LayoutResourceMgr.h
+
Account.cpp
Account.h
AutoDim.cpp
diff --git a/src/KingSystem/System/UI/ArcResource.h b/src/KingSystem/System/UI/ArcResource.h
new file mode 100644
index 00000000..1bc55f07
--- /dev/null
+++ b/src/KingSystem/System/UI/ArcResource.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <heap/seadDisposer.h>
+#include <prim/seadSafeString.h>
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys {
+namespace res {
+class Handle;
+}
+namespace ui {
+
+class ArcResourceMgr;
+
+class ArcResource : public sead::IDisposer {
+public:
+ ArcResource() = default;
+
+ void init(ArcResourceMgr* mgr, const sead::SafeString& name, u8* data, res::Handle* handle);
+
+private:
+ void* _20;
+ void* _28;
+ ArcResourceMgr* mArcResourceMgr;
+ sead::FixedSafeString<0x40> mName;
+ u8* mData;
+ void* mFile;
+ res::Handle* mHandle;
+};
+KSYS_CHECK_SIZE_NX150(ArcResource, 0xA8);
+
+} // namespace ui
+} // namespace ksys
diff --git a/src/KingSystem/System/UI/ArcResourceMgr.h b/src/KingSystem/System/UI/ArcResourceMgr.h
new file mode 100644
index 00000000..1882e3bf
--- /dev/null
+++ b/src/KingSystem/System/UI/ArcResourceMgr.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <container/seadTList.h>
+#include <prim/seadSafeString.h>
+#include "KingSystem/System/UI/ArcResource.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace sead {
+class ExpHeap;
+}
+
+namespace ksys::ui {
+
+class ArcResourceMgr {
+public:
+ ArcResourceMgr() = default;
+ virtual ~ArcResourceMgr();
+
+ virtual void sub_10();
+ virtual void loadArchive(sead::Heap* heap, const sead::SafeString& path);
+ virtual void sub_20();
+ virtual void sub_28();
+ virtual void addArchive(ArcResource* archive);
+
+private:
+ // TODO: fields
+ /* sead::TList */
+ char list[0x10];
+ int _18 = 0;
+ int _1c = 0x20;
+};
+KSYS_CHECK_SIZE_NX150(ArcResourceMgr, 0x20);
+
+} // namespace ksys::ui
diff --git a/src/KingSystem/System/UI/LayoutResourceMgr.cpp b/src/KingSystem/System/UI/LayoutResourceMgr.cpp
new file mode 100644
index 00000000..fa1d9dc2
--- /dev/null
+++ b/src/KingSystem/System/UI/LayoutResourceMgr.cpp
@@ -0,0 +1,268 @@
+#include <devenv/seadEnvUtil.h>
+#include <nn/pl.h>
+#include <prim/seadScopedLock.h>
+
+#include "KingSystem/Resource/resLoadRequest.h"
+#include "KingSystem/System/StarterPackMgr.h"
+#include "KingSystem/System/UI/ArcResource.h"
+#include "KingSystem/System/UI/LayoutResourceMgr.h"
+
+namespace ksys::ui {
+
+SEAD_SINGLETON_DISPOSER_IMPL(LayoutResourceMgr)
+
+void LayoutResourceMgr::init(sead::Heap* heap) {
+ mMsgPackHandle = new (heap) res::Handle;
+ mLangFontHandle = new (heap) res::Handle;
+ mVersionHandle = new (heap) res::Handle;
+
+ int count;
+ switch (sead::EnvUtil::getRegionLanguage().value()) {
+ case sead::RegionLanguageID::KRko:
+ case sead::RegionLanguageID::CNzh:
+ case sead::RegionLanguageID::TWzh:
+ count = cExtraLangFontCount;
+ break;
+ default:
+ count = 0;
+ break;
+ }
+ for (int i = 0; i < count; i++) {
+ mExtraLangFontHandles.pushBack(new (heap) res::Handle);
+ }
+ if (count > 0) {
+ mZeldaGlyphHandle = new (heap) res::Handle;
+ }
+}
+
+u8* LayoutResourceMgr::loadMsgPack(u32* size) {
+ mMsgPackHandle->resetUnitFlag20000IfSuccess();
+ mMsgPackHandle->unload();
+
+ res::LoadRequest req;
+ req.mRequester = "LayoutResourceMgr";
+ req._22 = true;
+ req._21 = true;
+ req.mLoadDataAlignment = 0x80;
+ req._26 = false;
+ req.mPackHandle = StarterPackMgr::instance()->getBootupLangPack();
+
+ sead::FixedSafeString<0x20> path;
+ path.format("Message/Msg_%s.product.sarc", sead::EnvUtil::getRegionLanguage().text());
+
+ res::Handle::Status status;
+ auto* resource =
+ sead::DynamicCast<sead::DirectResource>(mMsgPackHandle->load(path, &req, &status));
+
+ *size = resource->getRawSize();
+ return resource->getRawData();
+}
+
+void LayoutResourceMgr::loadLangFont(sead::Heap* heap) {
+ mLangFontHandle->resetUnitFlag20000IfSuccess();
+ mLangFontHandle->unload();
+ mLangFontResource = nullptr;
+
+ res::LoadRequest req;
+ req.mRequester = "LayoutResourceMgr";
+ req._22 = true;
+ req.mLoadDataAlignment = 0x1000;
+ req._26 = false;
+
+ sead::FixedSafeString<0x20> path;
+ path.format("Font/Font_%s.bfarc", sead::EnvUtil::getRegion().text());
+
+ mLangFontHandle->requestLoad(path, &req, nullptr);
+}
+
+constexpr const char* sExtraLangFontFiles[LayoutResourceMgr::cExtraLangCount *
+ LayoutResourceMgr::cExtraLangFontCount] = {
+ "AsiaKCUBE-R", "AsiaKDREAM2R", "AsiaKDREAM4R", "AsiaKDREAM7R", "DFP_GBZY9", "DFP_GB_H3",
+ "DFP_GB_H5", "DFHEI5A", "DFT_ZY9", "DFT_B3", "DFT_B5", "DFT_B9"};
+
+void LayoutResourceMgr::loadExtraLangFonts(sead::Heap* heap) {
+ sead::RegionLanguageID lang_id = sead::EnvUtil::getRegionLanguage();
+ auto* fonts = sExtraLangFontFiles;
+ for (int i = 0; i <= cExtraLangCount; i++) {
+ if (lang_id.value() == sead::RegionLanguageID::KRko + i) {
+ break;
+ }
+ if (i == cExtraLangCount - 1) {
+ return;
+ }
+ fonts += cExtraLangFontCount;
+ }
+
+ res::LoadRequest req;
+ req.mRequester = "ui::LayoutResourceMgr";
+ req._26 = false;
+
+ res::Handle::Status status = res::Handle::Status::NoFile;
+ for (int i = 0; i < cExtraLangFontCount; ++i) {
+ auto* handle = mExtraLangFontHandles[i];
+ sead::FixedSafeString<0x20> path;
+#ifdef MATCHING_HACK_NX_CLANG
+ asm("");
+#endif
+ path.format("Font/%s.bfttf", fonts[i]);
+ handle->requestLoad(path, &req, &status);
+ }
+
+ mZeldaGlyphHandle->requestLoad("Font/ZeldaGlyphs-v2-Deco.bfotf", &req, &status);
+ nn::pl::RequestSharedFontLoad(nn::pl::SharedFontType::STANDARD);
+}
+
+bool LayoutResourceMgr::checkLangFontReady() {
+ if (mLangFontResource) {
+ return true;
+ }
+ if (!mLangFontHandle->isReady()) {
+ return false;
+ }
+ mLangFontResource = sead::DynamicCast<sead::DirectResource>(mLangFontHandle->getResource());
+ return true;
+}
+
+bool LayoutResourceMgr::checkExtraLangFontsReady() const {
+ switch (sead::EnvUtil::getRegionLanguage().value()) {
+ case sead::RegionLanguageID::KRko:
+ case sead::RegionLanguageID::CNzh:
+ case sead::RegionLanguageID::TWzh:
+ break;
+ default:
+ return true;
+ }
+ for (const auto& handle : mExtraLangFontHandles) {
+ if (!handle.isReady()) {
+ return false;
+ }
+ }
+ if (!mZeldaGlyphHandle || mZeldaGlyphHandle->isReady()) {
+ return nn::pl::GetSharedFontLoadState(nn::pl::SharedFontType::STANDARD) ==
+ nn::pl::LoadState::LOADED;
+ }
+ return false;
+}
+
+void LayoutResourceMgr::loadVersion() {
+ res::LoadRequest req;
+ req.mRequester = "LayoutResourceMgr";
+ req._26 = false;
+
+ mVersionHandle->requestLoad("System/Version.txt", &req, nullptr);
+}
+
+bool LayoutResourceMgr::checkVersionReady() {
+ if (!mVersionHandle) {
+ return true;
+ }
+ if (mVersionHandle->isReady()) {
+ auto* resource = sead::DynamicCast<sead::DirectResource>(mVersionHandle->getResource());
+ instance()->mVersionString.copy(reinterpret_cast<const char*>(resource->getRawData()),
+ static_cast<s32>(resource->getRawSize()));
+ delete mVersionHandle;
+ mVersionHandle = nullptr;
+ return true;
+ }
+ return false;
+}
+
+void LayoutResourceMgr::loadCommonLayoutArchive(sead::ExpHeap* heap) {
+ mArcResourceMgr->loadArchive(heap, "Layout/Common.sblarc");
+}
+
+void LayoutResourceMgr::loadTitleLayout(sead::Heap* heap) {
+ mTitleLayout.allocate(heap);
+
+ res::LoadRequest req;
+ req.mRequester = "ui::LayoutResourceMgr";
+ req.mLoadDataAlignment = 0x1000;
+ req._22 = false;
+ req._26 = false;
+ req._c = 2;
+
+ res::Handle::Status status = res::Handle::Status::NoFile;
+ mTitleLayout.getHandle()->requestLoad("Layout/Title.blarc", &req, &status);
+}
+
+bool LayoutResourceMgr::loadTitleLayoutResource() {
+ return loadArcResource(mTitleLayout, "Title");
+}
+
+void LayoutResourceMgr::unloadTitleLayout() {
+ mTitleLayout.deallocate();
+}
+
+bool LayoutResourceMgr::loadHorseLayout(sead::Heap* heap) {
+ const auto lock = sead::makeScopedLock(mCriticalSection);
+
+ if (mHorseLayoutLoadCount++) {
+ return false;
+ }
+
+ mHorseLayout.allocate(heap);
+
+ res::LoadRequest req;
+ req.mRequester = "ui::LayoutResourceMgr";
+ req.mLoadDataAlignment = 0x1000;
+ req._22 = false;
+ req._26 = true;
+ req._c = 2;
+
+ res::Handle::Status status = res::Handle::Status::NoFile;
+ mHorseLayout.getHandle()->requestLoad("Layout/Horse.blarc", &req, &status);
+
+ return true;
+}
+
+bool LayoutResourceMgr::loadHorseLayoutResource() {
+ const auto lock = sead::makeScopedLock(mCriticalSection);
+ return loadArcResource(mHorseLayout, "Horse");
+}
+
+bool LayoutResourceMgr::hasHorseLayoutLoadFailure() const {
+ if (mHorseLayout.getHandle()) {
+ if (mHorseLayout.getHandle()->isReady() && !mHorseLayout.getHandle()->isSuccess()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LayoutResourceMgr::unloadHorseLayout() {
+ const auto lock = sead::makeScopedLock(mCriticalSection);
+ int old_count = mHorseLayoutLoadCount--;
+
+ if (mHorseLayoutLoadCount == 0) {
+ mHorseLayout.deallocate();
+ return true;
+ }
+
+ return old_count < 2;
+}
+
+bool LayoutResourceMgr::loadArcResource(Archive& archive, const char* name) {
+ if (archive.getResource()) {
+ return true;
+ }
+ if (!archive.getHandle()->isReady()) {
+ return false;
+ }
+ if (archive.getHandle()->isSuccess()) {
+ auto* resource =
+ sead::DynamicCast<sead::DirectResource>(archive.getHandle()->getResource());
+ if (resource) {
+ auto* arc_resource = reinterpret_cast<ArcResource*>(archive.mResourceStorage);
+ arc_resource->init(mArcResourceMgr, name, resource->getRawData(), archive.mHandle);
+ archive.mResource = arc_resource;
+ mArcResourceMgr->addArchive(archive.getResource());
+ }
+ }
+ return true;
+}
+
+void LayoutResourceMgr::unloadA8() {
+ _a8.deallocate();
+}
+
+} // namespace ksys::ui
diff --git a/src/KingSystem/System/UI/LayoutResourceMgr.h b/src/KingSystem/System/UI/LayoutResourceMgr.h
new file mode 100644
index 00000000..64378496
--- /dev/null
+++ b/src/KingSystem/System/UI/LayoutResourceMgr.h
@@ -0,0 +1,97 @@
+#pragma once
+
+#include <container/seadObjArray.h>
+#include <heap/seadDisposer.h>
+#include <hostio/seadHostIONode.h>
+#include <prim/seadSafeString.h>
+#include <thread/seadCriticalSection.h>
+#include "KingSystem/Resource/resHandle.h"
+#include "KingSystem/System/UI/ArcResource.h"
+#include "KingSystem/System/UI/ArcResourceMgr.h"
+#include "KingSystem/Utils/Types.h"
+
+namespace ksys::ui {
+
+class LayoutResourceMgr final : public sead::hostio::Node {
+ SEAD_SINGLETON_DISPOSER(LayoutResourceMgr)
+ LayoutResourceMgr() = default;
+ ~LayoutResourceMgr() = default;
+
+public:
+ static constexpr int cExtraLangFontCount = 4;
+ static constexpr int cExtraLangCount = 3;
+
+private:
+ class Archive {
+ friend class LayoutResourceMgr;
+
+ public:
+ void allocate(sead::Heap* heap) {
+ mHandle = new (heap) res::Handle;
+ mResourceStorage = new (heap) u8[sizeof(ArcResource)];
+ }
+ void deallocate() {
+ if (mResource) {
+ delete mResource;
+ mResource = nullptr;
+ } else {
+ delete mHandle;
+ delete[] mResourceStorage;
+ }
+ mHandle = nullptr;
+ mResourceStorage = nullptr;
+ }
+
+ res::Handle* getHandle() { return mHandle; }
+ const res::Handle* getHandle() const { return mHandle; }
+ ArcResource* getResource() { return mResource; }
+ const ArcResource* getResource() const { return mResource; }
+
+ private:
+ res::Handle* mHandle = nullptr;
+ ArcResource* mResource = nullptr;
+ u8* mResourceStorage = nullptr;
+ };
+
+public:
+ void init(sead::Heap* heap);
+ u8* loadMsgPack(u32* size);
+ void loadLangFont(sead::Heap* heap);
+ void loadExtraLangFonts(sead::Heap* heap);
+ bool checkLangFontReady();
+ bool checkExtraLangFontsReady() const;
+ void loadVersion();
+ bool checkVersionReady();
+ void loadCommonLayoutArchive(sead::ExpHeap* heap);
+ void loadTitleLayout(sead::Heap* heap);
+ bool loadTitleLayoutResource();
+ void unloadTitleLayout();
+ bool loadHorseLayout(sead::Heap* heap);
+ bool loadHorseLayoutResource();
+ bool hasHorseLayoutLoadFailure() const;
+ bool unloadHorseLayout();
+ void unloadA8();
+ void doSomethingWithFontTextureCache(void* texture_cache);
+
+ bool loadArcResource(Archive& archive, const char* name);
+
+private:
+ res::Handle* mMsgPackHandle = nullptr;
+ res::Handle* mLangFontHandle = nullptr;
+ res::Handle* mVersionHandle = nullptr;
+ sead::FixedPtrArray<res::Handle, 8> mExtraLangFontHandles;
+ res::Handle* mZeldaGlyphHandle = nullptr;
+ ArcResourceMgr* mArcResourceMgr = nullptr;
+ sead::DirectResource* mLangFontResource = nullptr;
+ Archive _a8;
+ Archive mTitleLayout;
+ Archive mHorseLayout;
+ u16 mMaxDefArtLen = 0;
+ u16 mMaxIndefArtLen = 0;
+ sead::FixedSafeString<16> mVersionString;
+ int mHorseLayoutLoadCount = 0;
+ sead::CriticalSection mCriticalSection;
+};
+KSYS_CHECK_SIZE_NX150(LayoutResourceMgr, 0x168);
+
+} // namespace ksys::ui
diff --git a/src/KingSystem/ksys.cpp b/src/KingSystem/ksys.cpp
index e370b003..c760838a 100644
--- a/src/KingSystem/ksys.cpp
+++ b/src/KingSystem/ksys.cpp
@@ -4,7 +4,9 @@
#include "KingSystem/ActorSystem/actBaseProcCreateTaskSelector.h"
#include "KingSystem/ActorSystem/actBaseProcInitializer.h"
#include "KingSystem/ActorSystem/actBaseProcMgr.h"
+#include "KingSystem/System/BasicProfiler.h"
#include "KingSystem/System/HavokWorkerMgr.h"
+#include "KingSystem/System/UI/LayoutResourceMgr.h"
namespace ksys {
@@ -29,4 +31,21 @@ void initBaseProcMgr(sead::Heap* heap) {
act::BaseProcMgr::sConstant4 = u32(act::JobType::Calc4);
}
+void preInitializeApp(const InitParams& params) {
+ ksys::BasicProfiler::Scope profiler_scope("ksys::PreInitializeApp");
+
+ // TODO - other parts
+
+ {
+ ksys::BasicProfiler::Scope profiler_scope("RequestFontLoad");
+ // TODO: FontMgr::createInstance()
+ ui::LayoutResourceMgr::createInstance(params.king_sys_heap);
+ ui::LayoutResourceMgr::instance()->init(params.king_sys_heap);
+ ui::LayoutResourceMgr::instance()->loadLangFont(params.king_sys_heap);
+ ui::LayoutResourceMgr::instance()->loadExtraLangFonts(params.king_sys_heap);
+ }
+
+ // TODO - other parts
+}
+
} // namespace ksys
diff --git a/src/KingSystem/ksys.h b/src/KingSystem/ksys.h
index 4775ea4f..46c17c82 100644
--- a/src/KingSystem/ksys.h
+++ b/src/KingSystem/ksys.h
@@ -6,6 +6,10 @@ class Heap;
namespace ksys {
+struct InitParams {
+ sead::Heap* king_sys_heap;
+};
+
// 0x0000007100f3a4e4
bool isGameOver();
// 0x0000007100f3a4f0
@@ -13,4 +17,7 @@ void setIsGameOver(bool is_game_over);
void initBaseProcMgr(sead::Heap* heap);
+// 0x0000007100f3a8d8
+void preInitializeApp(const InitParams& params);
+
} // namespace ksys