@benev/tact 0.4.0-0 → 0.4.0-2

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 +95 -66
  2. package/package.json +5 -4
  3. package/s/demo/main.bundle.ts +18 -3
  4. package/s/demo/main.css +40 -5
  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 +27 -14
  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 +53 -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 +25 -0
  83. package/s/lib/ui/views/visualizer/view.ts +17 -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 +812 -11
  90. package/x/demo/main.bundle.min.js.map +4 -4
  91. package/x/demo/main.css +40 -5
  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 +29 -16
  105. package/x/index.html.js +27 -14
  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 +32 -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 +24 -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 +12 -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,133 @@
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.**
6
+ i made tact because i want to make indie web game development easier. user input seems like it should be easy, but doing it well is actually really complex. especially when you start thinking of multiplayer and multithreading. my goal with tact is to tame the complexity and give people something elegant and flexible that "just works".
8
7
 
9
- ```ts
10
- npm install @benev/tact@next
11
- ```
8
+ 🌐 👉 ***https://tact.benev.gg/*** 👈 *try now*
12
9
 
10
+ 🖱 keyboards, mice, gamepads.
11
+ 🧩 expressive bindings json dsl.
12
+ 🎨 bindings are user-customizable.
13
+ 🫂 multiplayer and splitscreen capable.
14
+ 🧬 binary for efficient workers and networking.
15
+ 🎸 ready-to-rock drop-in user-interface.
16
+ ✍️ handcrafted by a human being.
13
17
 
14
18
 
15
- <br/>
16
19
 
17
- ## 🕹️ sources emit samples.
20
+ ![](https://i.imgur.com/dCAlD14.png)
18
21
 
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)*.
22
+ ![](https://i.imgur.com/IBW5Kkd.png)
31
23
 
32
24
 
33
25
 
34
26
  <br/>
35
27
 
36
- ## 🕹️ bindings describe controls.
28
+ ## 🎮 let's play.
37
29
 
38
- - **bindings are tiny programs,** a dsl in js data.
30
+ - 🍏 **install tact into your typescript project.**
31
+ ```sh
32
+ npm install @benev/tact@next
33
+ ```
34
+ - 🍏 **establish your app's standard bindings.**
39
35
  ```ts
40
36
  import {asBindings} from "@benev/tact"
37
+
38
+ const bindings = asBindings({
39
+ jump: "Space",
40
+ forward: "KeyW",
41
+ look: ["accumulate", "pointer.x"],
42
+ })
41
43
  ```
44
+ - 💡 *bindings is a tiny json dsl. see [expression.ts](./s/lib/input/expression.ts).*
45
+ - 🍏 **let's have two presets available to the user. one for gamepads.**
42
46
  ```ts
43
- const bindings = asBindings({
44
- forward: ["max", "KeyW", "ArrowUp"],
45
- jump: ["down", "Space"],
46
- look: ["accumulate", ["sum", "pointer.x"]],
47
+ import {asPresets} from "@benev/tact"
48
+
49
+ const presets = asPresets<typeof bindings>({
50
+ standard: {label: "⌨️standard", bindings},
51
+ gamepad: {label: "🎮gamer", bindings: {
52
+ jump: "gamepad.1",
53
+ forward: ["remap", 0, -1, 0, 1, "gamepad.axis.2"],
54
+ look: ["*", ["dt"], "gamepad.axis.3", 100],
55
+ }},
47
56
  })
48
57
  ```
49
- - see [expression.ts](./s/lib/input/expression.ts) to learn what's possible.
58
+ - 🍏 **setup tact.**
59
+ ```ts
60
+ import {setupTact} from "@benev/tact"
61
+
62
+ const tact = await setupTact({presets, maxPlayers: 4})
63
+ tact.mouseKeyboard()
64
+ tact.gamepads("gamepad")
65
+ tact.registerElements()
66
+ ```
67
+ - 💡 *set `maxPlayers` to 1 for single player.*
68
+ - 🍏 **put the `<tact-deck>` in your html page.**
69
+ ```html
70
+ <tact-deck></tact-deck>
71
+ ```
72
+ - 💡 *you also have each panel, `<tact-controllers>` and `<tact-customize>`.*
73
+ - 💡 *you can customize the colors with css:*
74
+ ```html
75
+ <style>
76
+ html {
77
+ --tact-prime: aqua;
78
+ --tact-bg: black;
79
+ }
80
+ </style>
81
+ ```
82
+ - 🎉 **now users can configure controllers and customize bindings!**
50
83
 
51
84
 
52
85
 
53
86
  <br/>
54
87
 
55
- ## 🕹️ encode and decode.
88
+ ## 🎮 encoding, decoding, and your game logic.
56
89
 
57
- - **the data is binary for efficient networking.**
90
+ - 🍏 **now it's time for the real action!**
58
91
  ```ts
59
- import {InputEncoder, InputDecoder} from "@benev/tact"
60
- ```
61
- ```ts
62
- const encoder = new InputEncoder(source, bindings)
63
- const decoder = new InputDecoder(bindings)
92
+ import {Collector} from "@benev/tact"
93
+
94
+ const collector = new Collector(bindings)
95
+
96
+ setInterval(() => {
97
+ const buffer = tact.deck.hub.encodeAll()
98
+ for (const {playerId, inputs} of collector.decodeAll(buffer)) {
99
+
100
+ // your game logic can read these handy input values.
101
+ inputs.jump.value // values are numbers 0 to 1.
102
+ inputs.jump.was // previous value (to detect up/down).
103
+ inputs.jump.sum // sum of values reported since last frame.
104
+
105
+ inputs.forward.value
106
+ inputs.look.value
107
+ }
108
+ }, 16.67)
64
109
  ```
65
- ```ts
66
- function frame() {
110
+ 💡 *you could stream the buffers across the network to a remote collector.*
111
+ 💡 *maybe imagine having the tact deck on the clientside, and the collector on the serverside (or a web worker!).*
67
112
 
68
- // data is an ArrayBuffer (you could stream it over the network).
69
- const data = encoder.encode()
70
113
 
71
- // decoding interprets the data as handy input objects.
72
- const inputs = decoder.decode(data)
73
114
 
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.
115
+ <br/>
78
116
 
79
- // this was so cool, let's do this forever.
80
- requestAnimationFrame(frame)
81
- }
117
+ ## 🎮 get down to brass tacks.
82
118
 
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.**
119
+ - 🍏 **use the core facilities directly,** without the ui or multiplayer.
96
120
  ```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
- }
121
+ import {Controller, InputDecoder, KeyboardSource, PointerSource, Sources} from "@benev/tact"
122
+
123
+ const controller = new Controller({
124
+ bindings,
125
+ source: new Sources(new KeyboardSource(), new PointerSource()),
126
+ })
127
+
128
+ const decoder = new InputDecoder(bindings)
129
+
130
+ // call this in your gameloop:
131
+ const inputs = decoder.decode(controller.encode())
103
132
  ```
104
133
 
105
134
 
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-2",
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
@@ -53,23 +53,51 @@
53
53
  background: var(--bg);
54
54
  }
55
55
 
56
+ html {
57
+ scrollbar-gutter: stable;
58
+ }
59
+
56
60
  body {
57
61
  display: flex;
58
62
  flex-direction: column;
59
63
  align-items: center;
60
64
 
61
65
  gap: 1em;
62
- padding: 2em;
66
+ padding: 0.5em;
67
+ padding-bottom: 8em;
63
68
 
64
69
  > * {
65
- width: 100%;
66
- max-width: 42em;
70
+ width: min(100%, 50em);
67
71
  }
68
72
 
69
73
  > header {
74
+ display: flex;
75
+ flex-wrap: wrap;
76
+ justify-content: space-between;
77
+ gap: 1em;
70
78
  padding: 0 2em;
71
- h1 small { font-size: 0.6em; font-weight: normal; }
72
- * + * { margin-top: 0.5em; }
79
+
80
+ h1 small {
81
+ font-size: 0.6em;
82
+ font-weight: normal;
83
+ }
84
+
85
+ blockquote {
86
+ opacity: 0.5;
87
+ font-style: italic;
88
+ padding-left: 1em;
89
+ }
90
+
91
+ label {
92
+ display: flex;
93
+ flex-direction: column;
94
+ align-items: end;
95
+ gap: 0.1em;
96
+ }
97
+
98
+ .links span {
99
+ opacity: 0.5;
100
+ }
73
101
  }
74
102
 
75
103
  > section {
@@ -78,6 +106,13 @@
78
106
  padding-left: 1em;
79
107
  }
80
108
  }
109
+
110
+ > footer {
111
+ padding: 1em 2em;
112
+ p {
113
+ opacity: 0.5;
114
+ }
115
+ }
81
116
  }
82
117
  }
83
118
 
@@ -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")}"/>
@@ -31,23 +31,36 @@ export default template(import.meta.url, async orb => html`
31
31
  </head>
