code wiki / _hdl_build / nx_wasm_explodelab_gate.nx
nx_wasm_explodelab_gate.nx source
↩ module page · 146 lines · 5626 B
1// nx_wasm_explodelab_gate.nx -- native teeth for the ExplodeLab surface BEFORE packing: the baked REAL as1
2// tree builds (18 parts), demo mode animates, drag orbits, short-click cycles highlight, E/D explode keys
3// work and stop the auto mode, frames are non-vacuous + differ assembled vs exploded, the whole session is
4// deterministic, and reset restores. expect_exit: 0 license_tier: ORIGINAL
5import "nx_wasm_explodelab.nx"
6
7func wg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
8func wg_putn(v: i64) -> i64 {
9 let bb: *u8 = sys_mmap(28)
10 var m: i64 = v
11 if m < 0 { wg_puts("-" as *u8); m = 0 - m }
12 let t: *u8 = sys_mmap(28)
13 var k: i64 = 0
14 if m == 0 { t[0] = 48 as u8; k = 1 }
15 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
16 var i: i64 = 0
17 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
18 sys_write(1, bb, k)
19 return 0
20}
21func wg_tooth(name: *u8, pass: i64, fails: *i64) -> i64 {
22 wg_puts(" " as *u8); wg_puts(name); wg_puts(" -> " as *u8)
23 if pass == 1 { wg_puts("PASS\n" as *u8); return 0 }
24 wg_puts("FAIL\n" as *u8)
25 fails[0] = fails[0] + 1
26 return 0
27}
28func wg_chk(base: i64) -> i64 {
29 let fb: *i64 = (base + 0) as *i64
30 var x: i64 = 0
31 var i: i64 = 0
32 while i < 320 * 240 { x = x + fb[i] * (1 + (i % 7)); i = i + 1 }
33 return x
34}
35func wg_cover(base: i64) -> i64 {
36 let fb: *i64 = (base + 0) as *i64
37 var k: i64 = 0
38 var i: i64 = 0
39 while i < 320 * 240 { if fb[i] != 4280293912 { k = k + 1 } i = i + 1 }
40 return k
41}
42
43func main() -> i64 {
44 wg_puts("=== nx_wasm_explodelab_gate -- native teeth on the interactive surface ===\n" as *u8)
45 let fails: *i64 = sys_mmap(8) as *i64
46 fails[0] = 0
47 let base: i64 = sys_mmap(mem_bytes()) as i64
48 let e: *i64 = e_ptr(base)
49 let st: *i64 = st_ptr(base)
50
51 start_at(base)
52 wg_puts("parts=" as *u8); wg_putn(e[4])
53 wg_puts(" verts=" as *u8); wg_putn(e[1])
54 wg_puts(" tris=" as *u8); wg_putn(e[3]); wg_puts("\n" as *u8)
55 var t1: i64 = 0
56 if e[4] == exl_n() { if e[4] == 18 { if e[1] > 200 { if e[3] > 400 { t1 = 1 } } } }
57 let ig1: i64 = wg_tooth("T1 baked as1 scene builds (18 parts)" as *u8, t1, fails)
58
59 // T2 demo mode: 60 idle ticks -> explode t moved and angle advanced
60 let a0: i64 = st[3]
61 var k: i64 = 0
62 while k < 60 { tick_at(base, 160, 120, 0); k = k + 1 }
63 var t2: i64 = 0
64 if st[2] > 0 { if st[3] != a0 { t2 = 1 } }
65 wg_puts("after 60 idle ticks t=" as *u8); wg_putn(st[2]); wg_puts(" angle=" as *u8); wg_putn(st[3]); wg_puts("\n" as *u8)
66 let ig2: i64 = wg_tooth("T2 demo mode auto-animates (t and angle move)" as *u8, t2, fails)
67
68 // T3 drag orbits: press at 100, drag to 160
69 let a1: i64 = st[3]
70 tick_at(base, 100, 120, 1)
71 var mx: i64 = 100
72 k = 0
73 while k < 12 { mx = mx + 5; tick_at(base, mx, 120, 1); k = k + 1 }
74 tick_at(base, mx, 120, 0)
75 var t3: i64 = 0
76 if st[3] != a1 { if st[10] == 1 { if st[4] == (0 - 1) { t3 = 1 } } }
77 let ig3: i64 = wg_tooth("T3 drag orbits (angle changes, no accidental select)" as *u8, t3, fails)
78
79 // T4 short click cycles selection 0 then 1
80 tick_at(base, 200, 120, 1)
81 tick_at(base, 200, 120, 0)
82 let s1: i64 = st[4]
83 tick_at(base, 200, 120, 1)
84 tick_at(base, 200, 120, 0)
85 let s2: i64 = st[4]
86 var t4: i64 = 0
87 if s1 == 0 { if s2 == 1 { t4 = 1 } }
88 let ig4: i64 = wg_tooth("T4 short click cycles highlight 0 then 1" as *u8, t4, fails)
89
90 // T5 explode keys: hold E to cap, then D reduces; auto mode stopped
91 k = 0
92 while k < 80 { tick_at(base, 200, 120, 4); k = k + 1 }
93 let tcap: i64 = st[2]
94 k = 0
95 while k < 10 { tick_at(base, 200, 120, 8); k = k + 1 }
96 var t5: i64 = 0
97 if tcap == 1024 { if st[2] < tcap { if st[6] == 1 { t5 = 1 } } }
98 let ig5: i64 = wg_tooth("T5 E/D explode controls (cap 1024, decrease, auto stopped)" as *u8, t5, fails)
99
100 // T6 render non-vacuous + assembled differs from exploded
101 st[2] = 0
102 render_at(base)
103 let c0: i64 = wg_cover(base)
104 let h0: i64 = wg_chk(base)
105 st[2] = 1024
106 render_at(base)
107 let c1: i64 = wg_cover(base)
108 let h1: i64 = wg_chk(base)
109 wg_puts("coverage assembled=" as *u8); wg_putn(c0); wg_puts(" exploded=" as *u8); wg_putn(c1); wg_puts("\n" as *u8)
110 var t6: i64 = 0
111 if c0 > 300 { if c1 > 300 { if h0 != h1 { t6 = 1 } } }
112 let ig6: i64 = wg_tooth("T6 frames non-vacuous + assembled != exploded" as *u8, t6, fails)
113
114 // T7 determinism: identical scripted session twice -> identical frame
115 let base2: i64 = sys_mmap(mem_bytes()) as i64
116 start_at(base)
117 start_at(base2)
118 k = 0
119 while k < 100 {
120 let sx: i64 = 40 + (k * 7) % 240
121 var bt: i64 = 0
122 if (k % 30) < 8 { bt = 1 }
123 if (k % 47) == 20 { bt = 4 }
124 tick_at(base, sx, 100, bt)
125 tick_at(base2, sx, 100, bt)
126 k = k + 1
127 }
128 render_at(base)
129 render_at(base2)
130 let d1: i64 = wg_chk(base)
131 let d2: i64 = wg_chk(base2)
132 var t7: i64 = 0
133 if d1 == d2 { t7 = 1 }
134 let ig7: i64 = wg_tooth("T7 deterministic (two identical sessions, same frame)" as *u8, t7, fails)
135
136 // T8 reset restores
137 tick_at(base, 100, 100, 2)
138 var t8: i64 = 0
139 if st[2] == 0 { if st[4] == (0 - 1) { if st[6] == 0 { t8 = 1 } } }
140 let ig8: i64 = wg_tooth("T8 reset restores demo state" as *u8, t8, fails)
141
142 wg_puts("\nfails=" as *u8); wg_putn(fails[0]); wg_puts("\n" as *u8)
143 if fails[0] == 0 { wg_puts("GREEN -- explodelab surface teeth 8/8\n" as *u8); return 0 }
144 wg_puts("RED\n" as *u8)
145 return 1
146}