code wiki / _hdl_build / nx_input_abstract_part.nx

nx_input_abstract_part.nx

buildroot/runtime/_hdl_build/nx_input_abstract_part.nx

9483 B221 linesdepth 2pulls 2 transitivereach 1 importersview sourcekind librarytopic input
docsdependenciesstructsconstsfunctions

about

nx_input_abstract_part.nx -- RENAMED FROM nx_input_abstract.nx 2026-07-31 (lib-reconcile). PERMANENT FIX for a two-libraries-one-name collision. runtime/nx_input_abstract.nx is a DIFFERENT program: the F1102 game-platform input CORE, whose API is ia_init(p) / ia_bind(p, code, act). THIS file is the gamebench capability-43 composable PART, whose API is ia_init(s, nact) and ia_bind(s, dev, act, raw) -- same names, INCOMPATIBLE arities. nx_cc binds an import to the IMPORTER'S OWN DIRECTORY FIRST, so which API a caller got depended on WHICH DIRECTORY IT SAT IN, and moving a file between directories silently swapped its input API. The rename removes the ambiguity by construction: one name now denotes one program corpus-wide. WHY THIS PART EXISTS (measured, not guessed): nx_gamebench 2026-07-25 ranked platform reach and found platform-desktop-native blocking 21 of 22 reference titles, vr-runtime a GAP for 4, and mobile only PARTIAL -- while EVERY game in the ecosystem wired its own controls. One loop per platform is how a codebase forks into four. This part is the single place a raw device code becomes a SEMANTIC ACTION, so the game loop above it never learns which device the player used. THE CONTRACT (each clause is a gate tooth): - DEVICE-INDEPENDENCE BY CONSTRUCTION: the same semantic action sequence delivered from keyboard, gamepad, touch or a VR controller drives IDENTICAL downstream state. The game cannot tell them apart because it never sees a device -- it sees actions. This is the flagship property. - NO DEAD ACTION: an action reachable on one device but not another is a platform that cannot play. ia_coverage MEASURES this per device; the gate requires 1000 permil on every bound device. - UNAMBIGUOUS BINDINGS: binding a second action to a (device, raw-code) already in use is REFUSED (IA_E_DUP) with state bit-identical. Ambiguous input is a bug you cannot debug later. - AN UNBOUND CODE PRODUCES NOTHING: a stray device code can never fabricate an action. - DETERMINISTIC REPLAY: the action trace replays to the same actions and the same checksum, and the serializable span rides nx_gamesave like every other certified part (rpgstats T8 / entity T9). Bindings are DATA, not code: a game declares its own action set and its own per-device codes, so a new platform is a binding table, never a fork of the loop. LIB, no main (ecosystem convention, cf. nx_swgpu.nx / nx_gamehud.nx). license_tier: ORIGINAL

dependencies 1 imports · 1 importers

nx_syscalls.nx nx_input_abstract_part.nx nx_m2d_engine.nx

imports: nx_syscalls.nx

imported by: nx_m2d_engine.nx

structs

none

consts

33const IA_D_KEY: i64 = 0
34const IA_D_PAD: i64 = 1
35const IA_D_TOUCH: i64 = 2
36const IA_D_VR: i64 = 3
37const IA_NDEV: i64 = 4
41const IA_A_PREV: i64 = 0
42const IA_A_NEXT: i64 = 1
43const IA_A_CONFIRM: i64 = 2
44const IA_A_CANCEL: i64 = 3
45const IA_A_PAUSE: i64 = 4
46const IA_A_NONE: i64 = 0-1
47const IA_MAXACT: i64 = 12
50const IA_F_NACT: i64 = 0 // declared action count
51const IA_F_NEV: i64 = 1 // events fed (lifetime)
52const IA_F_CK: i64 = 2 // order-sensitive rolling action checksum
53const IA_F_DEVM: i64 = 3 // bitmask of devices carrying at least one binding
54const IA_F_NTR: i64 = 4 // trace length
55const IA_O_BIND: i64 = 8 // binding table: IA_NDEV*IA_MAXACT raw codes -> 8 .. 8+48 = 56
56const IA_O_TRACE: i64 = 56 // recorded action trace -> 56 .. 56+64 = 120
57const IA_MAXTRACE: i64 = 64
58const IA_NSV: i64 = 120 // serializable span (IA_O_TRACE + IA_MAXTRACE)
61const IA_E_DEV: i64 = 0-1
62const IA_E_ACT: i64 = 0-2
63const IA_E_RAW: i64 = 0-3
64const IA_E_DUP: i64 = 0-4
65const IA_E_FULL: i64 = 0-5
67const IA_CK_SEED: i64 = 1469598103
68const IA_CK_PRIME: i64 = 16777619
69const IA_CK_MASK: i64 = 4611686018427387903 // 2^62-1: keep the checksum bounded and positive

functions

71func ia_bit(i: i64) -> i64 { var v: i64=1; var k: i64=0; while k<i { v=v*2; k=k+1 } return v }
72func ia_hasbit(m: i64, i: i64) -> i64 { let b: i64=ia_bit(i); if (m/b)%2==1 { return 1 } return 0 }
called by 2: ia_bindia_reach_permil calls 1: ia_bit
75func ia_init(s: *i64, nact: i64) -> i64
86func ia_binding(s: *i64, dev: i64, act: i64) -> i64
93func ia_bind(s: *i64, dev: i64, act: i64, raw: i64) -> i64
called by 3: md_runmd_playmain calls 2: ia_hasbitia_bit
113func ia_lookup(s: *i64, dev: i64, raw: i64) -> i64
called by 1: ia_feed
126func ia_mixck(ck: i64, v: i64) -> i64
called by 2: ia_feedia_replay
136func ia_feed(s: *i64, dev: i64, raw: i64) -> i64
called by 3: md_runmd_playmain calls 2: ia_lookupia_mixck
148func ia_ck(s: *i64) -> i64 { return s[IA_F_CK] }
149func ia_nev(s: *i64) -> i64 { return s[IA_F_NEV] }
150func ia_trace_len(s: *i64) -> i64 { return s[IA_F_NTR] }
151func ia_trace_at(s: *i64, i: i64) -> i64
159func ia_coverage(s: *i64, dev: i64) -> i64
174func ia_reach(s: *i64, act: i64) -> i64
calls 1: ia_bit
186func ia_reach_permil(s: *i64) -> i64
calls 1: ia_hasbit
206func ia_replay(src: *i64, dst: *i64) -> i64
calls 2: ia_initia_mixck