@benev/tact 0.4.0-0 → 0.4.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/README.md +90 -66
  2. package/package.json +5 -4
  3. package/s/demo/main.bundle.ts +18 -3
  4. package/s/demo/main.css +4 -3
  5. package/s/demo/presets.ts +54 -0
  6. package/s/gamepad/gamepad-app/element.ts +11 -4
  7. package/s/gamepad/gamepad-app/style.css.ts +5 -1
  8. package/s/gamepad/index.html.ts +1 -1
  9. package/s/gamepad/main.css +10 -1
  10. package/s/index.html.ts +13 -6
  11. package/s/lib/index.ts +15 -4
  12. package/s/lib/input/{encoder.ts → controller.ts} +23 -15
  13. package/s/lib/input/data/endian.ts +3 -0
  14. package/s/{_archive/lib3/input/data → lib/input/data/intent}/decode.ts +4 -3
  15. package/s/lib/input/data/intent/encode.ts +25 -0
  16. package/s/{_archive/lib3/input/data/params.ts → lib/input/data/intent/sizes.ts} +1 -2
  17. package/s/lib/input/data/intent/types.ts +6 -0
  18. package/s/lib/input/data/parcel/decode.ts +32 -0
  19. package/s/lib/input/data/parcel/encode.ts +30 -0
  20. package/s/lib/input/data/parcel/sizes.ts +5 -0
  21. package/s/lib/input/data/parcel/types.ts +8 -0
  22. package/s/lib/input/data/test.ts +23 -0
  23. package/s/lib/input/decoder.ts +16 -10
  24. package/s/lib/input/evaluate/context.ts +2 -3
  25. package/s/lib/input/evaluate/evaluate.ts +45 -15
  26. package/s/lib/input/expression.ts +5 -5
  27. package/s/lib/input/investigate/is-expression.ts +1 -0
  28. package/s/lib/input/investigate/make-input.ts +1 -5
  29. package/s/lib/input/sources/gamepad.ts +3 -9
  30. package/s/lib/input/sources/pointer.ts +0 -18
  31. package/s/lib/input/test.ts +194 -0
  32. package/s/lib/input/testing/quickbind.ts +6 -5
  33. package/s/lib/input/types.ts +3 -7
  34. package/s/lib/input/utils/mouse-button.ts +1 -6
  35. package/s/lib/test.ts +3 -177
  36. package/s/lib/ui/deck/auto-gamepads.ts +29 -0
  37. package/s/lib/ui/deck/collector.ts +52 -0
  38. package/s/lib/ui/deck/controls/controls.ts +76 -0
  39. package/s/lib/ui/deck/controls/internal/assignments.ts +24 -0
  40. package/s/lib/ui/deck/controls/internal/data.ts +51 -0
  41. package/s/lib/ui/deck/controls/internal/fns.ts +38 -0
  42. package/s/lib/ui/deck/controls/internal/profiles.ts +83 -0
  43. package/s/lib/ui/deck/controls/types.ts +23 -0
  44. package/s/lib/ui/deck/hub.ts +108 -0
  45. package/s/lib/ui/deck/setup/deck.ts +31 -0
  46. package/s/lib/ui/deck/setup/tact.ts +86 -0
  47. package/s/lib/ui/deck/setup/types.ts +12 -0
  48. package/s/lib/ui/deck/types.ts +26 -0
  49. package/s/lib/ui/deck/utils/first-preset.ts +9 -0
  50. package/s/lib/ui/icons/akar/LICENSE +23 -0
  51. package/s/lib/ui/icons/akar/backspace.svg.ts +4 -0
  52. package/s/lib/ui/icons/akar/circle-plus.svg.ts +4 -0
  53. package/s/lib/ui/icons/akar/copy.svg.ts +4 -0
  54. package/s/lib/ui/icons/akar/cross.svg.ts +4 -0
  55. package/s/lib/ui/icons/akar/devices.svg.ts +4 -0
  56. package/s/lib/ui/icons/akar/drag-vertical-fill.svg.ts +4 -0
  57. package/s/lib/ui/icons/akar/game-controller.svg.ts +4 -0
  58. package/s/lib/ui/icons/akar/key-cap.svg.ts +4 -0
  59. package/s/lib/ui/icons/akar/people-group.svg.ts +4 -0
  60. package/s/lib/ui/icons/akar/person-add.svg.ts +4 -0
  61. package/s/lib/ui/icons/akar/settings-horizontal.svg.ts +4 -0
  62. package/s/lib/ui/icons/akar/trash-can.svg.ts +4 -0
  63. package/s/lib/ui/icons/akar/x-small.svg.ts +4 -0
  64. package/s/lib/ui/views/controllers/style.css.ts +158 -0
  65. package/s/lib/ui/views/controllers/subviews/controller.ts +53 -0
  66. package/s/lib/ui/views/controllers/subviews/dropcard.ts +31 -0
  67. package/s/lib/ui/views/controllers/subviews/player.ts +38 -0
  68. package/s/lib/ui/views/controllers/view.ts +72 -0
  69. package/s/lib/ui/views/customize/parts/capture-gamepad-chord.ts +59 -0
  70. package/s/lib/ui/views/customize/parts/capture-key-chord.ts +70 -0
  71. package/s/lib/ui/views/customize/parts/capture-pointer-chord.ts +55 -0
  72. package/s/lib/ui/views/customize/parts/render-bindings.ts +67 -0
  73. package/s/lib/ui/views/customize/style.css.ts +144 -0
  74. package/s/lib/ui/views/customize/subviews/expression.ts +88 -0
  75. package/s/lib/ui/views/customize/subviews/recorder.ts +76 -0
  76. package/s/lib/ui/views/customize/view.ts +104 -0
  77. package/s/lib/ui/views/deck/style.css.ts +69 -0
  78. package/s/lib/ui/views/deck/types.ts +15 -0
  79. package/s/lib/ui/views/deck/view.ts +49 -0
  80. package/s/lib/ui/views/profile-select/view.ts +44 -0
  81. package/s/lib/ui/views/theme.css.ts +115 -0
  82. package/s/lib/ui/views/visualizer/style.css.ts +23 -0
  83. package/s/lib/ui/views/visualizer/view.ts +16 -0
  84. package/s/lib/ui/views/visualizer/visualizer.ts +17 -0
  85. package/s/lib/utils/ellipsis.ts +7 -0
  86. package/s/lib/utils/hueify.ts +5 -0
  87. package/x/demo/main.bundle.js +16 -3
  88. package/x/demo/main.bundle.js.map +1 -1
  89. package/x/demo/main.bundle.min.js +809 -11
  90. package/x/demo/main.bundle.min.js.map +4 -4
  91. package/x/demo/main.css +4 -3
  92. package/x/demo/presets.d.ts +30 -0
  93. package/x/demo/presets.js +51 -0
  94. package/x/demo/presets.js.map +1 -0
  95. package/x/gamepad/gamepad-app/element.js +9 -4
  96. package/x/gamepad/gamepad-app/element.js.map +1 -1
  97. package/x/gamepad/gamepad-app/style.css.js +5 -1
  98. package/x/gamepad/gamepad-app/style.css.js.map +1 -1
  99. package/x/gamepad/index.html +4 -4
  100. package/x/gamepad/index.html.js +1 -1
  101. package/x/gamepad/main.bundle.min.js +24 -20
  102. package/x/gamepad/main.bundle.min.js.map +4 -4
  103. package/x/gamepad/main.css +10 -1
  104. package/x/index.html +16 -9
  105. package/x/index.html.js +13 -6
  106. package/x/index.html.js.map +1 -1
  107. package/x/lib/index.d.ts +14 -1
  108. package/x/lib/index.js +14 -1
  109. package/x/lib/index.js.map +1 -1
  110. package/x/lib/input/controller.d.ts +15 -0
  111. package/x/lib/input/{encoder.js → controller.js} +19 -13
  112. package/x/lib/input/controller.js.map +1 -0
  113. package/x/lib/input/data/endian.d.ts +1 -0
  114. package/x/lib/input/data/endian.js +2 -0
  115. package/x/lib/input/data/endian.js.map +1 -0
  116. package/x/lib/input/data/intent/decode.d.ts +5 -0
  117. package/x/lib/input/data/{decode.js → intent/decode.js} +3 -2
  118. package/x/lib/input/data/intent/decode.js.map +1 -0
  119. package/x/lib/input/data/intent/encode.d.ts +2 -0
  120. package/x/lib/input/data/intent/encode.js +18 -0
  121. package/x/lib/input/data/intent/encode.js.map +1 -0
  122. package/x/lib/input/data/{params.d.ts → intent/sizes.d.ts} +1 -2
  123. package/x/lib/input/data/intent/sizes.js +5 -0
  124. package/x/lib/input/data/intent/sizes.js.map +1 -0
  125. package/x/lib/input/data/intent/types.d.ts +4 -0
  126. package/x/lib/input/data/intent/types.js +2 -0
  127. package/x/lib/input/data/intent/types.js.map +1 -0
  128. package/x/lib/input/data/parcel/decode.d.ts +2 -0
  129. package/x/lib/input/data/parcel/decode.js +22 -0
  130. package/x/lib/input/data/parcel/decode.js.map +1 -0
  131. package/x/lib/input/data/parcel/encode.d.ts +2 -0
  132. package/x/lib/input/data/parcel/encode.js +19 -0
  133. package/x/lib/input/data/parcel/encode.js.map +1 -0
  134. package/x/lib/input/data/parcel/sizes.d.ts +3 -0
  135. package/x/lib/input/data/parcel/sizes.js +4 -0
  136. package/x/lib/input/data/parcel/sizes.js.map +1 -0
  137. package/x/lib/input/data/parcel/types.d.ts +5 -0
  138. package/x/lib/input/data/parcel/types.js +2 -0
  139. package/x/lib/input/data/parcel/types.js.map +1 -0
  140. package/x/lib/input/data/test.d.ts +6 -0
  141. package/x/lib/input/data/test.js +19 -0
  142. package/x/lib/input/data/test.js.map +1 -0
  143. package/x/lib/input/decoder.d.ts +2 -2
  144. package/x/lib/input/decoder.js +12 -10
  145. package/x/lib/input/decoder.js.map +1 -1
  146. package/x/lib/input/evaluate/context.d.ts +2 -3
  147. package/x/lib/input/evaluate/context.js +2 -3
  148. package/x/lib/input/evaluate/context.js.map +1 -1
  149. package/x/lib/input/evaluate/evaluate.d.ts +1 -1
  150. package/x/lib/input/evaluate/evaluate.js +42 -14
  151. package/x/lib/input/evaluate/evaluate.js.map +1 -1
  152. package/x/lib/input/expression.d.ts +1 -1
  153. package/x/lib/input/investigate/is-expression.js +2 -0
  154. package/x/lib/input/investigate/is-expression.js.map +1 -1
  155. package/x/lib/input/investigate/make-input.js +1 -5
  156. package/x/lib/input/investigate/make-input.js.map +1 -1
  157. package/x/lib/input/sources/gamepad.js +3 -9
  158. package/x/lib/input/sources/gamepad.js.map +1 -1
  159. package/x/lib/input/sources/pointer.js +0 -21
  160. package/x/lib/input/sources/pointer.js.map +1 -1
  161. package/x/lib/input/test.d.ts +18 -0
  162. package/x/lib/input/test.js +143 -0
  163. package/x/lib/input/test.js.map +1 -0
  164. package/x/lib/input/testing/quickbind.d.ts +3 -2
  165. package/x/lib/input/testing/quickbind.js +6 -5
  166. package/x/lib/input/testing/quickbind.js.map +1 -1
  167. package/x/lib/input/types.d.ts +3 -8
  168. package/x/lib/input/types.js.map +1 -1
  169. package/x/lib/input/utils/mouse-button.js +1 -6
  170. package/x/lib/input/utils/mouse-button.js.map +1 -1
  171. package/x/lib/test.js +3 -133
  172. package/x/lib/test.js.map +1 -1
  173. package/x/lib/ui/deck/auto-gamepads.d.ts +4 -0
  174. package/x/lib/ui/deck/auto-gamepads.js +19 -0
  175. package/x/lib/ui/deck/auto-gamepads.js.map +1 -0
  176. package/x/lib/ui/deck/collector.d.ts +13 -0
  177. package/x/lib/ui/deck/collector.js +35 -0
  178. package/x/lib/ui/deck/collector.js.map +1 -0
  179. package/x/lib/ui/deck/controls/controls.d.ts +19 -0
  180. package/x/lib/ui/deck/controls/controls.js +56 -0
  181. package/x/lib/ui/deck/controls/controls.js.map +1 -0
  182. package/x/lib/ui/deck/controls/internal/assignments.d.ts +9 -0
  183. package/x/lib/ui/deck/controls/internal/assignments.js +16 -0
  184. package/x/lib/ui/deck/controls/internal/assignments.js.map +1 -0
  185. package/x/lib/ui/deck/controls/internal/data.d.ts +29 -0
  186. package/x/lib/ui/deck/controls/internal/data.js +29 -0
  187. package/x/lib/ui/deck/controls/internal/data.js.map +1 -0
  188. package/x/lib/ui/deck/controls/internal/fns.d.ts +6 -0
  189. package/x/lib/ui/deck/controls/internal/fns.js +19 -0
  190. package/x/lib/ui/deck/controls/internal/fns.js.map +1 -0
  191. package/x/lib/ui/deck/controls/internal/profiles.d.ts +18 -0
  192. package/x/lib/ui/deck/controls/internal/profiles.js +59 -0
  193. package/x/lib/ui/deck/controls/internal/profiles.js.map +1 -0
  194. package/x/lib/ui/deck/controls/types.d.ts +17 -0
  195. package/x/lib/ui/deck/controls/types.js +2 -0
  196. package/x/lib/ui/deck/controls/types.js.map +1 -0
  197. package/x/lib/ui/deck/hub.d.ts +21 -0
  198. package/x/lib/ui/deck/hub.js +85 -0
  199. package/x/lib/ui/deck/hub.js.map +1 -0
  200. package/x/lib/ui/deck/setup/deck.d.ts +3 -0
  201. package/x/lib/ui/deck/setup/deck.js +20 -0
  202. package/x/lib/ui/deck/setup/deck.js.map +1 -0
  203. package/x/lib/ui/deck/setup/tact.d.ts +17 -0
  204. package/x/lib/ui/deck/setup/tact.js +67 -0
  205. package/x/lib/ui/deck/setup/tact.js.map +1 -0
  206. package/x/lib/ui/deck/setup/types.d.ts +9 -0
  207. package/x/lib/ui/deck/setup/types.js +2 -0
  208. package/x/lib/ui/deck/setup/types.js.map +1 -0
  209. package/x/lib/ui/deck/types.d.ts +18 -0
  210. package/x/lib/ui/deck/types.js +3 -0
  211. package/x/lib/ui/deck/types.js.map +1 -0
  212. package/x/lib/ui/deck/utils/first-preset.d.ts +6 -0
  213. package/x/lib/ui/deck/utils/first-preset.js +5 -0
  214. package/x/lib/ui/deck/utils/first-preset.js.map +1 -0
  215. package/x/lib/ui/icons/akar/backspace.svg.d.ts +2 -0
  216. package/x/lib/ui/icons/akar/backspace.svg.js +3 -0
  217. package/x/lib/ui/icons/akar/backspace.svg.js.map +1 -0
  218. package/x/lib/ui/icons/akar/circle-plus.svg.d.ts +2 -0
  219. package/x/lib/ui/icons/akar/circle-plus.svg.js +3 -0
  220. package/x/lib/ui/icons/akar/circle-plus.svg.js.map +1 -0
  221. package/x/lib/ui/icons/akar/copy.svg.d.ts +2 -0
  222. package/x/lib/ui/icons/akar/copy.svg.js +3 -0
  223. package/x/lib/ui/icons/akar/copy.svg.js.map +1 -0
  224. package/x/lib/ui/icons/akar/cross.svg.d.ts +2 -0
  225. package/x/lib/ui/icons/akar/cross.svg.js +3 -0
  226. package/x/lib/ui/icons/akar/cross.svg.js.map +1 -0
  227. package/x/lib/ui/icons/akar/devices.svg.d.ts +2 -0
  228. package/x/lib/ui/icons/akar/devices.svg.js +3 -0
  229. package/x/lib/ui/icons/akar/devices.svg.js.map +1 -0
  230. package/x/lib/ui/icons/akar/drag-vertical-fill.svg.d.ts +2 -0
  231. package/x/lib/ui/icons/akar/drag-vertical-fill.svg.js +3 -0
  232. package/x/lib/ui/icons/akar/drag-vertical-fill.svg.js.map +1 -0
  233. package/x/lib/ui/icons/akar/game-controller.svg.d.ts +2 -0
  234. package/x/lib/ui/icons/akar/game-controller.svg.js +3 -0
  235. package/x/lib/ui/icons/akar/game-controller.svg.js.map +1 -0
  236. package/x/lib/ui/icons/akar/key-cap.svg.d.ts +2 -0
  237. package/x/lib/ui/icons/akar/key-cap.svg.js +3 -0
  238. package/x/lib/ui/icons/akar/key-cap.svg.js.map +1 -0
  239. package/x/lib/ui/icons/akar/people-group.svg.d.ts +2 -0
  240. package/x/lib/ui/icons/akar/people-group.svg.js +3 -0
  241. package/x/lib/ui/icons/akar/people-group.svg.js.map +1 -0
  242. package/x/lib/ui/icons/akar/person-add.svg.d.ts +2 -0
  243. package/x/lib/ui/icons/akar/person-add.svg.js +3 -0
  244. package/x/lib/ui/icons/akar/person-add.svg.js.map +1 -0
  245. package/x/lib/ui/icons/akar/settings-horizontal.svg.d.ts +2 -0
  246. package/x/lib/ui/icons/akar/settings-horizontal.svg.js +3 -0
  247. package/x/lib/ui/icons/akar/settings-horizontal.svg.js.map +1 -0
  248. package/x/lib/ui/icons/akar/trash-can.svg.d.ts +2 -0
  249. package/x/lib/ui/icons/akar/trash-can.svg.js +3 -0
  250. package/x/lib/ui/icons/akar/trash-can.svg.js.map +1 -0
  251. package/x/lib/ui/icons/akar/x-small.svg.d.ts +2 -0
  252. package/x/lib/ui/icons/akar/x-small.svg.js +3 -0
  253. package/x/lib/ui/icons/akar/x-small.svg.js.map +1 -0
  254. package/x/lib/ui/views/controllers/style.css.js +157 -0
  255. package/x/lib/ui/views/controllers/style.css.js.map +1 -0
  256. package/x/lib/ui/views/controllers/subviews/controller.d.ts +3 -0
  257. package/x/lib/ui/views/controllers/subviews/controller.js +45 -0
  258. package/x/lib/ui/views/controllers/subviews/controller.js.map +1 -0
  259. package/x/lib/ui/views/controllers/subviews/dropcard.d.ts +9 -0
  260. package/x/lib/ui/views/controllers/subviews/dropcard.js +20 -0
  261. package/x/lib/ui/views/controllers/subviews/dropcard.js.map +1 -0
  262. package/x/lib/ui/views/controllers/subviews/player.d.ts +2 -0
  263. package/x/lib/ui/views/controllers/subviews/player.js +32 -0
  264. package/x/lib/ui/views/controllers/subviews/player.js.map +1 -0
  265. package/x/lib/ui/views/controllers/view.d.ts +2 -0
  266. package/x/lib/ui/views/controllers/view.js +64 -0
  267. package/x/lib/ui/views/controllers/view.js.map +1 -0
  268. package/x/lib/ui/views/customize/parts/capture-gamepad-chord.d.ts +2 -0
  269. package/x/lib/ui/views/customize/parts/capture-gamepad-chord.js +46 -0
  270. package/x/lib/ui/views/customize/parts/capture-gamepad-chord.js.map +1 -0
  271. package/x/lib/ui/views/customize/parts/capture-key-chord.d.ts +2 -0
  272. package/x/lib/ui/views/customize/parts/capture-key-chord.js +58 -0
  273. package/x/lib/ui/views/customize/parts/capture-key-chord.js.map +1 -0
  274. package/x/lib/ui/views/customize/parts/capture-pointer-chord.d.ts +2 -0
  275. package/x/lib/ui/views/customize/parts/capture-pointer-chord.js +42 -0
  276. package/x/lib/ui/views/customize/parts/capture-pointer-chord.js.map +1 -0
  277. package/x/lib/ui/views/customize/parts/render-bindings.d.ts +3 -0
  278. package/x/lib/ui/views/customize/parts/render-bindings.js +32 -0
  279. package/x/lib/ui/views/customize/parts/render-bindings.js.map +1 -0
  280. package/x/lib/ui/views/customize/style.css.d.ts +2 -0
  281. package/x/lib/ui/views/customize/style.css.js +143 -0
  282. package/x/lib/ui/views/customize/style.css.js.map +1 -0
  283. package/x/lib/ui/views/customize/subviews/expression.d.ts +2 -0
  284. package/x/lib/ui/views/customize/subviews/expression.js +75 -0
  285. package/x/lib/ui/views/customize/subviews/expression.js.map +1 -0
  286. package/x/lib/ui/views/customize/subviews/recorder.d.ts +3 -0
  287. package/x/lib/ui/views/customize/subviews/recorder.js +60 -0
  288. package/x/lib/ui/views/customize/subviews/recorder.js.map +1 -0
  289. package/x/lib/ui/views/customize/view.d.ts +6 -0
  290. package/x/lib/ui/views/customize/view.js +82 -0
  291. package/x/lib/ui/views/customize/view.js.map +1 -0
  292. package/x/lib/ui/views/deck/style.css.d.ts +2 -0
  293. package/x/lib/ui/views/deck/style.css.js +68 -0
  294. package/x/lib/ui/views/deck/style.css.js.map +1 -0
  295. package/x/lib/ui/views/deck/types.d.ts +14 -0
  296. package/x/lib/ui/views/deck/types.js +2 -0
  297. package/x/lib/ui/views/deck/types.js.map +1 -0
  298. package/x/lib/ui/views/deck/view.d.ts +2 -0
  299. package/x/lib/ui/views/deck/view.js +41 -0
  300. package/x/lib/ui/views/deck/view.js.map +1 -0
  301. package/x/lib/ui/views/profile-select/view.d.ts +4 -0
  302. package/x/lib/ui/views/profile-select/view.js +34 -0
  303. package/x/lib/ui/views/profile-select/view.js.map +1 -0
  304. package/x/lib/ui/views/theme.css.d.ts +2 -0
  305. package/x/lib/ui/views/theme.css.js +113 -0
  306. package/x/lib/ui/views/theme.css.js.map +1 -0
  307. package/x/lib/ui/views/visualizer/style.css.d.ts +2 -0
  308. package/x/lib/ui/views/visualizer/style.css.js +22 -0
  309. package/x/lib/ui/views/visualizer/style.css.js.map +1 -0
  310. package/x/lib/ui/views/visualizer/view.d.ts +2 -0
  311. package/x/lib/ui/views/visualizer/view.js +11 -0
  312. package/x/lib/ui/views/visualizer/view.js.map +1 -0
  313. package/x/lib/ui/views/visualizer/visualizer.d.ts +5 -0
  314. package/x/lib/ui/views/visualizer/visualizer.js +13 -0
  315. package/x/lib/ui/views/visualizer/visualizer.js.map +1 -0
  316. package/x/lib/utils/ellipsis.d.ts +1 -0
  317. package/x/lib/utils/ellipsis.js +6 -0
  318. package/x/lib/utils/ellipsis.js.map +1 -0
  319. package/x/lib/utils/hueify.d.ts +1 -0
  320. package/x/lib/utils/hueify.js +4 -0
  321. package/x/lib/utils/hueify.js.map +1 -0
  322. package/x/lib/utils/make-id.d.ts +1 -0
  323. package/x/lib/utils/make-id.js +5 -0
  324. package/x/lib/utils/make-id.js.map +1 -0
  325. package/s/_archive/core/atom/defaults.ts +0 -32
  326. package/s/_archive/core/atom/lens-algo.ts +0 -84
  327. package/s/_archive/core/atom/types.ts +0 -44
  328. package/s/_archive/core/bindings/normalize.ts +0 -27
  329. package/s/_archive/core/bindings/shape.ts +0 -15
  330. package/s/_archive/core/bindings/table.ts +0 -22
  331. package/s/_archive/core/intent/bucket.ts +0 -28
  332. package/s/_archive/core/intent/consts.ts +0 -4
  333. package/s/_archive/core/intent/decode.ts +0 -23
  334. package/s/_archive/core/intent/encode.ts +0 -20
  335. package/s/_archive/core/intent/merge.ts +0 -15
  336. package/s/_archive/core/parts/action.ts +0 -36
  337. package/s/_archive/core/parts/sample-map.ts +0 -24
  338. package/s/_archive/core/resolvers/actions.ts +0 -30
  339. package/s/_archive/core/resolvers/intents.ts +0 -106
  340. package/s/_archive/core/types.ts +0 -40
  341. package/s/_archive/deck/controller.ts +0 -35
  342. package/s/_archive/deck/deck.ts +0 -92
  343. package/s/_archive/deck/parts/profiles.ts +0 -39
  344. package/s/_archive/deck/parts/runtime.ts +0 -11
  345. package/s/_archive/deck/parts/settings.ts +0 -30
  346. package/s/_archive/deck/port.ts +0 -35
  347. package/s/_archive/deck/types.ts +0 -16
  348. package/s/_archive/demo/demo-app/element.ts +0 -17
  349. package/s/_archive/demo/demo-app/style.css.ts +0 -10
  350. package/s/_archive/demo/main.bundle.ts +0 -71
  351. package/s/_archive/demo/main.css +0 -83
  352. package/s/_archive/device/devices.ts +0 -24
  353. package/s/_archive/device/gamepad.ts +0 -42
  354. package/s/_archive/device/keyboard.ts +0 -33
  355. package/s/_archive/device/pad/on-pad.ts +0 -50
  356. package/s/_archive/device/pad/pad.ts +0 -10
  357. package/s/_archive/device/pointer.ts +0 -89
  358. package/s/_archive/device/sampler.ts +0 -25
  359. package/s/_archive/device/stick.ts +0 -24
  360. package/s/_archive/index-ui.ts +0 -3
  361. package/s/_archive/lib/bindings/resolver.ts +0 -61
  362. package/s/_archive/lib/bindings/types.ts +0 -67
  363. package/s/_archive/lib/bindings/utils/action-resolver.ts +0 -51
  364. package/s/_archive/lib/bindings/utils/evaluator.ts +0 -162
  365. package/s/_archive/lib/bindings/utils/hash-bindings.ts +0 -22
  366. package/s/_archive/lib/bindings/utils/intent-coding.ts +0 -50
  367. package/s/_archive/lib/bindings/utils/intent-resolver.ts +0 -52
  368. package/s/_archive/lib/bindings/utils/investigate.ts +0 -47
  369. package/s/_archive/lib/bindings/utils/is-down.ts +0 -5
  370. package/s/_archive/lib/bindings/utils/is-expression.ts +0 -11
  371. package/s/_archive/lib/index.ts +0 -12
  372. package/s/_archive/lib/sampling/sources/example.ts +0 -7
  373. package/s/_archive/lib/sampling/sources/gamepad.ts +0 -63
  374. package/s/_archive/lib/sampling/sources/keyboard.ts +0 -52
  375. package/s/_archive/lib/sampling/sources/pointer.ts +0 -56
  376. package/s/_archive/lib/sampling/sources/sources.ts +0 -13
  377. package/s/_archive/lib/sampling/sources/stick.ts +0 -27
  378. package/s/_archive/lib/sampling/types.ts +0 -11
  379. package/s/_archive/lib/sampling/utils/add-sample.ts +0 -12
  380. package/s/_archive/lib/test.ts +0 -57
  381. package/s/_archive/lib/utils/backwards.ts +0 -6
  382. package/s/_archive/lib/utils/evergreen.ts +0 -10
  383. package/s/_archive/lib/utils/mouse-button.ts +0 -10
  384. package/s/_archive/lib/utils/pad/on-pad.ts +0 -50
  385. package/s/_archive/lib/utils/pad/pad.ts +0 -10
  386. package/s/_archive/lib/utils/split-axis.ts +0 -15
  387. package/s/_archive/lib2/core/decoder/decoder.ts +0 -34
  388. package/s/_archive/lib2/core/decoder/utils/update-input.ts +0 -21
  389. package/s/_archive/lib2/core/encoder/encoder.ts +0 -60
  390. package/s/_archive/lib2/core/encoder/evaluate/context.ts +0 -22
  391. package/s/_archive/lib2/core/encoder/evaluate/evaluate.ts +0 -144
  392. package/s/_archive/lib2/core/encoder/parts/expression-index.ts +0 -27
  393. package/s/_archive/lib2/core/encoder/parts/hash-bindings.ts +0 -22
  394. package/s/_archive/lib2/core/encoder/parts/investigate.ts +0 -50
  395. package/s/_archive/lib2/core/encoder/parts/sampler.ts +0 -22
  396. package/s/_archive/lib2/core/sources/example.ts +0 -9
  397. package/s/_archive/lib2/core/sources/sources.ts +0 -16
  398. package/s/_archive/lib2/core/types.ts +0 -78
  399. package/s/_archive/lib2/core/utils/data.ts +0 -50
  400. package/s/_archive/lib2/core/utils/is-down.ts +0 -5
  401. package/s/_archive/lib2/core/utils/is-expression.ts +0 -11
  402. package/s/_archive/lib3/input/data/encode.ts +0 -24
  403. package/s/_archive/lib3/input/decoder.ts +0 -56
  404. package/s/_archive/lib3/input/encoder.ts +0 -99
  405. package/s/_archive/lib3/input/evaluate/context.ts +0 -15
  406. package/s/_archive/lib3/input/evaluate/evaluate.ts +0 -142
  407. package/s/_archive/lib3/input/evaluate/utils/clock.ts +0 -14
  408. package/s/_archive/lib3/input/investigate/hash-bindings.ts +0 -22
  409. package/s/_archive/lib3/input/investigate/investigate.ts +0 -42
  410. package/s/_archive/lib3/input/investigate/is-expression.ts +0 -11
  411. package/s/_archive/lib3/input/investigate/make-input.ts +0 -18
  412. package/s/_archive/lib3/input/investigate/root-index.ts +0 -26
  413. package/s/_archive/lib3/input/mixer.ts +0 -20
  414. package/s/_archive/lib3/input/sources/gamepad.ts +0 -58
  415. package/s/_archive/lib3/input/sources/keyboard.ts +0 -49
  416. package/s/_archive/lib3/input/sources/plain.ts +0 -9
  417. package/s/_archive/lib3/input/sources/pointer.ts +0 -58
  418. package/s/_archive/lib3/input/sources/sources.ts +0 -24
  419. package/s/_archive/lib3/input/sources/stick.ts +0 -29
  420. package/s/_archive/lib3/input/testing/quickbind.ts +0 -20
  421. package/s/_archive/lib3/input/types.ts +0 -96
  422. package/s/_archive/lib3/input/utils/evergreen.ts +0 -10
  423. package/s/_archive/lib3/input/utils/is-down.ts +0 -5
  424. package/s/_archive/lib3/input/utils/mouse-button.ts +0 -10
  425. package/s/_archive/lib3/input/utils/pad/on-pad.ts +0 -50
  426. package/s/_archive/lib3/input/utils/pad/pad.ts +0 -10
  427. package/s/_archive/lib3/input/utils/sampler.ts +0 -28
  428. package/s/_archive/lib3/input/utils/split-axis.ts +0 -15
  429. package/s/_archive/lib3/test.ts +0 -100
  430. package/s/_archive/lib4/input/data/decode.ts +0 -25
  431. package/s/_archive/lib4/input/data/encode.ts +0 -24
  432. package/s/_archive/lib4/input/data/params.ts +0 -7
  433. package/s/_archive/lib4/input/encoder.ts +0 -100
  434. package/s/_archive/lib4/input/evaluate/context.ts +0 -16
  435. package/s/_archive/lib4/input/evaluate/evaluate.ts +0 -157
  436. package/s/_archive/lib4/input/evaluate/utils/clock.ts +0 -14
  437. package/s/_archive/lib4/input/investigate/hash-bindings.ts +0 -22
  438. package/s/_archive/lib4/input/investigate/investigate.ts +0 -37
  439. package/s/_archive/lib4/input/investigate/is.ts +0 -19
  440. package/s/_archive/lib4/input/investigate/make-input.ts +0 -18
  441. package/s/_archive/lib4/input/investigate/root-index.ts +0 -26
  442. package/s/_archive/lib4/input/sources/gamepad.ts +0 -58
  443. package/s/_archive/lib4/input/sources/keyboard.ts +0 -46
  444. package/s/_archive/lib4/input/sources/plain.ts +0 -9
  445. package/s/_archive/lib4/input/sources/pointer.ts +0 -50
  446. package/s/_archive/lib4/input/sources/sources.ts +0 -24
  447. package/s/_archive/lib4/input/sources/stick.ts +0 -25
  448. package/s/_archive/lib4/input/types.ts +0 -102
  449. package/s/_archive/lib4/input/utils/evergreen.ts +0 -10
  450. package/s/_archive/lib4/input/utils/is-down.ts +0 -5
  451. package/s/_archive/lib4/input/utils/mouse-button.ts +0 -10
  452. package/s/_archive/lib4/input/utils/pad/on-pad.ts +0 -50
  453. package/s/_archive/lib4/input/utils/pad/pad.ts +0 -10
  454. package/s/_archive/lib4/input/utils/sampler.ts +0 -28
  455. package/s/_archive/lib4/input/utils/split-axis.ts +0 -15
  456. package/s/_archive/lib4/test.ts +0 -12
  457. package/s/_archive/test.ts +0 -339
  458. package/s/_archive/ui/views/desk/style.css.ts +0 -70
  459. package/s/_archive/ui/views/desk/view.ts +0 -122
  460. package/s/_archive/utils/circular-clamp.ts +0 -14
  461. package/s/_archive/utils/do-async.ts +0 -5
  462. package/s/_archive/utils/evergreen.ts +0 -10
  463. package/s/_archive/utils/freeze-clone.ts +0 -7
  464. package/s/_archive/utils/identifier.ts +0 -30
  465. package/s/_archive/utils/insert.ts +0 -6
  466. package/s/_archive/utils/is-down.ts +0 -5
  467. package/s/_archive/utils/remap.ts +0 -7
  468. package/s/_archive/utils/shift-limit.ts +0 -9
  469. package/s/_archive/utils/sort-by-key.ts +0 -7
  470. package/s/_archive/utils/split-axis.ts +0 -15
  471. package/s/_archive/utils/tmax.ts +0 -7
  472. package/s/_archive/utils/tmin.ts +0 -7
  473. package/s/demo/demo-app/element.ts +0 -15
  474. package/s/demo/demo-app/style.css.ts +0 -10
  475. package/s/lib/input/data/decode.ts +0 -25
  476. package/s/lib/input/data/encode.ts +0 -24
  477. package/s/lib/input/data/params.ts +0 -7
  478. package/x/_archive/demo/main.css +0 -83
  479. package/x/demo/demo-app/element.d.ts +0 -1
  480. package/x/demo/demo-app/element.js +0 -12
  481. package/x/demo/demo-app/element.js.map +0 -1
  482. package/x/demo/demo-app/style.css.js +0 -9
  483. package/x/demo/demo-app/style.css.js.map +0 -1
  484. package/x/lib/input/data/decode.d.ts +0 -5
  485. package/x/lib/input/data/decode.js.map +0 -1
  486. package/x/lib/input/data/encode.d.ts +0 -2
  487. package/x/lib/input/data/encode.js +0 -17
  488. package/x/lib/input/data/encode.js.map +0 -1
  489. package/x/lib/input/data/params.js +0 -6
  490. package/x/lib/input/data/params.js.map +0 -1
  491. package/x/lib/input/encoder.d.ts +0 -10
  492. package/x/lib/input/encoder.js.map +0 -1
  493. /package/s/{_archive → lib}/utils/make-id.ts +0 -0
  494. /package/x/{demo/demo-app → lib/ui/views/controllers}/style.css.d.ts +0 -0
