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.
The item class's vtable (0x820b30b4) is a fixed 4-byte value at offset 0 of every
instance, so gmem.py finds the objects in the running game with no debugger and
no emulator change. Seven are live on the title screen.
Their first {ptr,count,capacity} triplet identifies them outright: counts of 24,
7 and 1 — exactly GP_TITLE's title build, loading overlay and PRESS (A) BUTTON
bundle. The two-bundle composition of the title screen, which the draw capture
had inferred, is visible directly in memory.
The element array at +0x08 is 48-byte entries in declaration order, and it was
checked against the file at five positions with no misses: elements 0, 1, 6, 9
and 21 carry pivots (451,50), (449,46), (320,160), (320,180) and (309,10) as
floats, matching build 4 exactly, and elements 0/1 carry keyframe count 8, which
is their count in the file.
Stated as the reason this was done and NOT achieved: the array is in declaration
order, which the capture already proves is not the paint order, so the renderer
walks something else or sorts. Three further triplets in the object are
unidentified; the 24-entry one at +0x14 is already ruled out as an index list
(its entries are pointers, not indices). The gain is that the question is now a
data question on a structure that dumps in seconds.