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

86 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`](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`](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`](../ready-room-probe.md) recorded as a no-go, and reaching
gameplay needs button input, which
[`ui-clock-freezes-at-settle.md`](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.