Files
Sylpheed/docs/re/structures/t32-blend-mode-not-on-disc.md
sylph-decoder 0af81d7549 handoff: deliver ADDITIVE, and correct the 'any blend you choose is authored' instruction
HANDOFF gets the measured table, the two controls, the three caveats that travel
with it (src=ONE is not evidence of premultiplied textures; the frames share a
draw call so ptframe4 comes free; read it as per-element facts because the
selecting field is still unknown), and the correction to the port's own
sharpener -- 'neither frame has a fully-opaque pixel' is true and is not the
discriminator, because pteff10 has none either and renders accurately.

t32-blend-mode-not-on-disc.md keeps its negative and its reach and loses its
conclusion. INDEX gets the row.

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

4.1 KiB
Raw Permalink Blame History

A textured element carries no blend/alpha mode — undecodable, with reach

SUPERSEDED IN ITS CONCLUSION, 2026-08-31 — the route this page named as "the one left" was taken, and it answered. The frames are drawn ADDITIVE (RB_BLENDCONTROL0 = 0x01010101, src ONE / dst ONE), measured off the GPU per draw on two screens: ui-blend-mode-measured.md.

What survives here is the negative and its reach, and it is still the reason the answer had to come from the running game: no field of the declaration entry, no word or bit of the T8aD header, and no field of the keyframe record separates the four too-dark frames from the elements rendered accurately beside them. The disc-side reach was also widened after this page was written — four elements over two screens, and a per-bit sweep — in data/frame-blend-field-hunt.txt.

⚠️ And the sentence this page ends the port's question with — "any blend you choose is authored and must carry that label" — is now WRONG as guidance. It was true of the disc; it is not true of the game. Additive is transcribed, not authored. It was delivered to the port in that form and has been corrected there too.

Answers sylpheed-port's ask: what blend/alpha mode do ptframe1 and ptframe2 use on the main menu? They measure those two elements as the only ones whose residual is higher on flat pixels than on edges (25.41/16.54 against 19.85/9.82), signed one direction, ptframe1 rendering at 88.4 against the capture's 129.1 with 0.1 % of pixels render-brighter — a body-intensity difference, not a geometric one.

The answer: it is not on the disc, and the port is authoring

⚠️ Prior work covers .prm primitives (ui-prm-blend-mode.md, undecodable with reach) and a refuted T8aD +0x04 bit. Neither covers a .t32 element, which is what was asked. This does.

Reach 1 — the declaration entry (60 bytes, all 15 words read)

words what they are
+0x00+0x0B the name string (ptfr, ame1, .t32)
+0x0C+0x1F constant 0 across every element on the screen
+0x20, +0x24 constant FFFFFFFF
+0x28 kind — 0 plain, 0x10 primitive, 0x3002 button
+0x2C focus/nav index1 for non-buttons, 1…5 for the five buttons
+0x30, +0x34 position / pivot
+0x38 constant 0

🔴 The two frames are kind 0 — identical to ptbase, pteff05, pteff10, pteff12 and ptmsg. Nothing in the declaration distinguishes them.

⚠️ A first pass reported +0x00 and +0x08 as "separating the frames". False positive of my own test: those words are the name, and the frames share a prefix and a suffix no other element has.

Reach 2 — the sprite's own T8aD header, and a candidate I refuted

+0x08 is the one word where both frames agree on a value no other menu sprite has: 0x8050. Tested disc-wide before offering it:

  • 38 sprites carry 0x8050, only 8 named *frame* — not frame-specific;
  • the high byte tracks the archive0x80xx in GP_TITLE, 0xb1xx in GP_OPTIONS, 0xd8xx in GP_GAMEOVER, 0xf0xx in GP_DIALOG.

So +0x08 is an atlas/format word, not a mode. The candidate is dead.

What this means for the port

Any blend the port picks for these elements is authored, not transcribed, and must be labelled that way. Their refusal to brighten the frames until they match is the right call for the reason they gave: a blend invented on their side is indistinguishable from a decoded one in a month — and this page is the evidence that there is nothing to decode it from.

⚠️ Reach of the negative: one screen's declaration table read exhaustively, the T8aD header's low words compared across every sprite on that screen and one candidate word censused disc-wide. Not looked at: the executable's draw path, which is where a mode selected in code rather than data would live. That is a route, and it is the one left.