32
32
  <body>
33
33
  <header>
34
- <h1>
35
- <strong>@benev/tact</strong>
36
- <small>v${orb.packageVersion()}</small>
37
- </h1>
38
34
  <div>
39
- <blockquote>"from keypress to couch co-op"</blockquote>
40
- <p>
41
- <a href="./gamepad/">gamepad visualizer</a>.
42
- </p>
43
- <p>
44
- <a href="https://github.com/benev-gg/tact">github</a>.
45
- <a href="https://benev.gg/">benev.gg</a>.
46
- </p>
35
+ <h1>
36
+ <strong>@benev/tact</strong>
37
+ <small>v${orb.packageVersion()}</small>
38
+ </h1>
39
+ <div>
40
+ <blockquote>"from keypress to couch co-op"</blockquote>
41
+ <p class=links>
42
+ <a href="./gamepad/">gamepad visualizer</a>
43
+ <span>—</span>
44
+ <a href="https://github.com/benev-gg/tact">github</a>
45
+ <span>—</span>
46
+ <a href="https://benev.gg/">benev.gg</a>
47
+ </p>
48
+ </div>
49
+ </div>
50
+ <div>
51
+ <label>
52
+ <input type="color"/>
53
+ <span>choose your color ☝️</span>
54
+ </label>
47
55
  </div>
48
56
  </header>
49
57
 
50
- <demo-app></demo-app>
58
+ <tact-deck></tact-deck>
59
+
60
+ <footer>
61
+ <p>binary data visualizer</p>
62
+ <tact-visualizer></tact-visualizer>
63
+ </footer>
51
64
  </body>
52
65
  </html>
53
66
  `)
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