code wiki / _hdl_build / nx_gen_explorer.nx

nx_gen_explorer.nx source

↩ module page · 116 lines · 9551 B

1// nx_gen_explorer.nx -- ★R10: a PUBLIC interactive generate front-end over the unified nx_gen surface. Renders a 2// matrix of assets across the parameter space (tree species x seed, creature plan x seed, figures, faces) via 3// nx_gen, bakes each into a self-contained page with an interactive picker (kind tabs + param buttons + seed 4// thumbnails + a big preview + a real per-asset DOWNLOAD) -- this is Infinigen's "downloadable pre-generated data" 5// offering, made interactive, on OUR generator. Worlds are excluded here (heavy ray-march; covered by /world). 6// license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_png.nx" 9import "nx_base64.nx" 10import "nx_gen.nx" 11const K_MAGIC_2026: i64 = 2026 12 13func 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 } 14func hn(fd: i64, v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} sys_write(fd,(b as i64+i+1) as *u8,31-i); return 0 } 15 16// render asset (kind,seed,p0) via nx_gen, downsample to a <=360px tile, write PNG, read back, base64, emit a JS 17// object {k,p,pl,s,src} to fd. plabel = param name string (or ""). 18func emit_asset(fd: i64, kind: i64, seed: i64, p0: i64, plabel: *u8, tile: *i64, scratch: *u8) -> i64 { 19 let spec: *i64 = sys_mmap(8*8) as *i64 20 let res: *i64 = sys_mmap(8*8) as *i64 21 spec[0]=kind; spec[1]=seed; spec[2]=p0; spec[3]=0 22 nx_gen(spec, res) 23 if res[0] != 1 { return 0 } 24 let sw: i64 = res[1]; let sh: i64 = res[2]; let sfb: *i64 = res[4] as *i64 25 var mx: i64 = sw 26 if sh > mx { mx = sh } 27 let tw: i64 = sw*360/mx 28 let th: i64 = sh*360/mx 29 var y: i64 = 0 30 while y < th { 31 var x: i64 = 0 32 while x < tw { tile[y*tw+x] = sfb[(y*sh/th)*sw + (x*sw/tw)]; x = x + 1 } 33 y = y + 1 34 } 35 write_png(tile, tw, th, scratch) 36 let lenp: *i64 = sys_mmap(16) as *i64 37 let png: *u8 = sys_read_file(scratch, lenp) 38 if (png as i64) == 0 { return 0 } 39 let b64: *u8 = sys_mmap(lenp[0]*2+64) as *u8 40 let blen: i64 = b64_encode(png, lenp[0], b64) 41 hw(fd, "{k:" as *u8); hn(fd, kind); hw(fd, ",p:" as *u8); hn(fd, p0) 42 hw(fd, ",pl:'" as *u8); hw(fd, plabel); hw(fd, "',s:" as *u8); hn(fd, seed) 43 hw(fd, ",src:'data:image/png;base64," as *u8) 44 sys_write(fd, b64, blen) 45 hw(fd, "'},\n" as *u8) 46 return 1 47} 48 49func main() -> i64 { 50 let fd: i64 = sys_openat_wr("knowledge/generate.html\x00" as *u8, 0x1a4) 51 if fd < 0 { hw(2, "gen_explorer: open failed\n" as *u8); return 1 } 52 let tile: *i64 = sys_mmap(360*360*8) as *i64 53 let scr: *u8 = "knowledge/_gxtile.png\x00" as *u8 54 55 hw(fd, "<!doctype html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Nishi Generator -- nx_gen(spec)</title><style>\n" as *u8) 56 hw(fd, "html,body{margin:0;background:#0a0d13;color:#cde;font-family:system-ui,sans-serif}.wrap{max-width:1000px;margin:0 auto;padding:16px}h1{font-size:22px;text-align:center}h1 .k{color:#8ef}p.intro{color:#9ab;font-size:14px;line-height:1.55;text-align:center;max-width:720px;margin:0 auto 18px}\n" as *u8) 57 hw(fd, "#tabs{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin:12px 0}.tab{background:#16222c;color:#cde;border:1px solid #223;border-radius:8px;padding:8px 16px;font-size:14px;cursor:pointer}.tab.on{background:#3fd0b0;color:#0a0d13;border-color:#3fd0b0;font-weight:600}\n" as *u8) 58 hw(fd, "#params{display:flex;gap:6px;justify-content:center;flex-wrap:wrap;margin:8px 0;align-items:center}.plab{color:#7f9;font-size:13px;font-family:ui-monospace,monospace}.pv{background:#111a22;color:#9ab;border:1px solid #223;border-radius:6px;padding:5px 11px;font-size:13px;cursor:pointer}.pv.on{background:#234;color:#8ef;border-color:#3fd0b0}\n" as *u8) 59 hw(fd, "#seeds{display:flex;gap:6px;justify-content:center;flex-wrap:wrap;margin:12px 0}.th{width:72px;height:72px;object-fit:cover;border-radius:7px;border:2px solid #223;cursor:pointer;background:#16222c}.th.on{border-color:#3fd0b0}\n" as *u8) 60 hw(fd, "#stage{text-align:center}#preview{max-width:100%;width:520px;border:1px solid #223;border-radius:9px;box-shadow:0 6px 24px #0009;background:#111a22}#meta{color:#7f9;font-size:14px;margin:8px 0}#dl{display:inline-block;background:#3fd0b0;color:#0a0d13;font-weight:600;text-decoration:none;padding:9px 20px;border-radius:8px;font-size:14px}#call{color:#8ef;font-family:ui-monospace,monospace;font-size:13px;background:#0e1420;border:1px solid #223;border-radius:7px;padding:10px;max-width:420px;margin:14px auto;text-align:center}\n" as *u8) 61 hw(fd, "</style></head><body><div class='wrap'>\n" as *u8) 62 hw(fd, "<h1>Nishi <span class='k'>Generator</span> &mdash; one API, every asset</h1>\n" as *u8) 63 hw(fd, "<p class='intro'>Every asset below is produced by a single sovereign call &mdash; <code style='color:#8ef'>nx_gen([kind, seed, params])</code> &mdash; the unified function-oriented generator surface (Infinigen's ProcFunc, ours). Pick a kind, choose a variant, browse seeds, and <b>download</b> any result. No ML, no libraries: integer procedural generation on our own stack. (Worlds live on <a href='/world' style='color:#8ef'>/world</a>.)</p>\n" as *u8) 64 hw(fd, "<div id='tabs'></div><div id='params'></div><div id='seeds'></div>\n" as *u8) 65 hw(fd, "<div id='stage'><img id='preview' alt='generated asset'><div id='meta'></div><a id='dl'>&#8681; Download PNG</a><pre id='call'></pre></div>\n" as *u8) 66 hw(fd, "</div>\n<script>\nvar A=[\n" as *u8) 67 68 // ---- TREES: 5 species x 4 seeds ---- 69 let tsp: *i64 = sys_mmap(8*8) as *i64 70 let tspn: *i64 = sys_mmap(8*8) as *i64 71 tspn[0]="broadleaf" as *u8 as i64; tspn[1]="conifer" as *u8 as i64; tspn[2]="birch" as *u8 as i64; tspn[3]="palm" as *u8 as i64; tspn[4]="dead" as *u8 as i64 72 let tseed: *i64 = sys_mmap(8*8) as *i64 73 tseed[0]=3; tseed[1]=9; tseed[2]=17; tseed[3]=42 74 var sp: i64 = 0 75 while sp < 5 { 76 var si: i64 = 0 77 while si < 4 { emit_asset(fd, GEN_TREE, tseed[si], sp, tspn[sp] as *u8, tile, scr); si = si + 1 } 78 sp = sp + 1 79 } 80 // ---- CREATURES: 3 plans x 3 seeds ---- 81 let cpn: *i64 = sys_mmap(8*8) as *i64 82 cpn[0]="quadruped" as *u8 as i64; cpn[1]="bird" as *u8 as i64; cpn[2]="fish" as *u8 as i64 83 let cseed: *i64 = sys_mmap(8*8) as *i64 84 cseed[0]=4; cseed[1]=11; cseed[2]=29 85 var pl: i64 = 0 86 while pl < 3 { 87 var ci: i64 = 0 88 while ci < 3 { emit_asset(fd, GEN_CREATURE, cseed[ci], pl, cpn[pl] as *u8, tile, scr); ci = ci + 1 } 89 pl = pl + 1 90 } 91 // ---- FIGURES: 6 seeds ---- 92 let fseed: *i64 = sys_mmap(8*8) as *i64 93 fseed[0]=7; fseed[1]=42; fseed[2]=57; fseed[3]=88; fseed[4]=101; fseed[5]=150 94 var fi: i64 = 0 95 while fi < 6 { emit_asset(fd, GEN_FIGURE, fseed[fi], 0, "" as *u8, tile, scr); fi = fi + 1 } 96 // ---- FACES: 6 seeds ---- 97 let xseed: *i64 = sys_mmap(8*8) as *i64 98 xseed[0]=7; xseed[1]=42; xseed[2]=99; xseed[3]=256; xseed[4]=777; xseed[5]=K_MAGIC_2026 99 var xi: i64 = 0 100 while xi < 6 { emit_asset(fd, GEN_FACE, xseed[xi], 0, "" as *u8, tile, scr); xi = xi + 1 } 101 102 hw(fd, "];\n" as *u8) 103 // ---- the picker (no '!' anywhere -- NishiLang literal trap) ---- 104 hw(fd, "var K=[{k:1,nm:'Trees',pn:'species',op:['broadleaf','conifer','birch','palm','dead']},{k:2,nm:'Creatures',pn:'plan',op:['quadruped','bird','fish']},{k:3,nm:'People',pn:'',op:[]},{k:4,nm:'Faces',pn:'',op:[]}];\n" as *u8) 105 hw(fd, "var ki=0,pp=0,ss=0;\nfunction cur(){return K[ki];}\n" as *u8) 106 hw(fd, "function matches(){var c=cur();return A.filter(function(a){return a.k===c.k&&(c.pn===''?true:a.p===pp);});}\n" as *u8) 107 hw(fd, "function draw(){var c=cur();var tb=document.getElementById('tabs').children;for(var i=0;i<tb.length;i++){tb[i].className=(i===ki?'tab on':'tab');}\n" as *u8) 108 hw(fd, "var pr=document.getElementById('params');pr.innerHTML='';if(c.pn.length>0){var lab=document.createElement('span');lab.className='plab';lab.textContent=c.pn+': ';pr.appendChild(lab);for(var j=0;j<c.op.length;j++){var b=document.createElement('button');b.className=(j===pp?'pv on':'pv');b.textContent=c.op[j];(function(jj){b.onclick=function(){pp=jj;ss=0;draw();};})(j);pr.appendChild(b);}}\n" as *u8) 109 hw(fd, "var lst=matches();if(ss>=lst.length){ss=0;}var sr=document.getElementById('seeds');sr.innerHTML='';for(var s=0;s<lst.length;s++){var im=document.createElement('img');im.className=(s===ss?'th on':'th');im.src=lst[s].src;(function(si){im.onclick=function(){ss=si;draw();};})(s);sr.appendChild(im);}\n" as *u8) 110 hw(fd, "var sel=lst[ss];if(sel){document.getElementById('preview').src=sel.src;var dl=document.getElementById('dl');dl.href=sel.src;dl.download='nishi_'+c.nm+'_'+(sel.pl||'')+'_seed'+sel.s+'.png';document.getElementById('meta').textContent=c.nm+(sel.pl?(' / '+sel.pl):'')+' / seed '+sel.s;document.getElementById('call').textContent='nx_gen(['+c.k+', '+sel.s+(c.pn.length>0?', '+pp:'')+'])';}}\n" as *u8) 111 hw(fd, "var tabs=document.getElementById('tabs');for(var i=0;i<K.length;i++){var t=document.createElement('button');t.className='tab';t.textContent=K[i].nm;(function(ii){t.onclick=function(){ki=ii;pp=0;ss=0;draw();};})(i);tabs.appendChild(t);}draw();\n" as *u8) 112 hw(fd, "</script></body></html>\n" as *u8) 113 sys_close(fd) 114 hw(1, "nx_gen_explorer: wrote knowledge/generate.html (interactive nx_gen catalog: 20 trees + 9 creatures + 6 figures + 6 faces)\n" as *u8) 115 return 0 116}