diff options
| author | Pistonight <pistonknight@outlook.com> | 2024-08-07 18:28:23 -0700 |
|---|---|---|
| committer | Pistonight <pistonknight@outlook.com> | 2024-10-14 23:18:35 -0700 |
| commit | c4e0a55dd90c8eda10577b20db76f831edef5f76 (patch) | |
| tree | 473be9619210e9f6b998f3adaeb1b48b66a20999 /src/KingSystem/System/UI | |
| parent | 0f88ba6f001df11b3f888cbbf3ecb17e7ef2872c (diff) | |
LayoutResourceMgr functions + update NintendoSDK.
Diffstat (limited to 'src/KingSystem/System/UI')
| -rw-r--r-- | src/KingSystem/System/UI/ArcResource.h | 33 | ||||
| -rw-r--r-- | src/KingSystem/System/UI/ArcResourceMgr.h | 34 | ||||
| -rw-r--r-- | src/KingSystem/System/UI/LayoutResourceMgr.cpp | 268 | ||||
| -rw-r--r-- | src/KingSystem/System/UI/LayoutResourceMgr.h | 97 |
4 files changed, 432 insertions, 0 deletions
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 |
