From 48087511130c210e24c0a0aa660a5fb0e4128dc4 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Wed, 19 Aug 2026 01:16:14 +0000 Subject: [PATCH] docs/re: find the guest's UI quad class from the layout the capture measured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The capture pinned the UI vertex exactly — prim 13, stride 24, float3 position at +0, k_8_8_8_8 colour at +12, float2 UV at +16 — so the binary was searched for code that writes that shape. Fifteen candidates; the tightest, sub_82250138, is unambiguous: it asks a renderer for 4 vertices of primitive type 13, then writes x/y/z, colour 0xFFFFFFFF at +12, u/v at +16/+20, stepping by 24. Every constant matches something measured rather than assumed. Its caller is a constructor that installs vtable 0x820A7264 (ANON_Class_AAFDBF89, 2 slots) — the UI quad/sprite class. Recorded with equal weight: this is NOT what the search was for. The chain up from it ends at sub_821A8578, which turns out to be an unrolled run of ~30 identical call triplets — a fixed subsystem sequence, not an element walk. No function that iterates screen elements has been found, and nothing here bears on the paint order yet. --- docs/re/ui-quad-class-foothold.md | 78 +++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 docs/re/ui-quad-class-foothold.md diff --git a/docs/re/ui-quad-class-foothold.md b/docs/re/ui-quad-class-foothold.md new file mode 100644 index 0000000..122e147 --- /dev/null +++ b/docs/re/ui-quad-class-foothold.md @@ -0,0 +1,78 @@ +# The guest's UI quad class — a foothold found from the capture's vertex layout + +**Status:** 🟡 `PROBABLE` for the identification below (it is a static read, but +the layout it matches was *measured* first). ❔ the element walk that decides +paint order is **not** in this note — that is what the search was for, and it was +not reached. + +## How it was found + +The runtime capture says exactly what a UI vertex looks like: +`prim = 13` (quad list), stride **24**, attributes `57@0` (`k_32_32_32_FLOAT` +position), `6@12` (`k_8_8_8_8` colour), `37@16` (`k_32_32_FLOAT` UV). That is a +fingerprint a store sequence in the guest must match, so the binary was searched +for functions that write floats at +0/+4/+8, a word at +12, floats at +16/+20, +and advance a pointer by 24 (`sylpheed.db`, 15 candidates ranked by how many of +each they contain). + +The tightest match is **`sub_82250138`** (288 B, three of each store, two +`addi …, 24`), and it is unambiguous: + +``` +82250150 addi r5, r0, 13 ; primitive type 13 = QUAD LIST +82250154 addi r4, r0, 4 ; 4 vertices +82250158 lwz r11, 0(r31) … ; renderer->slot0(4, 13) -> allocate +82250170 lwz r11, 8(r11) … ; renderer->slot2() -> vertex pointer +82250188 addi r10, r0, -1 ; colour = 0xFFFFFFFF +82250194 stfs f13, 0(r3) ; x +82250198 stw r10, 12(r3) ; colour ← +12, as the capture says +822501A0 stfs f13, 4(r3) ; y +822501A4 addi r11, r3, 24 ; next vertex ← stride 24, as the capture says +822501AC stfs f0, 8(r3) ; z +822501B0 stfs f0, 20(r3) ; v +822501B4 stfs f0, 16(r3) ; u +``` + +`prim = 13`, four vertices, colour `0xFFFFFFFF` and stride 24 all match what the +title screen was measured drawing. + +## What it is (and what it is not) + +Its only caller, `sub_8224FB78` (752 B), is a **constructor**: it stores a vtable +pointer into `0(r29)`, zeroes a run of fields, sets a colour, and has the emitter +lay down a default quad. So `sub_82250138` builds an object's *initial* geometry +rather than drawing a frame. + +The vtable it installs is **`0x820A7264`** — class `ANON_Class_AAFDBF89`, **2 +slots** (`sub_8224FF98`, `sub_8224FB18`). That is the UI quad/sprite class. + +**It is not the element walk.** Following the callers upward: + +``` +sub_82250138 (quad emitter) + └ sub_8224FB78 (constructor, installs vtable 0x820A7264) + └ sub_82222E70 (2 260 B) + └ sub_821A5F10 (756 B) + └ sub_821A8578 (3 120 B) ← a top-level render function + └ sub_821A8428 (284 B) +``` + +`sub_821A8578` is not data-driven: it is an **unrolled** run of about thirty +identical `bl 8217FA08 / bl 821AC450 / bl 82454918` triplets. So it sequences a +fixed list of subsystems, not a list of screen elements. The element order this +project is chasing is somewhere else — most likely behind one of those three +repeated calls, or behind the sprite class's own two vtable slots. + +## Why this is worth keeping + +Two reasons, neither of which is "it looks right": + +* the identification is anchored to a **measurement** — the vertex layout came + from the running game first, and the search was for code that matches it; +* it names a concrete class (`0x820A7264`) and a concrete API shape + (`allocate(count, prim)` then `get vertex pointer`), which is the thing to + instrument or trace next. + +**Not settled:** everything the search was actually for. No function that +iterates screen elements has been found, and nothing here bears on the paint +order yet.