Implement battery low mode rendering and update logic

This commit is contained in:
Joshua King
2026-02-10 17:09:05 -05:00
parent 0b627ffa75
commit b2752b8f72
2 changed files with 76 additions and 0 deletions

View File

@@ -36,12 +36,18 @@ void FaceRenderer::loop(const MoistureSensor& moisture, const BatterySensor& bat
updateMood(moisture.percent());
updateDeathMode(now);
updateBatteryLowMode(battery.percent());
if (_deadMode) {
renderDead(now, battery);
return;
}
if (_batteryLowMode) {
renderBatteryLow(now, battery);
return;
}
if (_mood == HAPPY) updateHappy(now);
else if (_mood == DRY) updateDry(now);
else updateTooWet(now);
@@ -76,6 +82,11 @@ void FaceRenderer::updateDeathMode(unsigned long now) {
}
}
void FaceRenderer::updateBatteryLowMode(int batteryPercent) {
// Enter nervous mode when battery is critically low (< 10%)
_batteryLowMode = (batteryPercent < 10);
}
void FaceRenderer::updateHappy(unsigned long now) {
if ((long)(now - _nextGazeMs) >= 0) {
_targetX = randRangeI8(-3, 3);
@@ -151,6 +162,48 @@ void FaceRenderer::renderDead(unsigned long now, const BatterySensor& battery) {
d.display();
}
void FaceRenderer::renderBatteryLow(unsigned long now, const BatterySensor& battery) {
auto &d = _display->oled();
d.clearDisplay();
// Nervous animation: eyes glance up at battery icon repeatedly
// Battery icon is at (110, 2) in top-right corner
// Eyes are centered at (40, 24) for left, (88, 24) for right
// Create a glancing pattern: look up at battery, then center, repeat
int glancePhase = (now / 800) % 3; // 3 phases: up, center, up
int pupilX = 0, pupilY = 0;
if (glancePhase == 0 || glancePhase == 2) {
// Look up toward battery icon (upper right)
pupilX = 3; // Look right
pupilY = -4; // Look up
} else {
// Brief center position between glances
pupilX = 0;
pupilY = -2; // Still slightly upward (worried/anxious)
}
// Draw eyes with pupils positioned
if (_blinking) {
drawEyesClosed();
} else {
drawEyesOpen(pupilX, pupilY);
}
// Worried eyebrows
drawBrowsWorried();
// Nervous mouth (wavy/uncertain)
drawMouthNervous();
// Draw battery icon in top-right corner (blinking)
_display->drawBatteryIcon(110, 2, battery.percent(), true);
d.display();
}
void FaceRenderer::renderNormal(unsigned long now, const BatterySensor& battery) {
auto &d = _display->oled();
d.clearDisplay();
@@ -212,6 +265,15 @@ void FaceRenderer::drawBrowsVerySad() {
d.drawLine(80, 18, 102, 12, 1);
}
void FaceRenderer::drawBrowsWorried() {
auto &d = _display->oled();
// Raised/arched worried eyebrows
d.drawLine(26, 14, 36, 10, 1);
d.drawLine(36, 10, 48, 12, 1);
d.drawLine(80, 12, 92, 10, 1);
d.drawLine(92, 10, 102, 14, 1);
}
void FaceRenderer::drawMouthHappy() {
auto &d = _display->oled();
for (int i = 0; i < 5; i++)
@@ -229,6 +291,15 @@ void FaceRenderer::drawMouthFlat() {
d.drawLine(52, 48, 76, 48, 1);
}
void FaceRenderer::drawMouthNervous() {
auto &d = _display->oled();
// Wavy/uncertain nervous mouth
d.drawLine(52, 48, 58, 47, 1);
d.drawLine(58, 47, 64, 48, 1);
d.drawLine(64, 48, 70, 47, 1);
d.drawLine(70, 47, 76, 48, 1);
}
void FaceRenderer::drawBubbles(int off) {
auto &d = _display->oled();
d.drawCircle(10 + off, 12, 4, 1);