The port is forbidden from reimplementing media assembly and Static.slb is exactly that case: no RIFF, no seek chunk, no XACT container, just a packed run of whole 2048-byte XMA1 packets, so a wave is defined only by (offset, packet count) and the header has to be synthesized. That step now happens once, in the crate that owns the format, instead of in each consumer. `slb::xma1_wave_riff` wraps raw packets; `media::se_wave_riff` looks the bank up and reads just the packets asked for. Both reuse the existing synth_xma1_fmt / build_riff, which are already byte-identical to what tools/re-capture/ slb_extract_wave.py writes -- so this is exposure, not a second implementation. It reads a TARGETED range rather than the whole bank, and that is load-bearing: Static.slb is the ONE entry of sound.pak's 9 519 whose declared extent runs past the end of the extracted segments -- by exactly 616 768 B -- so reading it whole fails outright on this extraction. Every cue we need is in the first few hundred KB. Recorded rather than worked around silently. Verified as an artifact, not a compile: all three cues decode through ffmpeg to mono 48 kHz PCM at 0.533 / 0.344 / 1.016 s, non-silent (rms 2085 / 2985 / 4327, peaks 29813 / 16973 / 32767). The refusal path is exercised in the same run -- an impossible packet count is rejected rather than returning a short stream, because a truncated XMA decodes to plausible-sounding garbage. Also adds docs/re/captures/ORACLE-CAPTURES.md: an index of the nine canary framebuffer captures already in this repo, and a plain statement that THEY are the reference and `screen render` is not.
54 lines
3.2 KiB
Markdown
54 lines
3.2 KiB
Markdown
# The oracle frames — what to verify a render against
|
||
|
||
**These are framebuffer captures of the real game running under Xenia Canary.**
|
||
They are the reference. `sylpheed-cli screen render` is **not** — Reborn is a GUI
|
||
explorer and extraction CLI built to check that our *decoding* is right, and it
|
||
may very well be wrong. Where a render and a capture disagree, the capture wins,
|
||
and the render is the thing to go and fix.
|
||
|
||
⚠️ Two renderers agreeing proves nothing: they share our assumptions. This corpus
|
||
has been bitten by exactly that three times — the dropped `pteff05` background,
|
||
the scale-0 rect, and `rest()`. Each was invisible to any render-vs-render diff
|
||
and visible immediately against a capture.
|
||
|
||
## The frames
|
||
|
||
All are **1279×675**, top-left aligned, cropped to the game surface by the
|
||
screenshot tool (the guest renders 1280×720; the missing row/column is the crop,
|
||
not a scale).
|
||
|
||
| screen | capture |
|
||
|---|---|
|
||
| publisher splash (SQUARE ENIX) | [`title-builds/live-splash-publisher.png`](title-builds/live-splash-publisher.png) |
|
||
| developer splash (GAME ARTS / SETA / anima) | [`title-builds/live-splash-developer.png`](title-builds/live-splash-developer.png) |
|
||
| title, **without** the `PRESS Ⓐ` plate | [`title-builds/live-title-build4-no-plate.png`](title-builds/live-title-build4-no-plate.png) |
|
||
| title, **with** the plate | [`title-builds/live-title-press-a.png`](title-builds/live-title-press-a.png) |
|
||
| main menu | [`title-builds/live-main-menu.png`](title-builds/live-main-menu.png) · [`main-menu-oracle.png`](main-menu-oracle.png) |
|
||
| main menu, **`OPTIONS` focused** | [`title-builds/live-main-menu-options-focused.png`](title-builds/live-main-menu-options-focused.png) |
|
||
| `EXTRAS` | [`title-builds/live-extras.png`](title-builds/live-extras.png) |
|
||
| title (alternate) | [`title-screen-oracle.png`](title-screen-oracle.png) |
|
||
| a screen transition, 13 frames | [`transitions/transition-filmstrip.png`](transitions/transition-filmstrip.png) + [`transition-luminance.csv`](transitions/transition-luminance.csv) |
|
||
|
||
The **focused** pair is the useful one for button states: the same screen with a
|
||
different button highlighted, so the difference isolates what focus changes.
|
||
|
||
## ⚠️ Before you compute an RMSE against one
|
||
|
||
* **They are not gamma-neutral.** `capture ≈ 255·(render/255)^γ` with γ ≈ 1.34–1.49,
|
||
and that is a ramp **the game installed**, not a capture-path artefact. So RMSE
|
||
against these has a floor and chasing it below that floor is chasing the ramp.
|
||
[`../structures/ui-render-tone-curve.md`](../structures/ui-render-tone-curve.md)
|
||
* **Geometry is sound**: cross-correlating a render against `live-main-menu.png`
|
||
over ±6 px puts the best alignment at exactly (0,0), correlation 0.9466. So a
|
||
positional disagreement is real, not a crop artefact.
|
||
* **A capture is one moment.** Several of these screens are still animating; the
|
||
title's two `ptloop` sweeps move continuously. Compare settled poses, or
|
||
compare regions you know are at rest.
|
||
|
||
## What is NOT here
|
||
|
||
No capture of the interactive title reached mid-run without a pad press — three
|
||
runs across two locales and two launch paths never reached it in ~35 minutes.
|
||
See [`../capture-harness-status.md`](../capture-harness-status.md). And no
|
||
`GP_READY_ROOM` capture; S1 ruled it out of scope.
|