fix: invert mouth curve (smile was rendering as frown); smoother blink

Parabola sign was backwards — positive curve bowed the center up, an
upside-down U. Also: lid reveal now sweeps bottom-up like a rising lid,
blink runs in smaller steps, and the pupil redraw waits until the lid
has actually cleared it instead of flashing through mid-blink.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mortdecai
2026-07-11 23:43:20 -04:00
parent 6dfa1d7fb4
commit 871a5f387f
+14 -8
View File
@@ -116,15 +116,19 @@ void setLids(int8_t pct) {
if (newH > oldH) {
tft.fillRect(cx - EYE_R, EYE_Y - EYE_R + oldH, 2 * EYE_R + 1, newH - oldH, BG);
} else if (newH < oldH) {
for (int y = EYE_Y - EYE_R + newH; y < EYE_Y - EYE_R + oldH; y++) {
// reveal bottom-up so the lid visually rises
for (int y = EYE_Y - EYE_R + oldH - 1; y >= EYE_Y - EYE_R + newH; y--) {
int dy = y - EYE_Y;
int w = (int)sqrt((float)(EYE_R * EYE_R - dy * dy));
tft.drawFastHLine(cx - w, y, 2 * w + 1, SCLERA);
}
tft.fillCircle(cx + cur.pdx, EYE_Y + cur.pdy, PUPIL_R, PUPIL);
tft.fillCircle(cx + cur.pdx - 8, EYE_Y + cur.pdy - 8, 7, SCLERA);
if (newH > 0)
tft.fillRect(cx - EYE_R, EYE_Y - EYE_R, 2 * EYE_R + 1, newH, BG);
// redraw pupil only once the lid has cleared it (no through-lid flash)
if (EYE_Y - EYE_R + newH <= EYE_Y + cur.pdy - PUPIL_R) {
tft.fillCircle(cx + cur.pdx, EYE_Y + cur.pdy, PUPIL_R, PUPIL);
tft.fillCircle(cx + cur.pdx - 8, EYE_Y + cur.pdy - 8, 7, SCLERA);
if (newH > 0)
tft.fillRect(cx - EYE_R, EYE_Y - EYE_R, 2 * EYE_R + 1, newH, BG);
}
}
}
cur.lid = pct;
@@ -138,7 +142,8 @@ void drawMouth(int8_t curve, int8_t openR) {
tft.drawCircle(MOUTH_X, MOUTH_Y, openR + 1, SCLERA);
} else {
for (int x = -MOUTH_HW; x <= MOUTH_HW; x += 4) {
int y = MOUTH_Y - (int32_t)curve * (32 - (x * x) / 113) / 100;
// +curve bows the center DOWN (U = smile), -curve up (frown)
int y = MOUTH_Y - 16 + (int32_t)curve * (32 - (x * x) / 113) / 100;
tft.fillCircle(MOUTH_X + x, y, 5, SCLERA);
}
}
@@ -225,8 +230,9 @@ void bumpMood(int8_t d) {
void blinkOnce() {
int8_t base = moodLid();
setLids(100);
delay(90);
setLids(55); delay(20);
setLids(100); delay(70);
setLids(55); delay(20);
setLids(base);
}