code wiki / (root) / nx_garment_gen.nx

nx_garment_gen.nx source

↩ module page · 80 lines · 3898 B

1// nx_garment_gen.nx -- THE GARMENT MESH GENERATOR (2026-08-30): grows conforming garment shells for every 2// id of the engine's garment table from the NPC asset's own body surface and appends them as one GARM 3// section (see nx_garment_gen_lib.nx for the geometry, the units and the fabric-table sources). 4// 5// nx_garment_gen <in.nxa> <out.nxa> [thick_permil] 6// thick_permil scales fabric thickness (1000 = as derived). 0 is the neg-control: REFUSED by name. 7// 8// EXIT: 0 written . 2 usage . 4 REFUSED (zero thickness) . 5 bad nxa . 6 REFUSED (an id selected no 9// triangle) . 7 REFUSED (a buffer cap -- named, never silently truncated) . 9 io 10// Prints one GARM line per kind (the receipt) and the section's word count; the gate re-derives the same 11// numbers IN-PROCESS from the lib, so no parser of this output exists anywhere. 12// license_tier: ORIGINAL. No hw writes (Rule 26). 13import "nx_syscalls.nx" 14import "nx_nxa.nx" 15import "nx_garment_gen_lib.nx" 16 17const GGP_EXIT_OK: i64 = 0 18const GGP_EXIT_USAGE: i64 = 2 19const GGP_EXIT_REFUSED: i64 = 4 20const GGP_EXIT_BADNXA: i64 = 5 21const GGP_EXIT_EMPTY: i64 = 6 22const GGP_EXIT_CAP: i64 = 7 23const GGP_EXIT_IO: i64 = 9 24 25func ggp_atoi(s: *u8) -> i64 { 26 var v: i64 = 0 27 var i: i64 = 0 28 var neg: i64 = 0 29 if s[0] == (45 as u8) { neg = 1; i = 1 } 30 while s[i] != (0 as u8) { 31 let c: i64 = s[i] as i64 32 if c < 48 { return 0 - 1 } 33 if c > 57 { return 0 - 1 } 34 v = v * 10 + (c - 48) 35 i = i + 1 36 } 37 if neg == 1 { return 0 - v } 38 return v 39} 40 41func main(argc: i64, argv: *i64) -> i64 { 42 if argc < 3 { gmg_puts("usage: nx_garment_gen <in.nxa> <out.nxa> [thick_permil]\n" as *u8); return GGP_EXIT_USAGE } 43 var pm: i64 = 1000 44 if argc >= 4 { pm = ggp_atoi(argv[3] as *u8) } 45 if pm < 0 { gmg_puts("usage: thick_permil must be a non-negative integer\n" as *u8); return GGP_EXIT_USAGE } 46 let lp: *i64 = sys_mmap(16) as *i64 47 let b: *u8 = sys_map_file(argv[1] as *u8, lp) 48 let flen: i64 = lp[0] 49 if (b as i64) == 0 { gmg_puts("GMG-REFUSED cannot map input\n" as *u8); return GGP_EXIT_BADNXA } 50 let G: *i64 = gmg_load(b, flen) 51 if (G as i64) == 0 { return GGP_EXIT_BADNXA } 52 G[GMG_C_THICK_PERMIL] = pm 53 gmg_puts("GMG body nv=" as *u8); gmg_pn(G[GMG_C_NV]) 54 gmg_puts(" nt=" as *u8); gmg_pn(G[GMG_C_NT]) 55 gmg_puts(" H=" as *u8); gmg_pn(G[GMG_C_H]) 56 gmg_puts(" nip_dm=" as *u8); gmg_pn(G[GMG_C_NIP]) 57 gmg_puts(" dyna=" as *u8); gmg_pn(G[GMG_C_ND]) 58 gmg_puts(" skirt_top_dm=" as *u8); gmg_pn(G[GMG_C_GTH]) 59 gmg_puts(" skirt_gap_units=" as *u8); gmg_pn(G[GMG_C_GAP]) 60 gmg_puts(" units_per_mm_x1000=" as *u8); gmg_pn(G[GMG_C_UPMK]) 61 gmg_puts(" thick_permil=" as *u8); gmg_pn(pm) 62 gmg_puts("\n" as *u8) 63 let sec: *i64 = sys_mmap(GMG_SEC_CAP * 8 + 64) as *i64 64 let stats: *i64 = sys_mmap(GMG_KINDS * GMG_STAT_N * 8 + 64) as *i64 65 let nw: i64 = gmg_gen_all(G, sec, stats) 66 if nw == GMG_ERR_REFUSED_THICK { gmg_puts("verdict=REFUSED zero-thickness\n" as *u8); return GGP_EXIT_REFUSED } 67 if nw == GMG_ERR_EMPTY { gmg_puts("verdict=REFUSED empty-kind\n" as *u8); return GGP_EXIT_EMPTY } 68 if nw == GMG_ERR_CAP { gmg_puts("verdict=REFUSED buffer-cap\n" as *u8); return GGP_EXIT_CAP } 69 if nw < 0 { gmg_puts("verdict=REFUSED\n" as *u8); return GGP_EXIT_BADNXA } 70 var k: i64 = 0 71 while k < GMG_KINDS { gmg_print_stat(((stats as i64) + k * GMG_STAT_N * 8) as *i64); k = k + 1 } 72 let rc: i64 = gmg_write_nxa(b, flen, sec, nw, argv[2] as *u8) 73 if rc < 0 { gmg_puts("GMG-REFUSED cannot open output for write\n" as *u8); return GGP_EXIT_IO } 74 gmg_puts("GARM section_words=" as *u8); gmg_pn(nw) 75 gmg_puts(" bytes=" as *u8); gmg_pn(nw * 8) 76 gmg_puts(" checksum=" as *u8); gmg_pn(nxa_check2(1, sec, nw)) 77 gmg_puts(" out=" as *u8); gmg_puts(argv[2] as *u8) 78 gmg_puts(" verdict=WRITTEN\n" as *u8) 79 return GGP_EXIT_OK 80}