The daemon reads the Windows "now playing" media session (WinRT SMTC) and
adds np/nt/na to the BLE payload; the watch shows a play/pause glyph, a
scrolling title, artist and status. Best-effort and token-independent, so
it works even when the rate-limit data is unavailable.
Cyrillic titles: Styrene B has no Cyrillic glyphs, so the title/artist use
new composite fonts (font_styrene_cyr_{28,20}) — Latin from Styrene B,
Cyrillic + typographic punctuation from Montserrat, merged by lv_font_conv.
Latin titles stay on-brand; only Cyrillic falls back to Montserrat.
- daemon: read_now_playing() via winrt-Windows.Media.Control (lazy import,
never raises; PLAYING->1, PAUSED->2, else 0; title/artist truncated,
empty fields omitted)
- firmware: UsageData np_state/np_title/np_artist + parser; the real Now
Playing screen replaces the shared stub (SCREEN_NOWPLAYING)
- fonts: assets/Montserrat-Medium.ttf, font_styrene_cyr_{28,20}.c
- tools: patch_lvgl9_font.py (automates the 4 LVGL 9 font patches),
screenshot_win.py (Windows serial screenshot via pyserial + Pillow)
- README: document Cyrillic composite font generation
Verified on hardware (waveshare_amoled_206): idle state, a live Latin
title (scrolling), and Cyrillic (Prohozhdenie / Dunduk) all render.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Splash animation tools
Two-step pipeline for getting third-party 20×20 pixel animations onto the device.
1. Scrape
node scrape_claudepix.js
Fetches the manifest from claudepix.vercel.app/app.js, then each animation's
HTML file, evaluates the embedded JS in a Node VM context (loading the same
creature-engine.js the site uses), and writes resolved frame data to
tools/claudepix_data/*.json.
Each output file looks like:
{
"filename": "idle_breathe.html",
"name": "idle breathe",
"category": "Idle",
"description": "...",
"frame_count": 17,
"frames": [{ "hold": 500, "grid": [[0,0,...],[0,1,1,...],...] }, ...]
}
Override URL or output dir with --base and --out.
2. Convert to C
node convert_to_c.js
Reads tools/claudepix_data/*.json and emits a single
firmware/src/splash_animations.h with:
splash_<ident>_frames[N][400]— per-frame cell codes (0 = empty, 1 = body, 2 = eye)splash_<ident>_holds[N]— per-frame hold time in mssplash_anims[]— master table with name, category, frame count, pointersSPLASH_ANIM_COUNT
The firmware (splash.cpp) consumes this header to render and animate.
Re-running
The scraper is idempotent — re-run any time the source library updates. The converter overwrites the header. Rebuild firmware after running both.
License note
The scraper hits a public site without a stated license. Confirm reuse is appropriate for your case before redistributing the output.