code wiki / _hdl_build / nx_wasm_html.nx
nx_wasm_html.nx source
↩ module page · 32 lines · 2927 B
1// nx_wasm_html.nx -- SOVEREIGN packager: a wasm game -> a self-contained playable .html. The JS canvas shim is
2// EMITTED OUTPUT (the accepted foreign-browser last-mile), not a build piece. Reads the .wasm (sys_read_file),
3// base64-encodes it with the sovereign codec (nx_base64.b64_encode), writes the HTML (single-quoted so no escapes).
4// Replaces the retired node make_html.js. usage: nx_wasm_html <in.wasm> <out.html>. license_tier: ORIGINAL
5import "nx_syscalls.nx"
6import "nx_base64.nx"
7
8func 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 }
9
10func main(argc: i64, argv: *i64) -> i64 {
11 if argc < 3 { hw(2, "usage: nx_wasm_html <in.wasm> <out.html>\n" as *u8); return 2 }
12 let wpath: *u8 = argv[1] as *u8
13 let hpath: *u8 = argv[2] as *u8
14 let wlen_p: *i64 = sys_mmap(8) as *i64
15 let wbytes: *u8 = sys_read_file(wpath, wlen_p)
16 if (wbytes as i64) == 0 { hw(2, "nx_wasm_html: read wasm failed\n" as *u8); return 3 }
17 let wlen: i64 = wlen_p[0]
18 let b64: *u8 = sys_mmap(wlen * 2 + 64) as *u8
19 let b64len: i64 = b64_encode(wbytes, wlen, b64)
20
21 let fd: i64 = sys_openat_wr(hpath, 0x1a4)
22 if fd < 0 { hw(2, "nx_wasm_html: open html failed\n" as *u8); return 4 }
23 // ---- HTML head + canvas + the start of the embedded wasm string ----
24 hw(fd, "<!doctype html><html><head><meta charset='utf-8'><title>Nishi f32 (wasm)</title><style>body{background:#161a24;margin:0;display:flex;flex-direction:column;justify-content:center;align-items:center;height:100vh;font-family:sans-serif;color:#9aa}canvas{image-rendering:pixelated;width:512px;height:512px;border:1px solid #333;background:#1c2030}</style></head><body><canvas id='c'></canvas><p>sovereign NishiLang to wat to wasm, hardware f32</p><script>\n" as *u8)
25 hw(fd, "const B='" as *u8)
26 sys_write(fd, b64, b64len)
27 // ---- the rAF render loop (EMITTED last-mile JS) ----
28 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);const mem=new Uint8Array(ex.memory.buffer);let t=0.6;function frame(){t+=0.02;const yc=Math.round(Math.cos(t)*1000),ys=Math.round(Math.sin(t)*1000);const xc=Math.round(Math.cos(0.45)*1000),xs=Math.round(Math.sin(0.45)*1000);ex.render(BigInt(yc),BigInt(ys),BigInt(xc),BigInt(xs));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);requestAnimationFrame(frame);}frame();}).catch(e=>{document.body.innerHTML+='<pre>'+e.message+'</pre>';});\n</script></body></html>\n" as *u8)
29 sys_close(fd)
30 hw(1, "nx_wasm_html: wrote html\n" as *u8)
31 return 0
32}