0x202/0x203 pack (alpha,color) via GfxState.PackColor onto the object; the actual alpha/additive blend is deferred and surfaced once through the trace sink (observe- only, parity held). Full suite 37 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
73 lines
3.1 KiB
C#
73 lines
3.1 KiB
C#
using System.Collections.Generic;
|
|
using Age.Engine.Model;
|
|
using Age.Engine.Sys4;
|
|
using Age.Engine.Vm;
|
|
using Xunit;
|
|
|
|
public class GfxCommandBufferTests
|
|
{
|
|
private static OpcodeTable T() => OpcodeTableJson.Load(Paths.OpcodesJson);
|
|
private static Operand G(int addr) => new(3, addr); // global-int
|
|
private static Operand I(long v) => new(0, v); // immediate
|
|
|
|
// op ctor helpers (0x217 set-geom3, 0x218 get-geom3, 0x215 query, 0x55 mov, 0x2 exit)
|
|
private static (int, Operand[]) SetGeom3(int handle, int a, int b, int c) => (0x217, new[] { G(handle), G(a), G(b), G(c) });
|
|
private static (int, Operand[]) GetGeom3(int handle, int a, int b, int c) => (0x218, new[] { G(handle), G(a), G(b), G(c) });
|
|
private static (int, Operand[]) Query(int outAddr, int handle) => (0x215, new[] { G(outAddr), G(handle) });
|
|
private static (int, Operand[]) MovGI(int dst, long v) => (0x55, new[] { G(dst), I(v) });
|
|
private static (int, Operand[]) Exit() => (0x2, System.Array.Empty<Operand>());
|
|
|
|
[Fact]
|
|
public void SetThenGetGeom3RoundTripsThroughTheObject()
|
|
{
|
|
var t = T();
|
|
// g[1]=handle; set V18 from g[2,3,4]=(10,20,30); read V18 back into g[5,6,7]; then exit.
|
|
var scene = ScriptAssembler.Assemble(t, "GFX", new List<(int, Operand[])>
|
|
{
|
|
MovGI(1, 0x1000), MovGI(2, 10), MovGI(3, 20), MovGI(4, 30),
|
|
SetGeom3(1, 2, 3, 4),
|
|
GetGeom3(1, 5, 6, 7),
|
|
Exit(),
|
|
}, System.Array.Empty<string>());
|
|
var vm = new VirtualMachine(scene, t, new RecordingHost());
|
|
vm.Run();
|
|
Assert.Equal(10, vm.Globals[5]);
|
|
Assert.Equal(20, vm.Globals[6]);
|
|
Assert.Equal(30, vm.Globals[7]);
|
|
}
|
|
|
|
[Fact]
|
|
public void QueryReturnsDistinctSlotsPerHandle_NotZero()
|
|
{
|
|
var t = T();
|
|
// create two objects via set-geom, then query each into g[10], g[11].
|
|
var scene = ScriptAssembler.Assemble(t, "GFX", new List<(int, Operand[])>
|
|
{
|
|
MovGI(1, 0x1000), MovGI(2, 0x2000), MovGI(3, 0),
|
|
SetGeom3(1, 3, 3, 3), SetGeom3(2, 3, 3, 3),
|
|
Query(10, 1), Query(11, 2), Exit(),
|
|
}, System.Array.Empty<string>());
|
|
var vm = new VirtualMachine(scene, t, new RecordingHost());
|
|
vm.Run();
|
|
Assert.NotEqual(0, vm.Globals[10]); // not collapsed to slot 0
|
|
Assert.NotEqual(vm.Globals[10], vm.Globals[11]); // distinct slots => no collapse
|
|
}
|
|
|
|
private static (int, Operand[]) BlitColor(int h, int x, int y, int alpha, int color)
|
|
=> (0x202, new[] { G(h), G(x), G(y), G(alpha), G(color) });
|
|
|
|
[Fact]
|
|
public void BlitColorStoresPackedArgbOnTheObject()
|
|
{
|
|
var t = T();
|
|
var scene = ScriptAssembler.Assemble(t, "GFX", new List<(int, Operand[])>
|
|
{
|
|
MovGI(1, 0x1000), MovGI(2, 0), MovGI(3, 0), MovGI(4, 0x80), MovGI(5, 0x112233),
|
|
BlitColor(1, 2, 3, 4, 5), Exit(),
|
|
}, System.Array.Empty<string>());
|
|
var vm = new VirtualMachine(scene, t, new RecordingHost());
|
|
vm.Run();
|
|
Assert.Equal(0x80_112233L, vm.Gfx.TryGet(0x1000)!.Color);
|
|
}
|
|
}
|