diff --git a/docs/opcode-reference.md b/docs/opcode-reference.md index 17bbbd2..4b25a21 100644 --- a/docs/opcode-reference.md +++ b/docs/opcode-reference.md @@ -102,12 +102,12 @@ Native handler sleep_op_0xc8 @0x420ec0 is NON-BLOCKING: it arms a timer (sleep_t - **evidence:** Ghidra handler 0x4227b0 (dispatch ctx[0x26c93+0x1ff]); FUN_0047e800(op1,(float)op2,(float)op3,(float)op4). ### 0x202 `gfx-blit-color` (gfx-blit-color, argc 5) -- **summary:** 0x202 (handle)(x)(y)(alpha)(color) — gfx cmd-type 0xb. Handler gfx_op_0x202_blit_color @0x4228d0: blits object `handle` at (x,y) with a packed ARGB built from alpha(op4, ≥0x100→0xff, <0→FUN_0047f3e0) and color(op5, <0→FUN_0047f3e0) → FUN_0047ea00. See docs/engine-re.md gfx op-contract table. +- **summary:** 0x202 (handle)(x)(y)(alpha)(color) — gfx cmd-type 0xb. Handler gfx_op_0x202_blit_color @0x4228d0: worker gfx_op_0x202_worker_set_color_anim @0x47ea00 sets an ANIMATED color/alpha target (obj+0x64) + anim bit; packs ARGB from alpha(op4, ≥0x100→0xff, <0→FUN_0047f3e0) and color(op5, <0→FUN_0047f3e0). C# VM (2026-07-08 blend slice): routes through GfxState.SetObjectColor → the compositor applies STATIC alpha/tint (BlendKind.Alpha); smooth color-anim interpolation deferred. See docs/engine-re.md §Blend & transparency. - **grounding:** source=investigation, confidence=high - **evidence:** Ghidra handler 0x4228d0 (dispatch ctx[0x26c93+0x202]); packs (alpha<<24|rgb) from operands 4/5, FUN_0047ea00(op1,op2,op3,packed). ### 0x203 `gfx-draw-color` (gfx-draw-color, argc 4) -- **summary:** 0x203 (handle)(v)(alpha)(color) — gfx cmd-type 9. Handler gfx_op_0x203_draw_color @0x4229a0: draws object `handle` with op2 + a packed ARGB from alpha(op3)/color(op4) → FUN_0047e9b0. Sibling of 0x202 with one fewer positional arg. See docs/engine-re.md gfx op-contract table. +- **summary:** 0x203 (handle)(v)(alpha)(color) — gfx cmd-type 9. Handler gfx_op_0x203_draw_color @0x4229a0: worker gfx_op_0x203_worker_set_color @0x47e9b0 sets a STATIC color/alpha (obj+0x60), no anim bit; packs ARGB from alpha(op3)/color(op4). Sibling of 0x202 (one fewer positional arg). C# VM (2026-07-08 blend slice): routes through GfxState.SetObjectColor → compositor applies static alpha/tint (BlendKind.Alpha). See docs/engine-re.md §Blend & transparency. - **grounding:** source=investigation, confidence=high - **evidence:** Ghidra handler 0x4229a0 (dispatch ctx[0x26c93+0x203]); packs color from operands 3/4, FUN_0047e9b0(op1,op2,packed). diff --git a/docs/phase-a-slice-plan.md b/docs/phase-a-slice-plan.md index 7ab9a2a..3714d4c 100644 --- a/docs/phase-a-slice-plan.md +++ b/docs/phase-a-slice-plan.md @@ -600,3 +600,32 @@ compositing + cold-object anchors (the thing that makes the paced opening actual the Ctrl `Speed` multiplier (ADV-mode-scope RE). (c) Full scene-coroutine framework (`0x7b`/`0x7c`/`0x140`) for interactive multi-object scenes. (d) Model `0xcd get-input-type` (name-entry interactivity, the separate input gap noted above). + +### A2b — Blend & transparency (slice A) ✅ DONE (2026-07-08) + +First of three graphics-fidelity slices (A blend/transparency, B geometry/anchors, C render-targets). +Spec `docs/superpowers/specs/2026-07-08-blend-transparency-design.md`, plan +`docs/superpowers/plans/2026-07-08-blend-transparency.md`, branch `feat/blend-transparency` (engine 69/69, +sweep exit=284/STEP-LIMIT=13 parity, `SELFTEST OK`). + +**Landed (hybrid: engine resolves, host blits):** +- `Age.Engine/Model/BlendMath.cs` — pure colorkey match + ARGB unpack (colorkey format reversed: + op arg 3 `<0` = none, else `0xRRGGBB` exact-match, `0` = key black; baked at surface-load, see + engine-re.md §Blend). +- `RenderObject` gains `Alpha`/`Tint`/`Blend` (`BlendKind` Opaque|Alpha|Additive); `GfxObject.HasColor`; + `GfxState.SetObjectColor`; `SnapshotVisibleObjects` resolves them. `0x202`/`0x203` route through + `SetObjectColor` (the stale "alpha deferred" trace stub is gone — alpha is now consumed). +- Godot compositor: colorkey-baked image cache (keyed by `(path, colorKey)`), `BlitLayer` applies + colorkey + object alpha + RGB-tint modulate, and **surfaceless colored objects fill a tint×alpha quad** + (the fades) instead of being skipped. + +**Result (pixels):** page-1 event-CG composites cleanly (dialogue + prompt, no opaque boxes); the opening's +mid-fade frames now alpha-blend (dark bg + light-ray burst, then a blended dark transition) instead of the +pre-change **full-screen opaque grey wall** that ate the CG. Verified via `--shot`/`--shot-sequence` on +`SC0000 --boot`. + +**Deferred (documented, NOT built — confirmed by a stalled interp RE pass, engine-re.md §Blend):** +smooth color-animation *interpolation* (the fade ramps snap to the correct end-state rather than gliding — +the `0x202` color channel's blit consumer + clock coupling is a dedicated dig) and **additive/glow blend** +(`local_2c` mode 2/3; its object field isn't pinned). `BlendKind.Additive` is an unused seam. Next graphics +slices unchanged: B (geometry/anchors — sprite *placement*) and C (render-targets). diff --git a/vm-map/opcodes.toml b/vm-map/opcodes.toml index 30654da..186c733 100644 --- a/vm-map/opcodes.toml +++ b/vm-map/opcodes.toml @@ -4791,7 +4791,7 @@ abi_source = "kelebek+decode-validated" [opcode.semantics] name = "gfx-blit-color" category = "draw" -summary = "0x202 (handle)(x)(y)(alpha)(color) — gfx cmd-type 0xb. Handler gfx_op_0x202_blit_color @0x4228d0: blits object `handle` at (x,y) with a packed ARGB built from alpha(op4, ≥0x100→0xff, <0→FUN_0047f3e0) and color(op5, <0→FUN_0047f3e0) → FUN_0047ea00. See docs/engine-re.md gfx op-contract table." +summary = "0x202 (handle)(x)(y)(alpha)(color) — gfx cmd-type 0xb. Handler gfx_op_0x202_blit_color @0x4228d0: worker gfx_op_0x202_worker_set_color_anim @0x47ea00 sets an ANIMATED color/alpha target (obj+0x64) + anim bit; packs ARGB from alpha(op4, ≥0x100→0xff, <0→FUN_0047f3e0) and color(op5, <0→FUN_0047f3e0). C# VM (2026-07-08 blend slice): routes through GfxState.SetObjectColor → the compositor applies STATIC alpha/tint (BlendKind.Alpha); smooth color-anim interpolation deferred. See docs/engine-re.md §Blend & transparency." noop_headless = false source = "investigation" confidence = "high" @@ -4832,7 +4832,7 @@ abi_source = "kelebek+decode-validated" [opcode.semantics] name = "gfx-draw-color" category = "draw" -summary = "0x203 (handle)(v)(alpha)(color) — gfx cmd-type 9. Handler gfx_op_0x203_draw_color @0x4229a0: draws object `handle` with op2 + a packed ARGB from alpha(op3)/color(op4) → FUN_0047e9b0. Sibling of 0x202 with one fewer positional arg. See docs/engine-re.md gfx op-contract table." +summary = "0x203 (handle)(v)(alpha)(color) — gfx cmd-type 9. Handler gfx_op_0x203_draw_color @0x4229a0: worker gfx_op_0x203_worker_set_color @0x47e9b0 sets a STATIC color/alpha (obj+0x60), no anim bit; packs ARGB from alpha(op3)/color(op4). Sibling of 0x202 (one fewer positional arg). C# VM (2026-07-08 blend slice): routes through GfxState.SetObjectColor → compositor applies static alpha/tint (BlendKind.Alpha). See docs/engine-re.md §Blend & transparency." noop_headless = false source = "investigation" confidence = "high"