From e9a227a13903d90d8098aebe96a9993e7a05833e Mon Sep 17 00:00:00 2001 From: DarthM Date: Fri, 18 Sep 2026 03:59:07 -0400 Subject: [PATCH 1/2] Document Section layout and type page registration --- src/ui/Section.hpp | 42 ++++++++++++++++++++++++++++++++++++++ src/ui/SectionAutogens.cpp | 4 ++-- src/ui/SectionAutogens.hpp | 6 ++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/ui/Section.hpp b/src/ui/Section.hpp index 6f70f09b..412e3b26 100644 --- a/src/ui/Section.hpp +++ b/src/ui/Section.hpp @@ -1 +1,43 @@ #pragma once + +#include + +#include + +namespace UI { + +class Page; + +// The top-level owner for a UI section's pages. This layout is derived from +// StaticR.rel's Section.o (0x80621D0C--0x80624690). The fields following the +// active page stack have not been named yet, but their exact locations matter +// to every function in this translation unit. +class Section { +public: + s32 sectionId; + u32 _04; + Page* pages[211]; + Page* activePages[10]; + s32 activePageCount; + Page* systemPages[2]; + u8 _388[8]; + u8 _390[0x54]; + void* allocator; + void* resourceAccessors; + void* layoutThings; + f32 _3f0; + f32 _3f4; + f32 _3f8; + f32 _3fc; + void* _400; + void* _404; +}; + +static_assert(offsetof(Section, pages) == 0x8); +static_assert(offsetof(Section, activePages) == 0x354); +static_assert(offsetof(Section, activePageCount) == 0x37c); +static_assert(offsetof(Section, systemPages) == 0x380); +static_assert(offsetof(Section, allocator) == 0x3e4); +static_assert(sizeof(Section) == 0x408); + +} // namespace UI diff --git a/src/ui/SectionAutogens.cpp b/src/ui/SectionAutogens.cpp index 9125d36a..77dee358 100644 --- a/src/ui/SectionAutogens.cpp +++ b/src/ui/SectionAutogens.cpp @@ -1,6 +1,6 @@ #include "SectionAutogens.hpp" -void Section_addPages(void* pSection, int sectionId) { +void Section_addPages(UI::Section* pSection, int sectionId) { switch (sectionId) { case 6: Section_addPage(pSection, 0); @@ -1587,7 +1587,7 @@ void Section_addPages(void* pSection, int sectionId) { } } -void Section_addActivePages(void* section, int sectionId) { +void Section_addActivePages(UI::Section* section, int sectionId) { switch (sectionId) { case 6: Section_addActivePage(section, 0); diff --git a/src/ui/SectionAutogens.hpp b/src/ui/SectionAutogens.hpp index 6b9026eb..1b32ae8e 100644 --- a/src/ui/SectionAutogens.hpp +++ b/src/ui/SectionAutogens.hpp @@ -5,7 +5,9 @@ #include #include +#include "Section.hpp" + extern "C" { -void Section_addActivePage(void*, int); -void Section_addPage(void*, int); +void Section_addActivePage(UI::Section*, int); +void Section_addPage(UI::Section*, int); } From e6faa4f6f3fe147a080f556bc66321c01bce0a1b Mon Sep 17 00:00:00 2001 From: DarthM Date: Fri, 18 Sep 2026 04:09:00 -0400 Subject: [PATCH 2/2] Decompile Section page stack helpers --- config/RMCP01/module/splits.txt | 4 +-- configure.py | 1 + src/ui/Section.cpp | 48 ++++++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/config/RMCP01/module/splits.txt b/config/RMCP01/module/splits.txt index af8db114..bd84f63a 100644 --- a/config/RMCP01/module/splits.txt +++ b/config/RMCP01/module/splits.txt @@ -155,8 +155,8 @@ ui/Page.cpp: .text start:0x8060197C end:0x80602D2C .data start:0x808BA5C0 end:0x808BA624 -ui/Section.o: - .text start:0x80621D0C end:0x80624690 +ui/Section.cpp: + .text start:0x80622D08 end:0x80622EC8 ui/SectionAutogens.cpp: .text start:0x8062C3A4 end:0x8063240C diff --git a/configure.py b/configure.py index c6cee541..6ab81653 100755 --- a/configure.py +++ b/configure.py @@ -804,6 +804,7 @@ def MatchingFor(*versions): Object(Matching, "ui/ControlGroup.cpp"), Object(Matching, "ui/MessageGroup.cpp"), + Object(Matching, "ui/Section.cpp"), Object(NonMatching, "ui/SectionAutogens.cpp"), Object(NonMatching, "ui/SectionManager.cpp"), Object(NonMatching, "ui/Page.cpp"), diff --git a/src/ui/Section.cpp b/src/ui/Section.cpp index c3e79214..761dcde6 100644 --- a/src/ui/Section.cpp +++ b/src/ui/Section.cpp @@ -1,3 +1,49 @@ #include "Section.hpp" -#include "SectionAutogens.hpp" +#include "Page.hpp" + +extern "C" UI::Page* Section_createPage(int pageId); +extern "C" UI::Page* createSystemPage(int pageId, int sectionId); +extern "C" void Page_init(UI::Page* page, int pageId); +extern "C" void Page_activate(UI::Page* page); +extern "C" void SystemPage_init(UI::Page* page); + +extern "C" void Section_addPage(UI::Section* section, int pageId) { + section->pages[pageId] = Section_createPage(pageId); + Page_init(section->pages[pageId], pageId); +} + +extern "C" void fn_1_1129A0(UI::Section* section, int pageId) { + section->systemPages[pageId] = createSystemPage(pageId, section->sectionId); + if (section->systemPages[pageId] != nullptr) { + SystemPage_init(section->systemPages[pageId]); + } +} + +extern "C" void Section_addActivePage(UI::Section* section, int pageId) { + UI::Page* page = section->pages[pageId]; + section->activePages[section->activePageCount++] = page; + page->setAnimationDirection(section->_04); + Page_activate(page); +} + +extern "C" UI::Page* Section_activatePage(UI::Section* section, int pageId, + int animationDirection) { + UI::Page* page = section->pages[pageId]; + section->activePages[section->activePageCount++] = page; + page->setAnimationDirection(animationDirection); + Page_activate(page); + return page; +} + +extern "C" int Section_isPageActive(UI::Section* section, UI::Page* page) { + return section->activePageCount >= 1 && + section->activePages[section->activePageCount - 1] == page; +} + +extern "C" UI::Page* Section_getVisiblePage(UI::Section* section) { + if (section->activePageCount < 1) { + return nullptr; + } + return section->activePages[section->activePageCount - 1]; +}