Fix screen flicker: incremental menu redraw instead of full fillScreen every 60ms

This commit is contained in:
2026-09-24 20:51:48 -07:00
parent 7b15a34570
commit 43761677de
2 changed files with 31 additions and 18 deletions

View File

@@ -103,25 +103,38 @@ void Shell::begin() {
add(makeActiveExploit()); add(makeActiveExploit());
add(makeLogViewer()); add(makeLogViewer());
ui::bootSplash(); ui::bootSplash();
drawMenu(); drawMenu(true);
} }
void Shell::drawMenu() { void Shell::drawMenu(bool force) {
auto& d = M5.Display; auto& d = M5.Display;
d.fillScreen(ui::bg()); if (force) {
ui::titleBar("Card-Crack", CARDCRACK_VERSION); d.fillScreen(ui::bg());
// animated selection glow bar ui::titleBar("Card-Crack", CARDCRACK_VERSION);
int y = ui::BODY_Y + sel * 12; d.setTextColor(ui::fg(), ui::bg());
uint16_t sb = ui::mix(theme::active().panel, theme::active().accent, 0.25f + 0.25f * ui::pulse(900)); d.setTextSize(1);
d.fillRect(0, y, ui::W, 12, sb); for (int i = 0; i < nmods; i++) {
for (int i = 0; i < nmods; i++) { d.setCursor(5, ui::BODY_Y + i * 12 + 1);
bool cur = i == sel; d.printf(" %-9s %s", mods[i]->name(), mods[i]->blurb());
uint16_t c = cur ? ui::accent() : ui::fg(); }
d.setTextColor(c, cur ? sb : ui::bg()); ui::hintBar("; up . down enter open home-lab only");
d.setCursor(5, ui::BODY_Y + i * 12 + 1); }
// Flicker-free: repaint ONLY the selection-bar strip (previous + current rows)
static int lastSel = -1;
int rows[2] = { lastSel, sel };
for (int k = 0; k < 2; k++) {
int i = rows[k];
if (i < 0 || i >= nmods) continue;
bool cur = (i == sel);
int y = ui::BODY_Y + i * 12;
uint16_t sb = cur ? ui::mix(theme::active().panel, theme::active().accent, 0.25f + 0.25f * ui::pulse(900)) : ui::bg();
d.fillRect(0, y, ui::W, 12, sb);
d.setTextColor(cur ? ui::accent() : ui::fg(), sb);
d.setTextSize(1);
d.setCursor(5, y + 1);
d.printf("%c %-9s %s", cur ? char(0x10) : ' ', mods[i]->name(), mods[i]->blurb()); d.printf("%c %-9s %s", cur ? char(0x10) : ' ', mods[i]->name(), mods[i]->blurb());
} }
ui::hintBar("; up . down enter open home-lab only"); lastSel = sel;
} }
void Shell::enter(int i) { void Shell::enter(int i) {
@@ -136,7 +149,7 @@ void Shell::enter(int i) {
void Shell::back() { void Shell::back() {
if (active >= 0) mods[active]->onExit(); if (active >= 0) mods[active]->onExit();
active = -1; active = -1;
drawMenu(); drawMenu(true);
} }
void Shell::loop() { void Shell::loop() {
@@ -158,8 +171,8 @@ void Shell::loop() {
} }
if (active < 0) { if (active < 0) {
// keep the menu selection breathing // keep the selection glow breathing — repaints only the bar strip (flicker-free)
if (millis() - lastTick > 60) { lastTick = millis(); drawMenu(); } if (millis() - lastTick > 90) { lastTick = millis(); drawMenu(false); }
return; return;
} }
if (millis() - lastTick > 33) { if (millis() - lastTick > 33) {

View File

@@ -14,7 +14,7 @@ private:
int active = -1; // -1 == in menu int active = -1; // -1 == in menu
uint32_t lastTick = 0; uint32_t lastTick = 0;
void add(Module* m) { if (nmods < MAX) mods[nmods++] = m; } void add(Module* m) { if (nmods < MAX) mods[nmods++] = m; }
void drawMenu(); void drawMenu(bool force = false);
void enter(int i); void enter(int i);
void back(); void back();
}; };