code wiki / (root) / nx_wasm_arcade.nx

nx_wasm_arcade.nx source

↩ module page · 120 lines · 5219 B

1// nx_wasm_arcade.nx -- the CORRECTED sovereign browser game: BASE-RELATIVE integer arcade. The SAME code 2// runs native (base = a real mmap -> render a frame to PNG for eyeball verify) AND in the browser (base = 0 3// = our own sovereign WASM linear memory). NO float, NO JS logic, NO 3rd-party canvas drawing. Game logic 4// (move/collect) + integer rasterizer write a packed-RGB framebuffer at a FIXED linear-mem offset; the blit 5// shim only copies that framebuffer to the screen + forwards keys. nx_wasm.nx auto-exports every func + 6// the linear memory, so init()/tick(dir)/render()/ww()/hh()/fb_off() become the wasm interface. The HUD 7// score is drawn into our OWN framebuffer by the sovereign Nishi font (no JS/canvas draws text). license_tier: ORIGINAL 8import "nx_nishi_font_core.nx" 9const W: i64 = 240 10const H: i64 = 192 11const CELL: i64 = 24 12const GW: i64 = 10 13const GH: i64 = 8 14const O_FB: i64 = 0 // framebuffer: W*H i64 (packed RGB), at linear-mem offset 0 15const O_GX: i64 = 368640 // W*H*8 16const O_GY: i64 = 368768 17const O_HX: i64 = 368896 18const O_HY: i64 = 369024 19const O_ST: i64 = 369152 // scalars: [0]=px [1]=py [2]=score [3]=ng [4]=nh 20const O_MSK: i64 = 376832 // HUD glyph scratch mask (base-relative; no sys_mmap -> works in wasm) 21const O_STR: i64 = 385024 // HUD score string scratch (decimal digits + reversal temp) 22 23func rgb(r: i64, g: i64, b: i64) -> i64 { return (r & 255) | ((g & 255) << 8) | ((b & 255) << 16) } 24 25func fillr(base: i64, x0: i64, y0: i64, x1: i64, y1: i64, c: i64) -> i64 { 26 let fb: *i64 = (base + O_FB) as *i64 27 var yy: i64 = y0; if yy < 0 { yy = 0 } 28 var ye: i64 = y1; if ye > H { ye = H } 29 while yy < ye { 30 var xx: i64 = x0; if xx < 0 { xx = 0 } 31 var xe: i64 = x1; if xe > W { xe = W } 32 while xx < xe { fb[yy*W + xx] = c; xx = xx + 1 } 33 yy = yy + 1 34 } 35 return 0 36} 37 38func init_impl(base: i64) -> i64 { 39 let st: *i64 = (base + O_ST) as *i64 40 let gx: *i64 = (base + O_GX) as *i64 41 let gy: *i64 = (base + O_GY) as *i64 42 let hx: *i64 = (base + O_HX) as *i64 43 let hy: *i64 = (base + O_HY) as *i64 44 st[0]=0; st[1]=0; st[2]=0; st[3]=4; st[4]=3 45 gx[0]=3; gy[0]=0; gx[1]=6; gy[1]=2; gx[2]=8; gy[2]=5; gx[3]=2; gy[3]=6 46 hx[0]=5; hy[0]=4; hx[1]=1; hy[1]=3; hx[2]=7; hy[2]=1 47 return 0 48} 49 50func tick_impl(base: i64, dir: i64) -> i64 { 51 let st: *i64 = (base + O_ST) as *i64 52 let gx: *i64 = (base + O_GX) as *i64 53 let gy: *i64 = (base + O_GY) as *i64 54 var nx: i64 = st[0] 55 var ny: i64 = st[1] 56 if dir == 0 { ny = ny - 1 } 57 if dir == 1 { ny = ny + 1 } 58 if dir == 2 { nx = nx - 1 } 59 if dir == 3 { nx = nx + 1 } 60 if nx < 0 { return 0 } 61 if ny < 0 { return 0 } 62 if nx >= GW { return 0 } 63 if ny >= GH { return 0 } 64 st[0] = nx; st[1] = ny 65 var i: i64 = 0 66 while i < st[3] { 67 if gx[i] == nx { if gy[i] == ny { gx[i] = 0 - 9; gy[i] = 0 - 9; st[2] = st[2] + 1; i = st[3] } else { i = i + 1 } } else { i = i + 1 } 68 } 69 return 0 70} 71 72func render_impl(base: i64) -> i64 { 73 let fb: *i64 = (base + O_FB) as *i64 74 let bg: i64 = rgb(16, 20, 30) 75 var p: i64 = 0 76 while p < W*H { fb[p] = bg; p = p + 1 } 77 var c: i64 = 0 78 while c <= GW { fillr(base, c*CELL, 0, c*CELL+1, GH*CELL, rgb(40,46,60)); c = c + 1 } 79 var r: i64 = 0 80 while r <= GH { fillr(base, 0, r*CELL, GW*CELL, r*CELL+1, rgb(40,46,60)); r = r + 1 } 81 let st: *i64 = (base + O_ST) as *i64 82 let gx: *i64 = (base + O_GX) as *i64 83 let gy: *i64 = (base + O_GY) as *i64 84 let hx: *i64 = (base + O_HX) as *i64 85 let hy: *i64 = (base + O_HY) as *i64 86 var i: i64 = 0 87 while i < st[3] { if gx[i] >= 0 { fillr(base, gx[i]*CELL+6, gy[i]*CELL+6, gx[i]*CELL+CELL-6, gy[i]*CELL+CELL-6, rgb(255,210,70)) } i = i + 1 } 88 var j: i64 = 0 89 while j < st[4] { fillr(base, hx[j]*CELL+4, hy[j]*CELL+4, hx[j]*CELL+CELL-4, hy[j]*CELL+CELL-4, rgb(224,80,58)) j = j + 1 } 90 fillr(base, st[0]*CELL+4, st[1]*CELL+4, st[0]*CELL+CELL-4, st[1]*CELL+CELL-4, rgb(90,210,122)) 91 // --- sovereign HUD: render the score as OUR font's pixels into the framebuffer (no JS/canvas text) --- 92 let sbuf: *u8 = (base + O_STR) as *u8 93 var slen: i64 = 0 94 var sv: i64 = st[2] 95 if sv <= 0 { 96 sbuf[0] = 48 as u8 // '0' 97 slen = 1 98 } else { 99 let tmp: *u8 = (base + O_STR + 16) as *u8 100 var k: i64 = 0 101 while sv > 0 { tmp[k] = (48 + (sv % 10)) as u8; sv = sv / 10; k = k + 1 } 102 var q: i64 = 0 103 while q < k { sbuf[q] = tmp[k - 1 - q]; q = q + 1 } 104 slen = k 105 } 106 let mask: *u8 = (base + O_MSK) as *u8 107 let hud_ch: i64 = 16 108 let hud_x: i64 = W - 4 - slen * nf_adv_px(hud_ch) 109 nf_draw_text_mem(fb, W, H, mask, hud_x, 3, hud_ch, sbuf, slen, rgb(235, 240, 250)) 110 return 0 111} 112 113// ---- WASM exports (base = 0 = our sovereign linear memory; auto-exported by nx_wasm.nx) ---- 114func init() -> i64 { return init_impl(0) } 115func tick(dir: i64) -> i64 { return tick_impl(0, dir) } 116func render() -> i64 { return render_impl(0) } 117func score() -> i64 { let st: *i64 = (0 + O_ST) as *i64; return st[2] } 118func fb_off() -> i64 { return O_FB } 119func ww() -> i64 { return W } 120func hh() -> i64 { return H }