nx_bspfacts.nx source
↩ module page · 96 lines · 4230 B
1// nx_bspfacts.nx -- CLI: BodySlide preset structural facts. nx_bspfacts probe|decode <preset.xml>
2// The Bethesda body-preset dialect beside nx_kkfacts (/compare/koikatsu card-class lane). Facts +
3// slider name/permil pairs of the FIRST preset; per-preset data goes to the CALLER's stdout only
4// and never enters a published plane (the k-wall in the lib header).
5// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
6import "nx_syscalls.nx"
7import "nx_bspfacts_lib.nx"
8
9const BSPC_CAP: i64 = 8388608 // presets measure KBs; 8MB is the refuse-beyond bound -- census abstains, never truncates silently
10const BSPD_MAX_VALS: i64 = 512 // 3BA-class presets carry ~50..300 sliders per size; overflow visible via parsed vs printed
11
12func bc_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
13func bc_w(s: *u8) -> i64 { sys_write(1, s, bc_slen(s)); return 0 }
14func bc_e(s: *u8) -> i64 { sys_write(2, s, bc_slen(s)); return 0 }
15func bc_span(buf: *u8, off: i64, len: i64) -> i64 {
16 if off < 0 { return 0 }
17 if len <= 0 { return 0 }
18 sys_write(1, ((buf as i64) + off) as *u8, len)
19 return 0
20}
21func bc_num(v: i64) -> i64 {
22 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
23 var m: i64 = v
24 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
25 let t: *u8 = sys_mmap(32)
26 var k: i64 = 0
27 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
28 let o: *u8 = sys_mmap(32)
29 var i: i64 = 0
30 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
31 sys_write(1, o, k)
32 return 0
33}
34func bc_eq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 }
35
36func main(argc: i64, argv: *i64) -> i64 {
37 if argc < 3 { bc_e("usage: nx_bspfacts probe|decode <preset.xml>\n" as *u8); sys_exit(2); return 2 }
38 let buf: *u8 = sys_mmap(BSPC_CAP)
39 let fd: i64 = sys_openat_rd(argv[2] as *u8)
40 if fd < 0 { bc_e("ERROR: cannot open file\n" as *u8); sys_exit(1); return 1 }
41 let size: i64 = sys_lseek(fd, 0, 2)
42 sys_lseek(fd, 0, 0)
43 var want: i64 = size
44 if want > BSPC_CAP { want = BSPC_CAP }
45 var got: i64 = 0
46 var stop: i64 = 0
47 while stop == 0 {
48 if got >= want { stop = 1 } else {
49 let k: i64 = sys_read(fd, ((buf as i64) + got) as *u8, want - got)
50 if k <= 0 { stop = 1 } else { got = got + k }
51 }
52 }
53 sys_close(fd)
54 let facts: *i64 = sys_mmap(BSP_N_SLOTS * 8) as *i64
55 bsp_probe(buf, got, size, facts)
56 bc_w("BSPFACT is_preset=" as *u8); bc_num(facts[0])
57 if facts[0] == 1 {
58 bc_w(" presets=" as *u8); bc_num(facts[1])
59 bc_w(" setsliders=" as *u8); bc_num(facts[2])
60 bc_w(" groups=" as *u8); bc_num(facts[3])
61 bc_w(" big=" as *u8); bc_num(facts[4])
62 bc_w(" small=" as *u8); bc_num(facts[5])
63 bc_w(" name=" as *u8); bc_span(buf, facts[6], facts[7])
64 bc_w(" set=" as *u8); bc_span(buf, facts[8], facts[9])
65 }
66 bc_w("\n" as *u8)
67 if facts[0] == 0 { sys_exit(4); return 4 }
68 if bc_eq(argv[1] as *u8, "decode" as *u8) == 1 {
69 let noffs: *i64 = sys_mmap(BSPD_MAX_VALS * 8) as *i64
70 let nlens: *i64 = sys_mmap(BSPD_MAX_VALS * 8) as *i64
71 let vals: *i64 = sys_mmap(BSPD_MAX_VALS * 8) as *i64
72 let meta: *i64 = sys_mmap(16) as *i64
73 var ki: i64 = 0
74 while ki < 2 {
75 var szname: *u8 = "big" as *u8
76 if ki == 1 { szname = "small" as *u8 }
77 let parsed: i64 = bsp_decode(buf, got, ki, noffs, nlens, vals, BSPD_MAX_VALS, meta)
78 bc_w("BSPDECODE size=" as *u8); bc_w(szname)
79 bc_w(" declared=" as *u8); bc_num(meta[0])
80 bc_w(" parsed=" as *u8); bc_num(parsed)
81 bc_w(" pairs:" as *u8)
82 var show: i64 = parsed
83 if show > BSPD_MAX_VALS { show = BSPD_MAX_VALS }
84 var vi: i64 = 0
85 while vi < show {
86 bc_w(" " as *u8); bc_span(buf, noffs[vi], nlens[vi])
87 bc_w("=" as *u8); bc_num(vals[vi])
88 vi = vi + 1
89 }
90 bc_w("\n" as *u8)
91 ki = ki + 1
92 }
93 }
94 sys_exit(0)
95 return 0
96}