code wiki / _hdl_build / nx_wasm_pong_html.nx

nx_wasm_pong_html.nx source

↩ module page · 32 lines · 3173 B

1// nx_wasm_pong_html.nx -- SOVEREIGN packager: the Pong wasm -> a self-contained REAL-TIME playable .html. 2// JS does ONLY: blit our wasm framebuffer, track held keys -> bitmask (up/down), a requestAnimationFrame loop 3// calling ex.tick(input)+ex.render(). All logic+render in sovereign wasm (no JS logic/canvas-draw/float). 4// usage: nx_wasm_pong_html <in.wasm> <out.html>. license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_base64.nx" 7import "nx_html_head_fd.nx" // seq702: the ONE accessible head (fd-streaming variant) 8 9func hw(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 10 11func main(argc: i64, argv: *i64) -> i64 { 12 if argc < 3 { hw(2, "usage: nx_wasm_pong_html <in.wasm> <out.html>\n" as *u8); return 2 } 13 let wlen_p: *i64 = sys_mmap(8) as *i64 14 let wbytes: *u8 = sys_read_file(argv[1] as *u8, wlen_p) 15 if (wbytes as i64) == 0 { hw(2, "read wasm failed\n" as *u8); return 3 } 16 let wlen: i64 = wlen_p[0] 17 let b64: *u8 = sys_mmap(wlen * 2 + 64) as *u8 18 let b64len: i64 = b64_encode(wbytes, wlen, b64) 19 let fd: i64 = sys_openat_wr(argv[2] as *u8, 0x1a4) 20 if fd < 0 { hw(2, "open html failed\n" as *u8); return 4 } 21 nxh_fd_head_open(fd, "Nishi Pong (sovereign wasm)" as *u8) 22 hw(fd, "<style>body{background:#0b0f1a;margin:0;display:flex;flex-direction:column;justify-content:center;align-items:center;height:100vh;font-family:sans-serif;color:#cdd}canvas{image-rendering:pixelated;width:480px;max-width:96vw;height:auto;border:1px solid #2a3140;background:#0c1016}p{margin:8px}</style>" as *u8) 23 nxh_fd_body_open(fd) 24 hw(fd, "<h2>Nishi Pong</h2><canvas id='c'></canvas><p id='hud'>&uarr; &darr; (or W / S) to move your paddle &middot; beat the AI</p><p style='color:#667;font-size:12px'>100% Nishi: logic + render + scores all in sovereign WASM; the browser only blits our framebuffer &amp; forwards keys</p><script>\n" as *u8) 25 hw(fd, "const B='" as *u8) 26 sys_write(fd, b64, b64len) 27 hw(fd, "';\nconst bytes=Uint8Array.from(atob(B),c=>c.charCodeAt(0));\nWebAssembly.instantiate(bytes).then(r=>{const ex=r.instance.exports;const W=Number(ex.ww()),H=Number(ex.hh()),off=Number(ex.fb_off());const cv=document.getElementById('c');cv.width=W;cv.height=H;const ctx=cv.getContext('2d');const img=ctx.createImageData(W,H);function blit(){const mem=new Uint8Array(ex.memory.buffer);for(let i=0;i<W*H;i++){const b=off+i*8;img.data[i*4]=mem[b];img.data[i*4+1]=mem[b+1];img.data[i*4+2]=mem[b+2];img.data[i*4+3]=255;}ctx.putImageData(img,0,0);}let inp=0;function bit(k){if(k=='ArrowUp'||k=='w')return 1;if(k=='ArrowDown'||k=='s')return 2;return 0;}document.addEventListener('keydown',function(e){const b=bit(e.key);if(b){e.preventDefault();inp|=b;}});document.addEventListener('keyup',function(e){const b=bit(e.key);if(b){e.preventDefault();inp&=~b;}});ex.init();function loop(){ex.tick(BigInt(inp));ex.render();blit();requestAnimationFrame(loop);}requestAnimationFrame(loop);}).catch(e=>{document.body.innerHTML+='<pre>'+e.message+'</pre>';});\n</script>\n" as *u8) 28 nxh_fd_close(fd) 29 sys_close(fd) 30 hw(1, "wrote pong html\n" as *u8) 31 return 0 32}