code wiki / (root) / nx_input_abstract_gate.nx

nx_input_abstract_gate.nx source

↩ module page · 202 lines · 8257 B

1// nx_input_abstract_gate.nx -- proves the device-agnostic input core (F1102) does what the game 2// platform needs: four sources drive ONE action state, edges are real (no held-repeat), releasing one 3// device never eats another's hold, axis hysteresis is asymmetric, bindings are data, and the whole 4// thing is deterministic. T8 is the anti-vacuity tooth: the scripted mixed-source session must have 5// actually produced actions, or a lib that returns 0 forever would score 7/8. 6// license_tier: ORIGINAL expect_exit: 0 7import "nx_input_abstract.nx" 8 9func vw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 10func vn(v: i64) -> i64 { 11 let t: *u8 = sys_mmap(32) as *u8 12 var m: i64 = v; var w: i64 = 0 13 if m<0 { t[w]=45 as u8; w=w+1; m=0-m } 14 if m==0 { t[w]=48 as u8; sys_write(1,t,w+1); return 0 } 15 let d: *u8 = sys_mmap(32) as *u8 16 var k: i64=0 17 while m>0 { d[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 18 var j: i64=0 19 while j<k { t[w]=d[k-1-j]; w=w+1; j=j+1 } 20 sys_write(1,t,w); return 0 21} 22func pop8(v: i64) -> i64 { 23 var c: i64 = 0 24 var i: i64 = 0 25 while i < 8 { if ((v >> i) & 1) == 1 { c = c + 1 } i = i + 1 } 26 return c 27} 28 29// the scripted mixed-source session used by T7 (determinism) and T8 (anti-vacuity). 30// st[0]=rolling ck st[1]=pressed-edge count st[2]=OR of every held mask st[3]=touch contributed 31func seq(p: *i64, stt: *i64) -> i64 { 32 stt[0]=0; stt[1]=0; stt[2]=0; stt[3]=0 33 ia_init(p) 34 var f: i64 = 0 35 while f < 19 { 36 if f == 0 { ia_key(p, 87, 1) } 37 if f == 2 { ia_key(p, 87, 0) } 38 if f == 3 { ia_pad(p, 0, 1) } 39 if f == 4 { ia_pad(p, 0, 0) } 40 if f == 5 { ia_axis(p, 0, 500) } 41 if f == 6 { ia_axis(p, 0, 300) } 42 if f == 7 { ia_axis(p, 0, 100) } 43 if f == 8 { ia_touch(p, 150, 10, 300, 300, 1) 44 if p[IA_TOUCH] != 0 { stt[3] = 1 } } 45 if f == 9 { ia_touch(p, 0, 0, 0, 0, 0) } 46 if f == 10 { ia_key(p, 65, 1); ia_pad(p, 15, 1) } 47 if f == 11 { ia_key(p, 65, 0) } 48 if f == 12 { ia_pad(p, 15, 0) } 49 if f == 13 { ia_key(p, 69, 1) } 50 if f == 14 { ia_key(p, 69, 0) } 51 if f == 15 { ia_key(p, 66, 1) } 52 if f == 16 { ia_key(p, 66, 0) } 53 if f == 17 { ia_key(p, 13, 1) } 54 if f == 18 { ia_key(p, 13, 0) } 55 let held: i64 = ia_held(p) 56 let pressed: i64 = ia_frame(p) 57 stt[0] = (stt[0]*131 + held*3 + pressed) % 1000000007 58 stt[1] = stt[1] + pop8(pressed) 59 stt[2] = stt[2] | held 60 f = f + 1 61 } 62 return 0 63} 64 65func main() -> i64 { 66 let p: *i64 = sys_mmap(IA_WORDS*8) as *i64 67 var pass: i64 = 0 68 let total: i64 = 10 69 vw("=== nx_input_abstract gate (F1102 device-agnostic input) ===\n" as *u8) 70 71 // T1 UNIFICATION: keyboard, pad button, axis, and touch each alone produce IA_UP, then release to 0 72 ia_init(p) 73 var t1: i64 = 0 74 ia_key(p, 87, 1) 75 if ia_held(p) == IA_UP { t1 = t1 + 1 } 76 ia_key(p, 87, 0) 77 if ia_held(p) == 0 { t1 = t1 + 1 } 78 ia_pad(p, 12, 1) 79 if ia_held(p) == IA_UP { t1 = t1 + 1 } 80 ia_pad(p, 12, 0) 81 if ia_held(p) == 0 { t1 = t1 + 1 } 82 ia_axis(p, 1, 0-600) 83 if ia_held(p) == IA_UP { t1 = t1 + 1 } 84 ia_axis(p, 1, 0) 85 if ia_held(p) == 0 { t1 = t1 + 1 } 86 ia_touch(p, 150, 10, 300, 300, 1) 87 if ia_held(p) == IA_UP { t1 = t1 + 1 } 88 ia_touch(p, 0, 0, 0, 0, 0) 89 if ia_held(p) == 0 { t1 = t1 + 1 } 90 vw("T1 four sources -> one action, each asserts+releases: " as *u8); vn(t1); vw("/8\n" as *u8) 91 if t1 == 8 { pass = pass + 1 } 92 93 // T2 EDGE: held two frames -> pressed only on the first (kills interact-repeats-while-held) 94 ia_init(p) 95 ia_key(p, 69, 1) 96 let p1: i64 = ia_frame(p) 97 let p2: i64 = ia_frame(p) 98 vw("T2 pressed frame1=" as *u8); vn(p1); vw(" frame2=" as *u8); vn(p2) 99 vw(" (held both frames)\n" as *u8) 100 if p1 == IA_A { if p2 == 0 { if ia_held(p) == IA_A { pass = pass + 1 } } } 101 102 // T3 RELEASE: keyup drops the bit; a fresh press after release is a NEW edge 103 ia_key(p, 69, 0) 104 var t3: i64 = 0 105 if ia_held(p) == 0 { t3 = 1 } 106 let pr3: i64 = ia_frame(p) 107 ia_key(p, 69, 1) 108 let pr4: i64 = ia_frame(p) 109 vw("T3 release clears, re-press re-edges: held0=" as *u8); vn(t3) 110 vw(" edge=" as *u8); vn(pr4); vw("\n" as *u8) 111 if t3 == 1 { if pr3 == 0 { if pr4 == IA_A { pass = pass + 1 } } } 112 113 // T4 CROSS-DEVICE UNION: kb LEFT + pad RIGHT held together; releasing the KEY leaves the PAD hold 114 ia_init(p) 115 ia_key(p, 65, 1) 116 ia_pad(p, 15, 1) 117 var t4: i64 = 0 118 if ia_held(p) == (IA_LEFT | IA_RIGHT) { t4 = 1 } 119 ia_key(p, 65, 0) 120 vw("T4 union then key-release: both=" as *u8); vn(t4) 121 vw(" after=" as *u8); vn(ia_held(p)); vw(" (must be RIGHT=8)\n" as *u8) 122 if t4 == 1 { if ia_held(p) == IA_RIGHT { pass = pass + 1 } } 123 124 // T5 AXIS HYSTERESIS: assert at 400, keep at 300, drop at 200, and 300 must NOT re-assert 125 ia_init(p) 126 var t5: i64 = 0 127 ia_axis(p, 0, 400) 128 if ia_held(p) == IA_RIGHT { t5 = t5 + 1 } 129 ia_axis(p, 0, 300) 130 if ia_held(p) == IA_RIGHT { t5 = t5 + 1 } 131 ia_axis(p, 0, 200) 132 if ia_held(p) == 0 { t5 = t5 + 1 } 133 ia_axis(p, 0, 300) 134 if ia_held(p) == 0 { t5 = t5 + 1 } 135 vw("T5 hysteresis 400:on 300:kept 200:off 300:stays-off = " as *u8); vn(t5); vw("/4\n" as *u8) 136 if t5 == 4 { pass = pass + 1 } 137 138 // T6 BINDINGS ARE DATA: bind Z->B, unbind E, unbound key is a no-op 139 ia_init(p) 140 var t6: i64 = 0 141 ia_bind(p, 90, IA_B) 142 ia_key(p, 90, 1) 143 if ia_held(p) == IA_B { t6 = t6 + 1 } 144 ia_key(p, 90, 0) 145 ia_bind(p, 69, 0) 146 ia_key(p, 69, 1) 147 if ia_held(p) == 0 { t6 = t6 + 1 } 148 ia_key(p, 81, 1) 149 if ia_held(p) == 0 { t6 = t6 + 1 } 150 vw("T6 rebind/unbind/no-op = " as *u8); vn(t6); vw("/3\n" as *u8) 151 if t6 == 3 { pass = pass + 1 } 152 153 // T7 DETERMINISM: the same mixed-source session on two fresh arenas folds to the same checksum 154 let pa: *i64 = sys_mmap(IA_WORDS*8) as *i64 155 let pb: *i64 = sys_mmap(IA_WORDS*8) as *i64 156 let sa: *i64 = sys_mmap(8*8) as *i64 157 let sb: *i64 = sys_mmap(8*8) as *i64 158 seq(pa, sa) 159 seq(pb, sb) 160 vw("T7 session ck " as *u8); vn(sa[0]); vw(" == " as *u8); vn(sb[0]); vw("\n" as *u8) 161 if sa[0] == sb[0] { if sa[0] != 0 { pass = pass + 1 } } 162 163 // T8 ANTI-VACUITY: that session really produced input -- >=3 distinct actions, >=5 edges, touch fed 164 vw("T8 distinct-bits=" as *u8); vn(pop8(sa[2])); vw(" edges=" as *u8); vn(sa[1]) 165 vw(" touch=" as *u8); vn(sa[3]); vw("\n" as *u8) 166 if pop8(sa[2]) >= 3 { if sa[1] >= 5 { if sa[3] == 1 { pass = pass + 1 } } } 167 168 // T9 16-ACTION WIDENING (seq1136): the original 8 values are FROZEN and the new bits bind+fire 169 var t9: i64 = 0 170 if IA_UP == 1 { if IA_DOWN == 2 { if IA_LEFT == 4 { if IA_RIGHT == 8 { t9 = t9 + 1 } } } } 171 if IA_A == 16 { if IA_B == 32 { if IA_MENU == 64 { if IA_PAUSE == 128 { t9 = t9 + 1 } } } } 172 if IA_JUMP == 256 { if IA_LUP == 512 { if IA_LDOWN == 1024 { if IA_MOD == 2048 { t9 = t9 + 1 } } } } 173 ia_init(p) 174 ia_bind(p, 32, IA_JUMP) // a consumer MAY rebind space -> jump 175 ia_key(p, 32, 1) 176 if ia_held(p) == IA_JUMP { t9 = t9 + 1 } 177 ia_key(p, 32, 0) 178 vw("T9 widened actions frozen+bindable: " as *u8); vn(t9); vw("/4\n" as *u8) 179 if t9 == 4 { pass = pass + 1 } 180 181 // T10 LOOK CHANNEL: deltas ACCUMULATE, drain exactly once, and clamp 182 ia_init(p) 183 var t10: i64 = 0 184 ia_look(p, 30, 0-10) 185 ia_look(p, 15, 0-5) 186 let lk: *i64 = sys_mmap(16) as *i64 187 ia_look_take(p, lk) 188 if lk[0] == 45 { if lk[1] == 0-15 { t10 = t10 + 1 } } 189 ia_look_take(p, lk) 190 if lk[0] == 0 { if lk[1] == 0 { t10 = t10 + 1 } } 191 ia_look(p, 999999, 0-999999) 192 ia_look_take(p, lk) 193 if lk[0] == IA_LOOK_CLAMP { if lk[1] == 0 - IA_LOOK_CLAMP { t10 = t10 + 1 } } 194 vw("T10 look accumulate/drain-once/clamp: " as *u8); vn(t10); vw("/3\n" as *u8) 195 if t10 == 3 { pass = pass + 1 } 196 197 vw("nx_input_abstract_gate: " as *u8); vn(pass); vw("/" as *u8); vn(total); vw("\n" as *u8) 198 if pass == total { vw("VERDICT GREEN -- one action state, four devices, edges+bindings proven\n" as *u8); sys_exit(0) } 199 vw("VERDICT RED\n" as *u8) 200 sys_exit(1) 201 return 0 202}