diff --git a/sdk/commands/inputs.ts b/sdk/commands/inputs.ts index 8e4491c..a0296a9 100644 --- a/sdk/commands/inputs.ts +++ b/sdk/commands/inputs.ts @@ -1,4 +1,4 @@ -import { bitFields, uint16_t } from "@nmann/struct-buffer"; +import { bits, uint16_t } from "@nmann/struct-buffer"; export type EachSensor = { up: T; @@ -7,6 +7,8 @@ export type EachSensor = { left: T; }; +export type PanelName = keyof EachPanel; + export type EachPanel = { up_left: T; up: T; @@ -19,15 +21,14 @@ export type EachPanel = { down_right: T; }; -// TODO: This should be a bits object probably -export const StageInputs = bitFields(uint16_t, { - up_left: 1, +export const StageInputs = bits(uint16_t, { + up_left: 0, up: 1, - up_right: 1, - left: 1, - center: 1, - right: 1, - down_left: 1, - down: 1, - down_right: 1, + up_right: 2, + left: 3, + center: 4, + right: 5, + down_left: 6, + down: 7, + down_right: 8, }); diff --git a/ui/stage/fsr-panel.tsx b/ui/stage/fsr-panel.tsx index 004acd9..cd68cac 100644 --- a/ui/stage/fsr-panel.tsx +++ b/ui/stage/fsr-panel.tsx @@ -3,12 +3,18 @@ import type { SMXPanelTestData } from "../../sdk/commands/sensor_test"; interface EnabledProps { data: SMXPanelTestData; + active: boolean | undefined; } export function FsrPanel(props: EnabledProps) { const { bad_sensor_input, have_data_from_panel, sensor_level } = props.data; return ( -
+
([]); + const [panelStates, setPanelStates] = useState([]); useEffect( () => @@ -27,7 +27,7 @@ export function SimplePad({ dev }: Props) { panelStates.down_right, ]); }), - [dev], + [dev] ); return ( diff --git a/ui/stage/stage-test.tsx b/ui/stage/stage-test.tsx index 7b62567..2999ab5 100644 --- a/ui/stage/stage-test.tsx +++ b/ui/stage/stage-test.tsx @@ -1,15 +1,37 @@ import { useAtomValue, type Atom } from "jotai"; import { useEffect, useState } from "react"; -import type { SMXSensorTestData } from "../../sdk/commands/sensor_test"; +import type { + SMXPanelTestData, + SMXSensorTestData, +} from "../../sdk/commands/sensor_test"; import { requestTestData } from "../pad-coms"; import { FsrPanel } from "./fsr-panel"; +import { SmxStage } from "../../sdk"; +import { + StageInputs, + type EachPanel, + type PanelName, +} from "../../sdk/commands/inputs"; +import { HID_REPORT_INPUT_STATE } from "../../sdk/packet"; -export function StageTest({ - deviceAtom, -}: { - deviceAtom: Atom; -}) { - const device = useAtomValue(deviceAtom); +function useInputState(dev: HIDDevice | undefined) { + const [panelStates, setPanelStates] = useState< + EachPanel | undefined + >(); + useEffect(() => { + if (!dev) return; + function handleInputReport(e: HIDInputReportEvent) { + if (e.reportId !== HID_REPORT_INPUT_STATE) return; + const state = StageInputs.decode(e.data, true); + setPanelStates(state); + } + dev.addEventListener("inputreport", handleInputReport); + return () => dev.removeEventListener("inputreport", handleInputReport); + }, [dev]); + return panelStates; +} + +function useTestData(device: HIDDevice | undefined) { const [testData, setTestData] = useState(); useEffect(() => { @@ -29,14 +51,31 @@ export function StageTest({ return () => cancelAnimationFrame(handle); }, [device]); + return testData; +} + +export function StageTest({ + deviceAtom, +}: { + deviceAtom: Atom; +}) { + const device = useAtomValue(deviceAtom); + const testData = useTestData(device); + const inputState = useInputState(device); + if (!testData) { return null; } + const entries = Object.entries(testData.panels) as [ + PanelName, + SMXPanelTestData + ][]; + return (
- {Object.entries(testData.panels).map(([key, data]) => ( - + {entries.map(([key, data]) => ( + ))}
); diff --git a/ui/state.ts b/ui/state.ts index 56a8bc3..c7fe862 100644 --- a/ui/state.ts +++ b/ui/state.ts @@ -31,4 +31,4 @@ export const statusText$ = atom( ); /** write-only atom. write to this to append a line to statusText */ -export const nextStatusTextLine$ = atom(null, (_, set, line: string) => set(statusText$, (prev) => prev + line)); +export const nextStatusTextLine$ = atom(null, (_, set, line: string) => set(statusText$, (prev) => prev + "\n" + line)); diff --git a/ui/styles.css b/ui/styles.css index 47eb5f7..01f3c7f 100644 --- a/ui/styles.css +++ b/ui/styles.css @@ -81,13 +81,17 @@ button:focus { gap: 1em 1em; height: 20em; width: 20em; + margin-right: 1em; } .panel { outline: 2px solid #ddd; position: relative; } .panel.active { - background-color: yellow; + background-color: #00ff00; +} +.panel.commErr { + background-color: red; } .fsr { diff --git a/ui/ui.tsx b/ui/ui.tsx index 28a99ab..509fe69 100644 --- a/ui/ui.tsx +++ b/ui/ui.tsx @@ -14,7 +14,7 @@ export function UI() { devices.map((device) => { console.log(`Found device: ${device.productName}`); open_smx_device(device); - }), + }) ); } }, []); @@ -22,8 +22,8 @@ export function UI() { return ( <>

SMX Web Config

- +