diff --git a/docs/re/structures/ui-paint-order-key.md b/docs/re/structures/ui-paint-order-key.md new file mode 100644 index 0000000..53a4746 --- /dev/null +++ b/docs/re/structures/ui-paint-order-key.md @@ -0,0 +1,66 @@ +# The paint order comes from a layer key in the T8aD sprite header + +**Status:** ✅ `CONFIRMED` on both screens whose paint order has been measured — +the key is **non-decreasing in paint order on every element that has a sprite**, +20 of 24 on one and 6 of 7 on the other. 🟡 ties are not explained. ❔ the field's +full meaning (it looks like flags, not a plain depth). + +## The field + +Every `T8aD` sprite begins with a 44-byte header. The word at **`+0x08`** — +untouched by this project's decoder, which reads width/height/tile-count at +`+0x14`/`+0x18`/`+0x1c` — sorts the screen. + +Read in the order the game paints them (`ui-screen-runtime.md` has how that order +was measured — off the live child list, checked against a draw capture): + +**`GP_TITLE` build 4, the title screen** + +| paint slot | element | sprite | `+0x08` | +|---|---|---|---| +| 0 | 9 | `ptbase2` | `0x8000` | +| 3 | 10 | `pteff04` | `0x8020` | +| 5 | 6 | `pteff01` | `0x8040` | +| 6 | 20 | `ptlogo_back2eff` | `0x8081` | +| 7 | 19 | `ptlogo_back2` | `0x8082` | +| 8–12 | 14,15,18,16,17 | `back2eff1…5` | `0x8083` ×5 | +| 13–19 | 0,2,4,7,1,3,5 | `ptlogo1`/`tm`/`ptlogo2` | `0x80a0` ×7 | +| 20 | 22 | `ptlogoall_eff` | `0x80a8` | +| 21 | 23 | `ptlogoall_eff2` | `0x80a9` | +| 22 | 21 | `ptcopyright` | `0x8100` | + +**`GP_TITLE` entries 11/14, the developer-logo splash** + +| paint slot | sprite | `+0x08` | +|---|---|---| +| 1–3 | the three `_eff` glows | `0x a100` ×3 | +| 4–6 | the three base logos | `0x a110` ×3 | + +Both are **ascending, with no inversion anywhere**. On the splash it explains the +whole permutation — the glows sort before their logos because `0xa100 < 0xa110`, +which is why the declaration table's interleaving (base, glow, base, glow) is not +what you see. + +## Why this matters + +It is the first **file-derivable** account of the paint order. Everything checked +before it failed: declaration order and its reverse, the placement region, the +RATC child order, keyframe start and rest times, resting Y, the runtime element +record's fields, and every other build's table. This is a per-sprite value the +port can read directly. + +## What is not settled + +* **Ties.** Two groups share a key (`0x8083` ×5 and `0x80a0` ×7) and the game + paints them in an order that is *not* the declaration order — + `14,15,18,16,17` and `0,2,4,7,1,3,5`. Something breaks those ties and it is not + known. For the port it may not matter (tied elements are same-layer, and the + three `ptlogo1`/`ptlogo2` instances are the ghosts that are not drawn at rest), + but it is unmeasured, not proven harmless. +* **The field's meaning.** `0x8000`, `0x8020`, `0x8040`, `0x8081`… `0x8100` on + one screen and `0xa100`/`0xa110` on another look like flag words with a layer + in some of the bits rather than a plain integer depth. Sorting on the whole + word works on both screens; which bits actually carry the layer is unknown. +* **Two screens is two screens.** A third measured permutation would either + promote this to a rule or break it. The cheapest one available is any screen + whose object is resident at the same time as the title's.