code wiki / _hdl_build / nx_wasm_charlab_gate.nx
nx_wasm_charlab_gate.nx source
↩ module page · 256 lines · 12505 B
1// nx_wasm_charlab_gate.nx -- gate for CHARLAB (the composed character surface: skeleton+morph-era organs
2// +regions+binding+IK in ONE interactive sim).
3// T1 BREATHING drives flesh: chest micro-rotation moves the bound region anchors measurably; click-toggle
4// stops it (controls are data)
5// T2 the IK ARM reaches a scripted mouse target (effector converges near it across ticks)
6// T3 HAND-IN-FLESH interactive: drive the hand into the right region -> contact holds (never-inside), far
7// side bulges; pull away -> area recovers to ~rest (elastic)
8// T4 determinism: two labs, same 300-tick mouse script -> region+skeleton state byte-identical
9// T5 render draws + PNG knowledge/nx_charlab.png (the eyeball: torso, two flesh rings, arm, hand)
10// license_tier: ORIGINAL expect_exit: 0
11import "nx_syscalls.nx"
12import "nx_png.nx"
13import "nx_wasm_charlab.nx"
14
15func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
16func pn(v: i64) -> i64 {
17 let b: *u8 = sys_mmap(32) as *u8
18 var x: i64 = v
19 var neg: i64 = 0
20 if x < 0 { neg = 1; x = 0 - x }
21 var i: i64 = 31
22 if x == 0 { b[i] = 48 as u8; i = i - 1 }
23 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 }
24 if neg == 1 { b[i] = 45 as u8; i = i - 1 }
25 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i)
26 return 0
27}
28func gabs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
29func isq(v: i64) -> i64 { if v <= 0 { return 0 } var x: i64 = v; var y: i64 = (x + 1) / 2; while y < x { x = y; y = (x + v / x) / 2 } return x }
30
31func main() -> i64 {
32 var fails: i64 = 0
33 let L: i64 = sys_mmap(mem_bytes()) as i64
34 start_at(L)
35
36 // T1 breathing: with the mouse parked far away, region-L anchor y must oscillate; after click-toggle, still
37 var miny: i64 = 99999999
38 var maxy: i64 = 0 - 99999999
39 var t: i64 = 0
40 while t < 240 {
41 tick_at(L, 20, 20, 0)
42 let hl: *i64 = sr_hdr(L + 803200)
43 if hl[3] < miny { miny = hl[3] }
44 if hl[3] > maxy { maxy = hl[3] }
45 t = t + 1
46 }
47 let swing: i64 = maxy - miny
48 tick_at(L, 20, 20, 1) // click edge -> breathing off
49 tick_at(L, 20, 20, 0)
50 var miny2: i64 = 99999999
51 var maxy2: i64 = 0 - 99999999
52 t = 0
53 while t < 240 {
54 tick_at(L, 20, 20, 0)
55 let hl2: *i64 = sr_hdr(L + 803200)
56 if hl2[3] < miny2 { miny2 = hl2[3] }
57 if hl2[3] > maxy2 { maxy2 = hl2[3] }
58 t = t + 1
59 }
60 let swing2: i64 = maxy2 - miny2
61 var t1: i64 = 1
62 if swing < 8 { t1 = 0 } // smaller after the tighter breast-bind offset; still clearly breathing
63 if swing2 > 4 { t1 = 0 }
64 if t1 == 1 { hw("T1 PASS breathing drives flesh: anchor swing " as *u8); pn(swing); hw(" breathing vs " as *u8); pn(swing2); hw(" toggled off (click = data control)\n" as *u8) }
65 else { hw("T1 FAIL swing=" as *u8); pn(swing); hw(" off=" as *u8); pn(swing2); hw("\n" as *u8); fails = fails + 1 }
66
67 // T2 IK reach: park the mouse at a REACHABLE point (arm reach = 1000 from the shoulder (250,2250);
68 // the first pick (240,60)->world(1440,2970) was 1390 away = correctly full-extension-pointed, test bug)
69 let mx: i64 = 210
70 let my: i64 = 70
71 t = 0
72 while t < 60 { tick_at(L, mx, my, 0); t = t + 1 }
73 let wx: i64 = (mx - 160) * 18
74 let wy: i64 = (225 - my) * 18
75 let eff: *i64 = sk_vs(L + 614400)
76 ik_effector(L + 614400, 6, 500, 0, 0, eff)
77 let dx: i64 = eff[0] - wx
78 let dy: i64 = eff[1] - wy
79 let dist: i64 = isq(dx * dx + dy * dy)
80 if dist <= 60 { hw("T2 PASS IK arm reaches the mouse: effector within " as *u8); pn(dist); hw(" of the target after 60 ticks\n" as *u8) }
81 else { hw("T2 FAIL dist=" as *u8); pn(dist); hw("\n" as *u8); fails = fails + 1 }
82
83 // T3 hand-in-flesh: drive the mouse INTO region R's center; contact + far bulge; then away; area recovers
84 let hr: *i64 = sr_hdr(L + 810112)
85 let restarea: i64 = sr_area(L + 810112)
86 let rmx: i64 = 160 + hr[2] / 18
87 let rmy: i64 = 225 - hr[3] / 18
88 t = 0
89 while t < 200 { tick_at(L, rmx, rmy, 0); t = t + 1 }
90 var minclear: i64 = 99999
91 var maxbulge: i64 = 0
92 t = 0
93 while t < 120 {
94 tick_at(L, rmx, rmy, 0)
95 let eff2: *i64 = sk_vs(L + 614400)
96 ik_effector(L + 614400, 6, 500, 0, 0, eff2)
97 var c: i64 = 0
98 while c < 16 {
99 let ny2: i64 = sr_pos(L + 810112, c, 1)
100 if ny2 > eff2[1] - 150 { if ny2 < eff2[1] + 150 {
101 let ddx: i64 = sr_pos(L + 810112, c, 0) - eff2[0]
102 let ddz: i64 = sr_pos(L + 810112, c, 2) - eff2[2]
103 let d: i64 = isq(ddx * ddx + ddz * ddz)
104 if d < minclear { minclear = d }
105 } }
106 c = c + 1
107 }
108 let h6: *i64 = sr_hdr(L + 810112)
109 var far: i64 = 0
110 c = 0
111 while c < 16 {
112 let ox: i64 = sr_pos(L + 810112, c, 0) - h6[2]
113 let oy: i64 = sr_pos(L + 810112, c, 1) - h6[3]
114 let ol: i64 = isq(ox * ox + oy * oy)
115 if ol - 320 > far { far = ol - 320 }
116 c = c + 1
117 }
118 if far > maxbulge { maxbulge = far }
119 t = t + 1
120 }
121 // pull the hand far away; the region must recover
122 t = 0
123 while t < 400 { tick_at(L, 20, 20, 0); t = t + 1 }
124 let recarea: i64 = sr_area(L + 810112)
125 var t3: i64 = 1
126 if minclear < 160 { t3 = 0 } // hand r=170: some clearance loss ok, no deep pass-through
127 if maxbulge < 10 { t3 = 0 }
128 var adev: i64 = recarea - restarea
129 if adev < 0 { adev = 0 - adev }
130 if adev * 100 > restarea * 5 { t3 = 0 }
131 if t3 == 1 { hw("T3 PASS hand-in-flesh: contact held (min clearance " as *u8); pn(minclear); hw("/170), far-side bulge +" as *u8); pn(maxbulge); hw(", area recovers within " as *u8); pn(adev * 100 / restarea); hw("%\n" as *u8) }
132 else { hw("T3 FAIL clear=" as *u8); pn(minclear); hw(" bulge=" as *u8); pn(maxbulge); hw(" areadev%=" as *u8); pn(adev * 100 / restarea); hw("\n" as *u8); fails = fails + 1 }
133
134 // T4 determinism
135 let A: i64 = sys_mmap(mem_bytes()) as i64
136 let B: i64 = sys_mmap(mem_bytes()) as i64
137 start_at(A)
138 start_at(B)
139 t = 0
140 while t < 300 {
141 let sx: i64 = 100 + (t * 2) % 140
142 let sy: i64 = 50 + (t * 3) % 100
143 var bt: i64 = 0
144 if t == 100 { bt = 1 }
145 tick_at(A, sx, sy, bt)
146 tick_at(B, sx, sy, bt)
147 t = t + 1
148 }
149 var diff: i64 = 0
150 var k: i64 = 0
151 while k < 6848 / 8 {
152 let pa: *i64 = (A + 803200) as *i64
153 let pb: *i64 = (B + 803200) as *i64
154 if pa[k] != pb[k] { diff = diff + 1 }
155 let qa: *i64 = (A + 810112) as *i64
156 let qb: *i64 = (B + 810112) as *i64
157 if qa[k] != qb[k] { diff = diff + 1 }
158 k = k + 1
159 }
160 if diff == 0 { hw("T4 PASS determinism: 300-tick mouse script incl toggle -> both regions byte-identical\n" as *u8) }
161 else { hw("T4 FAIL diff=" as *u8); pn(diff); hw("\n" as *u8); fails = fails + 1 }
162
163 // T5 render + PNG
164 render_at(A)
165 let fb: *i64 = (A + fb_off()) as *i64
166 var nonbg: i64 = 0
167 var pi: i64 = 0
168 while pi < ww() * hh() {
169 if fb[pi] != 0 { nonbg = nonbg + 1 }
170 pi = pi + 1
171 }
172 write_png(fb, ww(), hh(), "knowledge/nx_charlab.png" as *u8)
173 if nonbg * 10 >= ww() * hh() * 9 { hw("T5 PASS render draws + PNG knowledge/nx_charlab.png\n" as *u8) }
174 else { hw("T5 FAIL nonbg=" as *u8); pn(nonbg); hw("\n" as *u8); fails = fails + 1 }
175
176 // T6 SCENE PLAYBACK (beat-HS2 R2 wired in): press P (btn 4) -> the arm is driven by the DATA scene, NOT
177 // the mouse. The effector must trace the scene's authored path (deterministic, independent of the mouse)
178 // and LOOP.
179 let SP: i64 = sys_mmap(mem_bytes()) as i64
180 start_at(SP)
181 tick_at(SP, 20, 20, 4) // P edge: start playing
182 tick_at(SP, 20, 20, 0)
183 let effS: *i64 = sk_vs(SP + 614400)
184 // sample effector x at scene t~0 (arm parked far, ~2600) and at scene t~120 (arm in, ~200)
185 var t: i64 = 0
186 while t < 4 { tick_at(SP, 999, 999, 0); t = t + 1 } // mouse FAR AWAY -- proves the scene, not the mouse, drives
187 ik_effector(SP + 614400, 6, 500, 0, 0, effS)
188 let early_x: i64 = effS[0]
189 while t < 62 { tick_at(SP, 999, 999, 0); t = t + 1 } // ~t=120 in scene time (2/tick)
190 ik_effector(SP + 614400, 6, 500, 0, 0, effS)
191 let mid_x: i64 = effS[0]
192 // thresholds match REACHABLE coords: the scene's t=0 target (2600) exceeds arm reach, so IK clamps the
193 // effector to ~1168 (full-extension) -- correct physics, not 2600. What proves the scene drives it:
194 // reaching-out early (x large vs mid), pulled-in mid (x small), a big authored delta -- all while the
195 // mouse sat at (999,999) far away.
196 var t6: i64 = 1
197 if early_x < 900 { t6 = 0 } // scene start: arm reaching OUT (reachable-max ~1168)
198 if mid_x > 400 { t6 = 0 } // scene mid: arm pulled IN
199 if early_x - mid_x < 600 { t6 = 0 } // moved along the scene path, ignoring the far mouse
200 if t6 == 1 { hw("T6 PASS scene playback: the DATA scene drives the arm (x " as *u8); pn(early_x); hw("->" as *u8); pn(mid_x); hw(") ignoring the far mouse -- a 'position' as data\n" as *u8) }
201 else { hw("T6 FAIL early_x=" as *u8); pn(early_x); hw(" mid_x=" as *u8); pn(mid_x); hw("\n" as *u8); fails = fails + 1 }
202
203 // T7 CHARACTER AS DATA: cycling presets (key C = btn 8) makes a DIFFERENT body -- different region size +
204 // different skin. Prove the region rest-radius and skin color actually change between preset 0 and 1.
205 let CC: i64 = sys_mmap(mem_bytes()) as i64
206 start_at(CC)
207 let r0area: i64 = sr_area(CC + 810112)
208 let rec0: *i64 = chr_ptr(CC)
209 let skin0: i64 = rec0[10] // VALUE copies -- chr_ptr is one live buffer; capture before cycling
210 let name0: i64 = rec0[0]
211 tick_at(CC, 20, 20, 8) // C edge -> preset 1
212 tick_at(CC, 20, 20, 0)
213 var t7: i64 = 0
214 while t7 < 40 { tick_at(CC, 20, 20, 0); t7 = t7 + 1 }
215 let r1area: i64 = sr_area(CC + 810112)
216 let rec1: *i64 = chr_ptr(CC)
217 let skin1: i64 = rec1[10]
218 let name1: i64 = rec1[0]
219 var ok7: i64 = 1
220 if r1area <= r0area { ok7 = 0 } // preset 1 = fuller body -> bigger region
221 if skin1 == skin0 { ok7 = 0 } // different skin
222 if name1 == name0 { ok7 = 0 } // different name hash
223 if ok7 == 1 { hw("T7 PASS character-as-data: preset 0->1 = different body (region area " as *u8); pn(r0area); hw("->" as *u8); pn(r1area); hw(", skin " as *u8); pn(skin0); hw("->" as *u8); pn(skin1); hw(", named)\n" as *u8) }
224 else { hw("T7 FAIL a0=" as *u8); pn(r0area); hw(" a1=" as *u8); pn(r1area); hw(" s0=" as *u8); pn(skin0); hw(" s1=" as *u8); pn(skin1); hw("\n" as *u8); fails = fails + 1 }
225
226 // T8 NXCH1 pack round-trip (a character = a CID-shippable pack)
227 let recX: *i64 = sys_mmap(chr_bytes()) as *i64
228 chr_preset(recX, 1)
229 let blob: *u8 = sys_mmap(256) as *u8
230 let blen: i64 = chr_save(recX, blob)
231 let recY: *i64 = sys_mmap(chr_bytes()) as *i64
232 var t8: i64 = 1
233 if chr_load(recY, blob, blen) != 0 { t8 = 0 }
234 var cd: i64 = 0
235 var ci: i64 = 0
236 while ci < 16 { if recX[ci] != recY[ci] { cd = cd + 1 } ci = ci + 1 }
237 if cd != 0 { t8 = 0 }
238 blob[0] = 90 as u8
239 if chr_load(recY, blob, blen) != 0 - 1 { t8 = 0 }
240 if t8 == 1 { hw("T8 PASS NXCH1 character pack " as *u8); pn(blen); hw("B round-trips byte-exact; corrupt REJECTED -- a character is CID-shippable data\n" as *u8) }
241 else { hw("T8 FAIL cd=" as *u8); pn(cd); hw("\n" as *u8); fails = fails + 1 }
242
243 // re-render preset 2 for the eyeball (a third distinct body)
244 let PZ: i64 = sys_mmap(mem_bytes()) as i64
245 start_at(PZ)
246 tick_at(PZ, 20, 20, 8); tick_at(PZ, 20, 20, 0)
247 tick_at(PZ, 20, 20, 8); tick_at(PZ, 20, 20, 0)
248 var tp: i64 = 0
249 while tp < 60 { tick_at(PZ, 240, 120, 0); tp = tp + 1 }
250 render_at(PZ)
251 write_png((PZ + fb_off()) as *i64, ww(), hh(), "knowledge/nx_charlab_c2.png" as *u8)
252
253 if fails == 0 { hw("VERDICT GREEN: charlab 8/8 -- HUMANOID (filled body) + character-as-DATA (NXCH1) + skeleton/regions/IK/scene composed (PNGs nx_charlab.png + nx_charlab_c2.png)\n" as *u8) }
254 else { hw("VERDICT RED fails=" as *u8); pn(fails); hw("\n" as *u8) }
255 return fails
256}