Skip to content

feat: animate the corner creature on the usage screen - #144

Closed
TB1982 wants to merge 2 commits into
HermannBjorgvin:mainfrom
TB1982:feature/animated-corner-creature
Closed

feat: animate the corner creature on the usage screen#144
TB1982 wants to merge 2 commits into
HermannBjorgvin:mainfrom
TB1982:feature/animated-corner-creature

Conversation

@TB1982

@TB1982 TB1982 commented Aug 5, 2026

Copy link
Copy Markdown

No description provided.

TB1982 and others added 2 commits August 5, 2026 22:23
The corner slot held a static portrait of the creature (logo.h) while the
mini-animation engine sat one screen away, used only by the idle "Zzz" panel.
Same character, same 80x80 slot — now it moves, and it moves with the usage
rate, so the badge reads as a live indicator rather than decoration.

Groundwork: the mini engine was single-instance (module-level mini_* state),
so the idle panel already owned it. Moved that state into `struct splash_mini`
and handed callers a handle, letting the corner badge and the idle creature run
side by side with independent frame clocks.

Passing anim_name == NULL makes an instance follow usage_rate_group(),
re-picking on the same cadence as the full-screen splash. Each consumer carries
its own per-group slot cursor so the badge and the splash don't shuffle each
other's rotation along.

The badge only stands in for the portrait while data is fresh (view_state 2);
the pairing and idle screens keep the static image, since a dancing creature
there would claim a liveness the numbers don't have.

Verified on a Waveshare ESP32-S3-Touch-AMOLED-2.16: frames advance (two
framebuffer captures differ across the 80x80 slot), layout untouched, and all
five envs build.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds tools/make_custom_anims.js and a tools/custom_anims/ source directory
alongside the scraped set, plus three animations built from it: "fm listening"
(rate group 1) and "idle hearts" / "idle blossom" (group 0).

Nothing here draws a character. Each output takes a claudepix animation as its
base and overlays props that track the creature frame by frame — the head is
located per frame, so the headphones ride the bounce in dance_bounce rather
than being pinned to fixed coordinates. Every pixel of him is still claudepix's.

The new directory exists because the scraper owns claudepix_data/ outright and
may wipe it; a hand-composed file living there would vanish on the next
re-scrape. convert_to_c.js now takes a comma-separated --in list, defaulting to
both directories, and the generator clears stale outputs so a removed animation
doesn't linger as an orphan.

GROUP_MAX goes 4 -> 6 so the idle group can hold six. Idle is where the device
sits most of the day, and a creature with nothing to do is the one you actually
end up looking at.

Two art constraints found by rendering rather than by reasoning: props have to
be light, since the panel background is black and a dark prop is an invisible
one; and a 3x3 heart is illegible — its two top humps land on separate pixels
and read as antennae — so the heart is 5x3 and beats by brightness instead of
by resizing. Closed-eye hearts/blossom variants were also built and dropped:
expression_sleep already says "asleep", and a second sleeping animation spent
catalog space without adding a state readable at a glance.

Verified on a Waveshare ESP32-S3-Touch-AMOLED-2.16: the heart renders as
exactly 160 px of its lit color in the 80x80 corner badge — its 10 cells at
4x4 px each — and all five envs build. "fm listening" is in the catalog and
resolves into group 1, but has not yet been caught on screen: doing so needs a
sustained 0.10-0.20 %/min burn, which this session never held long enough.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@TB1982

TB1982 commented Aug 10, 2026

Copy link
Copy Markdown
Author

Closing this in favour of #153.

#153 brings its own corner mascot, so this one is superseded on the feature itself. It also removes tools/convert_to_c.js, which this branch modifies — that is a delete/modify conflict rather than something a rebase would sort out, and the 20×20 pipeline it was built on is not there any more.

No point leaving it in your queue. Thanks for taking a look at it while it was open.

(#151 is unaffected by any of this — it is a daemon-payload fix with no animation code in it.)

@TB1982 TB1982 closed this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant