Files
Sylpheed/docs/re/structures/ui-blend-mode-decoded.md
sylph-decoder bac8e17a7f re: the blend mode IS on the disc -- T8aD +0x04 bit 0x02, DECODED
Reverses two of my own pages. t32-blend-mode-not-on-disc.md said the mode is not
on the disc; ui-blend-mode-measured.md classified it measured and told the port
that which field selects it was unknown. Both were honest and neither is current.

Bit 0x02 of +0x04 set means the game draws that sprite ADDITIVE
(RB_BLENDCONTROL0 = 0x01010101); clear means premultiplied alpha-over.

Fit: 35 elements over three screens, 16 set/additive and 19 clear/alpha-over,
zero errors, every label read out of the guest command stream rather than off a
render.

Control: of every bit of the first twelve header words, exactly one separates
those 35 without error. Nothing ties with it -- which is precisely what the
+0x08 = 0x8050 candidate failed.

Within-pair: ptbtn00 0x0110 alpha-over against ptbtn00f 0x0112 additive, same
screen, same bundle, adjacent draws, one bit apart. And other f variants are
bit-clear and alpha-over, so it is not 'focused variants are additive'.

Out of sample: a prediction committed at 088df91, before its capture, on a
different archive -- GP_OPTIONS entry 19, 3 additive of 16, falsified if any
other element drew additive. The game drew exactly po_menu_eff01/02/03 additive
and nothing else.

This revives a claim REFUTED.md killed. The refutation said blending those
sprites additively worsens every measure against the capture -- a claim about
our renderer, made while that renderer had a stale keyframe association, no leaf
geometry and no rotation. Recorded as a revival with its evidence;
check_refuted.py passes with 0 unmarked assertions.

Two other readings of the same bit stay refuted and are explicitly not revived:
'the name contains eff' and 'premultiplied storage'. Those were the bit's
meaning; this is its effect.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-31 07:20:12 +00:00

5.7 KiB
Raw Blame History

The UI blend mode is on the disc after all — DECODED: T8aD +0x04 bit 0x02

Status: CONFIRMED, classification decoded — the field, plus a disc-wide check and an out-of-sample prediction that could have died and did not. 2026-08-31.

🔴 This reverses two of my own published conclusions. t32-blend-mode-not-on-disc.md said the mode is not on the disc, and ui-blend-mode-measured.md classified it measured and told the port to read the table as per-element facts because "which field selects the mode is still unknown". Both stand as honest records of what was known; neither is current. The port can derive the blend for any element on any screen instead of transcribing a table.

The field

T8aD +0x04 bit 0x02 set ⇒ the game draws that sprite ADDITIVE (RB_BLENDCONTROL0 = 0x01010101, src ONE / dst ONE). Clear ⇒ premultiplied alpha-over (0x07010701, src ONE / dst 1SRC_ALPHA).

Why the old refutation was wrong, and why that matters

REFUTED.md killed this exact claim: "T8aD +0x04 bit 0x02 selects an additive blend" → mine, and refuted. Blending those sprites additively worsens every measure against the capture.

That refutation is a claim about our renderer, which this corpus's own rule calls a hypothesis under test — and at the time the renderer had a stale keyframe association, no leaf geometry and no rotation. The claim was never tested against the game. It is now, and the field survives.

📌 The lesson is not "the old test was sloppy". It is that a negative produced by comparing two renders inherits every defect of both, and that a field can sit refuted for weeks because the instrument that killed it was the thing under repair.

The evidence

1. The fit — 35 elements, three screens, zero errors

Every label is an RB_BLENDCONTROL0 value read out of the guest command stream and attributed by quad size (data/blend-bit-vs-oracle.txt):

count
bit set and drawn additive 16
bit clear and drawn alpha-over 19
bit set but alpha-over 0
bit clear but additive 0

2. The control — no rival field

A perfect partition on 35 elements is worthless if half the header partitions equally well; that is exactly the mistake +0x08 = 0x8050 was. So every bit of the first twelve header words was tested against the same 35 labels:

Exactly one separates them without error, and it is +0x04 bit 0x02. Nothing ties with it.

3. The within-pair case that no confound survives

element +0x04 drawn
ptbtn00.t32 0x0110 alpha-over
ptbtn00f.t32 0x0112 ADDITIVE

The PRESS Ⓐ plate and its own highlight variant. Same screen, same bundle, adjacent in draw order, differing in exactly this bit — and the game blends them differently. Screen, archive, element family and draw order are all held fixed.

⚠️ And the obvious rival reading dies here too: ptbtn01f, ptbtn11f — other f highlight variants — are 0x8130, bit clear, and are drawn alpha-over. It is not "focused variants are additive".

4. The prediction, written and committed before the capture

data/blend-bit-prediction-gp-options.txt, committed at bbd85e9, said of GP_OPTIONSa different archive, an entirely different element set, never captured:

FALSIFIED IF: po_menu_eff01/02/03 draw alpha-over, or any other GP_OPTIONS element draws additive.

The developer splash was considered first and rejected as a test: both its elements predict alpha-over, so it can fail but cannot discriminate.

Result (data/blend-bit-prediction-result.txt, capture): the game was driven to OPTIONS and captured — 39 draws over 3 frames. Exactly three additive quads per frame, and they are po_menu_eff01, po_menu_eff02, po_menu_eff03. Entry 19 declares 16 sprites, 3 predicted additive and 13 not. Zero errors.

Reach, and what is not claimed

⚠️ The alpha-over side of the OPTIONS test is a count, not 13 identifications. Draw 1 is a 20-index batch of tiled 320×360 background quads, a size several elements share. What is measured there is that no draw on that screen carries 0x01010101 except the three. That asymmetry is the right way round: the prediction would have died on a fourth additive draw, and there was none.

⚠️ Two blend states, not a general mode field. Every UI draw observed on four screens is one of 0x01010101, 0x07010701, or 0x00010001 for the one non-UI blit that opens the frame. The bit chooses between the first two. Nothing here says what a third mode would look like or whether one exists.

⚠️ src = ONE in both states. The fixed-function stage multiplies the pixel shader's output by 1, so whatever alpha weighting happens is the shader's. This says nothing about whether .t32 texels are stored premultiplied; the shader is unread.

⚠️ Untextured primitives (.prm) have no T8aD header, so the bit cannot speak for them. pteff00.prm and pteff02.prm are observed alpha-over; that is a measurement, not a decode.

📊 Disc-wide population: the bit is set on 4 995 of 14 709 sprites (34 %), so it is not degenerate in either direction. Prior work established separately that it is not "the name contains eff" (P(eff|set) = 0.468 against P(eff|clear) = 0.144) and not premultiplied-alpha storage — both refuted disc-wide, and both remain refuted. Those were readings of the bit's meaning; this is its effect.