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}