35 lines
1.8 KiB
Markdown
35 lines
1.8 KiB
Markdown
# Crown control experiment (v0.9)
|
|
|
|
Firmware study of the O63 OTA (`upd_miwear.watch.o63.zip`) found how the crown
|
|
reaches quickapps: there is **no crown/rotary JS event** (no `onCrown`,
|
|
`onRotary`, wheel keyevents in `vela_quickapp.bin`), but the native layer
|
|
(`vela_ap.bin`, `inputmanager/lv_touchpad_wheel_interface.c` + the
|
|
`crown_scroll` input tag in `lvx_inputmanager.c`) routes crown rotation into
|
|
**scroll deltas of the focused scrollable container**.
|
|
|
|
So Snake listens to the crown indirectly:
|
|
|
|
- the page is wrapped in a full-screen vertical `scroll` component with the
|
|
dial centered inside it,
|
|
- `onscroll` fires for both crown rotation and finger scroll,
|
|
- the page converts each scroll delta into a **queued 90° turn**
|
|
(`snake.rotateDir`, already in the codebase): positive delta =
|
|
clockwise, negative = counterclockwise, `CROWN_STEP_PX` px of scroll per
|
|
turn,
|
|
- because turns are 90° relative steps, the crown always turns the snake
|
|
left/right regardless of where the head is pointing, and reversals are
|
|
structurally impossible (rotateDir never emits a 180° flip),
|
|
- the scroll position is actively re-centered (`scrollTo({ top: center })`)
|
|
after each event so the board never visually moves; only the idle-swipe
|
|
fallback path (when no scroll events arrive, e.g. some firmwares coalesce
|
|
crown scroll with the swipe handler) uses `onswipe` as before,
|
|
- swipes still work exactly as in 0.8; both input paths feed the same
|
|
two-slot turn queue.
|
|
|
|
Open questions that need the physical watch:
|
|
|
|
- does the Crown S4 emit scroll deltas with sign, and at what px granularity?
|
|
- does `onscroll` fire for crown motion at all on this firmware, or only for
|
|
touch scroll? If not, the `CROWN_STEP_PX` accumulator still catches the
|
|
swipe-path fallback but true crown control would need native access.
|