This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/structures/ui-8ax-fullres-background.md
Sylpheed RE agent 2b4ec20f00 re(ui): a full-screen element is dropped on three port screens -- do not "fix" it
Audited what `screen render` silently omits on the port's five screens,
since an element the game draws but we skip is the one defect class the
port agent has actually hit. Everything is accounted for -- kind & 0x4
ghost instances, .prm primitives, loop* animations -- except pteff04.t32
on the title and pteff05.t32 on both menus. Those are kind 0x0, one
keyframe, rest a=255, pivot (640,360): full-screen and opaque.

Cause: the element declares pteff05.t32, but the T8aD behind its `opt `
link is registered under the name 8AX, so build.sprites.get() misses and
compose hits a silent continue. Bytes at 0x0e2035 of GP_TITLE entry 5:

  opt  ... 70 74 65 66 66 30 35 2e 74 33 32 00  38 41 58  54 38 61 44
           p  t  e  f  f  0  5  .  t  3  2  \0  8  A  X   T  8  a  D

8AX is 1280x720 and present in all six title-family bundles; it is a
sprite in builds 4/5/6 and never an element.

It does not currently show, and that is the useful half. ptbase.t32 is
640x360 drawn at 200% and carries THE SAME ARTWORK: its 2x upscale
differs from 8AX by mean abs diff 2.05 (max 80), and our rendered
background is pixel-identical to 8AX in every patch sampled. So resolving
the name and drawing it in addition would double-draw an opaque
full-screen layer -- invisible as a doubling, which is worse than a
visible bug. Written into HANDOFF as a do-not-do.

The free win, offered and not taken: use 8AX at 1:1 and drop ptbase
instead of upscaling a half-res copy. That is a rendering choice and
ptbase's element carries the keyframes, so it is the port's call.

Not established: which of the two the game actually draws. Both carry the
same art, so pixels cannot separate them; it needs a per-draw capture
recording texture base addresses, since the two differ in size.
2026-08-29 01:00:36 +00:00

3.9 KiB
Raw Blame History

🟡 pteff04 / pteff05 are dropped — the texture is registered as 8AX

Status: 🟡 a real name-resolution gap, currently harmless to look at, and the obvious fix would make the render worse. Found by auditing what screen render silently omits on the port's five screens.

What screen render drops, and why

sylpheed-cli screen render reports its omissions. On the five screens the port needs, every one is accounted for except two:

screen not drawn reason
title (4) ptlogo1×2, ptlogo2×2 kind & 0x4 ghost instances — the draw capture shows one quad per wordmark
pteff00.prm, pteff02.prm .prm primitives, off without --primitives
ptloop01.rat, ptloop02.rat loop* animations, off without --animated
pteff04.t32 ⚠️ unexplained — this page
main menu (5), EXTRAS (6) as above, plus pteff05.t32 ⚠️ same
splash (10, 11) palogo_eff0.prm primitive

pteff04/pteff05 are kind = 0x0, one keyframe, rest a = 255, and pivot (640,360) — i.e. a full-screen, fully opaque element. Exactly the shape of the defect the port agent reported (an element the game draws that we omit).

The cause: the element's name and its texture's name differ

Both names occur twice per bundle, the same as pteff03.t32, which resolves fine. The difference is what follows the opt link:

pteff03.t32   @0x4661a4   opt  →  T8aD          ← resolves
pteff05.t32   @0x0e2035   opt  →  8AX  T8aD     ← the sprite is named 8AX

Hex at 0x0e2035:

opt  ....  70 74 65 66 66 30 35 2e 74 33 32 00  38 41 58  54 38 61 44
           p  t  e  f  f  0  5  .  t  3  2  \0  8  A  X   T  8  a  D

So the declaration says pteff05.t32 while the T8aD that follows is registered under 8AX. compose does build.sprites.get(sprite) and, on a miss, hits a silent continue. 8AX is a 1280×720 texture and appears in all six title-family bundles (a60fcb85, a715f485, a81c1d85 and the three JP twins); it is a sprite in builds 4/5/6 and never an element.

Why it does not currently show

The same artwork is already on screen. ptbase.t32 is 640×360 and its element draws at 200 %, and the background our render produces is pixel-identical to 8AX in every patch sampled:

patch capture our render 8AX
top-left 4.5, 9.4, 19.5 17.7, 29.7, 46.7 17.7, 29.7, 46.7
top-right 4.4, 9.0, 18.2 17.2, 28.2, 43.8 17.1, 28.2, 43.8
bottom-left 3.5, 6.0, 11.1 13.6, 20.5, 31.2 13.6, 20.5, 31.2

Directly: ptbase upscaled 2× against 8AX is mean abs diff 2.05 (max 80), not byte-identical. They are the same art at two resolutions8AX is the full-res copy, ptbase the half-res one the element scales back up.

⚠️ So do not "fix" this by drawing it

Resolving pteff05 → 8AX and drawing it in addition to ptbase would double-draw the background — an opaque full-screen layer over an identical one. It would not be visible as a doubling, which is worse: it would silently cost fill and hide any future change to either layer.

🟡 The free win, if a port wants it: use 8AX at 1:1 and drop ptbase, rather than upscaling a 640×360 copy 2×. That is a sharper background from a texture already in the bundle. Not done here — it is a rendering choice, and ptbase's element carries the keyframes.

Not established

  • Whether the game draws one, the other, or both. The pixel evidence says our background matches 8AX's art, which ptbase also carries — it cannot separate them. A per-draw capture of the main menu recording texture base addresses would, since the two textures are different sizes.
  • The capture is ~4× darker than the render in these patches (4.5 vs 17.7), and not by a constant ratio. That is a separate colour/gamma question, untouched here.