package/README.md CHANGED
@@ -2,104 +2,128 @@
2
2
  # 🎮 @benev/tact
3
3
  > *from keypress to couch co-op.*
4
4
 
5
- **tact is a tiny input toolkit for web games.**
6
- keyboards, mice, gamepads. expressive bindings json dsl.
7
- binary messages for efficient networking and web worker multithreading.
5
+ **tact is a user-input toolkit for web games.**
8
6
 
9
- ```ts
10
- npm install @benev/tact@next
11
- ```
7
+ 🌐 👉 ***https://tact.benev.gg/*** 👈 *try now*
12
8
 
9
+ 🖱 keyboards, mice, gamepads.
10
+ 🧩 expressive bindings json dsl.
11
+ 🎨 bindings are user-customizable.
12
+ 🫂 multiplayer and splitscreen capable.
13
+ 🧬 binary for efficient workers and networking.
14
+ 🎸 ready-to-rock drop-in user-interface.
13
15
 
16
+ ![](https://i.imgur.com/dCAlD14.png)
14
17
 
15
- <br/>
16
-
17
- ## 🕹️ sources emit samples.
18
-
19
- - **samples look like** `{code: "KeyW", value: 1}`
20
- ```ts
21
- import {Sources, KeyboardSource, PointerSource} from "@benev/tact"
22
- ```
23
- ```ts
24
- const source = new Sources(
25
- new KeyboardSource(),
26
- new PointerSource(),
27
- )
28
- ```
29
- - proper sources: [GamepadSource](./s/lib/input/sources/gamepad.ts), [KeyboardSource](./s/lib/input/sources/keyboard.ts), [PointerSource](./s/lib/input/sources/pointer.ts), [StickSource](./s/lib/input/sources/stick.ts).
30
- - utility sources: [Sources](./s/lib/input/sources/sources.ts) *(consolidates sources)*, [PlainSource](./s/lib/input/sources/plain.ts) *(handy base class)*.
18
+ ![](https://i.imgur.com/IBW5Kkd.png)
31
19
 
32
20
 
33
21
 
34
22
  <br/>
35
23
 
36
- ## 🕹️ bindings describe controls.
24
+ ## 🎮 let's play.
37
25
 
38
- - **bindings are tiny programs,** a dsl in js data.
26
+ - 🍏 **install tact.**
27
+ ```sh
28
+ npm install @benev/tact@next
29
+ ```
30
+ - 🍏 **establish your app's standard bindings.**
39
31
  ```ts
40
32
  import {asBindings} from "@benev/tact"
33
+
34
+ const bindings = asBindings({
35
+ jump: "Space",
36
+ forward: "KeyW",
37
+ look: ["accumulate", "pointer.x"],
38
+ })
41
39
  ```
40
+ - 💡 *bindings is a tiny json dsl. see [expression.ts](./s/lib/input/expression.ts).*
41
+ - 🍏 **let's have two presets available to the user. one for gamepads.**
42
42
  ```ts
43
- const bindings = asBindings({
44
- forward: ["max", "KeyW", "ArrowUp"],
45
- jump: ["down", "Space"],
46
- look: ["accumulate", ["sum", "pointer.x"]],
43
+ import {asPresets} from "@benev/tact"
44
+
45
+ const presets = asPresets<typeof bindings>({
46
+ standard: {label: "⌨️standard", bindings},
47
+ gamepad: {label: "🎮gamer", bindings: {
48
+ jump: "gamepad.1",
49
+ forward: ["remap", 0, -1, 0, 1, "gamepad.axis.2"],
50
+ look: ["*", ["dt"], "gamepad.axis.3", 100],
51
+ }},
47
52
  })
48
53
  ```
49
- - see [expression.ts](./s/lib/input/expression.ts) to learn what's possible.
54
+ - 🍏 **now we can setup tact and register the html elements.**
55
+ ```ts
56
+ import {setupTact} from "@benev/tact"
57
+
58
+ const tact = await setupTact({presets, maxPlayers: 4})
59
+ tact.mouseKeyboard()
60
+ tact.gamepads("gamepad")
61
+ tact.registerElements()
62
+ ```
63
+ - 🍏 **simply put the `<tact-deck>` in your html page.**
64
+ ```html
65
+ <tact-deck></tact-deck>
66
+ ```
67
+ - 💡 *you also have each panel, `<tact-controllers>` and `<tact-customize>`.*
68
+ - 🍏 **color the whole ui with css.**
69
+ ```html
70
+ <style>
71
+ html {
72
+ --tact-prime: aqua;
73
+ --tact-bg: black;
74
+ }
75
+ </style>
76
+ ```
50
77
 
51
78
 
52
79
 
53
80
  <br/>
54
81
 
55
- ## 🕹️ encode and decode.
82
+ ## 🎮 encoding, decoding, and your game logic.
56
83
 
57
- - **the data is binary for efficient networking.**
84
+ - 🍏 **make a collector.**
58
85
  ```ts
59
- import {InputEncoder, InputDecoder} from "@benev/tact"
86
+ import {Collector} from "@benev/tact"
87
+
88
+ const collector = new Collector(bindings)
60
89
  ```
90
+ - 🍏 **now it's time for the real action!**
61
91
  ```ts
62
- const encoder = new InputEncoder(source, bindings)
63
- const decoder = new InputDecoder(bindings)
92
+ setInterval(() => {
93
+ const buffer = tact.deck.hub.encodeAll()
94
+ for (const {playerId, inputs} of collector.decodeAll(buffer)) {
95
+
96
+ // your game logic can read these handy input values.
97
+ inputs.jump.value // values are numbers 0 to 1.
98
+ inputs.jump.was // previous value (to detect up/down).
99
+ inputs.jump.sum // sum of values reported since last frame.
100
+
101
+ inputs.forward.value
102
+ inputs.look.value
103
+ }
104
+ }, 16.67)
64
105
  ```
65
- ```ts
66
- function frame() {
106
+ 💡 *you could stream the buffers across the network to a remote collector.*
67
107
 
68
- // data is an ArrayBuffer (you could stream it over the network).
69
- const data = encoder.encode()
70
108
 
71
- // decoding interprets the data as handy input objects.
72
- const inputs = decoder.decode(data)
73
109
 
74
- // your game logic can read these handy input values.
75
- inputs.forward.value // current held state.
76
- inputs.jump.value // down-presses this frame.
77
- inputs.look.value // total accumulated mouse movement.
110
+ <br/>
78
111
 
79
- // this was so cool, let's do this forever.
80
- requestAnimationFrame(frame)
81
- }
112
+ ## 🎮 get down to brass tacks.
82
113
 
83
- requestAnimationFrame(frame)
84
- ```
85
- - **understanding networking situations.**
86
- - the encoder could be on your clientside.
87
- - the decoder could be on your serverside.
88
- - thus, clients are streaming their input data to the serverside, which is decoding it and using it in game logic.
89
- - don't worry, it's not a keylogger -- the encoded data is more like `jump: 1`, `look: 5`, etc.
90
- - the decoder can accept multiple data packets at once, `decoder.decode(...datas)`.
91
- - **understanding multithreaded worker situations.**
92
- - the encoder would be on the main thread, where javascript events are accessible.
93
- - you can then send the encoded input data to the thread where you're simulating the game.
94
- - you can have multiple encoders -- one encoder sending data to a worker thread -- another encoder sending data to the serverside.
95
- - **update the encoder's bindings anytime.**
114
+ - 🍏 **use the core facilities directly,** without the ui or multiplayer.
96
115
  ```ts
97
- // the new bindings must be schema-compatible or an error is thrown.
98
- encoder.bindings = {
99
- forward: "KeyE",
100
- jump: "Space",
101
- look: "gamepad.axis.2"
102
- }
116
+ import {Controller, InputDecoder, KeyboardSource, PointerSource, Sources} from "@benev/tact"
117
+
118
+ const controller = new Controller({
119
+ bindings,
120
+ source: new Sources(new KeyboardSource(), new PointerSource()),
121
+ })
122
+
123
+ const decoder = new InputDecoder(bindings)
124
+
125
+ // call this in your gameloop:
126
+ const inputs = decoder.decode(controller.encode())
103
127
  ```
104
128
 
105
129
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@benev/tact",
3
- "version": "0.4.0-0",
4
- "description": "🎮 keybindings and couch co-op",
3
+ "version": "0.4.0-1",
4
+ "description": "🎮 from keypress to couch co-op",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
7
7
  "type": "module",
@@ -28,13 +28,14 @@
28
28
  "dependencies": {
29
29
  "@benev/math": "0.4.0-9",
30
30
  "@e280/kv": "^0.2.4",
31
- "@e280/stz": "^0.4.11"
31
+ "@e280/shiny": "^0.1.1",
32
+ "@e280/stz": "^0.4.14"
32
33
  },
33
34
  "devDependencies": {
34
35
  "@e280/hottie": "^0.1.7",
35
36
  "@e280/octo": "^0.1.7",
36
37
  "@e280/science": "^0.1.14",
37
- "@e280/scute": "^0.5.3",
38
+ "@e280/scute": "^0.5.4",
38
39
  "http-server": "^14.1.1",
39
40
  "npm-run-all": "^4.1.5",
40
41
  "typescript": "^7.0.2"
@@ -1,8 +1,23 @@
1
1
 
2
2
  import {dom} from "@e280/sly"
3
- import {setupDemoApp} from "./demo-app/element.js"
3
+ import {cycle, nap} from "@e280/stz"
4
+ import {presets} from "./presets.js"
5
+ import {setupTact} from "../lib/ui/deck/setup/tact.js"
4
6
 
5
- dom.register({
6
- DemoApp: setupDemoApp(),
7
+ const tact = await setupTact({presets, maxPlayers: 4})
8
+ tact.mouseKeyboard()
9
+ tact.gamepads("gamer")
10
+ tact.registerElements()
11
+
12
+ cycle(async() => {
13
+ const data = tact.deck.hub.encodeAll()
14
+ tact.visualizer.update(data)
15
+ await nap(1000 / 60)
7
16
  })
8
17
 
18
+ {
19
+ const input = dom<HTMLInputElement>('input[type="color"]')
20
+ input.value = "#ffbb00"
21
+ input.oninput = () => document.body.style.setProperty("--tact-prime", input.value)
22
+ }
23
+
package/s/demo/main.css CHANGED
@@ -59,17 +59,18 @@
59
59
  align-items: center;
60
60
 
61
61
  gap: 1em;
62
- padding: 2em;
62
+ padding: 0.5em;
63
+ padding-bottom: 8em;
63
64
 
64
65
  > * {
65
- width: 100%;
66
- max-width: 42em;
66
+ width: min(100%, 50em);
67
67
  }
68
68
 
69
69
  > header {
70
70
  padding: 0 2em;
71
71
  h1 small { font-size: 0.6em; font-weight: normal; }
72
72
  * + * { margin-top: 0.5em; }
73
+ label { padding-left: 1em; }
73
74
  }
74
75
 
75
76
  > section {
@@ -0,0 +1,54 @@
1
+
2
+ import {asBindings} from "../lib/input/types.js"
3
+ import {asPresets} from "../lib/ui/deck/types.js"
4
+
5
+ export const bindings = asBindings({
6
+ looking: {
7
+ horizontal: ["accumulate", "pointer.x"],
8
+ vertical: ["accumulate", "pointer.y"],
9
+ },
10
+ moving: {
11
+ forward: "KeyW",
12
+ backward: "KeyS",
13
+ leftward: "KeyA",
14
+ rightward: "KeyD",
15
+ },
16
+ interactions: {
17
+ use: "KeyE",
18
+ },
19
+ })
20
+
21
+ export const presets = asPresets<typeof bindings>({
22
+ standard: {label: "⌨️standard", bindings},
23
+ gamer: {label: "🎮gamer", bindings: {
24
+ looking: {
25
+ horizontal: ["*", ["dt"], "gamepad.axis.3", 100],
26
+ vertical: ["*", ["dt"], "gamepad.axis.4", 100],
27
+ },
28
+ moving: {
29
+ forward: ["remap", 0, -1, 0, 1, "gamepad.axis.2"],
30
+ backward: ["remap", 0, 1, 0, 1, "gamepad.axis.2"],
31
+ leftward: ["remap", 0, -1, 0, 1, "gamepad.axis.1"],
32
+ rightward: ["remap", 0, 1, 0, 1, "gamepad.axis.1"],
33
+ },
34
+ interactions: {
35
+ use: "gamepad.1",
36
+ },
37
+ }},
38
+ micro: {label: "🦠micro", bindings: {
39
+ looking: {
40
+ horizontal: ["*", ["dt"], ["+", "gamepad.1", ["-", "gamepad.4"]], 100],
41
+ vertical: ["*", ["dt"], ["+", "gamepad.2", ["-", "gamepad.3"]], 100],
42
+ },
43
+ moving: {
44
+ forward: ["remap", 0, -1, 0, 1, "gamepad.axis.2"],
45
+ backward: ["remap", 0, 1, 0, 1, "gamepad.axis.2"],
46
+ leftward: ["remap", 0, -1, 0, 1, "gamepad.axis.1"],
47
+ rightward: ["remap", 0, 1, 0, 1, "gamepad.axis.1"],
48
+ },
49
+ interactions: {
50
+ use: ["*", "gamepad.5", "gamepad.6"],
51
+ },
52
+ }},
53
+ })
54
+
@@ -35,12 +35,15 @@ export const GamepadApp = shadowElement(() => {
35
35
  }))
36
36
 
37
37
  const renderSample = ([code, value]: [string, number]) => html`
38
- <li style="${`--percent: ${value * 100}%;`}">
38
+ <li ?data-neg="${value < 0}" style="${`--percent: ${Math.abs(value) * 100}%;`}">
39
39
  <span>${code}</span>
40
40
  <span>${value.toFixed(3)}</span>
41
41
  </li>
42
42
  `
43
43
 
44
+ const sortSamples = (a: [string, number], b: [string, number]) =>
45
+ a[0].localeCompare(b[0])
46
+
44
47
  return html`
45
48
  <div class=plate>
46
49
  ${connected.size > 0 ? [...connected].map(({samples, source: {gamepad}}) => html`
@@ -49,14 +52,18 @@ export const GamepadApp = shadowElement(() => {
49
52
  <div class=stats>
50
53
  <span>index ${gamepad.index}</span>
51
54
  <span>connected ${gamepad.connected ? "yes" : "no"}</span>
52
- <span>mapping ${gamepad.mapping}</span>
55
+ <span>mapping "${gamepad.mapping}"</span>
53
56
  <span>vibrationActuator ${gamepad.vibrationActuator ? "yes" : "no"}</span>
54
57
  </div>
55
58
  <ul>
56
- ${[...samples].filter(([code]) => code.startsWith("gamepad.button")).map(renderSample)}
59
+ ${[...samples]
60
+ .sort(sortSamples)
61
+ .filter(([code]) => !code.startsWith("gamepad.axis")).map(renderSample)}
57
62
  </ul>
58
63
  <ul>
59
- ${[...samples].filter(([code]) => code.startsWith("gamepad.axis")).map(renderSample)}
64
+ ${[...samples]
65
+ .sort(sortSamples)
66
+ .filter(([code]) => code.startsWith("gamepad.axis")).map(renderSample)}
60
67
  </ul>
61
68
  </div>
62
69
  `) : html`
@@ -57,10 +57,14 @@ export default css`
57
57
  display: block;
58
58
  content: "";
59
59
  inset: 0;
60
- background: #f004;
60
+ background: #08f4;
61
61
  width: var(--percent);
62
62
  }
63
63
 
64
+ &[data-neg]::before {
65
+ background: #f004;
66
+ }
67
+
64
68
  > span {
65
69
  position: relative;
66
70
  z-index: 2;
@@ -15,7 +15,7 @@ export default template(import.meta.url, async orb => html`
15
15
  <meta charset="utf-8"/>
16
16
  <meta name="viewport" content="width=device-width,initial-scale=1"/>
17
17
  <meta name="darkreader-lock"/>
18
- <style>@layer base{html{background:#000}}</style>
18
+ <style>@layer base{html{background:#111}}</style>
19
19
 
20
20
  <link rel="icon" href="${dataSvgEmoji("🎮")}"/>
21
21
  <link rel="stylesheet" href="${orb.hashurl("main.css")}"/>
@@ -54,7 +54,16 @@
54
54
  }
55
55
 
56
56
  body {
57
- padding: 1em;
57
+ display: flex;
58
+ flex-direction: column;
59
+ align-items: center;
60
+
61
+ gap: 1em;
62
+ padding: 0.5em;
63
+
64
+ > * {
65
+ width: min(100%, 50em);
66
+ }
58
67
  }
59
68
  }
60
69
 
package/s/index.html.ts CHANGED
@@ -15,7 +15,7 @@ export default template(import.meta.url, async orb => html`
15
15
  <meta charset="utf-8"/>
16
16
  <meta name="viewport" content="width=device-width,initial-scale=1"/>
17
17
  <meta name="darkreader-lock"/>
18
- <style>@layer base{html{background:#000}}</style>
18
+ <style>@layer base{html{background:#111}}</style>
19
19
 
20
20
  <link rel="icon" href="${dataSvgEmoji("🎮")}"/>
21
21
  <link rel="stylesheet" href="${orb.hashurl("demo/main.css")}"/>
@@ -37,17 +37,24 @@ export default template(import.meta.url, async orb => html`
37
37
  </h1>
38
38
  <div>
39
39
  <blockquote>"from keypress to couch co-op"</blockquote>
40
- <p>
41
- <a href="./gamepad/">gamepad visualizer</a>.
40
+ <p class=links>
41
+ <a href="./gamepad/">gamepad visualizer</a>
42
+ —
43
+ <a href="https://github.com/benev-gg/tact">github</a>
44
+ —
45
+ <a href="https://benev.gg/">benev.gg</a>
42
46
  </p>
43
47
  <p>
44
- <a href="https://github.com/benev-gg/tact">github</a>.
45
- <a href="https://benev.gg/">benev.gg</a>.
48
+ <label>
49
+ <span>➣ choose your color:</span>
50
+ <input type="color"/>
51
+ </label>
46
52
  </p>
47
53
  </div>
48
54
  </header>
49
55
 
50
- <demo-app></demo-app>
56
+ <tact-deck></tact-deck>
57
+ <tact-visualizer></tact-visualizer>
51
58
  </body>
52
59
  </html>
53
60
  `)
package/s/lib/index.ts CHANGED
@@ -1,18 +1,29 @@
1
1
 
2
2
  export * from "./input/investigate/is-compatible.js"
3
-
4
3
  export * from "./input/sources/gamepad.js"
5
4
  export * from "./input/sources/keyboard.js"
6
5
  export * from "./input/sources/plain.js"
7
6
  export * from "./input/sources/pointer.js"
8
7
  export * from "./input/sources/sources.js"
9
8
  export * from "./input/sources/stick.js"
10
-
11
9
  export * from "./input/utils/pad/on-pad.js"
12
10
  export * from "./input/utils/pad/pad.js"
13
11
  export * from "./input/utils/is-down.js"
14
-
15
- export * from "./input/encoder.js"
12
+ export * from "./input/controller.js"
16
13
  export * from "./input/decoder.js"
14
+ export * from "./input/expression.js"
17
15
  export * from "./input/types.js"
18
16
 
17
+ export * from "./ui/deck/controls/controls.js"
18
+ export * from "./ui/deck/controls/types.js"
19
+ export * from "./ui/deck/setup/deck.js"
20
+ export * from "./ui/deck/setup/tact.js"
21
+ export * from "./ui/deck/auto-gamepads.js"
22
+ export * from "./ui/deck/collector.js"
23
+ export * from "./ui/deck/hub.js"
24
+ export * from "./ui/deck/types.js"
25
+ export * from "./ui/views/customize/view.js"
26
+ export * from "./ui/views/deck/view.js"
27
+ export * from "./ui/views/controllers/view.js"
28
+ export * from "./ui/views/visualizer/view.js"
29
+
@@ -1,22 +1,23 @@
1
1
 
2
2
  import {deepFreeze} from "@e280/stz"
3
3
  import {Sampler} from "./utils/sampler.js"
4
- import {encodeData} from "./data/encode.js"
4
+ import {Intent} from "./data/intent/types.js"
5
5
  import {evaluate} from "./evaluate/evaluate.js"
6
+ import {encodeIntents} from "./data/intent/encode.js"
7
+ import {Bindings, Rebindings, Source} from "./types.js"
6
8
  import {EvaluationContext} from "./evaluate/context.js"
7
9
  import {investigate} from "./investigate/investigate.js"
8
- import {Bindings, InputData, Intent, Rebindings, Source} from "./types.js"
9
10
 
10
- export class InputEncoder<B extends Bindings = any> {
11
+ export class Controller<B extends Bindings = any> {
11
12
  #sampler
12
- #bindings
13
+ #bindings: Rebindings<B>
13
14
  #investigation
14
15
  #context
15
16
 
16
- constructor(source: Source, bindings: B) {
17
- this.#bindings = deepFreeze(structuredClone(bindings)) as any as Rebindings<B>
17
+ constructor(options: {source: Source, bindings: B}) {
18
+ this.#bindings = deepFreeze(structuredClone(options.bindings)) as any as Rebindings<B>
18
19
  this.#investigation = investigate(this.#bindings)
19
- this.#sampler = new Sampler(source)
20
+ this.#sampler = new Sampler(options.source)
20
21
  this.#context = new EvaluationContext()
21
22
  }
22
23
 
@@ -27,17 +28,13 @@ export class InputEncoder<B extends Bindings = any> {
27
28
  set bindings(b: Rebindings<B>) {
28
29
  const bindings = deepFreeze(structuredClone(b)) as Rebindings<B>
29
30
  const fresh = investigate(bindings)
31
+ const goodHash = this.#investigation.hash
30
32
 
31
- if (fresh.hash !== this.#investigation.hash)
33
+ if (fresh.hash !== goodHash)
32
34
  throw new Error("incompatible bindings")
33
35
 
34
36
  this.#bindings = bindings
35
37
  this.#investigation.rootList = fresh.rootList
36
- this.#context = new EvaluationContext()
37
- }
38
-
39
- encode(time = performance.now()): InputData {
40
- return encodeData(this.#investigation.hash, [...this.evaluate(time)])
41
38
  }
42
39
 
43
40
  *evaluate(time = performance.now()) {
@@ -50,13 +47,24 @@ export class InputEncoder<B extends Bindings = any> {
50
47
  for (const {code, value} of samples)
51
48
  this.#context.latestValues.set(code, value)
52
49
 
53
- for (const [id, expression] of this.#investigation.rootList.entries())
54
- yield {id, value: evaluate(this.#context, id, expression)} as Intent
50
+ for (const [id, expression] of this.#investigation.rootList.entries()) {
51
+ const value = evaluate(this.#context, expression)
52
+ if (value !== 0)
53
+ yield {id, value} as Intent
54
+ }
55
55
 
56
56
  for (const {code, value} of samples)
57
57
  this.#context.previousValues.set(code, value)
58
58
  }
59
59
 
60
+ encode(time = performance.now()) {
61
+ return encodeIntents(this.#investigation.hash, [...this.evaluate(time)])
62
+ }
63
+
64
+ clear() {
65
+ void this.#sampler.take()
66
+ }
67
+
60
68
  dispose() {
61
69
  return this.#sampler.dispose()
62
70
  }
@@ -0,0 +1,3 @@
1
+
2
+ export const endian = false
3
+
@@ -1,8 +1,9 @@
1
1
 
2
- import {Intent} from "../types.js"
3
- import {endian, sizeHash, sizeId, sizeValue} from "./params.js"
2
+ import {Intent} from "./types.js"
3
+ import {endian} from "../endian.js"
4
+ import {sizeHash, sizeId, sizeValue} from "./sizes.js"
4
5
 
5
- export function decodeData(buffer: ArrayBuffer) {
6
+ export function decodeIntents(buffer: ArrayBuffer) {
6
7
  const intents: Intent[] = []
7
8
  const dv = new DataView(buffer)
8
9
  let cursor = 0
@@ -0,0 +1,25 @@
1
+
2
+ import {Intent} from "./types.js"
3
+ import {endian} from "../endian.js"
4
+ import {sizeHash, sizeId, sizeIntent, sizeValue} from "./sizes.js"
5
+
6
+ export function encodeIntents(hash: number, intents: Intent[]) {
7
+ const byteCount = sizeHash + (intents.length * sizeIntent)
8
+ const buffer = new ArrayBuffer(byteCount)
9
+ const dv = new DataView(buffer)
10
+ let cursor = 0
11
+
12
+ dv.setUint32(cursor, hash, endian)
13
+ cursor += sizeHash
14
+
15
+ for (const intent of intents) {
16
+ dv.setUint16(cursor, intent.id, endian)
17
+ cursor += sizeId
18
+
19
+ dv.setFloat32(cursor, intent.value, endian)
20
+ cursor += sizeValue
21
+ }
22
+
23
+ return buffer
24
+ }
25
+
@@ -1,7 +1,6 @@
1
1
 
2
- export const endian = false
3
2
  export const sizeHash = 4
4
3
  export const sizeId = 2
5
4
  export const sizeValue = 4
6
- export const sizeIntention = sizeId + sizeValue
5
+ export const sizeIntent = sizeId + sizeValue
7
6
 
@@ -0,0 +1,6 @@
1
+
2
+ export type Intent = {
3
+ id: number
4
+ value: number
5
+ }
6
+
@@ -0,0 +1,32 @@
1
+
2
+ import {Parcel} from "./types.js"
3
+ import {endian} from "../endian.js"
4
+ import {sizeHeader, sizeLength, sizePlayerId} from "./sizes.js"
5
+
6
+ export function decodeParcels(buffer: ArrayBuffer): Parcel[] {
7
+ const view = new DataView(buffer)
8
+ const parcels: Parcel[] = []
9
+ let cursor = 0
10
+
11
+ while (cursor < buffer.byteLength) {
12
+ if (buffer.byteLength - cursor < sizeHeader)
13
+ throw new Error("truncated header")
14
+
15
+ const playerId = view.getUint32(cursor, endian)
16
+ cursor += sizePlayerId
17
+
18
+ const length = view.getUint32(cursor, endian)
19
+ cursor += sizeLength
20
+
21
+ if (length > buffer.byteLength - cursor)
22
+ throw new Error("truncated data")
23
+
24
+ const intents = buffer.slice(cursor, cursor + length)
25
+ cursor += length
26
+
27
+ parcels.push({playerId: playerId, intents})
28
+ }
29
+
30
+ return parcels
31
+ }
32
+