Files
retroDE_ps2/tools/gs_fb_to_png.py
T
thejayman77 ba74bbd5aa Snapshot: fog implementation + fidelity tooling baseline (pre bilinear-clamp fix)
Per-vertex GS fog end-to-end (gs_stub emit incl. persp_emit5, gs_prim_list_feeder
XYZ2->XYZF2 on PRIM.FGE, gs_make_sh3_scheduler_fixture.py F/FGE packing), new fog
TBs, fidelity attribution tooling. Functional baseline before removing the dead
bilinear lerp8 clamps (Codex: 161-node comb loop -> -0.042ns setup fail).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 19:56:46 -04:00

36 lines
1.5 KiB
Python

#!/usr/bin/env python3
# Convert a linear PSMCT32 framebuffer dump ($fwrite "%08x") to a PNG for visual triage.
# Word layout = PS2 PSMCT32 0xAABBGGRR (low byte R). Usage:
# gs_fb_to_png.py <fb.mem> <out.png> [width] [height] [scale]
# Defaults to the SH3 real-draw FB (256x120). No-op (exit 0) if input missing or PIL absent,
# so it can be chained after a sim without ever breaking the build.
import sys
def main():
a = sys.argv
src = a[1] if len(a) > 1 else "sim/data/top_psmct32_raster_demo/sh3_real_fb_out.mem"
dst = a[2] if len(a) > 2 else "sim/data/top_psmct32_raster_demo/sh3_real_fb_rtl.png"
W = int(a[3]) if len(a) > 3 else 256
H = int(a[4]) if len(a) > 4 else 120
SC = int(a[5]) if len(a) > 5 else 3
try:
from PIL import Image
except Exception:
print("[fb_to_png] PIL not available; skipping PNG"); return 0
try:
words = []
with open(src) as f:
for ln in f:
s = ln.strip()
if not s or s.startswith("/"): continue
words.append(int(s, 16) & 0xFFFFFFFF)
except FileNotFoundError:
print(f"[fb_to_png] {src} not found; skipping"); return 0
img = Image.new("RGB", (W, H))
for i, w in enumerate(words[:W*H]):
img.putpixel((i % W, i // W), (w & 0xFF, (w >> 8) & 0xFF, (w >> 16) & 0xFF))
img.resize((W*SC, H*SC), Image.NEAREST).save(dst)
print(f"[fb_to_png] wrote {dst} ({W}x{H} x{SC})")
return 0
if __name__ == "__main__":
sys.exit(main())