Files
Sylpheed/docs/re/structures/ui-prm-blend-mode.md
sylph-decoder 29c99e1b3e re: primitive blend mode -- undecodable with reach, and no longer a risk
Looked in four places. The bundle has no field: a primitive has no RATC child at
all and the declaration words are constant across every element of three measured
screens -- the two grounds ui-prm-primitives.md already used to refute a
bundle-side LAYER key, and they apply identically to blend.

The colour census: every full-screen *eff00* primitive on the disc carries pure
black at its various alphas, and the only non-black primitive anywhere is
pbafc.prm, RGB 00e8e0 cyan.

The occlusion constraint cannot reach that one. pbafc.prm looked alarming at a
declared 844x600 and alpha ff; it is a small moving glint. It strobes between
alpha 255 and 124 every 2 units, travels from x=178 to x=291, and is scaled
2%x3%, so it draws about 17x18 pixels. At that size it occludes essentially
nothing.

The oracle is unavailable: GP_READY_ROOM is a recorded no-go and gameplay needs
the A press that faults the guest in this container.

But the consequence closes even though the question does not. For a BLACK quad
-- which is every primitive forced_backdrop touches -- the hypotheses differ only
in whether it hides what is beneath. Drawn first it is correct under both; drawn
last it is correct only under additive. So the rule's verdict is robust to the
open question, and the port's original "layerless sorts last" was wrong under
alpha-over and merely pointless under additive. This is explicitly NOT evidence
for alpha-over.

The investigation also found forced_backdrop judging coverage from the pivot
alone, ignoring scale -- pbafc.prm is the disc's own proof that a nominally
844x600 element can draw at 2%. Checked before changing anything: all 80 forced
instances are at scale 100% on every opaque instant, so no verdict moved. The
guard now requires scale >= 100 at the instants it counts as opaque. Defensive,
not a fix. 4 + 13 disc tests green either side.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
2026-08-29 21:58:25 +00:00

4.2 KiB
Raw Blame History

Primitive blend mode — narrowed to one element, and it does not matter

Classification: undecodable, with reach. Looked in the bundle, in the colour census, in the occlusion constraint, and at the oracle. The question survives; its consequences do not.

The question

ui-prm-primitives.md leaves blend mode open: "a dim quad at 0x7f000000 is presumably straight alpha over what is beneath, but the flash (0xf0ffffff) and the coloured ones (0x60ff0000) may well be additive. Nothing measured." ui-forced-backdrop.md then assumed alpha-over, so the assumption became load-bearing.

Where I looked

1. The bundle — nothing. ui-prm-primitives.md already refuted a bundle-side key for a primitive's layer, on two grounds that apply identically to blend: the declaration entry's unread words are constant across every element of three measured screens, and the bundle carries no RATC child at all for a primitive. There is no field to read.

2. The colour census — the population is overwhelmingly black. Every full-screen *eff00* primitive on the disc carries pure black at its various alphas: ff000000, 7f000000, 40000000, b2000000, cc000000, d4000000, 00000000. The *base* elements are ffffffff. The only non-black primitive on the disc is pbafc.prm, RGB 00e8e0 — cyan.

3. The occlusion constraint — inapplicable to the one candidate. pbafc.prm looked alarming at a declared 844×600 and alpha ff. It is not what it looks like:

t=10  a=255  xy=(178,60)  s=2/3        t=22  a=255  xy=(186,60)  s=2/3
t=12  a=124  xy=(178,60)  s=2/3        t=24  a=124  xy=(194,60)  s=2/3
t=14  a=255  xy=(178,60)  s=2/3        …travelling to x=291…

It strobes between alpha 255 and 124 every 2 units, it travels across the screen, and its scale is 2 % × 3 % — so it draws about 17×18 pixels, not 844×600. It is a small moving glint. At that size it occludes essentially nothing, so the constraint that settles the backdrops cannot reach it.

4. The oracle — not reachable. pbafc.prm lives in GP_READY_ROOM, which ready-room-probe.md recorded as a no-go, and reaching gameplay needs button input, which ui-clock-freezes-at-settle.md records as faulting the guest in this container.

Why it does not matter for the rule that depended on it

For a black quad — which is every primitive forced_backdrop touches — the two hypotheses differ only in whether it hides what is beneath:

drawn first drawn last
alpha-over black at α=255 paints black, content over it — correct blanks the screen — wrong
additive black at α=255 adds nothing — correct adds nothing — correct

"First" is right under both hypotheses; "last" is right only under one. So the forced-backdrop rule's verdict is robust to the blend question even though the question is open — and the port's original "layerless sorts last", which produced solid black on build_12/build_15, is wrong under alpha-over and merely pointless under additive.

⚠️ This is not evidence that the blend is alpha-over. It is the reason the open question stops being a risk. pbafc.prm remains genuinely unknown, and it is the only element on the disc where the answer could change a pixel.

🔴 A guard the investigation added, which no current verdict needed

forced_backdrop tested coverage from the pivot alone. pbafc.prm is the disc's own proof that scale can shrink a nominally full-screen element to 2 %.

Checked before changing anything: all 80 forced instances are at scale 100 % on every opaque instant, so no verdict moved. The guard now requires scale_x >= 100 && scale_y >= 100 at the instants it counts as opaque — a guard against data not yet met, not a fix. 4 + 13 disc tests green either side.

Reach

⚠️ The colour census covers keyless elements. A sprite's blend is a separate question, and T8aD +0x04 bit 0x02 was already refuted as an additive flag.

pbafc.prm is unsettled and would need either a GP_READY_ROOM capture or a blend-state read from Canary, neither of which is available here.