code wiki / _hdl_build / nx_sitegen_game.nx

nx_sitegen_game.nx source

↩ module page · 45 lines · 2729 B

1// nx_sitegen_game.nx -- AUTO-BUILDER, GAME-PUBLISH page type. The Nishi team publishes a GAME onto a website 2// FROM DATA: it renders the sovereign last-mile game template (web_assets/_game_build/game_page.tpl.html -- 3// the operator's proven pets3d_mp.html shell, kept BYTE-VERBATIM so we never transcribe the wasm ABI binding) 4// against the game's fields (title / wasm_url / framebuffer dims / display dims / default room / controls). 5// The JS is the documented LAST-MILE ONLY shim (zero game or netcode logic; all logic is in the sovereign 6// wasm); on the Nishi browser this binding is native. Slots are filled by nx_cms_render's {{key}} engine, so 7// every non-_html field is injection-ESCAPED by construction (a malicious title/url cannot break out of the 8// page). Data-driven => the SAME engine publishes ANY game by swapping the wasm + fields. Composes 9// nx_cms_render + nx_cms_store. license_tier: ORIGINAL 10import "nx_cms_render.nx" 11import "nx_cms_store.nx" 12import "nx_syscalls.nx" 13 14// write one store record @key\nval\n at off; returns new off. (the line-based store format cst_find parses) 15func sgg_put(store: *u8, off: i64, key: *u8, val: *u8) -> i64 { 16 var o: i64 = off 17 store[o] = 64 as u8; o = o + 1 // '@' 18 var k: i64 = 0; while key[k] != (0 as u8) { store[o] = key[k]; o = o + 1; k = k + 1 } 19 store[o] = 10 as u8; o = o + 1 // '\n' 20 var v: i64 = 0; while val[v] != (0 as u8) { store[o] = val[v]; o = o + 1; v = v + 1 } 21 store[o] = 10 as u8; o = o + 1 // '\n' 22 return o 23} 24 25// build the game-publish page from DATA: render tpl_path with the game's fields, write to fd. Returns the 26// output byte count, or -1 if the template cannot be read. 27func sgg_build(fd: i64, tpl_path: *u8, title: *u8, wasm_url: *u8, fb_w: *u8, fb_h: *u8, disp_w: *u8, disp_h: *u8, room: *u8, controls_html: *u8) -> i64 { 28 let tpl: *u8 = sys_mmap(262144) 29 let tn: i64 = cst_read(tpl_path, tpl, 262143) 30 if tn < 0 { return 0 - 1 } 31 let store: *u8 = sys_mmap(16384) 32 var sn: i64 = 0 33 sn = sgg_put(store, sn, "title" as *u8, title) 34 sn = sgg_put(store, sn, "wasm_url" as *u8, wasm_url) 35 sn = sgg_put(store, sn, "fb_w" as *u8, fb_w) 36 sn = sgg_put(store, sn, "fb_h" as *u8, fb_h) 37 sn = sgg_put(store, sn, "disp_w" as *u8, disp_w) 38 sn = sgg_put(store, sn, "disp_h" as *u8, disp_h) 39 sn = sgg_put(store, sn, "room" as *u8, room) 40 sn = sgg_put(store, sn, "controls_html" as *u8, controls_html) // _html -> inserted raw (the <b> hints) 41 let out: *u8 = sys_mmap(262144) 42 let outn: i64 = crd_render(tpl, tn, store, sn, out, 262143) 43 sys_write(fd, out, outn) 44 return outn 45}