The port censused focus-record alpha over its own export -- 34 elements, 2 varying, both `ptbtn00f` -- and concluded there is nothing to fix. That is correct and correctly scoped. This asks the same question of the whole disc. 1 130 focus records, 2 664 timed elements, 210 with a varying alpha. 202 have `rest()` returning the PEAK, the `ui-settle-time` pathology. By pak: PILOTLOG 116, MOVIE_THEATER 54, HANGAR_ARSENAL 30, LEADERBOARD 8, GP_TITLE 2. So the port's 2 is right because GP_TITLE has 2. The scope was load-bearing and was not stated as a limit -- "only 2 have a varying alpha" reads as a fact about the format and is a fact about one pak. The pathology is concentrated in exactly the screens a wider port reaches next. The 8 LEADERBOARD ones are the worse mode. `py_ranking_btn01f` swings 255->127->255 with no two adjacent keyframes equal, so `rest()` falls through to its longest-dwell rule and returns 244 -- neither the peak nor the trough. A glow stuck at its peak is visibly wrong; one stuck at 244 of a 127..255 range looks entirely plausible and nothing reports it. Verified rather than asserted: two hits dumped keyframe by keyframe, and a control on `ptbtn01f`, which is genuinely constant across its cycle and is correctly NOT flagged. `py_ranking_btn01f` also confirms the loop-length decode independently -- its ramp ends at t=90 inside a declared 120-unit cycle, holding bright for 30 units. Reach stated: 210 is a floor. Focus records are matched by the `Xf.rat` name rule, and elements with constant alpha but varying scale, rotation or position have the same problem and are not counted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
111 lines
4.3 KiB
Markdown
111 lines
4.3 KiB
Markdown
# Every focus record that pulses — and why `rest()` is wrong for 210 of them
|
||
|
||
**Classification: decoded.** A census of the whole disc, with a control on a
|
||
record the census does *not* flag, and two hits verified keyframe by keyframe.
|
||
|
||
## Why this exists
|
||
|
||
The `PRESS Ⓐ` plate's focus record `ptbtn00f` pulses 0 → 80 → 0, so its last hold
|
||
keyframe is the **peak**, and `rest()` leaves it at maximum brightness forever —
|
||
the pathology of [`ui-settle-time.md`](ui-settle-time.md) applied to a focus glow.
|
||
|
||
The port checked this over its own export and found **34 focus-record elements, 2
|
||
of them varying** — both `ptbtn00f`, EN and JP — and concluded there is nothing to
|
||
fix. **That is correct, and correctly scoped.** For the five screens the menu port
|
||
ships it is the whole story.
|
||
|
||
It does not survive leaving `GP_TITLE`.
|
||
|
||
## Disc-wide
|
||
|
||
[`focus-record-alpha-census.txt`](../data/focus-record-alpha-census.txt)
|
||
|
||
| | count |
|
||
|---|---|
|
||
| focus records (`Xf.rat` where `X.rat` also exists) | **1 130** |
|
||
| their elements carrying timed keyframes | **2 664** |
|
||
| **with a varying alpha** | **210** |
|
||
| …of which `rest()` returns the **peak** | **202** |
|
||
| …of which `rest()` lands **mid-ramp** | **8** |
|
||
|
||
| pak | varying focus elements |
|
||
|---|---|
|
||
| `GP_DEBRIEFING_PILOTLOG` | 116 |
|
||
| `GP_MOVIE_THEATER` | 54 |
|
||
| `GP_HANGAR_ARSENAL` | 30 |
|
||
| `GP_LEADERBOARD` | 8 |
|
||
| `GP_TITLE` | **2** |
|
||
|
||
So the port's 2 is right — and it is 2 because `GP_TITLE` has 2. The pathology is
|
||
concentrated in exactly the screens a wider port needs next.
|
||
|
||
## The three behaviours, verified by hand
|
||
|
||
**1. A seamless breathing loop** — `GP_MOVIE_THEATER` `px_movie_tn000f`:
|
||
|
||
```
|
||
t=0 a=64 t=4 a=80 t=26 a=238 t=30 a=255
|
||
t=60 a=255 t=70 a=236 t=110 a=80 t=120 a=64 cycle +08 = 120
|
||
```
|
||
|
||
Starts and ends at 64 and fills its declared cycle exactly, so it loops with no
|
||
seam. `rest()` returns **255** — the peak. 54 elements in this pak do this.
|
||
|
||
**2. A ramp that holds** — `GP_LEADERBOARD` `py_ranking_btn01f`:
|
||
|
||
```
|
||
t=0 a=255 t=8 a=244 t=42 a=140 t=50 a=127
|
||
t=56 a=140 t=84 a=244 t=90 a=255 cycle +08 = 120
|
||
```
|
||
|
||
The ramp ends at t=90 inside a 120-unit cycle, so it holds bright for 30 units —
|
||
another instance of [`ui-record-loop-length.md`](ui-record-loop-length.md). Here
|
||
`rest()` returns **244**, which is **neither the peak (255) nor the trough (127)**.
|
||
No two adjacent keyframes are equal, so `rest()` falls through to its longest-dwell
|
||
rule and lands mid-ramp.
|
||
|
||
🔴 **This is the worse failure mode.** A glow stuck at its peak is at least
|
||
visibly wrong. A glow stuck at 244 of a 127–255 range looks entirely plausible and
|
||
nothing reports it.
|
||
|
||
**3. The control — genuinely constant** — `GP_TITLE` `ptbtn01f`, one of the five
|
||
main-menu focus records:
|
||
|
||
```
|
||
ptbtneff01.t32 t=0 a=255 t=120 a=255
|
||
ptbtn01f.t32 t=0 a=255
|
||
```
|
||
|
||
Constant across its whole cycle. The census does **not** flag it, which is the
|
||
check that the census is detecting variation rather than flagging every focus
|
||
record it meets.
|
||
|
||
## What this does and does not change
|
||
|
||
* ✅ **Nothing about the menu port.** `GP_TITLE`'s two are the plate's, the port
|
||
draws the plate through its loop path, and the other 32 elements in its export
|
||
are constant-alpha. Its conclusion stands for its scope.
|
||
* 🔴 **The scope is load-bearing and was not stated as a limit.** "Only 2 have a
|
||
varying alpha" reads as a fact about the format; it is a fact about `GP_TITLE`.
|
||
Extending the port to the Hangar, the Movie Theater or the Pilot Log meets 200
|
||
of these, and 8 of them fail in a way that looks correct.
|
||
* ⚠️ **A pulsing element has no resting pose at all.** For these records the
|
||
question `rest()` answers is malformed rather than mis-answered: the element's
|
||
state is a phase, not a value. `pose_at(t)` with `t` inside the record's own
|
||
declared cycle is the only well-formed query.
|
||
|
||
## Reach
|
||
|
||
⚠️ **"Focus record" here is a name rule** — `Xf.rat` where `X.rat` is also
|
||
present, the same pairing `mark_focused_states` uses. A record that animates while
|
||
focused but is not named that way is not counted, so 210 is a floor.
|
||
|
||
⚠️ **Varying alpha only.** An element with constant alpha and a varying scale,
|
||
rotation or position has the same problem and is not counted here.
|
||
|
||
## Reproducing
|
||
|
||
```bash
|
||
cargo run -p sylpheed-formats --example focus_alpha_census
|
||
```
|