re: the transition is overlap, not ramp-then-hold -- and the fade-in was 5x wrong
screen-transitions.md carried a 14-unit "black hold" that the page itself flagged as arithmetic rather than measurement. Measured it against the running game; the guess was wrong, and finding the instrument to measure it turned up a second, larger error in the same page. 1. fade_quads.py was STALE. It read each pose's time from blk+36 -- the next record's time word -- the association the keyframe record-layout fix retired in the crate. sylpheed-cli was rebuilt at the time; the Python helper was never swept with it. Signature: it cannot time a group's last pose, so it printed a trailing `t=-`. Fixed, controlled against the rebuilt `screen info` ([0 12 70 80] for build 5's pteff00.prm). 2. Through it, the page labelled the quad's CLEAR-hold as its fade-in and published 0.87 s / 0.97 s / 4.08 s for a ramp that is 0.20 s / 0.20 s / 0.27 s. A port pacing its menu fade-in off that would run it 5x too slow. 3. The measurement. fade_decompose.sh boots to the main menu, arms the UI draw capture there, then presses (B), so one 260-frame window holds the whole screen change. The fade quad is identified rather than guessed: a .prm carries no tex[base=] and paints last, so it is the last full-screen untextured quad of a frame. Control first -- the quad's ramp is decoded at 10 units = 5 frames, and measures 4 submitted-frame steps with one unlogged frame in the span. Result: content elements begin fading at frame 34; the black quad first appears at 40 and is opaque by 43; the menu's last frame is 45; frame 46 has 6 draws against 12. So the ~14 extra units are the content's own fade-outs OVERLAPPING the quad's ramp, not a hold after it, and the inter-screen black is one frame. Refutation attempted: sylpheed-port's entries 13/14 twins. Re-derived off the disc -- 3.06 / 4.33 / 47.91, identical to two decimals. Recorded as confirming their addressing and arithmetic, NOT as independent support: same renderer, same disc, which is their own rule. Reach: one transition, one run; the frame axis has gaps (232 headers over frames 3..260), so every span is +-1 frame. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
@@ -23,6 +23,80 @@ There is no fourth kind. If a row says *measured* or *undecodable*, the port is
|
||||
human can see it is a human decision, so that when it is later decoded the
|
||||
authored version can be deleted.
|
||||
|
||||
## 🔴 2026-08-30 — the transition is OVERLAP, not ramp-then-hold. And your menu fade-in is 5× too slow.
|
||||
|
||||
Two corrections and one measurement, all on
|
||||
[`screen-transitions.md`](../re/screen-transitions.md). **The fade-in one changes a
|
||||
number you are probably already using.**
|
||||
|
||||
### 🔴 1. The fade-in is 0.20 s, not 0.97 s
|
||||
|
||||
That page told you the screen "holds black for 0.20 s, then fades in over 0.87 s
|
||||
(`EXTRAS`), 0.97 s (main menu) or 4.08 s (the title)". **Those are not fade-ins.**
|
||||
They are the stretch where the fade quad sits at `α = 0` — the screen fully visible
|
||||
and not fading at all. Read correctly:
|
||||
|
||||
```
|
||||
build 4 (title) pteff00.prm t= 0 α=255 t= 16 α=0 t=261 α=0 t=269 α=255
|
||||
build 5 (main menu) pteff00.prm t= 0 α=255 t= 12 α=0 t= 70 α=0 t= 80 α=255
|
||||
build 6 (EXTRAS) pteff00.prm t= 0 α=255 t= 12 α=0 t= 64 α=0 t= 74 α=255
|
||||
```
|
||||
|
||||
**Fade-in = 12 units (0.20 s) on the menu and `EXTRAS`, 16 units (0.27 s) on the
|
||||
title.** Fade-out = 10 units, 10 units, and **8** on the title.
|
||||
|
||||
**Cause:** `tools/re-capture/fade_quads.py` read each pose's time from `blk+36` —
|
||||
the *next* record's time word — the same association the record-layout fix retired
|
||||
in the crate. `sylpheed-cli` was rebuilt then; the Python helper was not swept with
|
||||
it. Its signature is the trailing untimed keyframe (`t=—`) that page printed for
|
||||
years. Fixed and controlled against the rebuilt `screen info`, which gives
|
||||
`[0 12 70 80]` for the same element.
|
||||
|
||||
### ✅ 2. The ~14 "missing" units are not a black hold — measured
|
||||
|
||||
That page guessed the remainder of the ~0.4 s was the black hold and **said in as
|
||||
many words that this was arithmetic, not a measurement**. I measured it. It is
|
||||
wrong.
|
||||
|
||||
`fade_decompose.sh` boots to the main menu, arms the UI draw capture there, then
|
||||
presses Ⓑ — one 260-frame window holding the whole screen change. The fade quad is
|
||||
*identified*, not guessed: a `.prm` carries no `tex[base=…]` and paints last, so it
|
||||
is the last full-screen **untextured** quad of a frame.
|
||||
|
||||
**Control first:** the quad's ramp is decoded at 10 units = 5 frames. Measured, it
|
||||
is absent at frame 39 and `α=255` at 43 — 4 submitted-frame steps with one unlogged
|
||||
frame in the span. The instrument reproduces the decoded quantity before being
|
||||
trusted on the undecoded one.
|
||||
|
||||
```
|
||||
frame 34 content elements begin fading (255 → 223 → 207 → 175 → 95 → 31 → 15)
|
||||
frame 40 the BLACK QUAD first appears, α=102 → 127 → 255 by frame 43
|
||||
frame 45 last frame the menu draws
|
||||
frame 46 6 draws (vs 12) — ONE frame of black
|
||||
frame 47+ the title's build starts
|
||||
```
|
||||
|
||||
📌 **A transition is not "ramp the quad 10 units, then hold black 14".** It is
|
||||
**"start the content fading, and six frames later ramp the black quad over its
|
||||
declared 10 units on top of them"** — the two overlap. Total blackout is frame
|
||||
34→43 = **9 frames ≈ 0.30 s**, and the gap between screens is **one frame**.
|
||||
Authoring the hold puts a sixth of a second of dead black in the middle of every
|
||||
screen change the game does not have.
|
||||
|
||||
⚠️ **Reach:** one transition, one run. The frame axis has gaps — 232 headers over
|
||||
frames 3…260, ~10 % of submitted frames carry no UI draw — so every span here is
|
||||
±1 frame, which is why the ramp is 4 *steps* and not a duration to three digits.
|
||||
Whether the six-frame lead is constant across screens, or a property of these
|
||||
elements' keyframes, is **not measured**.
|
||||
|
||||
### Your entries 13/14 twins — re-derived, and it is not a second witness
|
||||
|
||||
I reran your comparison off the disc: publisher 10 vs 13 **3.06**, developer 11 vs
|
||||
14 **4.33**, control 10 vs 11 **47.91**. Identical to two decimals. ⚠️ But by your
|
||||
own rule this is *your renderer twice* — same `sylpheed-cli`, same disc — so what
|
||||
it establishes is that your addressing and arithmetic are right, **not** that the
|
||||
twins claim has independent support. I am recording it as the former.
|
||||
|
||||
## ✅ 2026-08-30 — I swept the whole disc for the ordinal foot-gun. Your screens are the exposed ones.
|
||||
|
||||
Last iteration I retracted three claims because `--build 10/11` on `GP_TITLE` are
|
||||
@@ -969,7 +1043,7 @@ discovered it after re-exporting. ❔ The sweeps may simply be a small term, and
|
||||
| Q4 | button → GamePart | ✅ answered | **measured** which screen all **5** buttons open, by pressing each one and reading the screen's own title off the framebuffer. ✅ **In the form you need it: exactly ONE main-menu button opens a `GP_TITLE` entry.** `EXTRAS` → **entry 6** (EN) / **9** (JP). The other four leave the archive: `NEW GAME` → `DIFFICULTY` → `SELECT DATA`; `LOAD GAME` → the save-slot list; `TUTORIAL` → the lesson list; `OPTIONS` → GAME/CONTROL/SOUND/SCREEN SETTINGS. None of those four is a `GP_TITLE` build — so a menu→submenu→back cycle inside this archive is `main menu ↔ EXTRAS` and nothing else. The **GamePart id is still a name match**, not a measurement, and 🔴 the "cheap way to measure it" this page used to point at is a dead route (the guest words are monotonic counters, not a screen id) — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md) |
|
||||
| Q5 | navigation semantics | ✅ answered, ⚠️ **per clause** | 🔴 **This row used to open with a single `**measured**` covering six clauses of different strength, and the port's `authored/flow.json` copied that word into a `MEASURED` provenance stamp for a clause whose evidence cell reads `none`. A bundled label is exactly as strong as its weakest cell.** Split: ✅ **measured** — initial focus varies boot to boot (2× `TUTORIAL`, 2× `NEW GAME`); ⬆⬇ move **one item per press** (indirect: the 4-press wrap count only works if each press moves one) and **wrap both ends**; ⬅➡ do nothing; Ⓑ on a submenu returns to the parent **with focus restored** (4/4); Ⓑ on the main menu → **title**, ≤ 0.4 s, no loading screen (2026-08-30). ✅ **AND BOTH WEAK CLAUSES ARE NOW MEASURED (2026-08-30, later)** — you can stamp them: **no auto-repeat** (a 2.0 s held ⬇ moves the cursor exactly **once**; the counter passes its control, a single tap giving exactly 1 spike) and **Ⓑ on the title → nothing** (20 s after a delivery-confirmed Ⓑ the screen is still the title with `PRESS Ⓐ BUTTON` up — and that run waited for the **plate pulse**, the title's own settled signature, which is what the confounded earlier attempt did not). ✅ The plate **is** re-drawn after Ⓑ from the menu, ~7 s later — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md) |
|
||||
| Q6 | boot sequence + what drives it | ✅ answered | sequence **measured** end to end; the driver is **code, not data** — four search spaces closed, so the port **authors** the sequence — [`boot-config-and-gamepart-registry.md`](../re/boot-config-and-gamepart-registry.md) |
|
||||
| Q7 | transitions | ✅ answered | a **fade through black**, drawn by the screen's own last-painting `.prm` quad. Fade-in ramp is **decoded** from its keyframes; the ~0.4 s fade-out is **measured** (not in the file) — [`screen-transitions.md`](../re/screen-transitions.md) |
|
||||
| Q7 | transitions | ✅ answered, **two numbers changed 2026-08-30** | a **fade through black**, drawn by the screen's own last-painting `.prm` quad. 🔴 **Fade-in is 12 units (0.20 s) on the menu/`EXTRAS` and 16 (0.27 s) on the title — this row's source used to say 0.87–4.08 s, which is the quad's CLEAR-hold, not its ramp** (a stale Python reader that shifted every keyframe time by one slot). Fade-out **is** on the disc: 10/10/8 units. ✅ **And the transition is OVERLAP, not ramp-then-hold, measured from the running game**: content elements start fading ~6 frames before the black quad's ramp begins, total blackout 9 frames ≈ 0.30 s, and the gap between screens is **one frame**. The "~14 units of black hold" this page used to carry was arithmetic and is **withdrawn** — [`screen-transitions.md`](../re/screen-transitions.md) |
|
||||
| Q8 | menu audio bindings | ✅ answered | cue vocabulary + bank **decoded**; event binding is a **name match** (the authors' own event names). ✅ **You CAN have the SE audio** — ⚠️ an earlier version of this row said it was "undecodable from the disc"; that was **retracted** and the row was stale. Three cues are located in `Static.slb` and **decode to PCM**: d-pad move `0x1ec0` (4 packets), Ⓑ back `0x0ec0` (2), Ⓐ confirm `0x5d6c0` (6), all mono 48 kHz. The bank is a packed run of XMA waves with no delimiter, so a wave is only (offset, packet count) — and ⚠️ the file order is **not** cue-id order, so the index cannot be counted out — [`menu-audio-cues.md`](../re/menu-audio-cues.md) |
|
||||
| Q9 | video binding + playback rules | ✅ answered | **decoded** from the movie manifest: `ADVERTISE_MOVIE`→`ADV.wmv` (boot intro *and* attract are one asset), `MS00A`→`S00A.wmv` is the new-game intro, `STAFF_ROLL`→the credits reel. ✅ **one Ⓐ skips a movie** (title at 57 s vs a 193 s baseline) — [`movie-binding.md`](../re/movie-binding.md) |
|
||||
| Q10 | music-bank sub-wave roles (intro+loop?) | ✅ answered | **two stems of one performance, played together** — sample-synchronous, equal duration, 32/32 banks. **Concatenating is wrong.** Not a seamless loop either — [`structures/bgm-two-stems.md`](../re/structures/bgm-two-stems.md). ⚠️ **Our reader said three until 2026-08-29** — the extra one was the **bank header**, emitted by `to_xma_riffs`; fixed, with a 28/28 disc-wide check and two regression tests — [`structures/slb-bank-header-not-a-wave.md`](../re/structures/slb-bank-header-not-a-wave.md) |
|
||||
|
||||
Reference in New Issue
Block a user