Commit Graph
7 Commits
Author SHA1 Message Date
JakubandClaude Sonnet 5 b067e95b24 fix(sim): accent-picker confirm was silently dropping the diacritic
Selecting a variant from the Hold-Enter accent popup (e.g. 'o' -> 'o with
acute') correctly stored the real UTF-8 character in the text buffer, but
the live-typing preview line rendered it as the plain base letter -- the
accent was invisible even though the data was right.

Root cause: DisplayDriver::translateUTF8ToBlocks() transliterates extended
Latin characters down to ASCII for display drivers whose font can't render
them; real boards with the pixel-perfect MiscFixedFont override it to a
plain passthrough once _single_font is set (SH1106Display.cpp etc).
SimDisplayDriverCanvas reuses that same MiscFixedFont/MiscFixedRenderer
(confirmed the popup's own preview renders diacritics correctly, since it
prints its own variants directly rather than through this path) but never
added the matching override, so every string routed through
translateUTF8ToBlocks() -- not just the keyboard preview -- silently lost
its diacritics.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 12:10:57 +02:00
JakubandClaude Sonnet 5 97a86216c6 feat(sim): board feature parity (reset/GPS/sensors/admin/keyboard) + input fixes
Rounds out the browser sim harness with the rest of the physical board's
interactions: a reset button (JS-driven, since board.reboot() is inert
under -sEXIT_RUNTIME=0), GPS input wired into a real LocationProvider via
new SimSensorManager, JS-settable battery/environment telemetry, an
admin/repeater-login test hook (sendRoomLogin against the default
"password"), and full physical-keyboard text entry (printable ASCII
passthrough into the existing KeyboardWidget, Tab->KEY_KB_ENTER submit).

Also fixes three real bugs found while exercising all of this in a real
browser:
- UITask.cpp's native-only stdin poll branch had no __EMSCRIPTEN__
  exclusion, so it also compiled into the wasm build and called a real,
  blocking window.prompt() on nearly every frame -- the actual cause of
  the reported time/controls jumping. Now gated to native only.
- 'n'/'p' were mapped as Next/Prev keyboard shortcuts, colliding with
  typing those literal letters. Removed the shortcuts; added explicit
  Next/Prev buttons to mesh.html (previously relied solely on them).
- Buttons grabbed native browser keyboard focus on click, so a later
  stray Enter/Space could silently re-trigger a previously-clicked button
  (e.g. Reset). mousedown now calls preventDefault() on all buttons.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 11:31:42 +02:00
JakubandClaude Sonnet 5 d7242ddc21 fix(sim): real text-size scaling + correct joystick-board menu hint
Two more real-vs-sim mismatches, found after seeing the rendered UI:

1. The Clock screen's big time display (setTextSize(2)) rendered at size 1
   -- SimDisplayDriverCanvas ignored setTextSize() entirely (a leftover
   no-op from the old system-font renderer) and never overrode
   getCharWidth()/getLineHeight(), so the big-digit layout math in
   UITask.cpp's drawBig() came out wrong even once print() itself gained
   real font support. Track _text_sz, scale both metrics by it (matching
   SSD1306Display's own getCharWidth()==6*_text_sz pattern), and pass it
   through to miscFixedPrint() in target.cpp instead of a hardcoded 1.

2. The Home carousel's "<PRESS_LABEL> to open" hint said "long press to
   open" -- true only for touchscreen-only boards with no dedicated Enter
   button (PRESS_LABEL's #if UI_HAS_JOYSTICK / #else split in
   examples/companion_radio/ui-new/UITask.cpp). The sim's D-pad + OK key
   behaves like a joystick board (a SHORT Enter press opens each page;
   holding it separately reaches the real context menu via
   handleLongPress()), so showing the touchscreen wording was both
   inaccurate and different from what a real joystick board like Heltec V3
   displays. Added SIM_PLATFORM to that #if alongside UI_HAS_JOYSTICK --
   UI_HAS_JOYSTICK itself stays unset, since its other two gates
   (begin()-ing/polling real joystick MomentaryButton objects) need
   hardware the sim's target.cpp doesn't declare.

Verified in real Chromium: Clock screen shows "08:11:10" at real double
size above the normal-size date line; Home carousel now says "press Enter
to open". Full regression clean: 3 native envs, wasm companion_radio, the
2-instance+repeater mesh demo, and the long-press context-menu test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 10:12:31 +02:00
JakubandClaude Sonnet 5 725e3b715e feat(sim): long-press context menu + pixel-perfect real font rendering
Two prototype polish fixes ahead of the website embed work:

1. Holding Enter (the sim's main way into "the rest of the options") did
   nothing -- the JS bridge's sim_enqueue_key() went straight to
   enqueueKey(), bypassing UITask::handleLongPress() entirely, so
   KEY_CONTEXT_MENU could never be reached. Add injectSimKeyLongPress()/
   sim_enqueue_key_longpress(), which does route through the real
   handleLongPress() (same code a real MomentaryButton(pin, 1000, ...)
   reaches), and wire up press-and-hold (buttons + Enter/Space key) in both
   web harnesses with the same 1000ms threshold real hardware uses.

2. SimDisplayDriverCanvas::print() drew text with the browser's own system
   font (ctx.fillText, '8px monospace') instead of the real bitmap font a
   MeshCore-Solo board renders with OLED_MISC_FIXED_FONT=1 (see
   solo/heltec_v3/platformio.ini). Vendor the real Adafruit_GFX (unmodified,
   from the same PlatformIO registry package a real board build pulls) into
   variants/sim/thirdparty/gfx/, and render print() through the real,
   shared src/helpers/ui/MiscFixedRenderer.h + MiscFixedFont.h -- byte-
   identical glyphs to real hardware, not a look-alike.

Verified in a real Chromium (Playwright): short Enter -> "CLOCK TOOLS",
held Enter -> "CLOCK FIELDS" (gotoDashboardConfig(), proving
KEY_CONTEXT_MENU is really reached); font renders as hard square pixels,
inverse/selected-row text still punches correctly through a filled bar.
Full regression re-run clean: all 3 native envs, wasm companion_radio, and
the two-instance + repeater mesh demo (relay routing, DM delivery).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 10:06:44 +02:00
JakubandClaude Sonnet 5 288a7d856b feat(sim): port examples/simple_room_server to variants/sim/
Mirrors the simple_repeater sim port exactly: headless (no DISPLAY_CLASS,
UITask.cpp excluded from the build), new sim_simple_room_server native env
plus build_wasm_room_server.sh, own SimFS root ./sim_data_room so its
identity storage can't collide with the companion or repeater instances on
the same page/cwd.

Verified beyond "it compiles": ran the native binary and confirmed a real
_main.id identity file gets persisted through the actual SimFS/IdentityStore
path, same as the other two sim targets.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 09:36:23 +02:00
JakubandClaude Sonnet 5 9cfb58a60b feat(sim): two-device messaging + repeater relay over a JS ether
Ports examples/simple_repeater to variants/sim/ (new sim_simple_repeater
native env + build_wasm_repeater.sh) and adds a JS "ether"
(variants/sim/web/mesh.html) that bridges two real companion_radio WASM
instances through a real simple_repeater instance in a strict A<->R<->B
topology (no direct A-B link), proving genuine relay routing rather than
a shortcut.

Also fixes multi-instance issues Phase 2's single-instance design never
surfaced: SimDisplayDriver's canvas context/id caching was keyed on a
single global instead of per-instance, and both wasm builds were missing
_malloc/_free/HEAPU8 runtime exports needed for the ether to poke bytes
into an instance's memory.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 09:14:15 +02:00
Jakub 8f4c92a217 feat(sim): add variants/sim/ — real companion_radio firmware on native + Emscripten
New board variant compiling the unmodified MyMesh/UITask/DataStore app
logic against real mesh::Radio/MainBoard/RTCClock/RNG interfaces, for
running the actual firmware outside embedded hardware:

- Native (plain g++, platform = native): ASCII-art display over stdout,
  stdin-driven input, local-disk-backed DataStore/IdentityStore.
- Emscripten/WASM (variants/sim/build_wasm.sh, since PlatformIO's native
  platform force-overrides any CC/CXX toolchain override back to system
  clang++): canvas-backed display, IDBFS-backed persistence across page
  reloads, JS-callable input via sim_enqueue_key(), emscripten_set_main_loop.

Real rweather/Crypto (AES128/SHA256/Ed25519) vendored unmodified and
proven working on both targets. variants/sim/web/index.html is a bare
verification harness, not the polished website embed.
2026-09-03 00:46:47 +02:00