formats: decode the HUD glyph quad behind the objective counter
Following the pointers that move with REMAINING OB lands on four identical objects whose first word is 0x820B2A64. Read live: that address holds 32 consecutive code pointers in 0x823c43b0..0x823c45a0 terminated by 0xfffffffc - a vtable - and sylpheed.db has three ref xrefs to it from sub_823C3060, sub_823C3148 and sub_823C31E0, i.e. three construction sites, the same pattern the splash item vtable shows. No name: the disc's RTTI carries none. The instance is a textured quad: a pixel size at +0x1c/+0x20 (34 x 42 for a digit) and four vertices at +0x30/+0x48/+0x60/+0x78, each a colour and a UV pair. The four UVs measured are the corners of an axis-aligned rectangle in order, all 0xffffffff. The atlas size is a check rather than a guess: the UV rectangle is 0.0265 x 0.0547, and multiplying by 1280 x 768 gives 33.9 x 42.0 against the 34.0 x 42.0 stored in the object's own size fields - two independent fields agreeing to a rounding step. Also recorded: these objects churn. Re-reading an old pointer target a minute later returned unrelated data, so this is a snapshot of a live pool. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
75
docs/re/structures/hud-glyph-quad.md
Normal file
75
docs/re/structures/hud-glyph-quad.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# The HUD's glyph quad — vtable `0x820B2A64`
|
||||
|
||||
**Status: ✅ `CONFIRMED` for the object layout and the atlas size**, read live off
|
||||
a Stage 02 run and checked against itself. 🟡 the class has no name (RTTI carries
|
||||
none disc-wide).
|
||||
|
||||
## How it was reached
|
||||
|
||||
[`mission-objective-counter.md`](mission-objective-counter.md) found that the
|
||||
words moving with `REMAINING OB` are four ASCII digits and four guest pointers.
|
||||
Following the pointers lands on four objects with an identical shape, whose first
|
||||
word is `0x820B2A64`.
|
||||
|
||||
## It is a vtable, with three constructors
|
||||
|
||||
Read out of guest memory: **32 consecutive code pointers**, all inside
|
||||
`0x823c43b0 … 0x823c45a0`, terminated by `0xfffffffc`. `sylpheed.db` has three
|
||||
`ref` xrefs to it, from `sub_823C3060`, `sub_823C3148` and `sub_823C31E0` — three
|
||||
construction sites, the same pattern the splash item vtable `0x820b30b4` shows.
|
||||
The DB does not classify `0x820B2A64` itself as a vtable and knows no name for
|
||||
it, which is expected: the disc's RTTI carries no class names.
|
||||
|
||||
## The instance
|
||||
|
||||
```
|
||||
-0x0c f32 1280.0 ) the design space, immediately before the object
|
||||
-0x08 f32 720.0 )
|
||||
+0x00 u32 0x820B2A64 vtable
|
||||
+0x1c f32 34.0 width in pixels
|
||||
+0x20 f32 42.0 height in pixels
|
||||
+0x30 u32 0xffffffff vertex 0 colour
|
||||
+0x34 f32 u u
|
||||
+0x38 f32 v v
|
||||
+0x48 … vertex 1 (+0x18 stride)
|
||||
+0x60 … vertex 2
|
||||
+0x78 … vertex 3
|
||||
```
|
||||
|
||||
Measured on one digit glyph:
|
||||
|
||||
| vertex | colour | u | v |
|
||||
|---|---|---|---|
|
||||
| 0 | `0xffffffff` | 0.5477 | 0.5013 |
|
||||
| 1 | `0xffffffff` | 0.5742 | 0.5013 |
|
||||
| 2 | `0xffffffff` | 0.5742 | 0.5560 |
|
||||
| 3 | `0xffffffff` | 0.5477 | 0.5560 |
|
||||
|
||||
Four corners of an axis-aligned rectangle, in order, all untinted — a textured
|
||||
quad.
|
||||
|
||||
## ✅ The atlas is 1280 × 768, and that is a check rather than a guess
|
||||
|
||||
The UV rectangle is 0.0265 × 0.0547. Multiply by **1280 × 768**:
|
||||
|
||||
```
|
||||
0.0265 × 1280 = 33.9 -> the width stored at +0x1c is 34.0
|
||||
0.0547 × 768 = 42.0 -> the height stored at +0x20 is 42.0
|
||||
```
|
||||
|
||||
Two independent fields of the same object agree to within a rounding step, which
|
||||
is what makes the atlas size a measurement instead of a plausible number.
|
||||
|
||||
## ⚠️ These objects churn
|
||||
|
||||
The four pointers next to the counter swap as the digit changes, and re-reading
|
||||
one of the *old* targets a minute later returned unrelated data — the object had
|
||||
been recycled. Anything read here is a snapshot of a live pool, not a stable
|
||||
address.
|
||||
|
||||
## What this is for
|
||||
|
||||
It gives the port a decoded HUD text primitive: a glyph is a quad with a pixel
|
||||
size and four UVs into a 1280×768 atlas, drawn by a class with 32 virtual methods
|
||||
and three constructors. And it explains why the objective counter was so easy to
|
||||
find in RAM — the value sits inside the widget that renders it.
|
||||
Reference in New Issue
Block a user