From 1bc4928a55fec6b866dc6963083dde6eedbbfb03 Mon Sep 17 00:00:00 2001 From: James Dansereau <106631954+jkdansereau@users.noreply.github.com> Date: Mon, 31 Aug 2026 11:13:53 -0400 Subject: [PATCH] d43_emit: validate PointUsage[] round-trip + index-range + non-zero (D120) Confirms the D120 fix converter-side: 1469 PointUsage regions / 70177 s16 entries across the model set (every guard/character has several) now byteswap-round-trip, every index < numVertices, and no region is all-zero (the pre-M-30 bug). Guards against a future emit-gap regression. --- tools_pc/d43_emit.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools_pc/d43_emit.py b/tools_pc/d43_emit.py index 35a6962b..194361e6 100644 --- a/tools_pc/d43_emit.py +++ b/tools_pc/d43_emit.py @@ -766,6 +766,27 @@ def validate(name, src, D, NS, NT, nodes, R0, placed, all_gdls, buf, D_PC, break j += 1; o += 8 + # D120: PointUsage[] round-trips + is a sane index chain (each entry is an + # s16 in [-32768, numVertices) -- an index into the same array, or negative + # to terminate). A zero-filled region (the pre-M-30 bug) trivially passes + # the range test but every entry == 0 -> flag that too. + for puo, punv in op24_pointusage.items(): + pn = remap(puo) + if pn is None: + err(f"PointUsage {puo:#x} not in region map"); continue + allzero = True + for k in range(punv): + want = struct.unpack_from(">h", src, puo + 2 * k)[0] + got = struct.unpack_from("= punv: + err(f"PointUsage {puo:#x}[{k}] = {got} >= numVertices {punv}") + if allzero and punv > 1: + err(f"PointUsage {puo:#x}: all {punv} entries zero (emit gap?)") + # PC pointer offsets per (op, n64 field) — for round-trip validation PC_PTR_OFF = { 1: {4: 8}, 2: {0x14: 24}, 3: {0x14: 24}, 8: {8: 8},