ba74bbd5aa
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>
65 lines
1.7 KiB
Python
65 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Preview the exact Ch437 separable-linear SH3 scanout map."""
|
|
import math
|
|
import sys
|
|
|
|
from PIL import Image
|
|
|
|
|
|
def blend(a, b, frac, denom):
|
|
return tuple(((denom - frac) * x + frac * y + denom // 2) // denom
|
|
for x, y in zip(a, b))
|
|
|
|
|
|
def score(a, b):
|
|
ae = 0
|
|
se = 0
|
|
n = a.width * a.height * 3
|
|
for pa, pb in zip(a.getdata(), b.getdata()):
|
|
for ca, cb in zip(pa, pb):
|
|
d = int(ca) - int(cb)
|
|
ae += abs(d)
|
|
se += d * d
|
|
return ae / n, math.sqrt(se / n)
|
|
|
|
|
|
def main(argv):
|
|
if len(argv) != 4:
|
|
raise SystemExit(
|
|
"usage: preview_scanout_ch437.py <fb.png> <reference.png> <out.png>"
|
|
)
|
|
|
|
src = Image.open(argv[1]).convert("RGB")
|
|
if src.size != (640, 480):
|
|
raise SystemExit(f"expected 640x480 framebuffer, got {src.size}")
|
|
ref = Image.open(argv[2]).convert("RGB").resize(
|
|
(640, 480), Image.Resampling.BILINEAR
|
|
)
|
|
|
|
out = Image.new("RGB", (640, 480))
|
|
px = out.load()
|
|
for y in range(480):
|
|
yn = y * 14
|
|
y0 = 32 + yn // 15
|
|
yf = yn % 15
|
|
y1 = min(y0 + 1, 479)
|
|
for x in range(640):
|
|
xn = x * 4
|
|
x0 = xn // 5
|
|
xf = xn % 5
|
|
x1 = min(x0 + 1, 511)
|
|
left = blend(src.getpixel((x0, y0)),
|
|
src.getpixel((x0, y1)), yf, 15)
|
|
right = blend(src.getpixel((x1, y0)),
|
|
src.getpixel((x1, y1)), yf, 15)
|
|
px[x, y] = blend(left, right, xf, 5)
|
|
|
|
out.save(argv[3])
|
|
mae, rmse = score(out, ref)
|
|
print(f"bilinear MAE={mae:.4f} RMSE={rmse:.4f}")
|
|
print(f"wrote {argv[3]}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv)
|