From 5c0ff62c9ca9e49cfbdde508532ca572c4c180b3 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 1 Nov 2025 00:01:43 +0100 Subject: [PATCH 1/6] Slice and match dSelectCursor_c For some reason, the built main.dol doesn't have the same hash though... --- include/game/bases/d_SelectCursor.hpp | 58 ++++++ slices/wiimj2d.json | 11 ++ source/dol/bases/d_SelectCursor.cpp | 243 ++++++++++++++++++++++++++ syms.txt | 1 + 4 files changed, 313 insertions(+) create mode 100644 include/game/bases/d_SelectCursor.hpp create mode 100644 source/dol/bases/d_SelectCursor.cpp diff --git a/include/game/bases/d_SelectCursor.hpp b/include/game/bases/d_SelectCursor.hpp new file mode 100644 index 00000000..d21550e1 --- /dev/null +++ b/include/game/bases/d_SelectCursor.hpp @@ -0,0 +1,58 @@ +#pragma once +#include +#include +#include +#include + +class dSelectCursor_c : public dBase_c { +public: + class Layout_c { + public: + LytBase_c mBase; + nw4r::lyt::Pane * mpRootPane; + nw4r::lyt::Picture * mPPanes[4]; + nw4r::lyt::Pane * mNPanes[5]; + bool mIsActive; + char mPaneName[NW4R_LYT_RES_NAME_LEN + 1]; + u8 mPad[86]; + mVec2_c mPaneSize; + float m_230 ; + float m_234 ; + mVec2_c mPaneGlbMtxScale; + mVec2_c mPaneGlbMtxTrans; + u8 mPad2[4]; + float m_24c; + float m_250; + float m_254; + u8 mPaneBasePosH; + u8 mPaneBasePosV; + u8 mPad3[2]; + int m_25c; + u8 m_260; + u8 mPad4[3]; + + Layout_c(); + }; + + d2d::ResAccMultLoader_c mResLoader; + Layout_c mLayouts[5]; + u8 m_d38; + u8 m_d39; + u8 m_d3a; + u8 m_d3b; + + dSelectCursor_c(); + virtual ~dSelectCursor_c(); + + int create(); + int doDelete(); + int execute(); + int draw(); + + void Cancel(int); + void PosSet(int); + void SetPane(const nw4r::lyt::Pane *param_2, int param_3, bool param_4); + void SetAlpha(const nw4r::lyt::Pane *param_2, int param_3); + + static dSelectCursor_c * m_instance; // 8042a5a8 +}; diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index 88e90d1b..e16836b7 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -321,6 +321,17 @@ ".data": "0x1de58-0x1de68" } }, + { + "source": "dol/bases/d_SelectCursor.cpp", + "memoryRanges": { + ".data": "0x24348-0x24478", + ".sbss": "0x708-0x710", + ".sbss2": "0x18-0x1c", + ".sdata": "0x1b88-0x1bb8", + ".sdata2": "0x2288-0x2290", + ".text": "0x1059b0-0x106360" + } + }, { "source": "dol/bases/d_SmallScoreManager.cpp", "memoryRanges": { diff --git a/source/dol/bases/d_SelectCursor.cpp b/source/dol/bases/d_SelectCursor.cpp new file mode 100644 index 00000000..0c296d6a --- /dev/null +++ b/source/dol/bases/d_SelectCursor.cpp @@ -0,0 +1,243 @@ +#include + +ACTOR_PROFILE(SELECT_CURSOR, dSelectCursor_c, 0); + +dSelectCursor_c *dSelectCursor_c::m_instance = nullptr; + +dSelectCursor_c::dSelectCursor_c() { + m_instance = this; + m_d38 = 0; +} + +dSelectCursor_c::Layout_c::Layout_c() : mPaneSize(0.0f, 0.0f), m_230(0.0f), m_234(0.0f) { } + +dSelectCursor_c::~dSelectCursor_c() { + dSelectCursor_c::m_instance = nullptr; +} + +int dSelectCursor_c::create() { + + static const char *AnmNameTbl[] = { + "select_cursor_04_loopCursor.brlan" + }; + + static const char *GROUP_NAME_DT[] = { + "A00_cursor" + }; + + static const int ANIME_INDEX_TBL[ARRAY_SIZE(GROUP_NAME_DT)] = { 0 }; + + static const char *PPANE_TABLE[] = { + "P_cursor_00", + "P_cursor_01", + "P_cursor_02", + "P_cursor_03" + }; + + static const char *NPANE_TABLE[] = { + "N_cursor_00", + "N_LU_00", + "N_RU_00", + "N_LD_00", + "N_RD_00" + }; + + + if (m_d38) { + return SUCCEEDED; + } + + if (! mResLoader.request("Layout/select_cursor/select_cursor.arc")) { + return NOT_READY; + } + + for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { + mLayouts[i].mBase.mpResAccessor = &mResLoader; + } + + for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { + mLayouts[i].mBase.build("select_cursor_04.brlyt", nullptr); + mLayouts[i].mBase.AnimeResRegister(AnmNameTbl, ARRAY_SIZE(AnmNameTbl)); + mLayouts[i].mBase.GroupRegister(GROUP_NAME_DT, ANIME_INDEX_TBL, ARRAY_SIZE(GROUP_NAME_DT)); + mLayouts[i].mpRootPane = mLayouts[i].mBase.getRootPane(); + mLayouts[i].mBase.PPaneRegister(PPANE_TABLE, mLayouts[i].mPPanes, ARRAY_SIZE(PPANE_TABLE)); + mLayouts[i].mBase.NPaneRegister(NPANE_TABLE, mLayouts[i].mNPanes, ARRAY_SIZE(NPANE_TABLE)); + mLayouts[i].mpRootPane->SetVisible(false); + + Cancel(i); + + if (i == 4) { + mLayouts[i].mBase.mDrawOrder = 0xE; + } else { + mLayouts[i].mBase.mDrawOrder = 0x93; + } + + mLayouts[i].mBase.LoopAnimeStartSetup(0); + } + + m_d38 = 1; + + return SUCCEEDED; +} + + +int dSelectCursor_c::execute() { + for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { + if (mLayouts[i].mIsActive) { + PosSet(i); + mLayouts[i].mBase.AnimePlay(); + mLayouts[i].mBase.calc(); + } + } + + return SUCCEEDED; +} + +int dSelectCursor_c::draw() { + for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { + if (mLayouts[i].mIsActive) { + mLayouts[i].mBase.entry(); + } + } + + return SUCCEEDED; +} + +int dSelectCursor_c::doDelete() { + if (! mResLoader.remove()) { + return NOT_READY; + } + + for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { + if (! mLayouts[i].mBase.doDelete()) { + return NOT_READY; + } + } + + return SUCCEEDED; +} + +void dSelectCursor_c::PosSet(int param_2) { + mLayouts[param_2].mpRootPane->SetVisible(true); + + mVec2_c pos; + + float b, c, d, e; + + d = mLayouts[param_2].mPaneGlbMtxScale.x; + e = mLayouts[param_2].mPaneGlbMtxScale.y; + + b = mLayouts[param_2].mPaneSize.x / 2.0f; + c = mLayouts[param_2].mPaneSize.y / 2.0f; + + pos.x = mLayouts[param_2].mPaneGlbMtxTrans.x + mLayouts[param_2].m_24c; + + if (mLayouts[param_2].mPaneBasePosH == 0) { + pos.x += b * d; + } else if (mLayouts[param_2].mPaneBasePosH == 2) { + pos.x -= b * d; + } + + pos.y = mLayouts[param_2].mPaneGlbMtxTrans.y + mLayouts[param_2].m_250; + if (mLayouts[param_2].mPaneBasePosV == 0) { + pos.y -= c * e; + } else if (mLayouts[param_2].mPaneBasePosV == 2) { + pos.y += c * e; + } + + mLayouts[param_2].mpRootPane->SetTranslate(mVec3_c(pos, 0.0f)); + + float m_230 = mLayouts[param_2].m_230; + float m_234 = mLayouts[param_2].m_234; + for (int i = 1; i < ARRAY_SIZE(mLayouts); i++) { + mVec3_c pos2; + if ((i == 1) || (i == 3)) { + pos2.x = (b * d); + pos2.x = -pos2.x; + pos2.x -= m_230; + } else { + pos2.x = (b * d); + pos2.x += m_230; + } + + if ((i == 1) || (i == 2)) { + pos2.y = (c * e); + pos2.y += m_234; + } else { + pos2.y = (c * e); + pos2.y = -pos2.y; + pos2.y -= m_234; + } + + pos2.z = 0.0f; + mLayouts[param_2].mNPanes[i]->SetTranslate(pos2); + } + + if (mLayouts[param_2].m_260 != 0) { + mLayouts[param_2].m_25c -= 26; + mLayouts[param_2].mNPanes[0]->SetAlpha(mLayouts[param_2].m_25c); + + if (mLayouts[param_2].m_25c < 0) { + mLayouts[param_2].m_25c = 0; + mLayouts[param_2].m_260 = 0; + Cancel(param_2); + } + } +} + +void dSelectCursor_c::Cancel(int param_2) { + if (mLayouts[param_2].mIsActive) { + mLayouts[param_2].mIsActive = false; + strcpy(mLayouts[param_2].mPaneName, ""); + mLayouts[param_2].mpRootPane->SetVisible(false); + } +} + +void dSelectCursor_c::SetPane(const nw4r::lyt::Pane *param_2, int param_3, bool param_4) { + mLayouts[param_3].mIsActive = true; + + strcpy(mLayouts[param_3].mPaneName, param_2->GetName()); + + mLayouts[param_3].mPaneSize.x = param_2->GetSize().width; + mLayouts[param_3].mPaneSize.y = param_2->GetSize().height; + + nw4r::math::MTX34 mtx = param_2->GetGlobalMtx(); + + mLayouts[param_3].mPaneGlbMtxTrans.x = mtx._03; + mLayouts[param_3].mPaneGlbMtxTrans.y = mtx._13; + mLayouts[param_3].mPaneGlbMtxScale.x = mtx._00; + mLayouts[param_3].mPaneGlbMtxScale.y = mtx._11; + + mLayouts[param_3].mPaneBasePosH = param_2->GetBasePositionH(); + mLayouts[param_3].mPaneBasePosV = param_2->GetBasePositionV(); + + mLayouts[param_3].m_230 = 0.0; + mLayouts[param_3].m_234 = 0.0; + mLayouts[param_3].m_24c = 0.0; + mLayouts[param_3].m_250 = 0.0; + mLayouts[param_3].m_254 = 0.0; + mLayouts[param_3].m_25c = 0xff; + mLayouts[param_3].m_260 = 0; + + if (param_4) { + mLayouts[param_3].mBase.mDrawOrder = 152; + } else { + for (int i = 0; i < ARRAY_SIZE(mLayouts); i++) { + if (i == 4) { + mLayouts[i].mBase.mDrawOrder = 14; + } else { + mLayouts[i].mBase.mDrawOrder = 147; + } + } + } +} + +void dSelectCursor_c::SetAlpha(const nw4r::lyt::Pane *param_2, int param_3) { + u8 alpha = param_2->GetGlbAlpha(); + Layout_c & layout = mLayouts[param_3]; + + layout.mPPanes[0]->SetAlpha(alpha); + layout.mPPanes[1]->SetAlpha(alpha); + layout.mPPanes[2]->SetAlpha(alpha); + layout.mPPanes[3]->SetAlpha(alpha); +} diff --git a/syms.txt b/syms.txt index 8671166d..2f0de041 100644 --- a/syms.txt +++ b/syms.txt @@ -670,3 +670,4 @@ typeInfo__Q34nw4r3lyt7TextBox=8042b0b8 typeInfo__Q34nw4r3lyt6Window=8042b0c0 remove__Q24dDvd8loader_cFv=8008f2b0 request__Q24dDvd8loader_cFPCcUcPQ23EGG4Heap=8008f1b0 +strcpy=802E1C28 From 5272197d9fe0b74ceda4758e1a68f58d1c181be3 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 1 Nov 2025 00:35:26 +0100 Subject: [PATCH 2/6] Match the dol Apparently the destructor needs to be explicit, otherwise the function ordering is wrong. Also aligning the slices. --- include/game/bases/d_SelectCursor.hpp | 1 + slices/wiimj2d.json | 2 +- source/dol/bases/d_SelectCursor.cpp | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/game/bases/d_SelectCursor.hpp b/include/game/bases/d_SelectCursor.hpp index d21550e1..23756b22 100644 --- a/include/game/bases/d_SelectCursor.hpp +++ b/include/game/bases/d_SelectCursor.hpp @@ -32,6 +32,7 @@ class dSelectCursor_c : public dBase_c { u8 mPad4[3]; Layout_c(); + ~Layout_c(); }; d2d::ResAccMultLoader_c mResLoader; diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index e16836b7..9a92a41e 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -326,7 +326,7 @@ "memoryRanges": { ".data": "0x24348-0x24478", ".sbss": "0x708-0x710", - ".sbss2": "0x18-0x1c", + ".sbss2": "0x18-0x20", ".sdata": "0x1b88-0x1bb8", ".sdata2": "0x2288-0x2290", ".text": "0x1059b0-0x106360" diff --git a/source/dol/bases/d_SelectCursor.cpp b/source/dol/bases/d_SelectCursor.cpp index 0c296d6a..0a0fa6e9 100644 --- a/source/dol/bases/d_SelectCursor.cpp +++ b/source/dol/bases/d_SelectCursor.cpp @@ -11,6 +11,8 @@ dSelectCursor_c::dSelectCursor_c() { dSelectCursor_c::Layout_c::Layout_c() : mPaneSize(0.0f, 0.0f), m_230(0.0f), m_234(0.0f) { } +dSelectCursor_c::Layout_c::~Layout_c() { } + dSelectCursor_c::~dSelectCursor_c() { dSelectCursor_c::m_instance = nullptr; } From db9d0e1a6c9fbfe40b13b125c23b7c7d92ca07d8 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 1 Nov 2025 14:40:03 +0100 Subject: [PATCH 3/6] Cleanup --- include/game/bases/d_SelectCursor.hpp | 34 ++---- source/dol/bases/d_SelectCursor.cpp | 152 +++++++++++++------------- 2 files changed, 85 insertions(+), 101 deletions(-) diff --git a/include/game/bases/d_SelectCursor.hpp b/include/game/bases/d_SelectCursor.hpp index 23756b22..6f036007 100644 --- a/include/game/bases/d_SelectCursor.hpp +++ b/include/game/bases/d_SelectCursor.hpp @@ -15,32 +15,22 @@ class dSelectCursor_c : public dBase_c { bool mIsActive; char mPaneName[NW4R_LYT_RES_NAME_LEN + 1]; u8 mPad[86]; - mVec2_c mPaneSize; - float m_230 ; - float m_234 ; + nw4r::lyt::Size mPaneSize; + nw4r::lyt::Size mPaneOffset; ///< Always (0, 0) mVec2_c mPaneGlbMtxScale; mVec2_c mPaneGlbMtxTrans; u8 mPad2[4]; - float m_24c; - float m_250; - float m_254; + mVec2_c mRootPaneOffset; ///< Always (0, 0) + float m_254; ///< Only set to 0, never read u8 mPaneBasePosH; u8 mPaneBasePosV; - u8 mPad3[2]; - int m_25c; - u8 m_260; - u8 mPad4[3]; - - Layout_c(); - ~Layout_c(); + int mPaneAlpha; + bool mDoFade; ///< Always false }; d2d::ResAccMultLoader_c mResLoader; Layout_c mLayouts[5]; - u8 m_d38; - u8 m_d39; - u8 m_d3a; - u8 m_d3b; + bool mIsLoaded; dSelectCursor_c(); virtual ~dSelectCursor_c(); @@ -50,10 +40,10 @@ class dSelectCursor_c : public dBase_c { int execute(); int draw(); - void Cancel(int); - void PosSet(int); - void SetPane(const nw4r::lyt::Pane *param_2, int param_3, bool param_4); - void SetAlpha(const nw4r::lyt::Pane *param_2, int param_3); + void PosSet(int layoutId); + void Cancel(int layoutId); + void SetPane(const nw4r::lyt::Pane *pane, int layoutId, bool dontSetAllDrawOrder); + void SetAlpha(const nw4r::lyt::Pane *pane, int layoutId); - static dSelectCursor_c * m_instance; // 8042a5a8 + static dSelectCursor_c * m_instance; }; diff --git a/source/dol/bases/d_SelectCursor.cpp b/source/dol/bases/d_SelectCursor.cpp index 0a0fa6e9..bc7296cb 100644 --- a/source/dol/bases/d_SelectCursor.cpp +++ b/source/dol/bases/d_SelectCursor.cpp @@ -6,13 +6,9 @@ dSelectCursor_c *dSelectCursor_c::m_instance = nullptr; dSelectCursor_c::dSelectCursor_c() { m_instance = this; - m_d38 = 0; + mIsLoaded = false; } -dSelectCursor_c::Layout_c::Layout_c() : mPaneSize(0.0f, 0.0f), m_230(0.0f), m_234(0.0f) { } - -dSelectCursor_c::Layout_c::~Layout_c() { } - dSelectCursor_c::~dSelectCursor_c() { dSelectCursor_c::m_instance = nullptr; } @@ -45,7 +41,7 @@ int dSelectCursor_c::create() { }; - if (m_d38) { + if (mIsLoaded) { return SUCCEEDED; } @@ -69,15 +65,15 @@ int dSelectCursor_c::create() { Cancel(i); if (i == 4) { - mLayouts[i].mBase.mDrawOrder = 0xE; + mLayouts[i].mBase.mDrawOrder = 14; } else { - mLayouts[i].mBase.mDrawOrder = 0x93; + mLayouts[i].mBase.mDrawOrder = 147; } mLayouts[i].mBase.LoopAnimeStartSetup(0); } - m_d38 = 1; + mIsLoaded = true; return SUCCEEDED; } @@ -119,110 +115,109 @@ int dSelectCursor_c::doDelete() { return SUCCEEDED; } -void dSelectCursor_c::PosSet(int param_2) { - mLayouts[param_2].mpRootPane->SetVisible(true); +void dSelectCursor_c::PosSet(int layoutId) { + mLayouts[layoutId].mpRootPane->SetVisible(true); mVec2_c pos; + float paneMidX, paneMidY, paneScaleX, paneScaleY; - float b, c, d, e; + paneScaleX = mLayouts[layoutId].mPaneGlbMtxScale.x; + paneScaleY = mLayouts[layoutId].mPaneGlbMtxScale.y; - d = mLayouts[param_2].mPaneGlbMtxScale.x; - e = mLayouts[param_2].mPaneGlbMtxScale.y; + paneMidX = mLayouts[layoutId].mPaneSize.width / 2.0f; + paneMidY = mLayouts[layoutId].mPaneSize.height / 2.0f; - b = mLayouts[param_2].mPaneSize.x / 2.0f; - c = mLayouts[param_2].mPaneSize.y / 2.0f; + pos.x = mLayouts[layoutId].mPaneGlbMtxTrans.x + mLayouts[layoutId].mRootPaneOffset.x; - pos.x = mLayouts[param_2].mPaneGlbMtxTrans.x + mLayouts[param_2].m_24c; - - if (mLayouts[param_2].mPaneBasePosH == 0) { - pos.x += b * d; - } else if (mLayouts[param_2].mPaneBasePosH == 2) { - pos.x -= b * d; + if (mLayouts[layoutId].mPaneBasePosH == 0) { + pos.x += paneMidX * paneScaleX; + } else if (mLayouts[layoutId].mPaneBasePosH == 2) { + pos.x -= paneMidX * paneScaleX; } - pos.y = mLayouts[param_2].mPaneGlbMtxTrans.y + mLayouts[param_2].m_250; - if (mLayouts[param_2].mPaneBasePosV == 0) { - pos.y -= c * e; - } else if (mLayouts[param_2].mPaneBasePosV == 2) { - pos.y += c * e; + pos.y = mLayouts[layoutId].mPaneGlbMtxTrans.y + mLayouts[layoutId].mRootPaneOffset.y; + if (mLayouts[layoutId].mPaneBasePosV == 0) { + pos.y -= paneMidY * paneScaleY; + } else if (mLayouts[layoutId].mPaneBasePosV == 2) { + pos.y += paneMidY * paneScaleY; } - mLayouts[param_2].mpRootPane->SetTranslate(mVec3_c(pos, 0.0f)); + mLayouts[layoutId].mpRootPane->SetTranslate(mVec3_c(pos, 0.0f)); - float m_230 = mLayouts[param_2].m_230; - float m_234 = mLayouts[param_2].m_234; + float hOffset = mLayouts[layoutId].mPaneOffset.width; + float vOffset = mLayouts[layoutId].mPaneOffset.height; for (int i = 1; i < ARRAY_SIZE(mLayouts); i++) { mVec3_c pos2; if ((i == 1) || (i == 3)) { - pos2.x = (b * d); + pos2.x = paneMidX * paneScaleX; pos2.x = -pos2.x; - pos2.x -= m_230; + pos2.x -= hOffset; } else { - pos2.x = (b * d); - pos2.x += m_230; + pos2.x = paneMidX * paneScaleX; + pos2.x += hOffset; } if ((i == 1) || (i == 2)) { - pos2.y = (c * e); - pos2.y += m_234; + pos2.y = paneMidY * paneScaleY; + pos2.y += vOffset; } else { - pos2.y = (c * e); + pos2.y = paneMidY * paneScaleY; pos2.y = -pos2.y; - pos2.y -= m_234; + pos2.y -= vOffset; } pos2.z = 0.0f; - mLayouts[param_2].mNPanes[i]->SetTranslate(pos2); + mLayouts[layoutId].mNPanes[i]->SetTranslate(pos2); } - if (mLayouts[param_2].m_260 != 0) { - mLayouts[param_2].m_25c -= 26; - mLayouts[param_2].mNPanes[0]->SetAlpha(mLayouts[param_2].m_25c); + if (mLayouts[layoutId].mDoFade) { + mLayouts[layoutId].mPaneAlpha -= (255 / 10) + 1; + mLayouts[layoutId].mNPanes[0]->SetAlpha(mLayouts[layoutId].mPaneAlpha); - if (mLayouts[param_2].m_25c < 0) { - mLayouts[param_2].m_25c = 0; - mLayouts[param_2].m_260 = 0; - Cancel(param_2); + if (mLayouts[layoutId].mPaneAlpha < 0) { + mLayouts[layoutId].mPaneAlpha = 0; + mLayouts[layoutId].mDoFade = false; + Cancel(layoutId); } } } -void dSelectCursor_c::Cancel(int param_2) { - if (mLayouts[param_2].mIsActive) { - mLayouts[param_2].mIsActive = false; - strcpy(mLayouts[param_2].mPaneName, ""); - mLayouts[param_2].mpRootPane->SetVisible(false); +void dSelectCursor_c::Cancel(int layoutId) { + if (mLayouts[layoutId].mIsActive) { + mLayouts[layoutId].mIsActive = false; + strcpy(mLayouts[layoutId].mPaneName, ""); + mLayouts[layoutId].mpRootPane->SetVisible(false); } } -void dSelectCursor_c::SetPane(const nw4r::lyt::Pane *param_2, int param_3, bool param_4) { - mLayouts[param_3].mIsActive = true; +void dSelectCursor_c::SetPane(const nw4r::lyt::Pane *pane, int layoutId, bool dontSetAllDrawOrder) { + mLayouts[layoutId].mIsActive = true; - strcpy(mLayouts[param_3].mPaneName, param_2->GetName()); + strcpy(mLayouts[layoutId].mPaneName, pane->GetName()); - mLayouts[param_3].mPaneSize.x = param_2->GetSize().width; - mLayouts[param_3].mPaneSize.y = param_2->GetSize().height; + mLayouts[layoutId].mPaneSize.width = pane->GetSize().width; + mLayouts[layoutId].mPaneSize.height = pane->GetSize().height; - nw4r::math::MTX34 mtx = param_2->GetGlobalMtx(); + nw4r::math::MTX34 mtx = pane->GetGlobalMtx(); - mLayouts[param_3].mPaneGlbMtxTrans.x = mtx._03; - mLayouts[param_3].mPaneGlbMtxTrans.y = mtx._13; - mLayouts[param_3].mPaneGlbMtxScale.x = mtx._00; - mLayouts[param_3].mPaneGlbMtxScale.y = mtx._11; + mLayouts[layoutId].mPaneGlbMtxTrans.x = mtx._03; + mLayouts[layoutId].mPaneGlbMtxTrans.y = mtx._13; + mLayouts[layoutId].mPaneGlbMtxScale.x = mtx._00; + mLayouts[layoutId].mPaneGlbMtxScale.y = mtx._11; - mLayouts[param_3].mPaneBasePosH = param_2->GetBasePositionH(); - mLayouts[param_3].mPaneBasePosV = param_2->GetBasePositionV(); + mLayouts[layoutId].mPaneBasePosH = pane->GetBasePositionH(); + mLayouts[layoutId].mPaneBasePosV = pane->GetBasePositionV(); - mLayouts[param_3].m_230 = 0.0; - mLayouts[param_3].m_234 = 0.0; - mLayouts[param_3].m_24c = 0.0; - mLayouts[param_3].m_250 = 0.0; - mLayouts[param_3].m_254 = 0.0; - mLayouts[param_3].m_25c = 0xff; - mLayouts[param_3].m_260 = 0; + mLayouts[layoutId].mPaneOffset.width = 0.0f; + mLayouts[layoutId].mPaneOffset.height = 0.0f; + mLayouts[layoutId].mRootPaneOffset.x = 0.0f; + mLayouts[layoutId].mRootPaneOffset.y = 0.0f; + mLayouts[layoutId].m_254 = 0.0f; + mLayouts[layoutId].mPaneAlpha = 0xff; + mLayouts[layoutId].mDoFade = false; - if (param_4) { - mLayouts[param_3].mBase.mDrawOrder = 152; + if (dontSetAllDrawOrder) { + mLayouts[layoutId].mBase.mDrawOrder = 152; } else { for (int i = 0; i < ARRAY_SIZE(mLayouts); i++) { if (i == 4) { @@ -234,12 +229,11 @@ void dSelectCursor_c::SetPane(const nw4r::lyt::Pane *param_2, int param_3, bool } } -void dSelectCursor_c::SetAlpha(const nw4r::lyt::Pane *param_2, int param_3) { - u8 alpha = param_2->GetGlbAlpha(); - Layout_c & layout = mLayouts[param_3]; +void dSelectCursor_c::SetAlpha(const nw4r::lyt::Pane *pane, int layoutId) { + u8 alpha = pane->GetGlbAlpha(); + Layout_c & layout = mLayouts[layoutId]; - layout.mPPanes[0]->SetAlpha(alpha); - layout.mPPanes[1]->SetAlpha(alpha); - layout.mPPanes[2]->SetAlpha(alpha); - layout.mPPanes[3]->SetAlpha(alpha); + for (int i = 0; i < ARRAY_SIZE(layout.mPPanes); i++) { + layout.mPPanes[i]->SetAlpha(alpha); + } } From 69a39394700c49f95622427885bc6a3d29359cc9 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 2 Nov 2025 16:53:16 +0100 Subject: [PATCH 4/6] First changes from review --- include/game/bases/d_SelectCursor.hpp | 69 +++++++++++++++++++-------- source/dol/bases/d_SelectCursor.cpp | 34 ++++++------- 2 files changed, 66 insertions(+), 37 deletions(-) diff --git a/include/game/bases/d_SelectCursor.hpp b/include/game/bases/d_SelectCursor.hpp index 6f036007..7e6373f7 100644 --- a/include/game/bases/d_SelectCursor.hpp +++ b/include/game/bases/d_SelectCursor.hpp @@ -4,34 +4,59 @@ #include #include +/// @brief The world map HUD. class dSelectCursor_c : public dBase_c { + + /// @brief The null panes used in the layout. + /// @unofficial + enum N_PANE_e { + N_cursor_00, + N_LU_00, + N_RU_00, + N_LD_00, + N_RD_00, + N_COUNT + }; + + /// @brief The picture panes used in the layout. + /// @unofficial + enum P_PANE_e { + P_cursor_00, + P_cursor_01, + P_cursor_02, + P_cursor_03, + P_COUNT + }; + + /// @brief The animations used for the layout. + /// @unofficial + enum ANIM_e { + ANIM_CURSOR, + ANIM_COUNT + }; + public: class Layout_c { public: LytBase_c mBase; - nw4r::lyt::Pane * mpRootPane; - nw4r::lyt::Picture * mPPanes[4]; - nw4r::lyt::Pane * mNPanes[5]; - bool mIsActive; - char mPaneName[NW4R_LYT_RES_NAME_LEN + 1]; - u8 mPad[86]; - nw4r::lyt::Size mPaneSize; - nw4r::lyt::Size mPaneOffset; ///< Always (0, 0) - mVec2_c mPaneGlbMtxScale; - mVec2_c mPaneGlbMtxTrans; - u8 mPad2[4]; - mVec2_c mRootPaneOffset; ///< Always (0, 0) - float m_254; ///< Only set to 0, never read + nw4r::lyt::Pane *mpRootPane; ///< The root pane of the view. + nw4r::lyt::Picture *mpPicturePanes[P_COUNT]; ///< The picture panes of the view. + nw4r::lyt::Pane *mpNullPanes[N_COUNT]; ///< The null panes of the view. + bool mIsActive; ///< Whether the layout is drawn. + char mPaneName[100]; ///< The name of the parent pane. + nw4r::lyt::Size mPaneSize; ///< The size of the parent pane. + nw4r::lyt::Size mPaneOffset; ///< Always (0, 0). + mVec2_c mPaneGlbMtxScale; ///< The scale of the parent pane's global matrix. + mVec2_c mPaneGlbMtxTrans; ///< The transform of the parent pane's global matrix. + u8 mPad[4]; + mVec2_c mRootPaneOffset; ///< Always (0, 0). + float m_254; ///< Only set to 0, never read. u8 mPaneBasePosH; u8 mPaneBasePosV; - int mPaneAlpha; - bool mDoFade; ///< Always false + int mPaneAlpha; ///< The opacity of the N_cursor_00 pane. + bool mDoFade; ///< Always false. If set, it fades out the opacity of the N_cursor_00 pane then deactivates. }; - d2d::ResAccMultLoader_c mResLoader; - Layout_c mLayouts[5]; - bool mIsLoaded; - dSelectCursor_c(); virtual ~dSelectCursor_c(); @@ -45,5 +70,9 @@ class dSelectCursor_c : public dBase_c { void SetPane(const nw4r::lyt::Pane *pane, int layoutId, bool dontSetAllDrawOrder); void SetAlpha(const nw4r::lyt::Pane *pane, int layoutId); - static dSelectCursor_c * m_instance; + d2d::ResAccMultLoader_c mResLoader; + Layout_c mLayouts[5]; + bool mIsLoaded; + + static dSelectCursor_c *m_instance; }; diff --git a/source/dol/bases/d_SelectCursor.cpp b/source/dol/bases/d_SelectCursor.cpp index bc7296cb..91c3b212 100644 --- a/source/dol/bases/d_SelectCursor.cpp +++ b/source/dol/bases/d_SelectCursor.cpp @@ -15,24 +15,24 @@ dSelectCursor_c::~dSelectCursor_c() { int dSelectCursor_c::create() { - static const char *AnmNameTbl[] = { + static const char *AnmNameTbl[ANIM_COUNT] = { "select_cursor_04_loopCursor.brlan" }; - static const char *GROUP_NAME_DT[] = { + static const char *GROUP_NAME_DT[ANIM_COUNT] = { "A00_cursor" }; - static const int ANIME_INDEX_TBL[ARRAY_SIZE(GROUP_NAME_DT)] = { 0 }; + static const int ANIME_INDEX_TBL[ANIM_COUNT] = { 0 }; - static const char *PPANE_TABLE[] = { + static const char *PPANE_TABLE[P_COUNT] = { "P_cursor_00", "P_cursor_01", "P_cursor_02", "P_cursor_03" }; - static const char *NPANE_TABLE[] = { + static const char *NPANE_TABLE[N_COUNT] = { "N_cursor_00", "N_LU_00", "N_RU_00", @@ -45,21 +45,21 @@ int dSelectCursor_c::create() { return SUCCEEDED; } - if (! mResLoader.request("Layout/select_cursor/select_cursor.arc")) { + if (!mResLoader.request("Layout/select_cursor/select_cursor.arc")) { return NOT_READY; } - for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { + for (int i = 0; i < ARRAY_SIZE(mLayouts); i++) { mLayouts[i].mBase.mpResAccessor = &mResLoader; } for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { mLayouts[i].mBase.build("select_cursor_04.brlyt", nullptr); - mLayouts[i].mBase.AnimeResRegister(AnmNameTbl, ARRAY_SIZE(AnmNameTbl)); - mLayouts[i].mBase.GroupRegister(GROUP_NAME_DT, ANIME_INDEX_TBL, ARRAY_SIZE(GROUP_NAME_DT)); + mLayouts[i].mBase.AnimeResRegister(AnmNameTbl, ANIM_COUNT); + mLayouts[i].mBase.GroupRegister(GROUP_NAME_DT, ANIME_INDEX_TBL, ANIM_COUNT); mLayouts[i].mpRootPane = mLayouts[i].mBase.getRootPane(); - mLayouts[i].mBase.PPaneRegister(PPANE_TABLE, mLayouts[i].mPPanes, ARRAY_SIZE(PPANE_TABLE)); - mLayouts[i].mBase.NPaneRegister(NPANE_TABLE, mLayouts[i].mNPanes, ARRAY_SIZE(NPANE_TABLE)); + mLayouts[i].mBase.PPaneRegister(PPANE_TABLE, mLayouts[i].mpPicturePanes, P_COUNT); + mLayouts[i].mBase.NPaneRegister(NPANE_TABLE, mLayouts[i].mpNullPanes, N_COUNT); mLayouts[i].mpRootPane->SetVisible(false); Cancel(i); @@ -102,12 +102,12 @@ int dSelectCursor_c::draw() { } int dSelectCursor_c::doDelete() { - if (! mResLoader.remove()) { + if (!mResLoader.remove()) { return NOT_READY; } for (int i = 0; i < (int) ARRAY_SIZE(mLayouts); i++) { - if (! mLayouts[i].mBase.doDelete()) { + if (!mLayouts[i].mBase.doDelete()) { return NOT_READY; } } @@ -167,12 +167,12 @@ void dSelectCursor_c::PosSet(int layoutId) { } pos2.z = 0.0f; - mLayouts[layoutId].mNPanes[i]->SetTranslate(pos2); + mLayouts[layoutId].mpNullPanes[i]->SetTranslate(pos2); } if (mLayouts[layoutId].mDoFade) { mLayouts[layoutId].mPaneAlpha -= (255 / 10) + 1; - mLayouts[layoutId].mNPanes[0]->SetAlpha(mLayouts[layoutId].mPaneAlpha); + mLayouts[layoutId].mpNullPanes[0]->SetAlpha(mLayouts[layoutId].mPaneAlpha); if (mLayouts[layoutId].mPaneAlpha < 0) { mLayouts[layoutId].mPaneAlpha = 0; @@ -233,7 +233,7 @@ void dSelectCursor_c::SetAlpha(const nw4r::lyt::Pane *pane, int layoutId) { u8 alpha = pane->GetGlbAlpha(); Layout_c & layout = mLayouts[layoutId]; - for (int i = 0; i < ARRAY_SIZE(layout.mPPanes); i++) { - layout.mPPanes[i]->SetAlpha(alpha); + for (int i = 0; i < ARRAY_SIZE(layout.mpPicturePanes); i++) { + layout.mpPicturePanes[i]->SetAlpha(alpha); } } From b562db91eb9f61932f743bf97a8a705c0f3f6888 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 2 Nov 2025 21:06:52 +0100 Subject: [PATCH 5/6] Fix incorrect class @brief --- include/game/bases/d_SelectCursor.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/game/bases/d_SelectCursor.hpp b/include/game/bases/d_SelectCursor.hpp index 7e6373f7..1ea95fcd 100644 --- a/include/game/bases/d_SelectCursor.hpp +++ b/include/game/bases/d_SelectCursor.hpp @@ -4,7 +4,8 @@ #include #include -/// @brief The world map HUD. +/// @brief A 2D layout element that adds little L-shaped rectangles around the +/// corners of a parent layout @ref nw4r::lyt::Pane. class dSelectCursor_c : public dBase_c { /// @brief The null panes used in the layout. From 09fd9b307e35cf2084c4cf5806914f30960f7830 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 2 Nov 2025 21:29:37 +0100 Subject: [PATCH 6/6] Remove symbols from syms.txt These `dSelectCursor_c` symbols are no longer needed. --- syms.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/syms.txt b/syms.txt index 2f0de041..1b847e14 100644 --- a/syms.txt +++ b/syms.txt @@ -192,8 +192,6 @@ m_instance__7dInfo_c=8042a25c m_startGameInfo__7dInfo_c=80315e90 isAllAnime__9LytBase_cFv=800c9730 pauseOffGameWithReset__6dAudioFv=8006a990 -m_instance__15dSelectCursor_c=8042a5a8 -Cancel__15dSelectCursor_cFi=8010c890 strrchr=802e1f30 __ct__10sStateID_cFPCc=8015f900 __dt__10sStateID_cFv=8015f940