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>
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>
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.