fix(ui): resolver reinicio por falta de RAM limitando sprite a 25KB y ralentizar transicion a 16 cuadros suaves

This commit is contained in:
Sebastián Nieto 2026-09-21 23:54:50 -03:00
parent 9e7b749404
commit 3eae5061a4

View file

@ -1276,12 +1276,10 @@ inline void renderPage0ToSprite(TFT_eSprite &s, int x_offset, int y_slice, int s
} }
String numStr = (val <= -900.0f) ? "---" : String(val, digit); String numStr = (val <= -900.0f) ? "---" : String(val, digit);
s.loadFont(DSEG7_Modern_BoldItalic_34);
s.setTextColor(priCol, bgCol); s.setTextColor(priCol, bgCol);
s.setTextPadding(114); s.setTextPadding(114);
s.drawRightString(numStr.c_str(), qx + 152, qy + 70, 1); s.drawRightString(numStr.c_str(), qx + 152, qy + 70, 1);
s.setTextPadding(0); s.setTextPadding(0);
s.unloadFont();
} }
// Crosshair dividers // Crosshair dividers
@ -1356,12 +1354,10 @@ inline void renderPage1ToSprite(TFT_eSprite &s, int x_offset, int y_slice, int s
// Value text // Value text
String numStr = (val <= -900.0f) ? "---" : (isInt ? String((int)val) : String(val, 1)); String numStr = (val <= -900.0f) ? "---" : (isInt ? String((int)val) : String(val, 1));
s.loadFont(DSEG7_Modern_BoldItalic_34);
s.setTextColor(accentCol, cardBg); s.setTextColor(accentCol, cardBg);
s.setTextPadding(100); s.setTextPadding(100);
s.drawRightString(numStr.c_str(), cardX + 262, cardY + 22, 1); s.drawRightString(numStr.c_str(), cardX + 262, cardY + 22, 1);
s.setTextPadding(0); s.setTextPadding(0);
s.unloadFont();
s.setTextColor(0xC618, cardBg); s.setTextColor(0xC618, cardBg);
s.drawString("`C", cardX + 268, cardY + 32, 2); s.drawString("`C", cardX + 268, cardY + 32, 2);
@ -1369,23 +1365,23 @@ inline void renderPage1ToSprite(TFT_eSprite &s, int x_offset, int y_slice, int s
} }
// 100% Flicker-Free Double-Buffered Mobile Slide Transition // 100% Flicker-Free Double-Buffered Mobile Slide Transition
// Safe 25KB sprite with single font load and smooth ease-out pacing
inline void animateSlideTransition(bool swipeLeft) { inline void animateSlideTransition(bool swipeLeft) {
touchBeep(); const int slice_h = 40; // 320x40 = only 25KB (100% safe, leaves 70KB+ free for Bluetooth)
const uint8_t numSlices = 240 / slice_h; // exactly 6 slices
TFT_eSprite spr(&tft); TFT_eSprite spr(&tft);
int slice_h = 240; if (spr.createSprite(320, slice_h) == nullptr) {
// Try 320x240 full double-buffer first; if heap is tight, allocate two 320x120 slices return; // Safety fallback
if (spr.createSprite(320, 240) == nullptr) {
slice_h = 120;
if (spr.createSprite(320, 120) == nullptr) {
return; // Fallback: switch instantly without crashing if RAM is fully depleted
}
} }
const uint8_t FRAMES = 10; spr.loadFont(DSEG7_Modern_BoldItalic_34); // Loaded ONCE before animation loop!
// Smooth cubic ease-out deceleration curve
const int16_t step_shifts[FRAMES] = { 45, 92, 140, 186, 228, 264, 290, 308, 317, 320 }; const uint8_t FRAMES = 16;
uint8_t numSlices = (slice_h == 240) ? 1 : 2; // Cubic ease-out deceleration curve over 16 frames: smooth, visible and elegant
const int16_t step_shifts[FRAMES] = {
28, 62, 102, 144, 184, 218, 246, 268, 284, 296, 305, 311, 315, 318, 319, 320
};
for (uint8_t f = 0; f < FRAMES; f++) { for (uint8_t f = 0; f < FRAMES; f++) {
int16_t shift = step_shifts[f]; int16_t shift = step_shifts[f];
@ -1420,14 +1416,16 @@ inline void animateSlideTransition(bool swipeLeft) {
spr.fillCircle(167, 2, 2, (splitX <= 160) ? getThemePrimaryColor() : 0x5AEB); spr.fillCircle(167, 2, 2, (splitX <= 160) ? getThemePrimaryColor() : 0x5AEB);
} }
// Direct single SPI push: ZERO visual flicker! // Direct single SPI push per slice: ZERO visual flicker!
spr.pushSprite(0, y_slice); spr.pushSprite(0, y_slice);
} }
delay(8); yield(); // Feed watchdog and give Bluetooth scheduler CPU cycles
delay(14); // Pacing for smooth, readable transition (~360ms total)
} }
spr.deleteSprite(); spr.unloadFont(); // Unload font once at the end
spr.deleteSprite(); // Release the 25KB
} }
/*-------------------*/ /*-------------------*/