Fix screen flicker: incremental menu redraw instead of full fillScreen every 60ms
This commit is contained in:
@@ -103,25 +103,38 @@ void Shell::begin() {
|
||||
add(makeActiveExploit());
|
||||
add(makeLogViewer());
|
||||
ui::bootSplash();
|
||||
drawMenu();
|
||||
drawMenu(true);
|
||||
}
|
||||
|
||||
void Shell::drawMenu() {
|
||||
void Shell::drawMenu(bool force) {
|
||||
auto& d = M5.Display;
|
||||
if (force) {
|
||||
d.fillScreen(ui::bg());
|
||||
ui::titleBar("Card-Crack", CARDCRACK_VERSION);
|
||||
// animated selection glow bar
|
||||
int y = ui::BODY_Y + sel * 12;
|
||||
uint16_t sb = ui::mix(theme::active().panel, theme::active().accent, 0.25f + 0.25f * ui::pulse(900));
|
||||
d.fillRect(0, y, ui::W, 12, sb);
|
||||
d.setTextColor(ui::fg(), ui::bg());
|
||||
d.setTextSize(1);
|
||||
for (int i = 0; i < nmods; i++) {
|
||||
bool cur = i == sel;
|
||||
uint16_t c = cur ? ui::accent() : ui::fg();
|
||||
d.setTextColor(c, cur ? sb : ui::bg());
|
||||
d.setCursor(5, ui::BODY_Y + i * 12 + 1);
|
||||
d.printf("%c %-9s %s", cur ? char(0x10) : ' ', mods[i]->name(), mods[i]->blurb());
|
||||
d.printf(" %-9s %s", mods[i]->name(), mods[i]->blurb());
|
||||
}
|
||||
ui::hintBar("; up . down enter open home-lab only");
|
||||
}
|
||||
// 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());
|
||||
}
|
||||
lastSel = sel;
|
||||
}
|
||||
|
||||
void Shell::enter(int i) {
|
||||
@@ -136,7 +149,7 @@ void Shell::enter(int i) {
|
||||
void Shell::back() {
|
||||
if (active >= 0) mods[active]->onExit();
|
||||
active = -1;
|
||||
drawMenu();
|
||||
drawMenu(true);
|
||||
}
|
||||
|
||||
void Shell::loop() {
|
||||
@@ -158,8 +171,8 @@ void Shell::loop() {
|
||||
}
|
||||
|
||||
if (active < 0) {
|
||||
// keep the menu selection breathing
|
||||
if (millis() - lastTick > 60) { lastTick = millis(); drawMenu(); }
|
||||
// keep the selection glow breathing — repaints only the bar strip (flicker-free)
|
||||
if (millis() - lastTick > 90) { lastTick = millis(); drawMenu(false); }
|
||||
return;
|
||||
}
|
||||
if (millis() - lastTick > 33) {
|
||||
|
||||
@@ -14,7 +14,7 @@ private:
|
||||
int active = -1; // -1 == in menu
|
||||
uint32_t lastTick = 0;
|
||||
void add(Module* m) { if (nmods < MAX) mods[nmods++] = m; }
|
||||
void drawMenu();
|
||||
void drawMenu(bool force = false);
|
||||
void enter(int i);
|
||||
void back();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user