code wiki / _hdl_build / nx_arcade_hud_gate.nx
nx_arcade_hud_gate.nx source
↩ module page · 120 lines · 5901 B
1import "nx_gate_base.nx"
2// nx_arcade_hud_gate.nx -- proves the SOVEREIGN FONT HUD: the arcade draws its SCORE as our own font's
3// pixels INTO the framebuffer (no JS/canvas text). Discriminator: a pixel is "near-white" iff R,G,B all > 220.
4// The bg(16,20,30), grid(40,46,60), gold(255,210,70 -> B=70), red(224,80,58 -> G=80) and green(90,210,122 ->
5// R=90) are NEVER near-white, so near-white pixels can ONLY be font ink -> a by-construction proof that our
6// font drew, and a liar-kill on stray ink. Tests: score renders in the HUD; NO ink outside the HUD; the HUD
7// changes when the score changes; rendering is deterministic; all digits 0-9 render and are distinct.
8// license_tier: ORIGINAL expect_exit: 0
9import "nx_syscalls.nx"
10import "nx_wasm_arcade.nx"
11import "nx_png.nx"
12
13func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
14" as *u8); return ok }
15func pn(v0: i64) -> i64 { var v: i64=v0; if v<0 { let m: *u8=sys_mmap(8); m[0]=45 as u8; sys_write(1,m,1); v=0-v } let b: *u8=sys_mmap(24); var k: i64=0; if v==0 {b[0]=48;k=1} while v>0 {b[k]=(48+(v%10)) as u8; v=v/10; k=k+1} let o: *u8=sys_mmap(24); var j: i64=0; while j<k {o[j]=b[k-1-j];j=j+1} sys_write(1,o,k); return 0 }
16func chk(cond: i64, label: *u8, pass: *i64) -> i64 {
17 gw(" " as *u8); gw(label); gw(": " as *u8)
18 if cond==1 { gw("OK\n" as *u8); pass[0]=pass[0]+1 } else { gw("FAIL\n" as *u8) }
19 return cond
20}
21
22func is_nw(px: i64) -> i64 {
23 let r: i64 = px & 255
24 let g: i64 = (px >> 8) & 255
25 let b: i64 = (px >> 16) & 255
26 if r > 220 { if g > 220 { if b > 220 { return 1 } } }
27 return 0
28}
29func count_nw(fb: *i64, fbw: i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 {
30 var n: i64 = 0
31 var y: i64 = y0
32 while y < y1 {
33 var x: i64 = x0
34 while x < x1 { if is_nw(fb[y*fbw + x]) == 1 { n = n + 1 } x = x + 1 }
35 y = y + 1
36 }
37 return n
38}
39
40func main() -> i64 {
41 let pass: *i64 = sys_mmap(8) as *i64; pass[0]=0
42 gw("=== ARCADE HUD GATE (sovereign font score drawn into the framebuffer) ===\n" as *u8)
43
44 let buf: *u8 = sys_mmap(524288)
45 let base: i64 = buf as i64
46 init_impl(base)
47 render_impl(base)
48 let fb: *i64 = (base + O_FB) as *i64
49
50 // HUD region = top-right strip (score digit is right-aligned at the top).
51 let hud_x0: i64 = W - 40
52 let hud_y1: i64 = 22
53 let nw0: i64 = count_nw(fb, W, hud_x0, 0, W, hud_y1)
54 let nw0_left: i64 = count_nw(fb, W, 0, 0, hud_x0, H)
55 let nw0_below: i64 = count_nw(fb, W, hud_x0, hud_y1, W, H)
56 let nw0_out: i64 = nw0_left + nw0_below
57 gw(" score=0: HUD near-white=" as *u8); pn(nw0); gw(" outside-HUD near-white=" as *u8); pn(nw0_out); gw("\n" as *u8)
58 chk((nw0 > 8) as i64, "score '0' drawn as font ink in the HUD\x00" as *u8, pass)
59 chk((nw0_out == 0) as i64, "LIAR-KILL: zero font ink outside the HUD (grid/entities never near-white)\x00" as *u8, pass)
60
61 // collect the goal at (3,0): walk right 3 cells -> score 1
62 tick_impl(base, 3); tick_impl(base, 3); tick_impl(base, 3)
63 render_impl(base)
64 let st: *i64 = (base + O_ST) as *i64
65 let nw1: i64 = count_nw(fb, W, hud_x0, 0, W, hud_y1)
66 gw(" after collect: score=" as *u8); pn(st[2]); gw(" HUD near-white=" as *u8); pn(nw1); gw("\n" as *u8)
67 chk((st[2] == 1) as i64, "score advanced to 1 on collect\x00" as *u8, pass)
68 chk((nw1 > 0) as i64, "score '1' drawn as font ink in the HUD\x00" as *u8, pass)
69 chk((nw1 != nw0) as i64, "HUD CHANGED when the score changed (digit 0 vs 1 distinct)\x00" as *u8, pass)
70
71 // determinism: same play into a fresh base must produce a byte-identical frame
72 let buf2: *u8 = sys_mmap(524288)
73 let base2: i64 = buf2 as i64
74 init_impl(base2); tick_impl(base2,3); tick_impl(base2,3); tick_impl(base2,3); render_impl(base2)
75 let fb2: *i64 = (base2 + O_FB) as *i64
76 var det: i64 = 1
77 var yy: i64 = 0
78 while yy < H { var xx: i64 = 0; while xx < W { if fb[yy*W+xx] != fb2[yy*W+xx] { det = 0 } xx = xx + 1 } yy = yy + 1 }
79 chk(det, "DETERMINISTIC: identical frame on re-run (byte-identical framebuffer)\x00" as *u8, pass)
80
81 // digits 0-9: blit "0123456789" into a cleared test fb, write a PNG, count ink per digit
82 let tw: i64 = 320
83 let th: i64 = 40
84 let tbuf: *u8 = sys_mmap(tw*th*8 + 65536)
85 let tbase: i64 = tbuf as i64
86 let tfb: *i64 = tbase as *i64
87 let tmask: *u8 = (tbase + tw*th*8) as *u8
88 let ds: *u8 = sys_mmap(16)
89 var di: i64 = 0
90 while di < 10 { ds[di] = (48 + di) as u8; di = di + 1 }
91 var ci: i64 = 0
92 while ci < tw*th { tfb[ci] = rgb(16,20,30); ci = ci + 1 }
93 let adv24: i64 = nf_adv_px(24)
94 nf_draw_text_mem(tfb, tw, th, tmask, 6, 6, 24, ds, 10, rgb(235,240,250))
95 write_png(tfb, tw, th, "knowledge/nx_font_digits.png" as *u8)
96 var allr: i64 = 1
97 var mn: i64 = 1000000
98 var mx: i64 = 0
99 var nw1c: i64 = 0
100 var nw8c: i64 = 0
101 var gi: i64 = 0
102 while gi < 10 {
103 let cx0: i64 = 6 + gi*adv24
104 let cnt: i64 = count_nw(tfb, tw, cx0, 0, cx0+adv24, th)
105 if cnt < 3 { allr = 0 }
106 if cnt < mn { mn = cnt }
107 if cnt > mx { mx = cnt }
108 if gi == 1 { nw1c = cnt }
109 if gi == 8 { nw8c = cnt }
110 gi = gi + 1
111 }
112 gw(" digits 0-9 ink: min=" as *u8); pn(mn); gw(" max=" as *u8); pn(mx); gw(" nw(1)=" as *u8); pn(nw1c); gw(" nw(8)=" as *u8); pn(nw8c); gw(" -> knowledge/nx_font_digits.png\n" as *u8)
113 chk(allr, "all digits 0-9 render ink (none blank)\x00" as *u8, pass)
114 chk((mx - mn > 10) as i64, "digits are DISTINCT (ink count varies across 0-9)\x00" as *u8, pass)
115 chk((nw1c < nw8c) as i64, "shape sanity: '1' (thin) has less ink than '8' (two bowls)\x00" as *u8, pass)
116
117 gw("ARCADE-HUD rows=9 pass=" as *u8); pn(pass[0])
118 if pass[0]==9 { gw(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
119 gw(" verdict=RED\n" as *u8); sys_exit(1); return 1
120}