docs/re: SOLVED — the paint order is the screen object's child array at +0x30
The screen object holds a SECOND list of its elements, a reordering built at load time, and that list is the paint order. It is 24 pointers at +0x30, each the +0x00 field of one of the 48-byte element records, so both arrays hold the same objects in different orders. Checked against the draw capture rather than asserted: the seven elements the capture can name sit at child slots 0, 6, 7, 13, 16, 17, 22 — strictly ascending, in exactly the captured submission order. It also resolves the one sub-order no static field could explain, the pair that decodes to the same 1133x280: slot 6 is element 20 and slot 7 is element 19, so they paint 20-then-19, DESCENDING in declaration terms. And the kind=0x4 repeat instances sit immediately after their template, where the declaration table interleaves them. Stated as unsolved, because the port cannot read a runtime array: deriving this order from the bundle. The order is clearly structured rather than arbitrary — elements sharing a sprite are adjacent and the full-screen effects lead — so it is worth attacking, but it is not attacked here.
This commit is contained in:
@@ -85,3 +85,64 @@ not small integers), so the obvious "draw order table" reading is already out.
|
||||
structure that can be dumped in seconds, rather than a code-reading exercise. The
|
||||
next probe is to dump `+0x24` and `+0x30` on the title build and see whether
|
||||
either is 24 entries in a non-declaration order.
|
||||
|
||||
## ✅ The paint order is the screen object's CHILD array at `+0x30`
|
||||
|
||||
**Status: `CONFIRMED`.** The question this project has carried since the first
|
||||
capture — *what orders the elements, given that the declaration table does not* —
|
||||
is answered: the screen object holds a **second list**, a reordering of the
|
||||
elements built at load time, and that list is the paint order.
|
||||
|
||||
`+0x30` is `{ptr, count, capacity}` → an array of **24 pointers** (not 12-byte
|
||||
records like `+0x14`). Each pointer is the `+0x00` field of one of the 48-byte
|
||||
element records, so the two arrays hold the same objects in different orders. The
|
||||
permutation, read live off the title screen:
|
||||
|
||||
| child slot | element | | child slot | element |
|
||||
|---|---|---|---|---|
|
||||
| 0 | 9 `ptbase2` | | 12 | 17 `back2eff4` |
|
||||
| 1 | 11 `ptloop01` | | 13 | **0 `ptlogo1`** |
|
||||
| 2 | 12 `ptloop02` | | 14 | 2 `ptlogo1` (copy) |
|
||||
| 3 | 10 `pteff04` | | 15 | 4 `ptlogo1` (copy) |
|
||||
| 4 | 13 `pteff02.prm` | | 16 | **7 `ptlogo_tm`** |
|
||||
| 5 | 6 `pteff01` | | 17 | **1 `ptlogo2`** |
|
||||
| 6 | **20 `ptlogo_back2eff`** | | 18 | 3 `ptlogo2` (copy) |
|
||||
| 7 | **19 `ptlogo_back2`** | | 19 | 5 `ptlogo2` (copy) |
|
||||
| 8 | 14 `back2eff1` | | 20 | 22 `ptlogoall_eff` |
|
||||
| 9 | 15 `back2eff2` | | 21 | 23 `ptlogoall_eff2` |
|
||||
| 10 | 18 `back2eff5` | | 22 | **21 `ptcopyright`** |
|
||||
| 11 | 16 `back2eff3` | | 23 | 8 `pteff00.prm` |
|
||||
|
||||
### Checked against the capture, not merely plausible
|
||||
|
||||
The seven elements the draw capture can name occupy child slots
|
||||
|
||||
```
|
||||
ptbase2 0 back2eff 6 back2 7 ptlogo1 13 tm 16 ptlogo2 17 copyright 22
|
||||
```
|
||||
|
||||
— **strictly ascending, in exactly the captured submission order**. Two details
|
||||
make this more than a coincidence of a short list:
|
||||
|
||||
* it **resolves the ambiguity** that no static field could: slot 6 is element
|
||||
**20** (`ptlogo_back2eff`), slot 7 is element 19, so the pair paints
|
||||
20-then-19 — *descending* in declaration terms. Nothing in the file predicts
|
||||
that, and the runtime list states it;
|
||||
* the three `kind = 0x4` repeat instances of each logo sit **immediately after
|
||||
their template** (slots 13,14,15 and 17,18,19), which the declaration table
|
||||
interleaves (0,1,2,3,4,5). They draw at α=0 and so never appeared in the
|
||||
capture, but their placement in the list is consistent with the grouping.
|
||||
|
||||
### What this means for the port, stated carefully
|
||||
|
||||
The reimplementation cannot read a runtime array — it has to *derive* this order
|
||||
from the bundle. **That derivation is not solved.** What the order shows is
|
||||
structure worth attacking: elements sharing a sprite are adjacent
|
||||
(`ptlogo1`×3 together, `ptlogo2`×3 together, the `back2eff*` family together),
|
||||
and the full-screen/effect elements lead. So the load-time build is doing some
|
||||
grouping, not an arbitrary shuffle.
|
||||
|
||||
Until it is derived, a reimplementation has two honest options: hard-code the
|
||||
captured order for the screens that have been captured, or paint in declaration
|
||||
order and accept that the title screen composites wrongly. The first is what the
|
||||
evidence supports; the second is what the viewer does today.
|
||||
|
||||
Reference in New Issue
Block a user