re: a candidate blend flag -- T8aD header +0x04, bit 0x02

Continuing the swoosh. Last iteration ended with "the next step is
finding where a blend mode would be encoded, and I do not know the format
carries one". It does carry a candidate.

The kind field is not it -- the swoosh sprites are kind 0x0, the same as
ordinary ones. But the T8aD header word at +0x04 splits the title's
sprites exactly along effect versus normal: pteff01, pteff03a,
ptlogo_back2eff1..5 and both ptlogoall_eff are 0x8832, while ptlogo1,
ptlogo2, ptlogo_tm, ptbase2, ptlogo_back2 and ptcopyright are 0x8830.
One bit, 0x02.

Disc-wide it behaves like a real flag rather than an artefact: 19216
sprites, 18 distinct values, bit 0x02 set in 27.1 percent, and it toggles
against otherwise identical words -- 0x8830 against 0x8832, 0x0830
against 0x0832, 0x0810 against 0x0812, 0x0030 against 0x0032.

Marked as correlation and not decode, because nothing here shows the bit
MEANS additive. The one thing that makes it more than a guess is
ptlogo_back2eff, which carries 0x8830 despite having eff in its name --
so the split is the field's and not my pattern-matching on names. The
test is to blend bit-0x02 sprites additively and re-correlate the title
against the plate-free capture.

METHOD gets the trap that cost the first attempt: searching for a
sprite's name and taking the next T8aD returns the SAME header for every
sprite, because the names all live together in the declaration table. It
failed its own control at once -- different sprites reporting identical
dimensions -- and the fix was to match on width and height instead of on
proximity.
This commit is contained in:
Sylpheed RE agent
2026-08-28 21:46:18 +00:00
parent 9dd2948d3e
commit 0788584e9f
3 changed files with 56 additions and 1 deletions

View File

@@ -96,7 +96,19 @@ authored version can be deleted.
mostly-transparent sprites (`ptlogo_back2` 5.4 % opaque, its glow 10.3 %, the
five `eff` segments 1023 %, all white or warm) stacked with plain alpha-over
saturate to opaque white — which is exactly what we draw, and would read as
"thicker" against the game's thin coloured stroke. ❔ Not diagnosed.
"thicker" against the game's thin coloured stroke.
🟡 **And there is a candidate field for it.** The `T8aD` header word at
**`+0x04`** splits the title's sprites exactly along effect-vs-normal:
`pteff01`, `pteff03a`, `ptlogo_back2eff1…5`, `ptlogoall_eff`/`_eff2` are
**`0x8832`**; `ptlogo1`/`2`, `ptlogo_tm`, `ptbase2`, `ptlogo_back2`,
`ptcopyright` and `ptlogo_back2eff` are **`0x8830`**. One bit — **`0x02`**.
Disc-wide it is a real independent flag: 19 216 sprites, 18 distinct values,
bit `0x02` set in **27.1 %**, and it toggles against otherwise-identical words
(`0x8830`/`0x8832`, `0x0830`/`0x0832`, `0x0810`/`0x0812`, `0x0030`/`0x0032`).
⚠️ **Correlation only — untested.** Nothing yet shows it *means* additive; the
test is to blend bit-`0x02` sprites additively and re-correlate the title
against the capture. Note `ptlogo_back2eff` is `0x8830` despite its name, so
this is a field and not a naming pattern. ❔ Not diagnosed.
🔴 **Refuted:** it is *not* that our dim covers the whole frame instead of
sitting beneath the UI — the logo reads +2.36 against a background of 0.74, so
the paint order is being honoured.

View File

@@ -287,3 +287,10 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the
`docs/re/` while the port's page kept the stale text. Writing the rule down was
not enough; the working fix is mechanical — `grep`/`sed -n` the target paragraph
in the same command that patches it, and check the commit's file count.
* **"The nearest header after the name" is not a name→header mapping.** Looking
for each sprite's `T8aD` header by searching for its name and taking the next
`T8aD` returned *the same header for every sprite* — all the names live together
in the declaration table near the top of the bundle, so "next" is always the
first one in the file. It failed its own control instantly: different sprites
reported identical dimensions. Match on something the header itself carries
(here width × height against the decoded PNGs) rather than on proximity.

View File

@@ -448,3 +448,39 @@ against the capture over the pixels where they disagree. That needs a rebuild of
same A/B this page already ran on the two screens that had oracles, and `EXTRAS`
would be the first screen where the two orders can be judged against ground
truth rather than declared indistinguishable.
## 🟡 A second flag in the same header: `+0x04`, bit `0x02` (2026-08-28)
This page reads the layer key at `+0x0A`. The word at **`+0x04`** is a different
flag word, and on the title screen it splits the sprites exactly along
**effect versus normal**:
| `+0x04` | title sprites |
|---|---|
| **`0x8832`** | `pteff01`, `pteff03a`, `ptlogo_back2eff1…5`, `ptlogoall_eff`, `ptlogoall_eff2` |
| **`0x8830`** | `ptlogo1`, `ptlogo2`, `ptlogo_tm`, `ptbase2`, `ptlogo_back2`, `ptcopyright`, `ptlogo_back2eff` |
One bit apart: **`0x02`**.
**Disc-wide** (19 216 `T8aD` sprites, top-level and `RATC`-nested): 18 distinct
values, and bit `0x02` is set in **27.1 %**. It varies independently of the rest
of the word — `0x8830`/`0x8832`, `0x0830`/`0x0832`, `0x0810`/`0x0812` and
`0x0030`/`0x0032` all occur — so it is a genuine flag, not part of a larger
enumeration.
**Why it matters:** the title's swoosh renders opaque white where the game draws
a thin coloured stroke, and every other candidate is eliminated — position and
size come from the texture and match, `fade` is white-with-alpha, `tint` is white,
and the texture itself is blue-leaning
([`../ui-title-build-map.md`](../ui-title-build-map.md)). A per-sprite **blend
mode** is what is left, and this is the only per-sprite field found that
distinguishes the elements involved.
⚠️ **This is a correlation, not a decode.** Nothing here shows the bit *means*
additive. The test: blend bit-`0x02` sprites additively and re-correlate the title
render against
[`../captures/title-builds/live-title-build4-no-plate.png`](../captures/title-builds/live-title-build4-no-plate.png).
Worth noting `ptlogo_back2eff` carries `0x8830` **despite** having `eff` in its
name — so the split is the field's, not a naming pattern's, which is the one thing
that makes it more than a guess.