code wiki / _hdl_build / nx_simlab_html.nx

nx_simlab_html.nx source

↩ module page · 31 lines · 3519 B

1// nx_simlab_html.nx -- SOVEREIGN packager: integer sim-lab wasm -> self-contained .html that runs in any browser. 2// The emitted JS does ONLY: (1) BLIT our wasm framebuffer to the canvas via putImageData (copy bytes, NOT canvas 3// drawing), (2) drive the sim each animation frame (ex.tick(0)) and forward L/E/R keys. ALL physics + integer 4// rasterization live in our sovereign wasm (no JS logic, no canvas-draw, no float, no 3rd-party). 5// usage: nx_simlab_html <in.wasm> <out.html>. license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_base64.nx" 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_simlab_html <in.wasm> <out.html>\n" as *u8); return 2 } 13 let wpath: *u8 = argv[1] as *u8 14 let hpath: *u8 = argv[2] as *u8 15 let wlen_p: *i64 = sys_mmap(8) as *i64 16 let wbytes: *u8 = sys_read_file(wpath, wlen_p) 17 if (wbytes as i64) == 0 { hw(2, "read wasm failed\n" as *u8); return 3 } 18 let wlen: i64 = wlen_p[0] 19 let b64: *u8 = sys_mmap(wlen * 2 + 64) as *u8 20 let b64len: i64 = b64_encode(wbytes, wlen, b64) 21 22 let fd: i64 = sys_openat_wr(hpath, 0x1a4) 23 if fd < 0 { hw(2, "open html failed\n" as *u8); return 4 } 24 hw(fd, "<!doctype html><html><head><meta charset='utf-8'><title>Nishi Sim-Lab (sovereign wasm)</title><style>body{background:#0b0e16;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:512px;height:512px;border:1px solid #2a3140;background:#0a0d14}p{margin:6px}b{color:#8eb}</style></head><body><h2>Nishi Sim-Lab &mdash; gravitational orbit (sovereign WASM, no float)</h2><canvas id='c'></canvas><p id='hud'><b>L</b> leapfrog (symplectic) &middot; <b>E</b> Euler (naive) &middot; <b>R</b> reset &middot; <b>space</b> pause</p><p style='color:#667;font-size:12px'>100% Nishi: integer leapfrog/Euler physics + isqrt + rasterizer all run in sovereign WASM; the browser only blits our framebuffer &amp; forwards keys. Watch GREEN (leapfrog) hold the orbit while RED (Euler) pumps energy and spirals out &mdash; the live face of NASA-STD-7009 solution verification.</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 paused=false;ex.init();function frame(){if(!paused){ex.tick(BigInt(0));ex.render();blit();}requestAnimationFrame(frame);}ex.render();blit();requestAnimationFrame(frame);document.addEventListener('keydown',function(e){const k=e.key.toLowerCase();if(k=='l'){ex.tick(BigInt(1));}else if(k=='e'){ex.tick(BigInt(2));}else if(k=='r'){ex.tick(BigInt(3));}else if(k==' '){paused=!paused;e.preventDefault();}ex.render();blit();});}).catch(e=>{document.body.innerHTML+='<pre>'+e.message+'</pre>';});\n</script></body></html>\n" as *u8) 28 sys_close(fd) 29 hw(1, "wrote simlab html\n" as *u8) 30 return 0 31}