Add four animated KonoSuba ESPHome pages

Megumin's daily explosion, the Adventurers' Guild quest board (agenda,
weather, solar), Megumin's adventurer card and a party battle against a
giant toad with a live-data battle log. Original 1-bit pixel art lives in
tools/konosuba_sprites.py, which generates konosuba_sprites.h and can
render a preview PNG.

Home data and drawing helpers shared by the themed pages move to
el512_pages.h; the display gains dither_mask() for a dissolve-in intro.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-18 23:46:24 +02:00
1 parent 50ee17b3f6
commit e9b91c5628
11 files changed
+1655 -61

No files matched your search

+1 -32
View File
@@ -23,42 +23,11 @@ constexpr int W = 512, H = 256;
// --- Small helpers -----------------------------------------------------------
// Integer hash for repeatable pseudo-random effects (lowbias32).
uint32_t hash(uint32_t x) {
x ^= x >> 16;
x *= 0x7feb352d;
x ^= x >> 15;
x *= 0x846ca68b;
x ^= x >> 16;
return x;
}
uint32_t hash(uint32_t a, uint32_t b) { return hash(a * 0x9e3779b9u ^ hash(b)); }
std::string str(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
std::string str(const char *fmt, ...) {
char buf[96];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
return buf;
}
std::string upper(std::string s) {
for (auto &c : s)
c = (char) toupper((unsigned char) c);
return s;
}
using namespace fx;
std::string temp_text(float v, const char *unit = "°") { return std::isnan(v) ? "--" : str("%.1f%s", v, unit); }
std::string watts_text(float v) { return std::isnan(v) ? "--" : watts(v); }
int text_width(Display &it, display::BaseFont *font, const char *text) {
int x, y, w, h;
it.get_text_bounds(0, 0, text, font, TextAlign::TOP_LEFT, &x, &y, &w, &h);
return w;
}
const char *const CODES[] = {"1C", "55", "BD", "E9", "7A", "FF"};
constexpr int CODE_COUNT = 6;