diag+docs: confirm grey-BG root cause = unfilled slot-table (label_125bd via stubbed coroutine op 0x140)
Traced end-to-end (AGE_DIAG_SETTEX): set-texture slot=G[0x62452] <- query-gfx-object? (-1 for unregistered CG handles) -> fallback lookup-array-2d(rec[s3]=G[0x3239])=0 because the slot table is never filled: label_125bd (SC0000 0x50f, slots 4..13) is gated behind the scene-coroutine framework (0x140 coroutine-yield, stubbed). Adds env-gated VM set-texture/query slot diagnostics + GfxState.IsRegistered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -637,11 +637,20 @@ Diagnosed with the new `--gfx-log` compositor/op trace (docs/tools-reference.md)
|
||||
the effect spritesheet (`AE001H`, an 800×400 4×2 grid of blob frames) **all set-texture into slot 0**.
|
||||
Objects live-reference their slot, so loading the effect **evicts** the BG → grey; and the effect is
|
||||
drawn full-screen from slot 0 (its object `src=(0,0 800x600)`) → the whole sheet (blob grid) covers the
|
||||
screen. ⇒ The layering failure is a **slot-assignment** problem: the slot-selecting globals aren't
|
||||
populated (unseeded boot/gfx state, or a stubbed op the display subroutine relies on), collapsing the
|
||||
scene into one slot. **Open (next):** trace an effect-display subroutine to find which global holds the
|
||||
slot and why it's 0 (`--boot`/INIT2 gap vs a stubbed slot-compute op). Same class as the known
|
||||
`G[0x624xx]` gfx boot-state gap. NOT a compositor/z-order/blend bug.
|
||||
screen. ⇒ The layering failure is a **slot-assignment** problem. **CONFIRMED CAUSE (2026-07-08, live
|
||||
`AGE_DIAG_SETTEX` trace):** every `set-texture` slot = `G[0x62452]`, written by `query-gfx-object?`
|
||||
(`0x215`) which returns **-1** for the (correctly-unregistered) CG/effect handles → the fallback at
|
||||
SC0000 `label_12649` does `G[0x62452] = lookup-array-2d(rec[s3]=G[0x3239], G[0x62450], 3, 0)` = **0**
|
||||
because the slot table `rec[s3]`/`G[0x3239]` is **empty**. That table is filled by `call label_125bd`
|
||||
(SC0000 `0x50f`, slots 4..13), which is reached **only through the scene-coroutine framework** — the
|
||||
`G[0xaba5c]` gate (`0x450`) + op `0x140` (`u0041F9C0`, coroutine LABEL/yield `"LABEL" "J"` @ `0x46d`).
|
||||
**Op `0x140` is stubbed** (SC0000 GAP list) → the coroutine re-entry never routes through `label_125bd`
|
||||
→ slot table stays 0 → all layers collapse into slot 0. This is exactly the "second still-latent gap"
|
||||
flagged above (§"the render drift's second half"), now confirmed as the cause of the visible grey BG on
|
||||
multi-object pages. **Fix = implement the scene-coroutine framework (`0x7b`/`0x7c`/`0x140` + `G[0xaba5c]`
|
||||
gate) so `label_125bd` runs** (or, as a targeted unblock, run `label_125bd`/seed `G[0x3239]` directly).
|
||||
NOT a compositor/z-order/blend bug. Diagnostics: `AGE_DIAG_SETTEX=1` env → VM logs each `set-texture`
|
||||
slot operand + `query-gfx-object?` result.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ public sealed class GfxState
|
||||
/// <summary>Op 0x215 (query-gfx-object): native returns std::map::find(handle) — the registered value (=handle),
|
||||
/// or 0xffffffff (=-1) when the handle was never 0x1a2-registered. NOT a fabricated slot allocator.</summary>
|
||||
public int QuerySlot(long handle) => _registry.Contains(handle) ? (int)handle : -1;
|
||||
public bool IsRegistered(long handle) { lock (_lock) { return _registry.Contains(handle); } }
|
||||
public long QueryField(long idx) => _fieldTable.TryGetValue(idx, out var v) ? v : 0;
|
||||
|
||||
public void Release(long handle)
|
||||
|
||||
@@ -16,6 +16,7 @@ public sealed class VirtualMachine
|
||||
private readonly IHost _host;
|
||||
private readonly VmOptions _o;
|
||||
private readonly IScriptProvider? _provider;
|
||||
private static readonly bool _diagSetTexture = System.Environment.GetEnvironmentVariable("AGE_DIAG_SETTEX") == "1";
|
||||
private ExecFrame _cur = null!;
|
||||
private int _depth;
|
||||
private readonly ITraceSink _sink;
|
||||
@@ -221,6 +222,9 @@ public sealed class VirtualMachine
|
||||
Gfx.ClearSurface((int)Read(a[0]));
|
||||
_host.CreateTexture((int)Read(a[0]), (int)Read(a[1]), (int)Read(a[2])); return pc + 1;
|
||||
case "set-texture": // 0x1f9 (resId)(slot)(colorkey) — load a file into the slot's surface
|
||||
if (_diagSetTexture) // AGE_DIAG_SETTEX: log the SLOT operand source (literal vs which global) — grey-BG slot dig
|
||||
System.Console.Error.WriteLine($"[settex] resId=0x{Read(a[0]):x} slot={(int)Read(a[1])} " +
|
||||
$"slotOp=(type={a[1].Type} val=0x{a[1].Value:x}){(a[1].Type == 3 ? $" G[0x{a[1].Value:x}]" : "")}");
|
||||
Gfx.SetSurface((int)Read(a[1]), Read(a[0]), a.Count > 2 ? Read(a[2]) : 0);
|
||||
_host.SetTexture(Read(a[0]), (int)Read(a[1])); return pc + 1; // host still tracks dims for get-texture-size
|
||||
case "draw-texture": // 0x1fb (handle)(slot)(srcX)(srcY)(w)(h)(dstX)(dstY) — bind object -> surface + rect + pos
|
||||
@@ -238,6 +242,12 @@ public sealed class VirtualMachine
|
||||
case "play-voice": _host.PlayVoice(Read(a[0])); return pc + 1;
|
||||
// ---- gfx command-buffer ops (VM-internal GfxState; docs/engine-re.md op-contract table) ----
|
||||
case "query-gfx-object?": // 0x215 (out)(handle) -> slot | -1
|
||||
if (_diagSetTexture) // reuse the flag: show what the slot query returns (grey-BG slot dig)
|
||||
{
|
||||
long h = Read(a[1]);
|
||||
System.Console.Error.WriteLine($"[query] handle=0x{h:x} handleOp=(type={a[1].Type} val=0x{a[1].Value:x}) " +
|
||||
$"-> QuerySlot={Gfx.QuerySlot(h)} registered={Gfx.IsRegistered(h)}");
|
||||
}
|
||||
Write(a[0], Gfx.QuerySlot(Read(a[1]))); return pc + 1;
|
||||
case "query-gfx-field?": // 0x216 (out)(idx)
|
||||
Write(a[0], Gfx.QueryField(Read(a[1]))); return pc + 1;
|
||||
|
||||
Reference in New Issue
Block a user