nx_indoorgen.nx source
↩ module page · 87 lines · 3764 B
1// nx_indoorgen.nx -- CLI: solve every shipped room archetype x variant by constraint (GR6, the
2// Infinigen 2.0 indoor expansion) and emit the engine data table the wasm worlds import.
3// nx_indoorgen [outpath] (default buildroot/runtime/nx_indoorgen_data.nx, nishihost cwd)
4// Every receipt is ANNOUNCED (arch/var/salt/rows, then wrote= of=) -- absence must be visible in
5// normal output, not only in failure. Stage+rename ship, size read back from the landed file.
6// Exit 0 EMITTED / 4 a variant or the emit REFUSED (named) / 1 io / 2 usage never (argv optional).
7// license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_part_solver_lib.nx"
10import "nx_indoorgen_lib.nx"
11
12const IGC_OUT_CAP: i64 = 32768
13const IGC_PATH_CAP: i64 = 512
14const IGC_MODE_0644: i64 = 420
15
16func igc_puts(s: *u8) -> i64 { sys_write(1, s, ig_slen(s)); return 0 }
17func igc_pn(v: i64) -> i64 {
18 let b: *u8 = sys_mmap(32) as *u8
19 let n: i64 = ig_wn(b, 0, v)
20 sys_write(1, b, n)
21 return 0
22}
23
24func main(argc: i64, argv: *i64) -> i64 {
25 var outp: *u8 = "buildroot/runtime/nx_indoorgen_data.nx" as *u8
26 if argc >= 2 { outp = argv[1] as *u8 }
27 // per-variant receipts BEFORE the emit: a refusal names its row
28 var a: i64 = 0
29 while a < IG_NARCH {
30 var v2: i64 = 0
31 while v2 < IG_NVAR {
32 let salt: i64 = ig_solve_salted(a, v2)
33 igc_puts("IG arch=" as *u8); igc_pn(a)
34 igc_puts(" var=" as *u8); igc_pn(v2)
35 if salt < 0 {
36 igc_puts(" REFUSED why=" as *u8); igc_pn(ig_why())
37 igc_puts(" last_worst=" as *u8); igc_puts(ps_kindname(ps_ckind(ps_worst())))
38 igc_puts(" violation=" as *u8); igc_pn(ps_worstv())
39 igc_puts(" -- the constraint set cannot be satisfied at any salt; refusing to fabricate a layout\n" as *u8)
40 sys_exit(4)
41 return 4
42 }
43 igc_puts(" salt=" as *u8); igc_pn(salt)
44 igc_puts(" rows=" as *u8); igc_pn(ig_nrows())
45 igc_puts("\n" as *u8)
46 v2 = v2 + 1
47 }
48 a = a + 1
49 }
50 let out: *u8 = sys_mmap(IGC_OUT_CAP)
51 let n: i64 = ige_emit(out)
52 if n <= 0 {
53 igc_puts("IG-DATA REFUSED code=" as *u8); igc_pn(n)
54 igc_puts("\n" as *u8)
55 sys_exit(4)
56 return 4
57 }
58 // stage + rename (the emit lane's founding law: never a half-written table on the live path)
59 let sp: *u8 = sys_mmap(IGC_PATH_CAP) as *u8
60 var q: i64 = 0
61 while outp[q] != (0 as u8) { sp[q] = outp[q]; q = q + 1 }
62 let sfx: *u8 = ".stage" as *u8
63 var q2: i64 = 0
64 while sfx[q2] != (0 as u8) { sp[q + q2] = sfx[q2]; q2 = q2 + 1 }
65 sp[q + q2] = 0 as u8
66 let fd: i64 = sys_openat_wr(sp, IGC_MODE_0644)
67 if fd < 0 { igc_puts("IG-DATA FAIL: stage open\n" as *u8); sys_exit(1); return 1 }
68 var off: i64 = 0
69 while off < n {
70 let w: i64 = sys_write(fd, ((out as i64) + off) as *u8, n - off)
71 if w <= 0 { sys_close(fd); igc_puts("IG-DATA FAIL: stage write\n" as *u8); sys_exit(1); return 1 }
72 off = off + w
73 }
74 sys_close(fd)
75 if sys_renameat(sp, outp) < 0 { igc_puts("IG-DATA FAIL: rename\n" as *u8); sys_exit(1); return 1 }
76 let box: *i64 = sys_mmap(16) as *i64
77 let back: *u8 = sys_read_file(outp, box)
78 if (back as i64) == 0 { igc_puts("IG-DATA FAIL: readback\n" as *u8); sys_exit(1); return 1 }
79 if box[0] != n { igc_puts("IG-DATA FAIL: readback bytes\n" as *u8); sys_exit(1); return 1 }
80 igc_puts("IG-DATA wrote=" as *u8); igc_pn(n)
81 igc_puts(" of=" as *u8); igc_puts(outp)
82 igc_puts(" archs=" as *u8); igc_pn(IG_NARCH)
83 igc_puts(" vars=" as *u8); igc_pn(IG_NVAR)
84 igc_puts(" (read back, sizes equal)\n" as *u8)
85 sys_exit(0)
86 return 0
87}