formats: teach the reference renderer the additive blend, and re-open 8 claims

The blend bit has been decoded against RB_BLENDCONTROL0 since 2026-08-31,
but ui_layout::blit could not draw it, and said so in a comment citing a
refutation that is <render-vs-capture> -- this renderer disagreeing with
itself while it had a stale keyframe association, no leaf geometry and no
rotation.

The consequence the port raised: verify-screen compares two renderers, so a
renderer that structurally cannot express a declared field makes the check
incapable on every screen that uses it -- 12 of 16 -- and the tolerance
silently excuses all of them. A quiet check is worse than a failing one.

Both equations come off the game's own pixel shader, which premultiplies
(oC0 = rgb*A, A), so only the blend register differs: 0x07010701 gives
rgb*A + dst*(1-A), 0x01010101 gives rgb*A + dst. Additive therefore
saturates rather than wrapping, and a transparent or black source is the
identity -- neither is a choice.

No plumbing needed: t8ad::parse already stores +0x04 as T8adImage::flags.

Four controls, pinned against arithmetic per the rotation precedent. The
fourth is the only one that can fail for the right reason: the first three
pass just as well if blit ignores the flag and draws everything additive,
so the discriminator flips only the blend on one sprite and requires two
different answers, each equal to its own equation. That is the same failure
class as the port's non-inverting latch check and my own backward scan that
resolved every guard to "internal".

120 passed, 0 failed on the full lib suite.

67 sprites over 14 screens were being drawn with the wrong blend, including
10 of 18 on the title and ptbtn00f, the PRESS (A) plate's highlight.

R1: tools/stale-instrument render-vs-capture lists 8 claims that died to
this instrument, including both legs of the rest() pair and "the plate-free
title capture may be too early to be settled", which sits on play-test
finding 3. None is re-derived here; this only records that the instrument
no longer exists in that form.

Also corroborates the port's H5: pgloading_loop5 is an ELEMENT resolving to
sprite pgloading_ring.t32, which is additive. I could not find loop5 as a
sprite in any pak and nearly reported a false contradiction from the
element/sprite name split.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
This commit is contained in:
sylph-decoder
2026-09-01 19:03:53 +00:00
parent 9ea6ee7555
commit fa27509937
4 changed files with 396 additions and 11 deletions

View File

@@ -0,0 +1,100 @@
# Which elements the reference renderer now draws ADDITIVE, per screen.
# Source: T8aD +0x04 bit 0x02, docs/re/structures/ui-blend-mode-decoded.md.
# Generated after ui_layout::blit gained an additive path (2026-09-01).
# Before that change EVERY row below was drawn alpha-over by our renderer,
# which is why `verify-screen` was structurally incapable on these screens.
GP_TITLE entry 0 -- 2 of 7 sprites additive
pgloading_circle1.t32
pgloading_delta.t32
GP_TITLE entry 1 -- 2 of 7 sprites additive
pgloading_circle1.t32
pgloading_delta.t32
GP_TITLE entry 2 -- 1 of 2 sprites additive
ptbtn00f.t32
GP_TITLE entry 3 -- 1 of 2 sprites additive
ptbtn00f.t32
GP_TITLE entry 4 -- 10 of 18 sprites additive
pteff01.t32
pteff03.t32
pteff03a.t32
ptlogo_back2eff1.t32
ptlogo_back2eff2.t32
ptlogo_back2eff3.t32
ptlogo_back2eff4.t32
ptlogo_back2eff5.t32
ptlogoall_eff.t32
ptlogoall_eff2.t32
GP_TITLE entry 5 -- 6 of 21 sprites additive
pteff03.t32
pteff03a.t32
pteff10.t32
pteff12.t32
ptframe1.t32
ptframe2.t32
GP_TITLE entry 6 -- 9 of 20 sprites additive
pteff03.t32
pteff03a.t32
pteff10.t32
pteff20.t32
pteff21.t32
pteff22.t32
pteff23.t32
ptframe3.t32
ptframe4.t32
GP_TITLE entry 7 -- 9 of 24 sprites additive
pteff03.t32
pteff03a.t32
ptlogo_back2eff1.t32
ptlogo_back2eff2.t32
ptlogo_back2eff3.t32
ptlogo_back2eff4.t32
ptlogo_back2eff5.t32
ptlogo_eff2.t32
ptlogo_eff3.t32
GP_TITLE entry 8 -- 6 of 21 sprites additive
pteff03.t32
pteff03a.t32
pteff10.t32
pteff12.t32
ptframe1.t32
ptframe2.t32
GP_TITLE entry 9 -- 9 of 20 sprites additive
pteff03.t32
pteff03a.t32
pteff10.t32
pteff20.t32
pteff21.t32
pteff22.t32
pteff23.t32
ptframe3.t32
ptframe4.t32
GP_TITLE entry 12 -- 3 of 9 sprites additive
pgloading_circle1.t32
pgloading_delta.t32
pgloading_ring.t32
GP_TITLE entry 15 -- 3 of 9 sprites additive
pgloading_circle1.t32
pgloading_delta.t32
pgloading_ring.t32
GP_OPTIONS entry 19 -- 3 of 16 sprites additive
po_menu_eff01.t32
po_menu_eff02.t32
po_menu_eff03.t32
GP_OPTIONS entry 21 -- 3 of 16 sprites additive
po_menu_eff01.t32
po_menu_eff02.t32
po_menu_eff03.t32