Some checks failed
BGM_001.slb is three sub-waves (10 KB, 4.47 MB, 4.67 MB) and the decoder concatenates them into one 347 s track. That is a default nobody chose, not a decision: two near-equal halves could be intro + loop, two variations, or two halves of one piece, and a menu that loops its music needs to know which. Found while wiring the Audio Library up to the shared banks. Recorded in HANDOFF.md as a trap too, so the port does not build looping on top of the concatenated track before the question is answered. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
100 lines
5.5 KiB
Markdown
100 lines
5.5 KiB
Markdown
# Handoff — what the menu port needs, and where it stands
|
||
|
||
The single page the **port agent** reads. Everything here is produced by the
|
||
container agent's reverse engineering; nothing here is a design decision about
|
||
the port itself.
|
||
|
||
Keep it current. It is a summary with links into `docs/re/`, not a second copy of
|
||
the findings — but an answer that is not reachable from this page has not been
|
||
delivered.
|
||
|
||
## How to read an answer
|
||
|
||
Every row below is one of exactly three things, and the distinction is the point:
|
||
|
||
| | meaning | what the port should do |
|
||
|---|---|---|
|
||
| **decoded** | a field on the disc, with a disc-wide check | read it from the data |
|
||
| **measured** | not on the disc in any form we found, but the running game does *this* | hardcode it, and cite this page |
|
||
| **undecodable** | we looked in these places, it is not there, here is the reach of the negative | author it by hand, knowingly |
|
||
|
||
There is no fourth kind. If a row says *measured* or *undecodable*, the port is
|
||
**authoring** that value, not transcribing it — and it should be kept somewhere a
|
||
human can see it is a human decision, so that when it is later decoded the
|
||
authored version can be deleted.
|
||
|
||
## Status
|
||
|
||
| | Question | State | Answer / link |
|
||
|---|---|---|---|
|
||
| Q1 | keyframe time unit + ramp shape | ❔ open | blocks all animation |
|
||
| Q2 | which build is which screen state | 🟡 partial | build 4 title, 5 main menu, 6/8/9 submenus, `palogo` splash — unconfirmed against captures |
|
||
| Q3 | paint order for the six screens | ❔ open | runtime-solved only; declaration table is refuted |
|
||
| Q4 | button → GamePart | ❔ open | labels are baked into sprites |
|
||
| Q5 | navigation semantics | ❔ open | |
|
||
| Q6 | boot sequence + what drives it | 🟡 partial | order observed; the driver is not decoded |
|
||
| Q7 | transitions | ❔ open | |
|
||
| Q8 | menu audio bindings | ❔ open | cue table complete, event binding is not |
|
||
| Q9 | video binding + playback rules | 🟡 partial | `ADV.wmv` is the boot intro; new-game intro unidentified |
|
||
| Q10 | music-bank sub-wave roles (intro+loop?) | ❔ open | we concatenate blindly today |
|
||
| S1 | Ready Room go/no-go | ❔ open | probe not run |
|
||
|
||
## Already settled — the port can rely on these today
|
||
|
||
* **`GP_TITLE.pak` is the whole title-side tree.** Build 4 is the title with the
|
||
animating wordmarks, build 5 the five-button main menu, builds 6/8/9 are
|
||
submenus, and the developer splash is the `palogo` bundle in the same archive.
|
||
✅ decoded (enumeration), 🟡 the state labels are not yet capture-confirmed.
|
||
* **Buttons are identifiable as data.** Element kind `0x3002` = button, `0x0` =
|
||
decoration, `0x10` = primitive. ✅ decoded.
|
||
* **Menu order is geometric.** Buttons sorted top-to-bottom by resting Y. This is
|
||
✅ correct for a vertical menu and is **not** a decoded neighbour graph — the
|
||
disc's real navigation structure is unknown, and `opt ` is *not* a focus link
|
||
(measured and refuted, see
|
||
[`ui-focus-and-effect-elements.md`](../re/structures/ui-focus-and-effect-elements.md)).
|
||
* **Highlighted states pair by name** — `ptbtn01.rat` ↔ `ptbtn01f.rat`. 🟡 a
|
||
naming convention that holds for all 54 real pairs, not a decoded field.
|
||
* **The resting pose is the hold**, not the first, last or longest-dwell keyframe;
|
||
a keyframe is the **start of a ramp**.
|
||
[`ui-resting-pose.md`](../re/structures/ui-resting-pose.md). ✅
|
||
* **The GamePart id table** — 29 entries at `.rdata 0x820A1630`, confirmed by the
|
||
executable's own registration strings. ✅ This is the screen vocabulary; which
|
||
button reaches which entry is Q4 and is *not* part of it.
|
||
* **The logo splash is a screen, not a video.** `logo1`–`logo4` are
|
||
manifest-bound with no `.wmv` on the disc. ✅
|
||
* **Sprites carry their own labels.** No font rendering or localisation is needed
|
||
for this milestone. ✅
|
||
|
||
## Facts the port will trip over
|
||
|
||
* **`ADV.wmv` is WMV3 video + WMA Pro audio**, 1280×720 at 30 fps, 137 s. Godot 4
|
||
plays only Ogg Theora natively. How to handle that is the port's decision, not
|
||
ours — but it is not optional.
|
||
* **The disc holds 3.3 GB of video.** Only the boot intro and the one new-game
|
||
intro are in scope.
|
||
* **`Static.slb` over-declares its size** by 616 768 bytes — it is the
|
||
highest-offset entry in `sound.pak` and its size field is an allocation size. A
|
||
reader must allow a short read there and only there.
|
||
* **Voice downmixes to mono, music does not.** The left-channel downmix is correct
|
||
for spoken lines and discards half a music mix.
|
||
* **A music bank has several sub-waves and we glue them together.** `BGM_001`
|
||
is 10 KB + 4.47 MB + 4.67 MB, concatenated into one 347 s track. Nobody has
|
||
established whether those are intro + loop, two variations, or two halves —
|
||
see Q10. Do not build menu looping on the concatenated track until it is
|
||
answered.
|
||
* **`JNGL_001.slb` does not decode.** One bank in 9 519; its payload is not a whole
|
||
number of XMA1 packets from any known data offset.
|
||
|
||
## Reference data
|
||
|
||
Committed alongside the findings, so the port can be built without a disc in the
|
||
loop during development:
|
||
|
||
* `sylpheed-cli screen info --build <n> GP_TITLE.pak` — the element table, per
|
||
build, with pivots, kinds, focus links, keyframes and resting poses.
|
||
* `sylpheed-cli screen render` — the reference composite. When the port draws a
|
||
screen, this is what it should be diffed against; where they disagree, one of
|
||
them is wrong and the disagreement is worth reporting back.
|
||
* `docs/re/captures/` — framebuffer captures of the real screens, for anything
|
||
that has to be checked against the game rather than against our renderer.
|