docs/re: re-refute the time orderings on the right build, and kill a Y-sort
Two of the paint-order refutations were computed with build 7's keyframe times, and build 7 is not the build the game runs. Re-checked on build 4: both still fail, on the same element (ptlogo1 paints after ptlogo_back2 though it starts at t=26 against t=66, and rests at t=42 against t=80). A new candidate is recorded and refuted rather than left implicit, because it is the kind that gets adopted on partial agreement: painter's order by resting Y reproduces the captured order to within a single transposition — and is wrong twice, on ptlogo_tm (drawn before a sprite 63 px higher) and on the background (drawn first, though its resting Y would sort it fourth). Also scoped, not walked: the guest-code avenue. The splash item vtable 0x820b30b4 is real (25 slots, three construction sites); RTTI carries no class names anywhere in the binary; the format tags are fourcc immediates behind a virtual call, not strings; and the obvious shortcut — searching for the 60-byte declaration stride — leads to a time-string parser, not the table.
This commit is contained in:
@@ -175,6 +175,27 @@ had to be cleared to establish that much — see
|
||||
[`canary-scripted-input-traps.md`](canary-scripted-input-traps.md), which also
|
||||
carries the reproduction and the fix for two of them.
|
||||
|
||||
### 2026-08-18 (fourth pass) — the crash is named, and the code avenue is scoped
|
||||
|
||||
The crash PC resolves to an MSVC `std::map`/`set` erase that throws
|
||||
`'invalid map/set<T> iterator'` — a 40-second reproduction of the Ready-Room
|
||||
crash, in [`title-crash-stl-tree.md`](title-crash-stl-tree.md). That is a
|
||||
by-product of this item, and it belongs to whoever picks up the crash bisection.
|
||||
|
||||
For the ordering itself, three more negatives, all recorded in
|
||||
[`ui-title-paint-order-capture.md`](ui-title-paint-order-capture.md): the two
|
||||
time-based orderings were re-checked against **build 4** (the previous pass used
|
||||
build 7's numbers, and build 7 is not what runs) and both still fail on the same
|
||||
element; and a fresh candidate — painter's order by resting **Y** — reproduces
|
||||
the capture to within a single transposition but is refuted by `ptlogo_tm` and by
|
||||
the background, so it is not the rule either.
|
||||
|
||||
The code avenue is scoped rather than walked: the splash item vtable
|
||||
`0x820b30b4` is real (25 slots, three construction sites), RTTI carries **no**
|
||||
class names disc-wide, and the format tags are fourcc immediates behind a virtual
|
||||
call rather than strings — so this needs a deliberate read of the UI engine, not
|
||||
a keyword search.
|
||||
|
||||
|
||||
## Capital ships assemble wrong in the viewer
|
||||
|
||||
|
||||
@@ -213,3 +213,54 @@ sequence across frames, no bound-texture identity, and de-dups on a key that
|
||||
happens not to collide here only because the game rebuilds its UI vertex buffer
|
||||
every frame. But "it cannot see UI draws" was wrong, and the cost of the new hook
|
||||
was justified with a wrong reason.
|
||||
|
||||
---
|
||||
|
||||
## The refutations, re-checked against the build the game actually runs
|
||||
|
||||
The two time-based orderings were first refuted with build 7's numbers, and build
|
||||
7 is not what runs. Re-checked on **build 4**, both still fail, and by the same
|
||||
element:
|
||||
|
||||
| ordering | build 4 values, in the observed paint order | verdict |
|
||||
|---|---|---|
|
||||
| first keyframe time | bg 0, `back2eff5` 62, `back2` 66, **`logo1` 26**, `tm` 98, **`logo2` 26**, `copyright` 138 | not monotonic — refuted |
|
||||
| resting keyframe time | `back2eff5` 74 / `back2eff` 66, `back2` 80, **`logo1` 42**, `tm` 116, **`logo2` 42**, `copyright` 160 | not monotonic — refuted |
|
||||
|
||||
**A new candidate, and its counterexamples.** Painter's order by *screen depth*
|
||||
would be the obvious runtime rule, and sorting the identified sprites by resting
|
||||
**Y** very nearly reproduces the capture:
|
||||
|
||||
```
|
||||
sorted by rest Y : back2eff5 117, back2 126, logo1 186, logo2 315, tm 378, copyright 655
|
||||
captured order : back2eff5, back2, logo1, tm, logo2, copyright
|
||||
```
|
||||
|
||||
— one transposition away. It is still **refuted**, twice over: `ptlogo_tm`
|
||||
(y 378) is painted before `ptlogo2` (y 315), and the full-screen background is
|
||||
painted *first* although `ptbase2`'s resting Y (180) would sort it after both
|
||||
`back2` elements. Recorded because "nearly sorted by Y" is the kind of result
|
||||
that gets adopted as a rule if only the agreeing five are counted.
|
||||
|
||||
## A foothold in the guest code, and what it is not
|
||||
|
||||
The remaining avenue is the code, and `xenia-rs/sylpheed.db` is in the container.
|
||||
What is established so far is small, and stated so it is not mistaken for more:
|
||||
|
||||
* **The item class from the splash-era work is real.** Vtable `0x820b30b4` is
|
||||
class `ANON_Class_03A0925F` with **25 slots**, constructed at three sites
|
||||
(`sub_823CB2A0`, `sub_823CB558`, `sub_823CBB90`, each with a single caller).
|
||||
* **RTTI carries no names.** All 851 classes in the database are
|
||||
`ANON_Class_########`; the retail binary has the RTTI structure but not the
|
||||
type names, so nothing can be found by searching for "screen" or "sprite".
|
||||
* **The format tags are immediates, not strings.** `RATC` appears as
|
||||
`addis 0x5241` / `ori 0x5443` in ~10 functions in the `0x82188`–`0x821B1`
|
||||
range, always loaded into `r4` before a **virtual** call — e.g. `sub_821881D8`
|
||||
does `obj->slot1('RATC', &out)`, then passes the result to `sub_82187B78`. So
|
||||
the container walk is behind an interface, and a plain string search for
|
||||
`.rat` / `.t32` finds nothing (2 hits disc-wide, both unrelated).
|
||||
* **A dead end worth recording:** searching for the declaration table's 60-byte
|
||||
stride (`mulli rX, rY, 60`) finds 49 sites, and the most promising,
|
||||
`sub_821B4498`, turns out to be a **time-string parser** (`MM:SS.mmm` — it
|
||||
splits on `:` and `.` and multiplies by 60, then 100). The guest does not
|
||||
necessarily index that table with a multiply at all.
|
||||
|
||||
Reference in New Issue
Block a user