nx_nxa.nx source
↩ module page · 58 lines · 2488 B
1const NXA_MAGIC_1000003: i64 = 1000003
2// nx_nxa.nx -- NXA (Nishi Animated 3D) format v1: shared identity + integrity primitives.
3// The format spec lives in knowledge/nxa_format_spec.md. This organ is the ONLY place the
4// magic, tags, and checksum are defined -- writer (nx_fbx_measure) and readers (nx_mesh_view)
5// import it so they can never drift (DRY, rule-15).
6// license_tier: ORIGINAL
7
8const NXA_VER: i64 = 1
9
10// magic = the 8 ASCII bytes "NXANIM01" read as one little-endian i64 (no 64-bit hex literal risk)
11func nxa_magic() -> i64 {
12 let s: *u8 = "NXANIM01" as *u8
13 return ((s[0] & 0xff) as i64) | (((s[1] & 0xff) as i64) << 8)
14 | (((s[2] & 0xff) as i64) << 16) | (((s[3] & 0xff) as i64) << 24)
15 | (((s[4] & 0xff) as i64) << 32) | (((s[5] & 0xff) as i64) << 40)
16 | (((s[6] & 0xff) as i64) << 48) | (((s[7] & 0xff) as i64) << 56)
17}
18// 4-char section tag ("VERT", "TRIS", ...) as u32
19func nxa_tag4(s: *u8) -> i64 {
20 return ((s[0] & 0xff) as i64) | (((s[1] & 0xff) as i64) << 8)
21 | (((s[2] & 0xff) as i64) << 16) | (((s[3] & 0xff) as i64) << 24)
22}
23// order-sensitive rolling checksum over i64 words (seeded so writers can fold split buffers)
24func nxa_check2(seed: i64, w: *i64, nw: i64) -> i64 {
25 var c: i64 = seed
26 var i: i64 = 0
27 while i < nw { c = c*NXA_MAGIC_1000003 + w[i]; i = i + 1 }
28 return c
29}
30// locate section `tag` in a mapped NXA file; VERIFIES version, TOC check, and the section's
31// payload check BEFORE returning. Returns the payload's WORD offset (into file-as-*i64),
32// or -1 not-found/not-NXA, -2 future-version (refuse), -3 corrupt (refuse).
33func nxa_find(b: *u8, flen: i64, tag: i64) -> i64 {
34 if flen < 32 { return 0 - 1 }
35 let h: *i64 = b as *i64
36 if h[0] != nxa_magic() { return 0 - 1 }
37 if h[1] > NXA_VER { return 0 - 2 }
38 let ns: i64 = h[2]
39 if ns < 1 { return 0 - 3 }
40 if ns > 64 { return 0 - 3 }
41 if flen < 32 + ns*32 { return 0 - 3 }
42 let tb: *i64 = ((b as i64) + 32) as *i64
43 if h[3] != nxa_check2(1, tb, ns*4) { return 0 - 3 }
44 var s: i64 = 0
45 while s < ns {
46 if tb[s*4] == tag {
47 let off: i64 = tb[s*4+1]
48 let wl: i64 = tb[s*4+2]
49 if off < 32 + ns*32 { return 0 - 3 }
50 if off + wl*8 > flen { return 0 - 3 }
51 let pw: *i64 = ((b as i64) + off) as *i64
52 if tb[s*4+3] != nxa_check2(1, pw, wl) { return 0 - 3 }
53 return off/8
54 }
55 s = s + 1
56 }
57 return 0 - 1
58}