Reverse shared SAVE.DAT integer opcodes
This commit is contained in:
@@ -36,19 +36,16 @@ public class GfxCommandBufferTests
|
||||
Assert.Equal(30, vm.Globals[7]);
|
||||
}
|
||||
|
||||
private static (int, Operand[]) Register(int handle) => (0x1a2, new[] { G(handle) });
|
||||
|
||||
[Fact]
|
||||
public void QueryReturnsZeroForCreatedUnboundObject_ThenBoundSourceSlot()
|
||||
{
|
||||
// Op 0x215 returns obj+4 from the retained gfx object. Native initialization leaves an unbound object's
|
||||
// field at zero; op 0x1a2 is unrelated. Draw-texture replaces it with the bound source slot.
|
||||
// field at zero. Draw-texture replaces it with the bound source slot.
|
||||
var t = T();
|
||||
var scene = ScriptAssembler.Assemble(t, "GFX", new List<(int, Operand[])>
|
||||
{
|
||||
MovGI(1, 0xcb2a), MovGI(2, 6), MovGI(3, 0), MovGI(4, 200),
|
||||
SetGeom3(1, 3, 3, 3),
|
||||
Register(1),
|
||||
Query(10, 1),
|
||||
(0x1fb, new[] { G(1), G(2), I(0), I(0), G(4), G(4), G(3), G(3) }),
|
||||
Query(11, 1), Exit(),
|
||||
|
||||
@@ -4,17 +4,14 @@ using Xunit;
|
||||
public class GfxStateTests
|
||||
{
|
||||
[Fact]
|
||||
public void QueryReturnsBoundSourceSlot_NotOperandRegistryValue()
|
||||
public void QueryReturnsBoundSourceSlot()
|
||||
{
|
||||
// Native op 0x215 queries the retained-object map and returns obj+4. The default initializer zeroes
|
||||
// that field, while draw-texture replaces it with the bound slot. Op 0x1a2 is a separate registry.
|
||||
// that field, while draw-texture replaces it with the bound slot.
|
||||
var g = new GfxState();
|
||||
g.GetOrCreate(0xcb2a).V18 = (400, 600, 0);
|
||||
Assert.Equal(0, g.QuerySlot(0xcb2a));
|
||||
|
||||
g.Register(0xcb2a);
|
||||
Assert.Equal(0, g.QuerySlot(0xcb2a));
|
||||
|
||||
g.BindDraw(0xcb2a, 6, 0, 0, 200, 200, 10, 20);
|
||||
Assert.Equal(6, g.QuerySlot(0xcb2a));
|
||||
Assert.Equal(-1, g.QuerySlot(0x9999));
|
||||
|
||||
@@ -115,11 +115,6 @@ public sealed class GfxState
|
||||
// returns the object's live source slot (obj+4), or -1 when the handle has not been drawn/bound yet.
|
||||
private readonly Dictionary<long, GfxObject> _objects = new();
|
||||
|
||||
// ---- opcode 0x1a2's operand-descriptor registry. Native op 0x1a2 hashes the lvalue descriptor string;
|
||||
// it is separate from the retained-object map queried by op 0x215. We retain membership for diagnostics
|
||||
// and teardown parity, but it does not make an undrawn gfx object queryable as a surface slot. ----
|
||||
private readonly HashSet<long> _operandRegistry = new();
|
||||
|
||||
private readonly Dictionary<long, long> _fieldTable = new(); // ctx+0x46d14 (0x216); no family writer -> default 0
|
||||
public long CurrentObject { get; private set; }
|
||||
|
||||
@@ -181,10 +176,6 @@ public sealed class GfxState
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Op 0x1a2: retain the operand's current value in the separate descriptor registry. This does
|
||||
/// not populate the retained-object map used by op 0x215.</summary>
|
||||
public void Register(long handle) { lock (_lock) { _operandRegistry.Add(handle); } }
|
||||
|
||||
public GfxObject? TryGet(long handle) => _objects.TryGetValue(handle, out var o) ? o : null;
|
||||
|
||||
/// <summary>Op 0x215: look up <paramref name="handle"/> in the retained gfx-object map and return obj+4,
|
||||
@@ -204,7 +195,6 @@ public sealed class GfxState
|
||||
if (_objects.TryGetValue(handle, out var obj) && obj.SourceSlot == fromSlot)
|
||||
obj.SourceSlot = toSlot;
|
||||
}
|
||||
public bool IsRegistered(long handle) { lock (_lock) { return _operandRegistry.Contains(handle); } }
|
||||
public long QueryField(long idx) => _fieldTable.TryGetValue(idx, out var v) ? v : 0;
|
||||
|
||||
public void Release(long handle)
|
||||
@@ -212,7 +202,6 @@ public sealed class GfxState
|
||||
lock (_lock) // re-entrant: EraseRange already holds _lock
|
||||
{
|
||||
_objects.Remove(handle);
|
||||
_operandRegistry.Remove(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1068,9 +1068,6 @@ public sealed class VirtualMachine
|
||||
{
|
||||
var o = Gfx.GetOrCreate(Read(a[0])); o.Field68 = Read(a[1]); o.Field6c = Read(a[2]); return pc + 1;
|
||||
}
|
||||
case "gfx-cmd-register": // 0x1a2 (handle) — operand-descriptor hash insert; separate from
|
||||
// op 0x215's retained gfx-object/source-slot lookup
|
||||
Gfx.Register(Read(a[0])); return pc + 1;
|
||||
case "gfx-elem-erase": // 0x1f7 (handle)(count) — erase retained-object range
|
||||
Gfx.EraseRange(Read(a[0]), Read(a[1])); return pc + 1;
|
||||
case "gfx-elem-release": // 0x1fa (surface slot)
|
||||
|
||||
Reference in New Issue
Block a user