@benev/tact 0.1.0-4 → 0.1.0-5
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.
- package/README.md +4 -3
- package/package.json +4 -4
- package/s/core/bindings/parts/defaults.ts +1 -0
- package/s/core/bindings/parts/lens-algo.ts +5 -1
- package/s/core/bindings/parts/lookup-proxies.ts +17 -0
- package/s/core/bindings/types.ts +1 -0
- package/s/core/devices/standard/gamepad.ts +1 -1
- package/s/core/devices/standard/pointer.ts +4 -0
- package/s/deck/components/components.ts +22 -0
- package/s/deck/components/deck-bindings/component.ts +99 -0
- package/s/{demo/ui/tact-demo → deck/components/deck-bindings}/style.css.ts +3 -1
- package/s/deck/components/deck-overlay/component.ts +51 -0
- package/s/deck/{views → components}/deck-overlay/style.css.ts +0 -2
- package/s/deck/components/framework.ts +17 -0
- package/s/deck/deck.ts +12 -7
- package/s/deck/index.ts +2 -2
- package/s/deck/parts/db.ts +1 -1
- package/s/demo/main.bundle.ts +7 -2
- package/s/demo/ui/theater/styles.css.ts +1 -0
- package/s/demo/ui/theater/view.ts +51 -44
- package/s/demo/ui/theater/virtual/view.ts +1 -1
- package/s/demo/ui/utils/loader.ts +2 -2
- package/s/index.html.ts +1 -1
- package/s/nubs/vpad/styles.css.ts +4 -4
- package/s/utils/types.ts +19 -0
- package/x/core/bindings/parts/defaults.js +1 -0
- package/x/core/bindings/parts/defaults.js.map +1 -1
- package/x/core/bindings/parts/lens-algo.js +5 -1
- package/x/core/bindings/parts/lens-algo.js.map +1 -1
- package/x/core/bindings/parts/lookup-proxies.d.ts +1 -0
- package/x/core/bindings/parts/lookup-proxies.js +19 -0
- package/x/core/bindings/parts/lookup-proxies.js.map +1 -0
- package/x/core/bindings/types.d.ts +1 -0
- package/x/core/devices/standard/gamepad.js +1 -1
- package/x/core/devices/standard/gamepad.js.map +1 -1
- package/x/core/devices/standard/pointer.js +4 -0
- package/x/core/devices/standard/pointer.js.map +1 -1
- package/x/deck/components/components.d.ts +14 -0
- package/x/deck/components/components.js +9 -0
- package/x/deck/components/components.js.map +1 -0
- package/x/deck/components/deck-bindings/component.d.ts +6 -0
- package/x/deck/components/deck-bindings/component.js +83 -0
- package/x/deck/components/deck-bindings/component.js.map +1 -0
- package/x/deck/components/deck-bindings/style.css.js +5 -0
- package/x/deck/components/deck-bindings/style.css.js.map +1 -0
- package/x/deck/components/deck-overlay/component.d.ts +6 -0
- package/x/deck/components/deck-overlay/component.js +44 -0
- package/x/deck/components/deck-overlay/component.js.map +1 -0
- package/x/deck/components/deck-overlay/style.css.js.map +1 -0
- package/x/deck/components/framework.d.ts +7 -0
- package/x/deck/components/framework.js +13 -0
- package/x/deck/components/framework.js.map +1 -0
- package/x/deck/deck.d.ts +8 -6
- package/x/deck/deck.js +12 -7
- package/x/deck/deck.js.map +1 -1
- package/x/deck/index.d.ts +2 -2
- package/x/deck/index.js +2 -2
- package/x/deck/index.js.map +1 -1
- package/x/deck/parts/db.d.ts +1 -1
- package/x/deck/parts/db.js +1 -1
- package/x/deck/parts/db.js.map +1 -1
- package/x/demo/main.bundle.js +8 -2
- package/x/demo/main.bundle.js.map +1 -1
- package/x/demo/main.bundle.min.js +90 -45
- package/x/demo/main.bundle.min.js.map +4 -4
- package/x/demo/ui/theater/styles.css.js +1 -0
- package/x/demo/ui/theater/styles.css.js.map +1 -1
- package/x/demo/ui/theater/view.d.ts +367 -1
- package/x/demo/ui/theater/view.js +25 -17
- package/x/demo/ui/theater/view.js.map +1 -1
- package/x/demo/ui/theater/virtual/view.js +1 -1
- package/x/demo/ui/theater/virtual/view.js.map +1 -1
- package/x/demo/ui/utils/loader.d.ts +2 -1
- package/x/demo/ui/utils/loader.js +2 -2
- package/x/demo/ui/utils/loader.js.map +1 -1
- package/x/index.html +3 -3
- package/x/index.html.js +1 -1
- package/x/nubs/vpad/styles.css.js +4 -4
- package/x/utils/types.d.ts +3 -0
- package/x/utils/types.js +3 -0
- package/x/utils/types.js.map +1 -0
- package/s/deck/views/deck-overlay/component.ts +0 -48
- package/s/deck/views/framework.ts +0 -14
- package/s/demo/ui/tact-demo/component.ts +0 -13
- package/x/deck/views/deck-overlay/component.d.ts +0 -2
- package/x/deck/views/deck-overlay/component.js +0 -40
- package/x/deck/views/deck-overlay/component.js.map +0 -1
- package/x/deck/views/deck-overlay/style.css.js.map +0 -1
- package/x/deck/views/framework.d.ts +0 -3
- package/x/deck/views/framework.js +0 -8
- package/x/deck/views/framework.js.map +0 -1
- package/x/demo/ui/tact-demo/component.d.ts +0 -4
- package/x/demo/ui/tact-demo/component.js +0 -12
- package/x/demo/ui/tact-demo/component.js.map +0 -1
- package/x/demo/ui/tact-demo/style.css.js +0 -3
- package/x/demo/ui/tact-demo/style.css.js.map +0 -1
- /package/x/deck/{views/deck-overlay → components/deck-bindings}/style.css.d.ts +0 -0
- /package/x/{demo/ui/tact-demo → deck/components/deck-overlay}/style.css.d.ts +0 -0
- /package/x/deck/{views → components}/deck-overlay/style.css.js +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
2
|
> [!CAUTION]
|
|
4
3
|
> ### 🚨🚨 TACT IS UNDER DEVELOPMENT!! 🚨🚨
|
|
5
4
|
> *everything is half-broken right now.. just gimmie a minute to finish coding this, will ya?*
|
|
@@ -246,14 +245,16 @@ the deck ties together all the important pieces of tact into a single user exper
|
|
|
246
245
|
["code", "KeyA", {
|
|
247
246
|
scale: 1,
|
|
248
247
|
invert: false,
|
|
249
|
-
deadzone: 0,
|
|
250
248
|
timing: ["direct"],
|
|
251
249
|
}]
|
|
252
250
|
```
|
|
253
251
|
- defaults shown
|
|
254
252
|
- `scale` is sensitivity, the value gets multiplied by this
|
|
255
253
|
- `invert` will invert a value by subtracting it from 1
|
|
256
|
-
- `
|
|
254
|
+
- `clamp` clamps the value with a lower and upper bound
|
|
255
|
+
- `range` restricts value to the given range, and remaps that range 0 to 1
|
|
256
|
+
- `bottom` zeroes the value if it's less than the given bottom value
|
|
257
|
+
- `top` clamps the value to an upper bound
|
|
257
258
|
- `timing` lets you specify special timing considerations
|
|
258
259
|
- `["direct"]` ignores timing considerations
|
|
259
260
|
- `["tap", 250]` only fires for taps under 250ms
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benev/tact",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-5",
|
|
4
4
|
"description": "keybindings and gamepad support for web games",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Chase Moskal <chasemoskal@gmail.com>",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@benev/math": "^0.2.0-4",
|
|
36
36
|
"@e280/kv": "^0.1.0",
|
|
37
|
-
"@e280/sly": "^0.2.0-
|
|
38
|
-
"@e280/strata": "^0.2.0-
|
|
39
|
-
"@e280/stz": "^0.2.
|
|
37
|
+
"@e280/sly": "^0.2.0-24",
|
|
38
|
+
"@e280/strata": "^0.2.0-14",
|
|
39
|
+
"@e280/stz": "^0.2.7"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@e280/science": "^0.1.2",
|
|
@@ -13,6 +13,10 @@ export const lensAlgo = (
|
|
|
13
13
|
|
|
14
14
|
function clippings(value) {
|
|
15
15
|
const {settings} = state
|
|
16
|
+
if (settings.clamp) {
|
|
17
|
+
const [bottom, top] = settings.clamp
|
|
18
|
+
value = Scalar.clamp(value, bottom, top)
|
|
19
|
+
}
|
|
16
20
|
if (settings.range) {
|
|
17
21
|
const [bottom, top] = settings.range
|
|
18
22
|
value = Scalar.isBetween(value, bottom, top)
|
|
@@ -24,7 +28,7 @@ export const lensAlgo = (
|
|
|
24
28
|
)
|
|
25
29
|
: 0
|
|
26
30
|
}
|
|
27
|
-
if (settings.bottom) value =
|
|
31
|
+
if (settings.bottom) value = (value < settings.bottom) ? 0 : value
|
|
28
32
|
if (settings.top) value = Math.min(settings.top, value)
|
|
29
33
|
return value
|
|
30
34
|
},
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// // TODO
|
|
2
|
+
//
|
|
3
|
+
// import {Bindings} from "../types.js"
|
|
4
|
+
//
|
|
5
|
+
// export function makeLookupProxies<B extends Bindings>(
|
|
6
|
+
// bindings: B,
|
|
7
|
+
// ) {
|
|
8
|
+
//
|
|
9
|
+
// const getModeProxy = (mode: string) => new Proxy(bindings[mode], {
|
|
10
|
+
// get: (_, action: string) => {},
|
|
11
|
+
// })
|
|
12
|
+
//
|
|
13
|
+
// return new Proxy(bindings, {
|
|
14
|
+
// get: (_, mode: string) => getModeProxy(mode),
|
|
15
|
+
// })
|
|
16
|
+
// }
|
|
17
|
+
//
|
package/s/core/bindings/types.ts
CHANGED
|
@@ -59,7 +59,7 @@ export class GamepadDevice extends SamplerDevice {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
#pollSticks(gamepad: Gamepad) {
|
|
62
|
-
const [leftX, leftY, rightX, rightY] = gamepad.axes
|
|
62
|
+
const [leftX = 0, leftY = 0, rightX = 0, rightY = 0] = gamepad.axes
|
|
63
63
|
|
|
64
64
|
const stickLeft = splitVector(
|
|
65
65
|
circularClamp(new Vec2(leftX, leftY), this.range)
|
|
@@ -31,6 +31,10 @@ export class PointerDevice extends SamplerDevice {
|
|
|
31
31
|
},
|
|
32
32
|
|
|
33
33
|
wheel: (event: WheelEvent) => {
|
|
34
|
+
this.sampleMap.set("pointer.wheel.right", 0)
|
|
35
|
+
this.sampleMap.set("pointer.wheel.left", 0)
|
|
36
|
+
this.sampleMap.set("pointer.wheel.up", 0)
|
|
37
|
+
this.sampleMap.set("pointer.wheel.down", 0)
|
|
34
38
|
for (const [code, value] of PointerDevice.wheelCodes(event))
|
|
35
39
|
this.setSample(code, value)
|
|
36
40
|
},
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
import {ob} from "@e280/stz"
|
|
3
|
+
import {Deck} from "../deck.js"
|
|
4
|
+
import {DropFirstParam} from "../../utils/types.js"
|
|
5
|
+
import {DeckOverlay} from "./deck-overlay/component.js"
|
|
6
|
+
import {DeckBindings} from "./deck-bindings/component.js"
|
|
7
|
+
|
|
8
|
+
const components = {DeckOverlay, DeckBindings}
|
|
9
|
+
|
|
10
|
+
export const deckComponents = (deck: Deck<any>) => (
|
|
11
|
+
ob(components)
|
|
12
|
+
.map(C => class extends C { deck = deck })
|
|
13
|
+
) as DeckComponents
|
|
14
|
+
|
|
15
|
+
export type DeckComponents = typeof components
|
|
16
|
+
|
|
17
|
+
export type DeckViews = {
|
|
18
|
+
[P in keyof DeckComponents]: (
|
|
19
|
+
DropFirstParam<DeckComponents[P]["view"]>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
|
|
2
|
+
import {html} from "lit"
|
|
3
|
+
import {Bytename} from "@e280/stz"
|
|
4
|
+
import {cssReset, view} from "@e280/sly"
|
|
5
|
+
|
|
6
|
+
import {Deck} from "../../deck.js"
|
|
7
|
+
import styleCss from "./style.css.js"
|
|
8
|
+
import {DeckComponent} from "../framework.js"
|
|
9
|
+
import {Port} from "../../../core/hub/port.js"
|
|
10
|
+
import {Profile} from "../../parts/catalog.js"
|
|
11
|
+
import {Atom, Bindings, Bracket} from "../../../core/bindings/types.js"
|
|
12
|
+
|
|
13
|
+
export class DeckBindings extends (
|
|
14
|
+
view(use => (deck: Deck<any>) => {
|
|
15
|
+
use.css(cssReset, styleCss)
|
|
16
|
+
use.attrs.strings.deck = "bindings"
|
|
17
|
+
const {db, hub} = deck
|
|
18
|
+
|
|
19
|
+
const catalog = db.$catalog()
|
|
20
|
+
const defaultProfile: Profile = {id: "default", label: "default", bindings: deck.baseBindings}
|
|
21
|
+
const allProfiles = [defaultProfile, ...catalog.profiles.values()]
|
|
22
|
+
const $selectedProfileId = use.signal<string>("default")
|
|
23
|
+
const profile = db.$catalog().getProfile($selectedProfileId()) ?? defaultProfile
|
|
24
|
+
|
|
25
|
+
function renderPort(port: Port<Bindings>, index: number) {
|
|
26
|
+
const portProfile = catalog.getProfileForPort(index) ?? defaultProfile
|
|
27
|
+
return html`
|
|
28
|
+
<div class=port>
|
|
29
|
+
<span>port ${index + 1}</span>
|
|
30
|
+
<select>
|
|
31
|
+
${allProfiles.map(profile => html`
|
|
32
|
+
<option
|
|
33
|
+
data-id="${profile.id}"
|
|
34
|
+
?selected="${profile.id === portProfile.id}">
|
|
35
|
+
${profile.label}
|
|
36
|
+
</option>
|
|
37
|
+
`)}
|
|
38
|
+
</select>
|
|
39
|
+
</div>
|
|
40
|
+
`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function renderBindingBracket([mode, bracket]: [mode: string, bracket: Bracket]) {
|
|
44
|
+
return html`
|
|
45
|
+
<div class=bracket>
|
|
46
|
+
<strong class=mode>${mode}</strong>
|
|
47
|
+
<div>${Object.entries(bracket).map(renderBinds)}</div>
|
|
48
|
+
</div>
|
|
49
|
+
`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function renderBinds([action, atom]: [action: string, atom: Atom]) {
|
|
53
|
+
return html`
|
|
54
|
+
<div class=bind>
|
|
55
|
+
<span class=action>${action}</span>
|
|
56
|
+
</div>
|
|
57
|
+
`
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const clickClone = async() => {
|
|
61
|
+
const {bindings} = profile
|
|
62
|
+
const label = Bytename.random(4)
|
|
63
|
+
const p = await db.createProfile(label, bindings)
|
|
64
|
+
$selectedProfileId(p.id)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const deleteProfile = (id: string) => async() => {
|
|
68
|
+
await db.deleteProfile(id)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const onSelected = (event: InputEvent) => {
|
|
72
|
+
const select = event.target as HTMLSelectElement
|
|
73
|
+
const id = select.value
|
|
74
|
+
$selectedProfileId(id)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return html`
|
|
78
|
+
<div class=portlist>
|
|
79
|
+
${hub.ports.map(renderPort)}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class=bindable>
|
|
83
|
+
<select @input="${onSelected}">
|
|
84
|
+
${allProfiles.map(p => html`
|
|
85
|
+
<option value="${p.id}" ?selected="${p.id === profile.id}">${p.label}</option>
|
|
86
|
+
`)}
|
|
87
|
+
</select>
|
|
88
|
+
<button @click="${clickClone}">clone</button>
|
|
89
|
+
<button ?disabled="${profile.id === defaultProfile.id}" @click="${deleteProfile(profile.id)}">delete</button>
|
|
90
|
+
<div class=bindings>
|
|
91
|
+
${Object.entries(profile.bindings).map(renderBindingBracket)}
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
`
|
|
95
|
+
})
|
|
96
|
+
.component(DeckComponent)
|
|
97
|
+
.props(el => [el.deck])
|
|
98
|
+
) {}
|
|
99
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
import {html} from "lit"
|
|
3
|
+
import {cssReset, view} from "@e280/sly"
|
|
4
|
+
import {Deck} from "../../deck.js"
|
|
5
|
+
import styleCss from "./style.css.js"
|
|
6
|
+
import {DeckComponent} from "../framework.js"
|
|
7
|
+
import {Device} from "../../../core/devices/device.js"
|
|
8
|
+
|
|
9
|
+
export class DeckOverlay extends (
|
|
10
|
+
view(use => (deck: Deck<any>) => {
|
|
11
|
+
use.css(cssReset, styleCss)
|
|
12
|
+
use.attrs.strings.deck = "overlay"
|
|
13
|
+
const {hub, deviceSkins, overlayVisibility: {$visible, $showLabels}} = deck
|
|
14
|
+
|
|
15
|
+
function renderDevice(device: Device) {
|
|
16
|
+
const skin = deviceSkins.get(device)
|
|
17
|
+
const style = `--color: ${skin.color};`
|
|
18
|
+
const next = () => hub.shimmy(device, 1)
|
|
19
|
+
const previous = () => hub.shimmy(device, -1)
|
|
20
|
+
return html`
|
|
21
|
+
<div class=device style="${style}">
|
|
22
|
+
<div class="primary row">
|
|
23
|
+
<button @click="${previous}"><</button>
|
|
24
|
+
<div class=icon>${skin.icon}</div>
|
|
25
|
+
<button @click="${next}">></button>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
${$showLabels() ? html`
|
|
29
|
+
<div class="secondary row">
|
|
30
|
+
<div class=label>${skin.label}</div>
|
|
31
|
+
</div>
|
|
32
|
+
` : null}
|
|
33
|
+
</div>
|
|
34
|
+
`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return html`
|
|
38
|
+
<div class=portlist ?data-active="${$visible()}">
|
|
39
|
+
${hub.ports.map((port, index) => html`
|
|
40
|
+
<div class=port>
|
|
41
|
+
<header>P${index + 1}</header>
|
|
42
|
+
${port.devices.array().map(renderDevice)}
|
|
43
|
+
</div>
|
|
44
|
+
`)}
|
|
45
|
+
</div>
|
|
46
|
+
`
|
|
47
|
+
})
|
|
48
|
+
.component(DeckComponent)
|
|
49
|
+
.props(el => [el.deck])
|
|
50
|
+
) {}
|
|
51
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
import {BaseElement} from "@e280/sly"
|
|
3
|
+
import {Deck} from "../deck.js"
|
|
4
|
+
|
|
5
|
+
export class DeckComponent extends BaseElement {
|
|
6
|
+
#deck: Deck<any> | undefined
|
|
7
|
+
|
|
8
|
+
get deck() {
|
|
9
|
+
if (!this.#deck) throw new Error(".deck was not set on component, but is required")
|
|
10
|
+
return this.#deck
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
set deck(d: Deck<any>) {
|
|
14
|
+
this.#deck = d
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
package/s/deck/deck.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import {Kv} from "@e280/kv"
|
|
3
|
+
import {dom} from "@e280/sly"
|
|
3
4
|
import {disposer, ob, range} from "@e280/stz"
|
|
4
5
|
|
|
5
6
|
import {Db} from "./parts/db.js"
|
|
@@ -8,13 +9,11 @@ import {Port} from "../core/hub/port.js"
|
|
|
8
9
|
import {Bindings} from "../core/bindings/types.js"
|
|
9
10
|
import {mergeBindings} from "./parts/merge-bindings.js"
|
|
10
11
|
import {MetaBindings, metaMode} from "../core/hub/types.js"
|
|
11
|
-
import {autoGamepads} from "../core/devices/auto-gamepads.js"
|
|
12
|
-
import {DeckOverlay} from "./views/deck-overlay/component.js"
|
|
13
12
|
import {makeMetaBindings} from "../core/hub/meta-bindings.js"
|
|
14
13
|
import {DeviceSkins} from "./parts/device-skins/device-skin.js"
|
|
15
14
|
import {OverlayVisibility} from "./parts/overlay-visibility.js"
|
|
16
15
|
import {PrimaryDevice} from "../core/devices/standard/primary.js"
|
|
17
|
-
import {
|
|
16
|
+
import {deckComponents, DeckViews} from "./components/components.js"
|
|
18
17
|
|
|
19
18
|
export type DeckOptions<B extends Bindings, MB extends MetaBindings = any> = {
|
|
20
19
|
kv: Kv
|
|
@@ -39,22 +38,28 @@ export class Deck<B extends Bindings, MB extends MetaBindings = any> {
|
|
|
39
38
|
?? makeMetaBindings(),
|
|
40
39
|
)
|
|
41
40
|
|
|
42
|
-
return new this(hub, db)
|
|
41
|
+
return new this(options.bindings, options.metaBindings, hub, db)
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
dispose = disposer()
|
|
46
45
|
deviceSkins = new DeviceSkins()
|
|
47
|
-
overlayVisibility: OverlayVisibility
|
|
48
46
|
primaryDevice = new PrimaryDevice()
|
|
47
|
+
overlayVisibility: OverlayVisibility
|
|
48
|
+
|
|
49
|
+
components = deckComponents(this)
|
|
49
50
|
|
|
50
|
-
views =
|
|
51
|
-
|
|
51
|
+
views = (
|
|
52
|
+
ob(this.components as any)
|
|
53
|
+
.map(c => (...a: any[]) => c.view(this, ...a))
|
|
54
|
+
) as DeckViews
|
|
52
55
|
|
|
53
56
|
registerComponents() {
|
|
54
57
|
dom.register(this.components)
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
constructor(
|
|
61
|
+
public baseBindings: B,
|
|
62
|
+
public baseMetaBindings: MB,
|
|
58
63
|
public hub: Hub<B, MB>,
|
|
59
64
|
public db: Db,
|
|
60
65
|
) {
|
package/s/deck/index.ts
CHANGED
|
@@ -7,8 +7,8 @@ export * from "./parts/local-storage-kv.js"
|
|
|
7
7
|
export * from "./parts/merge-bindings.js"
|
|
8
8
|
export * from "./parts/overlay-visibility.js"
|
|
9
9
|
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./
|
|
10
|
+
export * from "./components/deck-overlay/component.js"
|
|
11
|
+
export * from "./components/deck-overlay/style.css.js"
|
|
12
12
|
|
|
13
13
|
export * from "./deck.js"
|
|
14
14
|
|
package/s/deck/parts/db.ts
CHANGED
|
@@ -57,7 +57,7 @@ export class Db {
|
|
|
57
57
|
})
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
async
|
|
60
|
+
async assignPortProfile(index: number, profileId: string | null) {
|
|
61
61
|
return this.#mutateAndSave(catalog => {
|
|
62
62
|
catalog.portProfiles[index] = profileId
|
|
63
63
|
})
|
package/s/demo/main.bundle.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
|
|
2
2
|
import {dom} from "@e280/sly"
|
|
3
|
-
import {
|
|
3
|
+
import {Game} from "./game/game.js"
|
|
4
|
+
import {DemoTheater} from "./ui/theater/view.js"
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const game = await Game.load()
|
|
7
|
+
|
|
8
|
+
dom.register({
|
|
9
|
+
DemoTheater: class extends DemoTheater { game = game },
|
|
10
|
+
})
|
|
6
11
|
|
|
7
12
|
console.log("🎮 tact")
|
|
8
13
|
|
|
@@ -1,53 +1,60 @@
|
|
|
1
1
|
|
|
2
2
|
import {html} from "lit"
|
|
3
|
-
import {cssReset, view} from "@e280/sly"
|
|
4
3
|
import {repeat} from "lit/directives/repeat.js"
|
|
4
|
+
import {BaseElement, cssReset, view} from "@e280/sly"
|
|
5
5
|
|
|
6
6
|
import {styles} from "./styles.css.js"
|
|
7
7
|
import {Game} from "../../game/game.js"
|
|
8
8
|
import {VirtualDeviceView} from "./virtual/view.js"
|
|
9
9
|
import {VirtualDevice} from "../../game/parts/virtual-device.js"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
use
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
10
|
+
import {DeckBindings} from "../../../deck/components/deck-bindings/component.js"
|
|
11
|
+
|
|
12
|
+
export class DemoTheater extends (
|
|
13
|
+
view(use => (game: Game) => {
|
|
14
|
+
use.css(cssReset, styles)
|
|
15
|
+
use.mount(() => game.loop(60))
|
|
16
|
+
use.mount(() => game.deck.hub.on(use.render))
|
|
17
|
+
|
|
18
|
+
const addVirtual = () => game.plug(new VirtualDevice(game.deck.hub))
|
|
19
|
+
const revealOverlay = () => game.deck.overlayVisibility.bump()
|
|
20
|
+
|
|
21
|
+
const virtualDevices = game.deck.hub.ports
|
|
22
|
+
.flatMap(port => port.devices.array())
|
|
23
|
+
.filter(device => device instanceof VirtualDevice)
|
|
24
|
+
.map(device => ({device, skin: game.deck.deviceSkins.get(device)}))
|
|
25
|
+
.sort((a, b) => a.skin.label < b.skin.label ? -1 : 1)
|
|
26
|
+
|
|
27
|
+
return html`
|
|
28
|
+
<div class=surface>
|
|
29
|
+
${game.renderer.canvas}
|
|
30
|
+
${game.deck.views.DeckOverlay()}
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class=dlist>
|
|
34
|
+
${repeat(
|
|
35
|
+
virtualDevices,
|
|
36
|
+
d => d.skin.label,
|
|
37
|
+
({device, skin}) => {
|
|
38
|
+
return VirtualDeviceView
|
|
39
|
+
.props(game.deck.hub, device, skin)
|
|
40
|
+
.attr("style", `--color: ${skin.color};`)
|
|
41
|
+
.render()
|
|
42
|
+
},
|
|
43
|
+
)}
|
|
44
|
+
|
|
45
|
+
<button @click="${addVirtual}">
|
|
46
|
+
✨
|
|
47
|
+
</button>
|
|
48
|
+
|
|
49
|
+
<button @click="${revealOverlay}">
|
|
50
|
+
👁️
|
|
51
|
+
</button>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
${DeckBindings.view(game.deck)}
|
|
55
|
+
`
|
|
56
|
+
})
|
|
57
|
+
.component(class extends BaseElement { game!: Game })
|
|
58
|
+
.props(el => [el.game])
|
|
59
|
+
) {}
|
|
53
60
|
|
package/s/index.html.ts
CHANGED
|
@@ -85,11 +85,11 @@ button {
|
|
|
85
85
|
flex-direction: row-reverse;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
[x-code^="
|
|
88
|
+
[x-code^="gamepad.trigger"] {
|
|
89
89
|
width: 6em;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
[x-code^="
|
|
92
|
+
[x-code^="gamepad.bumper"] {
|
|
93
93
|
width: 4em;
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -121,11 +121,11 @@ button {
|
|
|
121
121
|
width: max(15cqw, 15cqh);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
[x-code^="
|
|
124
|
+
[x-code^="gamepad.trigger"] {
|
|
125
125
|
width: 9cqw;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
[x-code^="
|
|
128
|
+
[x-code^="gamepad.bumper"] {
|
|
129
129
|
width: 7cqw;
|
|
130
130
|
}
|
|
131
131
|
}
|
package/s/utils/types.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
// TODO replace these types when they're available in stz
|
|
3
|
+
|
|
4
|
+
export type First<A extends any[]> = (
|
|
5
|
+
A extends [infer X, ...any[]]
|
|
6
|
+
? X
|
|
7
|
+
: never
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
export type DropFirst<A extends any[]> = (
|
|
11
|
+
A extends [any, ...infer X]
|
|
12
|
+
? X
|
|
13
|
+
: never
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
export type DropFirstParam<Fn extends (...params: any[]) => any> = (
|
|
17
|
+
(...params: DropFirst<Parameters<Fn>>) => ReturnType<Fn>
|
|
18
|
+
)
|
|
19
|
+
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../../s/core/bindings/parts/defaults.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;AAElC,MAAM,UAAU,gBAAgB,CAAC,CAAC,EAAC,EAAC,QAAQ,CAAO;IAClD,OAAO;QACN,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QACZ,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,CAAC;KAC1C,CAAA;AACF,CAAC;AAED,SAAS,mBAAmB;IAC3B,OAAO;QACN,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,CAAC,QAAQ,CAAC;KAClB,CAAA;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,UAAiC,EAAE;IAClE,OAAO;QACN,GAAG,mBAAmB,EAAE;QACxB,GAAG,OAAO;KACV,CAAA;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../../s/core/bindings/parts/defaults.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;AAElC,MAAM,UAAU,gBAAgB,CAAC,CAAC,EAAC,EAAC,QAAQ,CAAO;IAClD,OAAO;QACN,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QACZ,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,CAAC;KAC1C,CAAA;AACF,CAAC;AAED,SAAS,mBAAmB;IAC3B,OAAO;QACN,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,CAAC,QAAQ,CAAC;KAClB,CAAA;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,UAAiC,EAAE;IAClE,OAAO;QACN,GAAG,mBAAmB,EAAE;QACxB,GAAG,OAAO;KACV,CAAA;AACF,CAAC"}
|
|
@@ -4,6 +4,10 @@ import { isPressed } from "./is-pressed.js";
|
|
|
4
4
|
import { defaultHoldTime } from "./defaults.js";
|
|
5
5
|
export const lensAlgo = (now, state, v) => pipe(v).line(function clippings(value) {
|
|
6
6
|
const { settings } = state;
|
|
7
|
+
if (settings.clamp) {
|
|
8
|
+
const [bottom, top] = settings.clamp;
|
|
9
|
+
value = Scalar.clamp(value, bottom, top);
|
|
10
|
+
}
|
|
7
11
|
if (settings.range) {
|
|
8
12
|
const [bottom, top] = settings.range;
|
|
9
13
|
value = Scalar.isBetween(value, bottom, top)
|
|
@@ -11,7 +15,7 @@ export const lensAlgo = (now, state, v) => pipe(v).line(function clippings(value
|
|
|
11
15
|
: 0;
|
|
12
16
|
}
|
|
13
17
|
if (settings.bottom)
|
|
14
|
-
value =
|
|
18
|
+
value = (value < settings.bottom) ? 0 : value;
|
|
15
19
|
if (settings.top)
|
|
16
20
|
value = Math.min(settings.top, value);
|
|
17
21
|
return value;
|