From 04e53199d2d4d872b83110224fffab1b5faac77c Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sun, 5 Apr 2026 03:52:46 -0400 Subject: [PATCH] RPSysFontManager WIP --- config/RSPE01_01/symbols.txt | 32 ++--- include/Pack/RPSystem/RPSysFontManager.h | 43 +++++-- include/Pack/RPSystem/RPSysResourceManager.h | 4 + include/nw4r/ut/ut_ResFontBase.h | 2 +- include/nw4r/ut/ut_RomFont.h | 2 +- src/Pack/RPSystem/RPSysFontManager.cpp | 124 +++++++++++++++++++ 6 files changed, 177 insertions(+), 30 deletions(-) create mode 100644 src/Pack/RPSystem/RPSysFontManager.cpp diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index bbcedb197..dc23e8e4f 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -6182,7 +6182,7 @@ VFipdm_open_partition = .text:0x8014FC90; // type:function size:0x5C scope:globa VFipdm_close_partition = .text:0x8014FCEC; // type:function size:0x40 scope:global VFiPFCACHE_InitPageList = .text:0x8014FD2C; // type:function size:0x280 scope:global VFiPFCACHE_SearchForPage = .text:0x8014FFAC; // type:function size:0xD8 scope:global -VFiPFCACHE_SearchForFreePage = .text:0x80150084; // type:function size:0x8C scope:global +VFiPFCACHE_SearchForFreePage = .text:0x80150084; // type:function size:0x8C scope:local VFiPFCACHE_FlushPageIfNeeded = .text:0x80150110; // type:function size:0x100 scope:global VFiPFCACHE_DoAllocatePage = .text:0x80150210; // type:function size:0x278 scope:global VFiPFCACHE_DoReadPage = .text:0x80150488; // type:function size:0x20C scope:global @@ -6392,10 +6392,10 @@ VFiPFSYS_GetCurrentContextID = .text:0x80162510; // type:function size:0x10 scop VFiPFSYS_TimeStamp = .text:0x80162520; // type:function size:0x64 scope:global VFIsAvailable = .text:0x80162584; // type:function size:0x14 scope:global VFInitEx = .text:0x80162598; // type:function size:0xC0 scope:global -VF_activate_drive_common = .text:0x80162658; // type:function size:0xF4 scope:global +VF_activate_drive_common = .text:0x80162658; // type:function size:0xF4 scope:local VFMountDriveNANDFlashEx = .text:0x8016274C; // type:function size:0x18C scope:global VFUnmountDrive = .text:0x801628D8; // type:function size:0xDC scope:global -VF_path2handleidx = .text:0x801629B4; // type:function size:0xDC scope:global +VF_path2handleidx = .text:0x801629B4; // type:function size:0xDC scope:local VFOpenFile = .text:0x80162A90; // type:function size:0xDC scope:global VFCloseFile = .text:0x80162B6C; // type:function size:0x6C scope:global VFSeekFile = .text:0x80162BD8; // type:function size:0x8C scope:global @@ -7174,10 +7174,10 @@ getHandPrimary__18RPSportsPlayerDataCFQ218RPSportsPlayerData6ESport = .text:0x80 reset__18RPSportsPlayerDataFv = .text:0x8018B994; // type:function size:0x30C __ct__18RPSportsPlayerDataFv = .text:0x8018BCA0; // type:function size:0x3C GetResFontData__16RPSysFontManagerCFPCc = .text:0x8018BCDC; // type:function size:0x88 -fn_8018BD64 = .text:0x8018BD64; // type:function size:0xAC -fn_8018BE10 = .text:0x8018BE10; // type:function size:0x54 -fn_8018BE64 = .text:0x8018BE64; // type:function size:0x40 -fn_8018BEA4 = .text:0x8018BEA4; // type:function size:0xB0 +LoadResFonts__16RPSysFontManagerFv = .text:0x8018BD64; // type:function size:0xAC +LoadRomFont__16RPSysFontManagerFv = .text:0x8018BE10; // type:function size:0x54 +__dt__16RPSysFontManagerFv = .text:0x8018BE64; // type:function size:0x40 +CreateInstance__16RPSysFontManagerFv = .text:0x8018BEA4; // type:function size:0xB0 getSaveFileSize__13RPSysSaveDataFv = .text:0x8018BF54; // type:function size:0x8 write__13RPSysSaveDataCFRQ23EGG9RamStreamPCv = .text:0x8018BF5C; // type:function size:0x184 read__13RPSysSaveDataFRQ23EGG9RamStreamPCv = .text:0x8018C0E0; // type:function size:0x24C @@ -14934,7 +14934,7 @@ __DVDErrorMessage = .rodata:0x8037CAD0; // type:object size:0x1C scope:global DAYS_OF_MONTH = .rodata:0x8037CB30; // type:object size:0xC scope:global DAYS_OF_YEAR = .rodata:0x8037CB40; // type:object size:0x18 scope:global VFipf_valid_fn_char = .rodata:0x8037CB58; // type:object size:0x60 scope:global -fat_special_values = .rodata:0x8037CBB8; // type:object size:0x40 +fat_special_values = .rodata:0x8037CBB8; // type:object size:0x3C cp932_to_unicode = .rodata:0x8037CBF8; // type:object size:0x4278 scope:global data:2byte noreloc l_nand_func = .rodata:0x80380E70; // type:object size:0x20 scope:global scCoordinate = .rodata:0x80380E90; // type:object size:0x10 scope:local data:4byte @@ -15086,7 +15086,7 @@ lbl_803829EB = .rodata:0x803829EB; // type:object size:0x10 data:string lbl_803829FB = .rodata:0x803829FB; // type:object size:0x35 @7451 = .rodata:0x80382A30; // type:object size:0x10 scope:local data:4byte @7468 = .rodata:0x80382A40; // type:object size:0x10 scope:local data:4byte -lbl_80382A50 = .rodata:0x80382A50; // type:object size:0x1C +sIsNeedResFont__16RPSysFontManager = .rodata:0x80382A50; // type:object size:0x1C lbl_80382A6C = .rodata:0x80382A6C; // type:object size:0x17 data:string lbl_80382A83 = .rodata:0x80382A83; // type:object size:0x18 data:string lbl_80382A9B = .rodata:0x80382A9B; // type:object size:0x18 data:string @@ -18591,8 +18591,8 @@ lbl_803B98A8 = .data:0x803B98A8; // type:object size:0x60 jumptable_803B9908 = .data:0x803B9908; // type:object size:0x20 scope:local lbl_803B9928 = .data:0x803B9928; // type:object size:0x10 __vt__16RPSysSaveDataMgr = .data:0x803B9938; // type:object size:0x14 -lbl_803B9950 = .data:0x803B9950; // type:object size:0x1C -lbl_803B996C = .data:0x803B996C; // type:object size:0xC +RES_FONT_NAMES__16RPSysFontManager = .data:0x803B9950; // type:object size:0x1C +__vt__16RPSysFontManager = .data:0x803B996C; // type:object size:0xC lbl_803B9978 = .data:0x803B9978; // type:object size:0xC lbl_803B9988 = .data:0x803B9988; // type:object size:0xC __vt__18IRPSysHostIOSocket = .data:0x803B9998; // type:object size:0x14 @@ -19848,9 +19848,9 @@ nwc24TimeCommonResult = .bss:0x8047A8A0; // type:object size:0x20 scope:local ShutdownFuncInfo = .bss:0x8047A8C0; // type:object size:0x10 scope:local data:4byte shtBuffer$1986 = .bss:0x8047A8E0; // type:object size:0x20 scope:local data:4byte shtResult$1987 = .bss:0x8047A900; // type:object size:0x20 scope:local -VFipdm_disk_set = .bss:0x8047A920; // type:object size:0xB68 data:2byte +VFipdm_disk_set = .bss:0x8047A920; // type:object size:0xB64 data:2byte VFipf_vol_set = .bss:0x8047B488; // type:object size:0x27FB8 data:4byte -l_Mutex = .bss:0x804A3440; // type:object size:0x18 scope:global +l_Mutex = .bss:0x804A3440; // type:object size:0x18 scope:local l_vfsys_dev_table = .bss:0x804A3458; // type:object size:0x68 scope:global data:4byte l_dev_init_info_table = .bss:0x804A34C0; // type:object size:0xD0 scope:global l_tmpWName = .bss:0x804A3590; // type:object size:0x10 data:2byte @@ -21851,9 +21851,9 @@ NWC24iIsRequestPending = .sbss:0x804BF460; // type:object size:0x4 scope:local d nwc24ShtRetryRest = .sbss:0x804BF468; // type:object size:0x4 scope:local data:4byte shuttingdown$1993 = .sbss:0x804BF46C; // type:object size:0x4 scope:local data:4byte result$1994 = .sbss:0x804BF470; // type:object size:0x4 scope:local data:4byte -VFipf_sys_set = .sbss:0x804BF478; // type:object size:0x8 data:4byte -l_vf_init = .sbss:0x804BF480; // type:object size:0x4 scope:global data:4byte -l_InitedMutex = .sbss:0x804BF484; // type:object size:0x4 scope:global data:4byte +VFipf_sys_set = .sbss:0x804BF478; // type:object size:0x4 scope:local data:4byte +l_vf_init = .sbss:0x804BF480; // type:object size:0x4 scope:local data:4byte +l_InitedMutex = .sbss:0x804BF484; // type:object size:0x4 scope:local data:4byte l_vfsys_vol_max = .sbss:0x804BF488; // type:object size:0x4 scope:global data:4byte l_vfsys_last_err = .sbss:0x804BF48C; // type:object size:0x4 scope:global data:4byte l_vfsys_exp_heap_handle = .sbss:0x804BF490; // type:object size:0x4 scope:global data:4byte diff --git a/include/Pack/RPSystem/RPSysFontManager.h b/include/Pack/RPSystem/RPSysFontManager.h index a87bfbe0c..5de0c20ca 100644 --- a/include/Pack/RPSystem/RPSysFontManager.h +++ b/include/Pack/RPSystem/RPSysFontManager.h @@ -41,21 +41,31 @@ class RPSysFontManager { public: /** - * @brief Sets up the ROM font + * @brief Loads the ROM font provided by the system */ void LoadRomFont(); + /** - * @brief Sets up all resource fonts required by this pack + * @brief Loads all resource fonts required by this pack */ void LoadResFonts(); /** - * @brief Gets resource font data by name + * @brief Gets the index of the specified resource font + * + * @param pName Font name + */ + u8 GetResFontIndex(const char* pName) const; + + /** + * @brief Gets the data of the specified resource font + * + * @param pName Font name */ - void* GetResFontData(const char* name) const; + void* GetResFontData(const char* pName) const; /** - * @brief Accesses the ROM font + * @brief Accesses the ROM font provided by the system */ nw4r::ut::RomFont* GetRomFont() const { return mpRomFont; @@ -66,22 +76,31 @@ class RPSysFontManager { * * @param idx Font index */ - nw4r::ut::ResFont* GetResFont(int idx) const { + nw4r::ut::ResFont* GetResFont(u8 idx) const { return mpResFonts[idx]; } private: - //! Resource font filenames - static const char* sResFontNames[ResFontType_Max]; - //! Table which marks the resource fonts needed by this pack - static BOOL sIsNeedResFont[ResFontType_Max]; + /** + * @brief Loads the specified resource font from the provided archive + * + * @param idx Font index + * @param pArchive Font archive + */ + void LoadResFont(u8 idx, EGG::Archive* pArchive); + +private: + //! Font resource filenames + static const char* RES_FONT_NAMES[ResFontType_Max]; + //! Whether each font resource is required by this pack + static const BOOL sIsNeedResFont[ResFontType_Max]; //! ROM font provided by the system nw4r::ut::RomFont* mpRomFont; // at 0x4 - //! Resource fonts provided by the disc + //! Resource fonts nw4r::ut::ResFont* mpResFonts[ResFontType_Max]; // at 0x8 - //! Serialized versions of resource fonts (for layout access) + //! Serialized versions of resource fonts void* mpResFontData[ResFontType_Max]; // at 0x24 }; diff --git a/include/Pack/RPSystem/RPSysResourceManager.h b/include/Pack/RPSystem/RPSysResourceManager.h index 8ba7591e4..28b5c5328 100644 --- a/include/Pack/RPSystem/RPSysResourceManager.h +++ b/include/Pack/RPSystem/RPSysResourceManager.h @@ -168,6 +168,10 @@ class RPSysResourceManager { return mpKokeshiArchive; } + EGG::Archive* GetFontArchive() const { + return mpFontArchive; + } + void* GetMultiHandle() { return &mpMultiHandle; } diff --git a/include/nw4r/ut/ut_ResFontBase.h b/include/nw4r/ut/ut_ResFontBase.h index 07b081777..b34b489ce 100644 --- a/include/nw4r/ut/ut_ResFontBase.h +++ b/include/nw4r/ut/ut_ResFontBase.h @@ -99,11 +99,11 @@ class ResFontBase : public Font { virtual void GetGlyph(Glyph* pGlyph, u16 ch) const; // at 0x50 virtual FontEncoding GetEncoding() const; // at 0x54 -protected: bool IsManaging(const void* pBuffer) const { return mResource == pBuffer; } +protected: void SetResourceBuffer(void* pBuffer, FontInformation* pInfo); private: diff --git a/include/nw4r/ut/ut_RomFont.h b/include/nw4r/ut/ut_RomFont.h index 097f16360..9a0a70bd0 100644 --- a/include/nw4r/ut/ut_RomFont.h +++ b/include/nw4r/ut/ut_RomFont.h @@ -40,8 +40,8 @@ class RomFont : public Font { virtual void GetGlyph(Glyph* pGlyph, u16 ch) const; // at 0x50 virtual FontEncoding GetEncoding() const; // at 0x54 - u32 GetRequireBufferSize(); bool Load(void* pBuffer); + static u32 GetRequireBufferSize(); private: static const int CHAR_PTR_BUFFER_SIZE = 4; diff --git a/src/Pack/RPSystem/RPSysFontManager.cpp b/src/Pack/RPSystem/RPSysFontManager.cpp new file mode 100644 index 000000000..569764cb1 --- /dev/null +++ b/src/Pack/RPSystem/RPSysFontManager.cpp @@ -0,0 +1,124 @@ +#include +#include + +#include + +#include + +RP_SINGLETON_IMPL(RPSysFontManager); + +/** + * @brief Font resource filenames + */ +const char* RPSysFontManager::RES_FONT_NAMES[ResFontType_Max] = { + "pac_nRodDb_32_I4.brfnt", // ResFontType_nRodDb_32_I4 + "pac_nRodDb_32_IA4.brfnt", // ResFontType_nRodDb_32_IA4 + "pac_nRodDb_62_IA4.brfnt", // ResFontType_nRodDb_62_IA4 + "pac_nRodDb_200_IA4.brfnt", // ResFontType_nRodDb_200_IA4 + "pac_nRodEb_32_I4.brfnt", // ResFontType_nRodEb_32_I4 + "pac_nRodEb_70_IA4.brfnt", // ResFontType_nRodEb_70_IA4 + "pac_healthTime.brfnt", // ResFontType_HealthTime +}; + +/** + * @brief Whether each font resource is required by this pack + */ +const BOOL RPSysFontManager::sIsNeedResFont[ResFontType_Max] = { + TRUE, // ResFontType_nRodDb_32_I4 + TRUE, // ResFontType_nRodDb_32_IA4 + TRUE, // ResFontType_nRodDb_62_IA4 + FALSE, // ResFontType_nRodDb_200_IA4 + TRUE, // ResFontType_nRodEb_32_I4 + TRUE, // ResFontType_nRodEb_70_IA4 + FALSE, // ResFontType_HealthTime +}; + +/** + * @brief Constructor + */ +RPSysFontManager::RPSysFontManager() { + mpRomFont = new nw4r::ut::RomFont(); + + for (int i = 0; i < ResFontType_Max; i++) { + mpResFonts[i] = new nw4r::ut::ResFont(); + mpResFontData[i] = NULL; + } +} + +/** + * @brief Destructor + */ +RPSysFontManager::~RPSysFontManager() {} + +/** + * @brief Loads the ROM font provided by the system + */ +void RPSysFontManager::LoadRomFont() { + EGG::Heap* pResHeap = RP_GET_INSTANCE(RPSysSystem)->getResourceHeap(); + u32 requireSize = nw4r::ut::RomFont::GetRequireBufferSize(); + + void* pBuffer = new (pResHeap, 32) u8[requireSize]; + mpRomFont->Load(pBuffer); +} + +/** + * @brief Loads all resource fonts required by this pack + */ +void RPSysFontManager::LoadResFonts() { + EGG::Archive* pFontArchive = + RP_GET_INSTANCE(RPSysResourceManager)->GetFontArchive(); + + for (u8 i = 0; i < ResFontType_Max; i++) { + if (!sIsNeedResFont[i]) { + continue; + } + + LoadResFont(i, pFontArchive); + } +} + +/** + * @brief Gets the index of the specified resource font + * + * @param pName Font name + */ +u8 RPSysFontManager::GetResFontIndex(const char* pName) const { + for (u8 i = 0; i < ResFontType_Max; i++) { + if (std::strcmp(pName, RES_FONT_NAMES[i]) == 0) { + return i; + } + } + + return ResFontType_nRodDb_32_I4; +} + +/** + * @brief Gets the data of the specified resource font + * + * @param pName Font name + */ +void* RPSysFontManager::GetResFontData(const char* pName) const { + u8 idx = GetResFontIndex(pName); + return mpResFontData[idx]; +} + +/** + * @brief Loads the specified resource font from the provided archive + * + * @param idx Font index + * @param pArchive Font archive + */ +void RPSysFontManager::LoadResFont(u8 idx, EGG::Archive* pArchive) { + // TODO(kiwi) Inline? + ResFontType type = static_cast(idx); + + void* pResFontData = + RPSysResourceManager::GetFileFromArchive(pArchive, RES_FONT_NAMES[idx]); + + mpResFontData[idx] = pResFontData; + + if (!mpResFonts[type]->IsManaging(pResFontData)) { + mpResFonts[type]->SetResource(pResFontData); + mpResFonts[type]->SetAlternateChar(L'?'); + } +}