Add Interstellar and Your Name pages

Interstellar: Gargantua with a time dilation clock (Earth today vs.
Miller's planet), TARS with his settings and remarks about the house,
the Endurance spinning at a solar-driven RPM while a Ranger docks, and
the tesseract's bookshelf with the time in binary dust and the Message's
first word in Morse on a watch.

Your Name: comet Tiamat splitting over Itomori's lake, and
kataware-doki, a countdown to sunset from sun.sun where two silhouettes
stand on the crater rim during the twilight hour.

HomeData gains sunset, sunrise and sun elevation (with an ISO time
parser); wrap() and typed() move to el512_pages.h. Share Tech Mono 22
gets the full Latin set. All pages are in the renderer, checked with
normal, busy and empty data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-19 18:59:00 +02:00
1 parent a4ce97d744
commit f46f7ab6c5
22 files changed
+1159 -110

No files matched your search

+2
View File
@@ -12,9 +12,11 @@
#include "el512_helpers.h"
#include "esphome/components/display/display.h"
#include "esphome/core/hal.h"
#include "interstellar.h"
#include "konosuba.h"
#include "steins.h"
#include "trek.h"
#include "yourname.h"
namespace esphome::el512 {
+14
View File
@@ -50,6 +50,10 @@ static HomeData sample(const std::string &scenario) {
d.rooms[1] = {"Voorkamer", 19.8f};
d.rooms[2] = {"Patrick", 20.5f};
d.rooms[3] = {"Badkamer", 22.1f};
// Sunset 40 minutes after the sample time: twilight.
d.sunset = 1792420645 + 40 * 60;
d.sunrise = 1792420645 + 17 * 3600;
d.sun_elevation = 3.5f;
if (scenario == "busy") {
d.weather = "lightning-rainy";
d.temp = -12.6f;
@@ -65,6 +69,8 @@ static HomeData sample(const std::string &scenario) {
"Thu 22|19:00|Dinner";
d.rooms[0] = {"Vloerverwarming", 23.9f};
d.rooms[1] = {"Stans & Paul", 18.2f};
d.sunset = 1792420645 + 3 * 3600 + 25 * 60;
d.sun_elevation = 24.0f;
}
// Today's solar curve up to now (14:37), for the world line chart.
for (int s = 7 * 4; s <= 14 * 4 + 2; s++) {
@@ -85,6 +91,8 @@ static std::vector<Page> pages() {
const konosuba::Fonts ks{f_ks_title, f_ks_big, f_ks_text, f_ks_pixel, f_ks_pixel_l, f_ks_jp, f_ks_jp_big, icons_l};
const steins::Fonts sg{f_sg_nixie, f_sg_title, f_cp_mono, f_cp_code, f_ks_pixel, f_sg_jp};
const trek::Fonts st{f_st_small, f_st_medium, f_st_large, f_ks_text, f_ks_pixel};
const interstellar::Fonts is{f_is_title, f_is_large, f_cp_mono, f_cp_code};
const yourname::Fonts yn{f_yn_jp, f_yn_hand, f_yn_clock, f_cp_mono};
return {
{"cyber_hud", {2000}, [=](auto &it, auto &d, auto now) { cyber::netrunner_hud(it, cp, d, now); }},
{"cyber_breach", {4500, 9000}, [=](auto &it, auto &, auto) { cyber::breach_protocol(it, cp); }},
@@ -103,6 +111,12 @@ static std::vector<Page> pages() {
{"st_roster", {1500}, [=](auto &it, auto &d, auto now) { trek::duty_roster(it, st, d, now); }},
{"st_warp", {2000}, [=](auto &it, auto &d, auto) { trek::warp_core(it, st, d); }},
{"st_log", {14000, 6000}, [=](auto &it, auto &d, auto now) { trek::captains_log(it, st, d, now); }},
{"is_gargantua", {3000}, [=](auto &it, auto &, auto now) { interstellar::gargantua(it, is, now); }},
{"is_tars", {3500, 38500}, [=](auto &it, auto &d, auto) { interstellar::tars(it, is, d); }},
{"is_endurance", {8000, 2000, 12000}, [=](auto &it, auto &d, auto now) { interstellar::endurance(it, is, d, now); }},
{"is_tesseract", {1700, 900}, [=](auto &it, auto &d, auto now) { interstellar::tesseract(it, is, d, now); }},
{"yn_comet", {14000, 6000}, [=](auto &it, auto &d, auto now) { yourname::comet(it, yn, d, now); }},
{"yn_twilight", {3000}, [=](auto &it, auto &d, auto now) { yourname::twilight(it, yn, d, now); }},
};
}
+5 -3
View File
@@ -2,7 +2,8 @@
"""Render the themed ESPHome pages to PNG on this PC, for checking layouts
without flashing and for example images.
Compiles the page code (components/el512/cyberpunk, konosuba, steins, trek)
Compiles the page code (components/el512/cyberpunk, konosuba, steins, trek,
interstellar, yourname)
natively with g++ against ESPHome's own display and font code (from the
installed esphome package) and the exact font bitmaps of the last
`esphome compile` (its generated main.cpp), then draws each page at given
@@ -29,8 +30,9 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
WORK = ROOT / ".render"
PAGE_SOURCES = ["cyberpunk", "konosuba", "steins", "trek"]
PAGE_HEADERS = ["el512_pages.h", "el512_helpers.h", "konosuba_sprites.h", "steins_sprites.h", "trek_sprites.h"]
PAGE_SOURCES = ["cyberpunk", "konosuba", "steins", "trek", "interstellar", "yourname"]
PAGE_HEADERS = ["el512_pages.h", "el512_helpers.h", "konosuba_sprites.h", "steins_sprites.h", "trek_sprites.h",
"yourname_sprites.h"]
ESPHOME_PARTS = ["core", "components/display", "components/font", "components/host", "components/time",
"components/lvgl", "components/graph"]
ESPHOME_SOURCES = ["components/display/display.cpp", "components/display/rect.cpp",
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env python3
"""Pixel art for the Your Name pages (components/el512/yourname.cpp).
Original 1-bit fan art: '#' is a lit pixel. Writes
components/el512/yourname_sprites.h and, with --preview, a magnified PNG.
python tools/yourname_sprites.py
python tools/yourname_sprites.py --preview sprites.png
"""
from konosuba_sprites import main, padded
SPRITES = {
# Shrine gate on the hill above the lake.
"TORII": [
"####################",
".##################.",
"...##..........##...",
"..################..",
"...##..........##...",
"...##..........##...",
"...##..........##...",
"...##..........##...",
"...##..........##...",
"..####........####..",
],
# Two silhouettes on the crater rim at twilight: him facing right...
"TAKI": [
"...####...",
"..######..",
"..######..",
"..#####...",
"...###....",
"..#####...",
".#######..",
".#######..",
".##.###...",
".##.###...",
"....###...",
"...####...",
"...#..#...",
"...#..#...",
"...#..#...",
"...#..#...",
"..##..##..",
],
# ... and her facing left, the cord tied in her hair, a skirt.
"MITSUHA": [
"...####...",
"..######..",
"..######..",
"...#####..",
"....###.##",
"...#####.#",
"..#######.",
"..#######.",
"...###.##.",
"..#####...",
".#######..",
".#######..",
"...#..#...",
"...#..#...",
"...#..#...",
"...#..#...",
"..##..##..",
],
}
for _name in SPRITES:
SPRITES[_name] = padded(SPRITES[_name])
if __name__ == "__main__":
main(SPRITES, "Your Name", "yourname_sprites.py", "yourname", __doc__)