Files
Sylpheed/docs/re/screen-transitions.md
Sylpheed RE agent 7fef19b3a0 re: the transition between screens is a fade through black, and most of
its timing is on the disc

Q7. Every title-side screen carries a full-screen black .prm quad that
paints last, and its keyframe group IS the transition: black at T0, clear
by T1, clear until T2, then back to black on exit. Read with the corpus's
start-of-a-ramp rule and Q1's time unit that gives 0.87s for EXTRAS,
0.97s for the main menu, 4.08s for the title -- from the file, not from a
stopwatch.

The disc-wide check is per-pak all-or-nothing rather than the 41% the
headline count suggests, and GP_TITLE's 6 of 12 is the useful row: the
six builds carrying a fade quad are exactly the six SCREENS, and the six
without are exactly the six overlays. GP_DIALOG is 0 of 133. That is
independent corroboration of the overlay finding from two iterations ago.

One piece is NOT on the disc and says so: the fade-OUT length. The fourth
keyframe has no time slot, because a group's last block stops four bytes
short. Measured instead, at 30fps, ~0.4s and the same both directions.

And a warning I earned: the luminance rise after a transition is NOT the
quad's ramp. The incoming screen's own elements animate in after the quad
has cleared -- 1.47s observed against a declared 0.97s. Time the fade
from where the frame is pure black.

Rig: screenshot samples at 0.5 Hz and cannot see a 0.4s fade at all,
which is why an earlier burst called this an instant cut. ffmpeg x11grab
at 30fps instead; both go in METHOD.
2026-08-28 18:05:19 +00:00

5.4 KiB
Raw Blame History

What happens between two screens — a fade through black, and where its timing lives

Status: CONFIRMED. The quad and its ramp are decoded (a keyframe group on the disc, with a disc-wide check); the wall-clock timings are measured off the running game at 30 fps. One piece is undecodable from this field and is called out below.

Answers MISSION Q7.

The mechanism — decoded

Every title-side screen carries a full-screen untextured primitive that is black, and paints last: pteff00.prm in GP_TITLE, pfeff00.prm in GP_SAVE_LOAD. That it sorts last was already established (structures/ui-paint-order-key.md); what is new here is that its keyframe group is the transition.

The group is always four blocks, and always this shape:

block alpha meaning
1 0xff at t = T0 the screen starts black
2 0x00 at t = T1 ramp to fully clear — the screen fades in
3 0x00 at t = T2 clear; this is the resting pose, the quad is invisible
4 0xff, no time ramp back to black — the screen fades out on exit

Read with the corpus's rule that a keyframe is the start of a ramp (structures/ui-resting-pose.md).

$ tools/re-capture/fade_quads.py 4 5 6          # GP_TITLE
build 4 (title)      pteff00.prm   t=16 α=255   t=261 α=0   t=269 α=0   t=— α=255
build 5 (main menu)  pteff00.prm   t=12 α=255   t= 70 α=0   t= 80 α=0   t=— α=255
build 6 (EXTRAS)     pteff00.prm   t=12 α=255   t= 64 α=0   t= 74 α=0   t=— α=255

Under Q1's 1 unit = 1/60 s: 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).

The fade-OUT duration is not in this field

The fourth block has no time — a group's last block stops 4 bytes short and that word is already the next group's element index (ui_layout.rs documents the packing). So the disc gives the ramp's target (black) and not its length. That duration is measured below, and the port is authoring it.

The disc-wide check, and what it shows about overlays

Over every GP_*.pak, counting bundles that have a .prm element and ≥8 elements (screen-sized rather than a two-element fragment):

40 of 97 carry a 255 → 0 → 255 quad; 56 of the 60 found disc-wide have exactly 4 keyframes.

41 % sounds weak until it is read per pak, where it is nearly all-or-nothing:

pak with quad / screen-sized
GP_MISSION_SELECT, GP_MOVIE_THEATER, GP_OPTIONS, GP_TUTORIAL, GP_SYSTEM 2/2 each
GP_BUNK, GP_CHALLENGE 6/6
GP_STAGE_CLEAR 4/4
GP_SAVE_LOAD 10/12
GP_TITLE 6/12
GP_DIALOG 0/133
GP_DEBRIEFING_PILOTLOG 4/102

GP_TITLE's 6 of 12 is the interesting row, and it is not a gap. The six that carry the quad are exactly the six screen builds — title, main menu and EXTRAS, English and Japanese. The six that do not are exactly the six overlays: the PRESS Ⓐ BUTTON plate and the two DELTASABER plates (ui-title-build-map.md). An overlay composited onto a screen has no transition of its own, so it has no fade quad — which is independent corroboration that those builds are overlays rather than screens. GP_DIALOG's 0/133 says the same thing about dialog boxes.

The timing — measured

Recorded with ffmpeg -f x11grab -framerate 30 over the game surface, mean frame luminance per frame; raw data in captures/transitions/transition-luminance.csv, filmstrip in transition-filmstrip.png.

main menu → EXTRAS (Ⓐ) EXTRAS → main menu (Ⓑ)
press → first visible change 0.07 s 0.37 s
fade-out to black 0.367 s 0.400 s
pure black (luminance 0.02) 0.233 s 0.167 s
luminance rise until settled 0.567 s 1.467 s

The fade-out is the number the file cannot give, and it comes out the same both ways: ~0.4 s, i.e. ~24 units under Q1's rule.

The black hold is consistent with the file's 12 units (0.20 s) but does not confirm it — the plateau spans the tail of the outgoing screen's fade-out and the head of the incoming screen's black, and this measurement cannot separate them.

⚠️ The luminance rise is not the quad's ramp

The two columns differ by 2.6× where the quad's declared ramps differ by only 1.12× (58 units vs 52). The filmstrip says why: the background reappears first and the labels arrive after it, so what the luminance curve is timing is the incoming screen's own element animations, not the fade quad. Quoting 1.47 s as "the main menu's fade" would be wrong. The quad's ramp is decoded; the screen's build-in is a separate, longer thing.

For the port

  • a screen change is: fade the outgoing screen to black over ~0.4 s, hold black briefly, then fade the incoming screen in over its own declared ramp while its elements play their own keyframes;
  • the fade-in ramp is read from the file (T1 T0 on the screen's fade quad);
  • the ~0.4 s fade-out and the black hold are authored from this page — the disc does not carry them.