nx_kkfacts.nx source
↩ module page · 64 lines · 2580 B
1// nx_kkfacts.nx -- CLI: Koikatsu card structural facts. nx_kkfacts probe <card.png>
2// Reads up to 64MB (cards are full files, payload census needs the whole artifact). Facts only:
3// structure + sizes + block census; slider values / names / creative content stay unread.
4// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
5import "nx_syscalls.nx"
6import "nx_kkfacts_lib.nx"
7
8const KKC_CAP: i64 = 67108864
9
10func kc_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
11func kc_w(s: *u8) -> i64 { sys_write(1, s, kc_slen(s)); return 0 }
12func kc_e(s: *u8) -> i64 { sys_write(2, s, kc_slen(s)); return 0 }
13func kc_num(v: i64) -> i64 {
14 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
15 var m: i64 = v
16 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
17 let t: *u8 = sys_mmap(32)
18 var k: i64 = 0
19 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
20 let o: *u8 = sys_mmap(32)
21 var i: i64 = 0
22 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
23 sys_write(1, o, k)
24 return 0
25}
26
27func main(argc: i64, argv: *i64) -> i64 {
28 if argc < 3 { kc_e("usage: nx_kkfacts probe <card.png>\n" as *u8); sys_exit(2); return 2 }
29 let buf: *u8 = sys_mmap(KKC_CAP)
30 let fd: i64 = sys_openat_rd(argv[2] as *u8)
31 if fd < 0 { kc_e("ERROR: cannot open file\n" as *u8); sys_exit(1); return 1 }
32 let size: i64 = sys_lseek(fd, 0, 2)
33 sys_lseek(fd, 0, 0)
34 var want: i64 = size
35 if want > KKC_CAP { want = KKC_CAP }
36 var got: i64 = 0
37 var stop: i64 = 0
38 while stop == 0 {
39 if got >= want { stop = 1 } else {
40 let k: i64 = sys_read(fd, ((buf as i64) + got) as *u8, want - got)
41 if k <= 0 { stop = 1 } else { got = got + k }
42 }
43 }
44 sys_close(fd)
45 let facts: *i64 = sys_mmap(KK_N_SLOTS * 8) as *i64
46 kk_probe(buf, got, size, facts)
47 kc_w("KKFACT is_card=" as *u8); kc_num(facts[0])
48 if facts[0] == 1 {
49 kc_w(" portrait_bytes=" as *u8); kc_num(facts[1])
50 kc_w(" portrait_px=" as *u8); kc_num(facts[2]); kc_w("x" as *u8); kc_num(facts[3])
51 kc_w(" payload_bytes=" as *u8); kc_num(facts[4])
52 if facts[5] >= 0 {
53 kc_w(" custom=" as *u8); kc_num(facts[5])
54 kc_w(" coordinate=" as *u8); kc_num(facts[6])
55 kc_w(" parameter=" as *u8); kc_num(facts[7])
56 kc_w(" status=" as *u8); kc_num(facts[8])
57 kc_w(" kkex=" as *u8); kc_num(facts[9])
58 }
59 }
60 kc_w("\n" as *u8)
61 if facts[0] == 0 { sys_exit(4); return 4 }
62 sys_exit(0)
63 return 0
64}