code wiki / _hdl_build / nx_scene_gate.nx

nx_scene_gate.nx source

↩ module page · 135 lines · 6237 B

1// nx_scene_gate.nx -- gate for SCENE-AS-DATA (beat-HS2 rung 2). 2// T1 keyframe interp EXACT: endpoints hit the key values; a midpoint = exact linear blend; pre/post clamp 3// T2 MULTI-CHANNEL independence: 3 channels (an IK-target x, a morph weight, a region param) sampled at the 4// same t give their own interpolated values 5// T3 determinism: sample the whole timeline twice -> identical 6// T4 NXSC1 pack round-trip: save -> load into a FRESH scene -> every channel samples IDENTICALLY; corrupt REJECT 7// T5 PNG knowledge/nx_scene_curve.png: the 3 channel curves plotted across the timeline (eyeball the keyframes) 8// license_tier: ORIGINAL expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_png.nx" 11import "nx_scene.nx" 12 13func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 14func pn(v: i64) -> i64 { 15 let b: *u8 = sys_mmap(32) as *u8 16 var x: i64 = v 17 var neg: i64 = 0 18 if x < 0 { neg = 1; x = 0 - x } 19 var i: i64 = 31 20 if x == 0 { b[i] = 48 as u8; i = i - 1 } 21 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } 22 if neg == 1 { b[i] = 45 as u8; i = i - 1 } 23 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i) 24 return 0 25} 26func gabs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 27 28// channel target ids (a scene addresses the rig by these) 29const CH_HANDX: i64 = 100 30const CH_MORPH_SMILE: i64 = 200 31const CH_REGION_SOFT: i64 = 300 32 33func build(base: i64) -> i64 { 34 sc_init(base) 35 let a: i64 = sc_channel(base, CH_HANDX) // hand x: 0 -> 1000 -> 200 over t 0..100..200 36 sc_key_add(base, a, 0, 0) 37 sc_key_add(base, a, 100, 1000) 38 sc_key_add(base, a, 200, 200) 39 let b: i64 = sc_channel(base, CH_MORPH_SMILE) // smile 0 -> 256 over t 50..150 (flat before/after) 40 sc_key_add(base, b, 50, 0) 41 sc_key_add(base, b, 150, 256) 42 let c: i64 = sc_channel(base, CH_REGION_SOFT) // softness 40 -> 16 over t 0..200 43 sc_key_add(base, c, 0, 40) 44 sc_key_add(base, c, 200, 16) 45 return 0 46} 47 48func main() -> i64 { 49 var fails: i64 = 0 50 let S: i64 = sys_mmap(sc_bytes()) as i64 51 build(S) 52 53 // T1 hand-x channel (chan 0) 54 var t1: i64 = 1 55 if sc_sample(S, 0, 0) != 0 { t1 = 0 } 56 if sc_sample(S, 0, 100) != 1000 { t1 = 0 } 57 if sc_sample(S, 0, 50) != 500 { t1 = 0 } // half of 0->1000 58 if sc_sample(S, 0, 150) != 600 { t1 = 0 } // half of 1000->200 59 if sc_sample(S, 0, 0 - 10) != 0 { t1 = 0 } // pre-clamp 60 if sc_sample(S, 0, 999) != 200 { t1 = 0 } // post-clamp 61 if sc_duration(S) != 200 { t1 = 0 } 62 if t1 == 1 { hw("T1 PASS keyframe interp exact: endpoints/midpoints/clamps (hand-x 50%=500, 75%=600), duration=200\n" as *u8) } 63 else { hw("T1 FAIL s0=" as *u8); pn(sc_sample(S, 0, 0)); hw(" s50=" as *u8); pn(sc_sample(S, 0, 50)); hw(" s150=" as *u8); pn(sc_sample(S, 0, 150)); hw("\n" as *u8); fails = fails + 1 } 64 65 // T2 multi-channel at t=100: hand=1000, smile=(100-50)/(150-50)*256=128, soft=40+(16-40)*100/200=28 66 var t2: i64 = 1 67 if sc_sample(S, 0, 100) != 1000 { t2 = 0 } 68 if sc_sample(S, 1, 100) != 128 { t2 = 0 } 69 if sc_sample(S, 2, 100) != 28 { t2 = 0 } 70 if sc_target(S, 1) != CH_MORPH_SMILE { t2 = 0 } 71 if t2 == 1 { hw("T2 PASS multi-channel @t=100: hand=1000, smile=128, soft=28 -- each channel its own curve\n" as *u8) } 72 else { hw("T2 FAIL hand=" as *u8); pn(sc_sample(S, 0, 100)); hw(" smile=" as *u8); pn(sc_sample(S, 1, 100)); hw(" soft=" as *u8); pn(sc_sample(S, 2, 100)); hw("\n" as *u8); fails = fails + 1 } 73 74 // T3 determinism 75 var acc1: i64 = 0 76 var t: i64 = 0 77 while t <= 200 { 78 acc1 = acc1 * 31 + sc_sample(S, 0, t) + sc_sample(S, 1, t) * 7 + sc_sample(S, 2, t) * 13 79 t = t + 1 80 } 81 var acc2: i64 = 0 82 t = 0 83 while t <= 200 { 84 acc2 = acc2 * 31 + sc_sample(S, 0, t) + sc_sample(S, 1, t) * 7 + sc_sample(S, 2, t) * 13 85 t = t + 1 86 } 87 if acc1 == acc2 { hw("T3 PASS determinism: full-timeline sampling identical\n" as *u8) } 88 else { hw("T3 FAIL\n" as *u8); fails = fails + 1 } 89 90 // T4 NXSC1 round-trip 91 let blob: *u8 = sys_mmap(8192) as *u8 92 let blen: i64 = sc_save(S, blob) 93 let S2: i64 = sys_mmap(sc_bytes()) as i64 94 let nc: i64 = sc_load(S2, blob, blen) 95 var t4: i64 = 1 96 if nc != 3 { t4 = 0 } 97 t = 0 98 while t <= 200 { 99 if sc_sample(S2, 0, t) != sc_sample(S, 0, t) { t4 = 0 } 100 if sc_sample(S2, 1, t) != sc_sample(S, 1, t) { t4 = 0 } 101 if sc_sample(S2, 2, t) != sc_sample(S, 2, t) { t4 = 0 } 102 t = t + 20 103 } 104 blob[1] = 90 as u8 105 if sc_load(S2, blob, blen) != 0 - 1 { t4 = 0 } 106 if t4 == 1 { hw("T4 PASS NXSC1 pack " as *u8); pn(blen); hw("B round-trips (every channel samples identical); corrupt magic REJECTED -- scenes = mod-economy content\n" as *u8) } 107 else { hw("T4 FAIL nc=" as *u8); pn(nc); hw("\n" as *u8); fails = fails + 1 } 108 109 // T5 PNG 110 let TW: i64 = 256 111 let TH: i64 = 128 112 let fb: *i64 = sys_mmap(TW * TH * 8) as *i64 113 var pi: i64 = 0 114 while pi < TW * TH { fb[pi] = 22 + 26 * 256 + 34 * 65536; pi = pi + 1 } 115 var px: i64 = 0 116 while px < TW { 117 let tt: i64 = px * 200 / TW 118 // hand (amber): 0..1000 -> y 118..10 119 let hy: i64 = 118 - sc_sample(S, 0, tt) * 108 / 1000 120 if hy >= 0 { if hy < TH { fb[hy * TW + px] = 235 + 190 * 256 + 120 * 65536 } } 121 // smile (rose): 0..256 -> y 118..10 122 let sy: i64 = 118 - sc_sample(S, 1, tt) * 108 / 256 123 if sy >= 0 { if sy < TH { fb[sy * TW + px] = 235 + 140 * 256 + 150 * 65536 } } 124 // soft (blue): 0..40 -> y 118..10 125 let cy: i64 = 118 - sc_sample(S, 2, tt) * 108 / 40 126 if cy >= 0 { if cy < TH { fb[cy * TW + px] = 120 + 180 * 256 + 240 * 65536 } } 127 px = px + 1 128 } 129 write_png(fb, TW, TH, "knowledge/nx_scene_curve.png" as *u8) 130 hw("T5 PNG written: knowledge/nx_scene_curve.png (3 channel keyframe curves)\n" as *u8) 131 132 if fails == 0 { hw("VERDICT GREEN: scene-as-data 5/5 -- keyframed multi-channel timelines, exact integer interp, NXSC1 packs (Illusion 'positions' as CID mod content, on our data law)\n" as *u8) } 133 else { hw("VERDICT RED fails=" as *u8); pn(fails); hw("\n" as *u8) } 134 return fails 135}