code wiki / _hdl_build / nx_wasm_shmup_gate.nx
nx_wasm_shmup_gate.nx source
↩ module page · 72 lines · 4670 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_wasm_shmup_gate.nx -- NATIVE gate for the browser-playable shmup core (nx_wasm_shmup). Runs the SAME
4// base-relative code the wasm runs, with base = a real mmap, to verify the game + render BEFORE lowering to
5// wasm (the verify-by-eye loop that replaces a browser we can't click here).
6// T1 KILL: aim + shoot advances a bullet that destroys an enemy (score rises). PNG (mid-game frame).
7// T2 RENDER REAL: the rendered frame has a green ship + a red enemy + the bullet.
8// T3 GAME-OVER + RESTART: a wave reaching the ship line ends the game; shoot restarts it.
9// T4 NEVER-BRICK (#26): deterministic, bounded, no float, base-relative (no sys_mmap in the core).
10// expect_exit: 0 license_tier: ORIGINAL
11import "nx_wasm_shmup.nx"
12import "nx_png.nx"
13import "nx_syscalls.nx"
14
15func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
16" as *u8); return ok }
17
18func main() -> i64 {
19 gw("=== nx_wasm_shmup_gate: browser-playable shmup core, verified NATIVE before wasm ===\n" as *u8)
20 var pass: i64 = 0; var total: i64 = 0
21 let base: i64 = sys_mmap(2*1024*1024) as i64
22 let st: *i64 = (base + O_ST) as *i64
23 let ea: *i64 = (base + O_EA) as *i64
24
25 // ---- T1: aim + shoot + advance -> an enemy is destroyed ----
26 init_impl(base)
27 var m: i64=0; while m < 22 { tick_impl(base, 1); m=m+1 } // move ship left to align with enemy 0 (x=18)
28 tick_impl(base, 4) // fire
29 var f: i64=0; while f < 40 { if st[4] > 0 { f=40 } else { tick_impl(base, 0); f=f+1 } } // advance the bullet
30 var t1ok: i64=1; if st[4] < 10 {t1ok=0} if ea[0] != 0 {t1ok=0}
31 total=total+1; if t1ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
32 gw("T1 kill: aim+shoot destroyed an enemy, score=" as *u8); gn(st[4]); gw(", enemy0 alive=" as *u8); gn(ea[0]); gw("\n" as *u8)
33
34 // ---- render a fresh mid-game frame (ship + bullet in flight + a wave) ----
35 init_impl(base)
36 tick_impl(base, 4) // fire
37 var a: i64=0; while a < 5 { tick_impl(base, 0); a=a+1 } // bullet mid-flight
38 render_impl(base)
39 let fb: *i64 = (base + O_FB) as *i64
40 write_png(fb, W, H, "knowledge/nx_wasm_shmup_native.png" as *u8)
41 gw(" (live evidence: PNG knowledge/nx_wasm_shmup_native.png -- ship + bullet + enemy wave + HUD score)\n" as *u8)
42
43 // ---- T2: render real -- green ship + red enemy in the framebuffer ----
44 let ship: i64 = fb[SY*W + (W/2)] // ship center
45 let enemy: i64 = fb[st[6]*W + 18] // enemy 0 at (18, ey)
46 var t2ok: i64=1
47 if ((ship>>8)&255) <= (ship&255) {t2ok=0} // ship: green > red
48 if (enemy&255) <= ((enemy>>8)&255) {t2ok=0} // enemy: red > green
49 total=total+1; if t2ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
50 gw("T2 render real: ship cell green (g=" as *u8); gn((ship>>8)&255); gw(">r=" as *u8); gn(ship&255); gw("), enemy cell red (r=" as *u8); gn(enemy&255); gw(">g=" as *u8); gn((enemy>>8)&255); gw(")\n" as *u8)
51
52 // ---- T3: game-over when a wave reaches the ship line, restart on shoot ----
53 init_impl(base)
54 var g: i64=0; while g < 2000 { if st[7]==1 { g=2000 } else { tick_impl(base, 0); g=g+1 } }
55 let over: i64 = st[7]
56 tick_impl(base, 4) // shoot -> restart
57 var t3ok: i64=1; if over != 1 {t3ok=0} if st[7] != 0 {t3ok=0}
58 total=total+1; if t3ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
59 gw("T3 game-over+restart: a wave reached the ship line (over=" as *u8); gn(over); gw("), shoot restarted (gameover now=" as *u8); gn(st[7]); gw(")\n" as *u8)
60
61 // ---- T4: never-brick / determinism ----
62 init_impl(base)
63 m=0; while m < 22 { tick_impl(base, 1); m=m+1 } tick_impl(base, 4)
64 f=0; while f < 40 { if st[4] > 0 { f=40 } else { tick_impl(base, 0); f=f+1 } }
65 let score2: i64 = st[4]
66 total=total+1; if score2 >= 10 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
67 gw("T4 never-brick (#26): deterministic re-run (score=" as *u8); gn(score2); gw("), base-relative, no float, no sys_mmap in the core\n" as *u8)
68
69 gw("\n=== nx_wasm_shmup_gate " as *u8); gn(pass); gw("/" as *u8); gn(total)
70 if pass == total { gw(" GREEN (a real-time playable shmup core, verified native, ready to lower to sovereign wasm)\n" as *u8); sys_exit(0); return 0 }
71 gw(" RED\n" as *u8); sys_exit(1); return 1
72}