feat(gfx): label + dispatch set-anim-transform 0x21e/0x220 into GfxState

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-07-07 23:37:28 -04:00
parent 6339b93c72
commit 328c25bc56
4 changed files with 6875 additions and 6841 deletions

View File

@@ -149,6 +149,22 @@ This also names the whole call graph statically (build/callscript-names.json).
- **grounding:** source=investigation, confidence=high
- **evidence:** Ghidra handler 0x42a1b0; FUN_0047f2e0(obj op1) + 3x→FUN_00425fb0(2/3/4). label_12649 site 0x00c86 handle=G[0x62457] → G[0x62498/9/a].
### 0x21e `set-anim-transform-norm` (set-anim-transform-norm, argc 6)
- **summary:** (handle)(p1)(p2)(x)(y)(z) — set sprite transform channel, NORMALIZED (float operands /_DAT_00571c28 ~percent); cmd-type 0xd, worker gfx_anim_set_channel@0x47eaa0. SC0000 opening @0xf73+ on INIT2 CG handles. Cluster 0x21c-0x243. Handler 0x423350; Kelebek VA 0x421450 is drift.
- **grounding:** source=investigation, confidence=high
### 0x220 `set-anim-transform-abs` (set-anim-transform-abs, argc 6)
- **summary:** (handle)(p1)(p2)(x)(y)(z) — set sprite transform channel, ABSOLUTE (raw floats); cmd-type 0xd, worker 0x47ecc0. Twin of 0x21e. SC0000 opening @0x18a5+ on INIT2 CG handles. Cluster 0x21c-0x243. Handler 0x4234e0; Kelebek VA 0x4215D0 is drift.
- **grounding:** source=investigation, confidence=high
### 0x234 `anim-start` (anim-start, argc 5)
- **summary:** (handle)(duration)(x)(y)(z) — animate object toward target vec3 (x,y,z) over the GLOBAL clock; cmd-type 0xb, worker gfx_anim_start. op2=this object's duration (label_1235a maxes into the clock). SC0000 opening @0xdaf on INIT2 CG handles. Handler 0x423da0; Kelebek VA 0x422060 is drift.
- **grounding:** source=investigation, confidence=high
### 0x238 `set-anim-clock` (set-anim-clock, argc 1)
- **summary:** (duration) — set the GLOBAL animation clock: native ctx+0x51b78=0 (elapsed), +0x51b7c=duration. cmd-type 3. NON-BLOCKING: only configures; the render loop advances it and interpolates all animating objects. SC0000 opening @0x123bd/@0x13858. Handler 0x4240e0; Kelebek VA 0x422390 is drift.
- **grounding:** source=investigation, confidence=high
## input
### 0x90 `hotspot-branch` (u0041BEB0, argc 7)
@@ -922,18 +938,10 @@ op 0x90 (u0041BEB0, argc 7): `0x90 x y w h tgt_a tgt_b tgt_c`. Kelebek left it "
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x21e `u00421450` (u00421450, argc 6)
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x21f `u00421510` (u00421510, argc 7)
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x220 `u004215D0` (u004215D0, argc 6)
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x222 `u004216C0` (u004216C0, argc 2)
- **summary:** —
- **grounding:** source=kelebek, confidence=low
@@ -986,18 +994,10 @@ op 0x90 (u0041BEB0, argc 7): `0x90 x y w h tgt_a tgt_b tgt_c`. Kelebek left it "
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x234 `u00422060` (u00422060, argc 5)
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x236 `u004221A0` (u004221A0, argc 4)
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x238 `u00422390` (u00422390, argc 1)
- **summary:** —
- **grounding:** source=kelebek, confidence=low
### 0x239 `u004223C0` (u004223C0, argc 6)
- **summary:** —
- **grounding:** source=kelebek, confidence=low

View File

@@ -42,4 +42,31 @@ public class GfxAnimationTests
Assert.Equal(400, g.AnimClockDurationTicks);
Assert.Equal(cg0 + 1, g.AnimClockGeneration);
}
// ---- Tasks 3-5: VM dispatch + snapshot (synthesized scenes) ----
private static OpcodeTable T() => OpcodeTableJson.Load(Paths.OpcodesJson);
private static Operand G(int a) => new(3, a);
private static Operand I(long v) => new(0, v);
private static (int, Operand[]) MovGI(int d, long v) => (0x55, new[] { G(d), I(v) });
private static (int, Operand[]) Exit() => (0x2, System.Array.Empty<Operand>());
[Fact]
public void SetAnimTransformAbs_DispatchRecordsChannel()
{
var t = T();
// handle g[1]=0x1000; p1 g[2]=7; p2 g[3]=9; target g[4,5,6]=(800,500,0)
var scene = ScriptAssembler.Assemble(t, "ANIM", new List<(int, Operand[])>
{
MovGI(1, 0x1000), MovGI(2, 7), MovGI(3, 9), MovGI(4, 800), MovGI(5, 500), MovGI(6, 0),
(0x220, new[] { G(1), G(2), G(3), G(4), G(5), G(6) }),
Exit(),
}, System.Array.Empty<string>());
var vm = new VirtualMachine(scene, t, new RecordingHost());
vm.Run();
var o = vm.Gfx.TryGet(0x1000)!;
Assert.Equal((800L, 500L, 0L), o.AnimTarget);
Assert.False(o.AnimNormalized);
Assert.True(o.AnimEnabled);
}
}

View File

@@ -270,6 +270,13 @@ public sealed class VirtualMachine
case "gfx-draw-color": // 0x203 (handle)(v)(alpha)(color) — blend deferred
Gfx.GetOrCreate(Read(a[0])).Color = GfxState.PackColor(Read(a[2]), Read(a[3]));
WarnAlphaDeferredOnce(); return pc + 1;
// ---- sprite transform / animation cluster (docs/engine-re.md "0x21c-0x243 ... ANIMATION") ----
case "set-anim-transform-abs": // 0x220 (handle)(p1)(p2)(x)(y)(z) — set transform directly
Gfx.SetAnimTransform(Read(a[0]), Read(a[1]), Read(a[2]),
(Read(a[3]), Read(a[4]), Read(a[5])), normalized: false); return pc + 1;
case "set-anim-transform-norm": // 0x21e — same, operands are ~percent (/_DAT_00571c28)
Gfx.SetAnimTransform(Read(a[0]), Read(a[1]), Read(a[2]),
(Read(a[3]), Read(a[4]), Read(a[5])), normalized: true); return pc + 1;
default:
// Stub is per-instruction frequency (the VM handles ~30 ops; the rest hit here, e.g.
// 0x258/0x259 stmt markers appear en masse), so gate it with Step — else --trace floods.

File diff suppressed because it is too large Load Diff