Extract VM animation opcode handler
This commit is contained in:
@@ -183,6 +183,8 @@ surface release; its labels remain at their existing dispatcher positions around
|
||||
object cases. `engine/Age.Engine/Vm/VirtualMachine.RetainedObjects.cs` owns retained-object registry queries,
|
||||
default-slot and geometry mutation, direct and range transforms, clone, and erase dispatch; animation, surface,
|
||||
ADV-binding, and presentation labels remain in their respective dispatcher groups.
|
||||
`engine/Age.Engine/Vm/VirtualMachine.Animation.cs` owns retained spritesheet and color channels, timed and cyclic
|
||||
transforms, per-object animation control, frame-time sampling, and the shared animation-clock opcode handler.
|
||||
|
||||
The disposable `build/page-map-<SCENE>.jsonl` files are produced by editor/development Godot runs and map
|
||||
runtime ADV page ordinals to their authoritative script offsets for `tools/locate_page.py`. Packaged exports
|
||||
|
||||
@@ -649,6 +649,12 @@ do not mix mechanical moves with semantic changes.
|
||||
color, surface release, ADV binding, and presentation behavior remain outside this handler. Runtime validation
|
||||
remains green.
|
||||
|
||||
The fifth bounded `VirtualMachine.Step` extraction moved retained spritesheet and color channels, timed and
|
||||
cyclic transforms, per-object animation control, frame-time sampling, and shared animation-clock dispatch into
|
||||
`engine/Age.Engine/Vm/VirtualMachine.Animation.cs`. The top-level dispatcher retains all labels at their
|
||||
existing positions and routes the separated groups through `StepAnimation`; presentation transitions and movie
|
||||
masking remain outside the guarded handler. Runtime validation remains green.
|
||||
|
||||
**Gate:** no externally visible behavior or command changes; generated artifacts are byte-identical where
|
||||
deterministic, and the corresponding engine, Python, Godot, and corpus validations remain green after
|
||||
each domain move.
|
||||
@@ -1020,9 +1026,8 @@ layer's rendering diverges from ADV; save layout.
|
||||
## 8. Immediate next step
|
||||
Continue step 2 of the **codebase consolidation** maintenance slice: behavior-neutral physical splits backed
|
||||
by the tracked launcher and layered validation driver. With the planned `Main`, `GodotAdvHost`, and `GfxState`
|
||||
domains isolated and the audio, movie, and surface/texture `VirtualMachine.Step` families routed through domain
|
||||
handlers, with retained-object query/mutation and transform dispatch now isolated as well, extract the retained
|
||||
animation/color/spritesheet opcode family next without replacing the proven dispatcher or changing public types,
|
||||
commands, and generated output.
|
||||
domains isolated and the audio, movie, surface/texture, retained-object, and animation `VirtualMachine.Step`
|
||||
families routed through domain handlers, extract retained presentation/transition dispatch next without replacing
|
||||
the proven dispatcher or changing public types, commands, and generated output.
|
||||
Concrete playthrough blockers may still preempt this bounded maintenance work; the consolidation effort does
|
||||
not replace Phase B gameplay validation or the open cross-platform gates.
|
||||
|
||||
54
engine/Age.Engine/Vm/VirtualMachine.Animation.cs
Normal file
54
engine/Age.Engine/Vm/VirtualMachine.Animation.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Age.Engine.Model;
|
||||
|
||||
namespace Age.Engine.Vm;
|
||||
|
||||
public sealed partial class VirtualMachine
|
||||
{
|
||||
private int StepAnimation(string label, IReadOnlyList<Operand> a, int pc)
|
||||
{
|
||||
switch (label)
|
||||
{
|
||||
case "u004223C0": // 0x239 spritesheet cell: (handle)(delay)(duration)(frame count)(columns)(cell)
|
||||
Gfx.SetSrcRect(Read(a[0]), Read(a[3]), Read(a[4]), Read(a[5]), 0); return pc + 1;
|
||||
case "reset-gfx-cyclic-animations": // 0x230: stop all five retained looping channels
|
||||
case "u00421E70":
|
||||
Gfx.ResetCyclicAnimationChannels(Read(a[0])); return pc + 1;
|
||||
case "u00421EA0": // 0x231 looping spritesheet: (handle)(ms per frame)(frame count)(columns)
|
||||
Gfx.SetSrcRect(Read(a[0]), Read(a[2]), Read(a[3]), 0, Read(a[1])); return pc + 1;
|
||||
case "u00421EF0": // 0x232 cyclic packed ARGB; negative alpha/RGB preserve static obj color
|
||||
Gfx.SetColorAnimResolved(Read(a[0]), Read(a[1]), Read(a[2]), Read(a[3])); return pc + 1;
|
||||
case "set-scale-cycle": // 0x233 (handle)(period ms)(target scale x/y/z percent)
|
||||
Gfx.SetScaleCycle(Read(a[0]), Read(a[1]), (Read(a[2]), Read(a[3]), Read(a[4])));
|
||||
return pc + 1;
|
||||
case "sample-frame-time": // 0x23c: previous <- current; current <- monotonic time
|
||||
Gfx.SampleFrameTime(_host.InputClockMilliseconds); return pc + 1;
|
||||
case "gfx-blit-color": // 0x202 (handle)(delay)(duration)(alpha)(color) — one-shot color
|
||||
Gfx.SetAnimatedObjectColorResolved(Read(a[0]), Read(a[1]), Read(a[2]), Read(a[3]), Read(a[4]));
|
||||
return pc + 1;
|
||||
case "gfx-draw-color": // 0x203 (handle)(v)(alpha)(color) — static alpha/tint
|
||||
Gfx.SetStaticObjectColorResolved(Read(a[0]), Read(a[1]), Read(a[2]), Read(a[3])); return pc + 1;
|
||||
// ---- sprite transform / animation cluster (docs/engine-re.md "0x21c-0x243 ... ANIMATION") ----
|
||||
case "set-anim-transform-abs": // 0x220 (handle)(delay)(duration)(tx)(ty)(tz)
|
||||
Gfx.SetTranslationChannel(Read(a[0]), Read(a[1]), Read(a[2]),
|
||||
(Read(a[3]), Read(a[4]), Read(a[5]))); return pc + 1;
|
||||
case "set-anim-transform-norm": // 0x21e (handle)(delay)(duration)(sx%)(sy%)(sz%)
|
||||
Gfx.SetScaleChannel(Read(a[0]), Read(a[1]), Read(a[2]),
|
||||
(Read(a[3]), Read(a[4]), Read(a[5]))); return pc + 1;
|
||||
case "set-anim-rotation-axis-angle": // 0x21f (handle)(delay)(duration)(axis x/y/z)(angle deg)
|
||||
Gfx.SetRotationChannel(Read(a[0]), Read(a[1]), Read(a[2]),
|
||||
(Read(a[3]), Read(a[4]), Read(a[5])), Read(a[6])); return pc + 1;
|
||||
case "anim-start": // 0x234 legacy name: (handle)(period)(axis x/y/z), cyclic rotation channel
|
||||
Gfx.SetRotationCycle(Read(a[0]), Read(a[1]), (Read(a[2]), Read(a[3]), Read(a[4]))); return pc + 1;
|
||||
case "set-anim-clock": // 0x238 (duration) — global, non-blocking (host advances it per-frame)
|
||||
Gfx.SetAnimClock(Read(a[0])); return pc + 1;
|
||||
case "set-object-animation-detached": // 0x242 (handle)(flags): bit 0 is nonblocking/force-proof
|
||||
Gfx.SetOneShotAnimationControl(Read(a[0]), Read(a[1])); return pc + 1;
|
||||
case "reset-anim-clock": // 0x243: force unprotected one-shots and reset the global service clock
|
||||
Gfx.ResetAnimClock(); return pc + 1;
|
||||
case "set-gfx-animation-service-flags": // 0x24e: bit 1 suppresses op 0x243
|
||||
Gfx.SetAnimationServiceFlags(Read(a[0])); return pc + 1;
|
||||
default:
|
||||
throw new InvalidOperationException($"Non-animation opcode routed to animation handler: {label}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2550,25 +2550,20 @@ public sealed partial class VirtualMachine
|
||||
case "set-gfx-range-scale-target": // 0x22d (delay)(duration)(sx%)(sy%)(sz%)
|
||||
return StepRetainedObject(label, a, pc);
|
||||
case "u004223C0": // 0x239 spritesheet cell: (handle)(delay)(duration)(frame count)(columns)(cell)
|
||||
Gfx.SetSrcRect(Read(a[0]), Read(a[3]), Read(a[4]), Read(a[5]), 0); return pc + 1;
|
||||
case "reset-gfx-cyclic-animations": // 0x230: stop all five retained looping channels
|
||||
case "u00421E70":
|
||||
Gfx.ResetCyclicAnimationChannels(Read(a[0])); return pc + 1;
|
||||
case "u00421EA0": // 0x231 looping spritesheet: (handle)(ms per frame)(frame count)(columns)
|
||||
Gfx.SetSrcRect(Read(a[0]), Read(a[2]), Read(a[3]), 0, Read(a[1])); return pc + 1;
|
||||
case "u00421EF0": // 0x232 cyclic packed ARGB; negative alpha/RGB preserve static obj color
|
||||
Gfx.SetColorAnimResolved(Read(a[0]), Read(a[1]), Read(a[2]), Read(a[3])); return pc + 1;
|
||||
case "set-scale-cycle": // 0x233 (handle)(period ms)(target scale x/y/z percent)
|
||||
Gfx.SetScaleCycle(Read(a[0]), Read(a[1]), (Read(a[2]), Read(a[3]), Read(a[4])));
|
||||
return pc + 1;
|
||||
return StepAnimation(label, a, pc);
|
||||
case "u00421940": // 0x228: (succ)(handle)(outX)(outY)(outZ) <- target translation matrix
|
||||
return StepRetainedObject(label, a, pc);
|
||||
case "u00422930":
|
||||
case "query-surface-stop-time-ms":
|
||||
case "query-movie-surface-active":
|
||||
return StepMovie(label, ins, pc);
|
||||
case "sample-frame-time": // 0x23c: previous <- current; current <- monotonic time
|
||||
Gfx.SampleFrameTime(_host.InputClockMilliseconds); return pc + 1;
|
||||
case "sample-frame-time":
|
||||
return StepAnimation(label, a, pc);
|
||||
case "set-gfx-geom3-c":
|
||||
case "u00420620": // upstream ABI label
|
||||
case "gfx-set-scale-current": // 0x1fd (handle)(sx%)(sy%)(sz%) -> current scale matrix
|
||||
@@ -2596,31 +2591,18 @@ public sealed partial class VirtualMachine
|
||||
_host.ReleaseSurface((int)Read(a[0])); Gfx.ClearSurface((int)Read(a[0])); return pc + 1;
|
||||
case "clone-gfx-object":
|
||||
return StepRetainedObject(label, a, pc);
|
||||
case "gfx-blit-color": // 0x202 (handle)(delay)(duration)(alpha)(color) — one-shot color
|
||||
Gfx.SetAnimatedObjectColorResolved(Read(a[0]), Read(a[1]), Read(a[2]), Read(a[3]), Read(a[4]));
|
||||
return pc + 1;
|
||||
case "gfx-draw-color": // 0x203 (handle)(v)(alpha)(color) — static alpha/tint
|
||||
Gfx.SetStaticObjectColorResolved(Read(a[0]), Read(a[1]), Read(a[2]), Read(a[3])); return pc + 1;
|
||||
case "gfx-blit-color":
|
||||
case "gfx-draw-color":
|
||||
// ---- sprite transform / animation cluster (docs/engine-re.md "0x21c-0x243 ... ANIMATION") ----
|
||||
case "set-anim-transform-abs": // 0x220 (handle)(delay)(duration)(tx)(ty)(tz)
|
||||
Gfx.SetTranslationChannel(Read(a[0]), Read(a[1]), Read(a[2]),
|
||||
(Read(a[3]), Read(a[4]), Read(a[5]))); return pc + 1;
|
||||
case "set-anim-transform-norm": // 0x21e (handle)(delay)(duration)(sx%)(sy%)(sz%)
|
||||
Gfx.SetScaleChannel(Read(a[0]), Read(a[1]), Read(a[2]),
|
||||
(Read(a[3]), Read(a[4]), Read(a[5]))); return pc + 1;
|
||||
case "set-anim-rotation-axis-angle": // 0x21f (handle)(delay)(duration)(axis x/y/z)(angle deg)
|
||||
Gfx.SetRotationChannel(Read(a[0]), Read(a[1]), Read(a[2]),
|
||||
(Read(a[3]), Read(a[4]), Read(a[5])), Read(a[6])); return pc + 1;
|
||||
case "anim-start": // 0x234 legacy name: (handle)(period)(axis x/y/z), cyclic rotation channel
|
||||
Gfx.SetRotationCycle(Read(a[0]), Read(a[1]), (Read(a[2]), Read(a[3]), Read(a[4]))); return pc + 1;
|
||||
case "set-anim-clock": // 0x238 (duration) — global, non-blocking (host advances it per-frame)
|
||||
Gfx.SetAnimClock(Read(a[0])); return pc + 1;
|
||||
case "set-object-animation-detached": // 0x242 (handle)(flags): bit 0 is nonblocking/force-proof
|
||||
Gfx.SetOneShotAnimationControl(Read(a[0]), Read(a[1])); return pc + 1;
|
||||
case "reset-anim-clock": // 0x243: force unprotected one-shots and reset the global service clock
|
||||
Gfx.ResetAnimClock(); return pc + 1;
|
||||
case "set-gfx-animation-service-flags": // 0x24e: bit 1 suppresses op 0x243
|
||||
Gfx.SetAnimationServiceFlags(Read(a[0])); return pc + 1;
|
||||
return StepAnimation(label, a, pc);
|
||||
case "play-movie-mask-transition":
|
||||
return StepMovie(label, ins, pc);
|
||||
case "queue-surface-alpha-transition": // 0x223: target surface crossfade over two object ranges
|
||||
|
||||
Reference in New Issue
Block a user