diff --git a/TODO.txt b/TODO.txt index ac23e63..0f369eb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -13,3 +13,6 @@ Hardware: Heatsink Extend Matrix (double?) Microphone + +MQTT: + register globally, so the values are already there when switching mode \ No newline at end of file diff --git a/src/BASICS.h b/src/BASICS.h index 75bac6d..37df22a 100644 --- a/src/BASICS.h +++ b/src/BASICS.h @@ -6,11 +6,6 @@ #define X true #define _ false -#define ____ 0 -#define QUAR 64 -#define HALF 128 -#define FULL 255 - typedef int64_t microseconds_t; typedef unsigned long milliseconds_t; diff --git a/src/Node.h b/src/Node.h index 6c4525b..9285266 100644 --- a/src/Node.h +++ b/src/Node.h @@ -117,8 +117,8 @@ inline void web_player(AsyncWebServerRequest *request) { request->send(400, "text/plain", "Missing 'index'"); return; } - double value = request->getParam("index")->value().toDouble(); - int index = (int) value; + const auto value = request->getParam("index")->value().toDouble(); + const auto index = static_cast(value); auto *response = request->beginResponseStream("text/html"); @@ -161,6 +161,7 @@ inline void web_player(AsyncWebServerRequest *request) { } inline void web_player_move(AsyncWebServerRequest *request) { + // ReSharper disable once CppJoinDeclarationAndAssignment double value; if (!request->hasParam("index")) { @@ -168,21 +169,21 @@ inline void web_player_move(AsyncWebServerRequest *request) { return; } value = request->getParam("index")->value().toDouble(); - int index = (int) value; + const auto index = static_cast(value); if (!request->hasParam("x")) { request->send(400, "text/plain", "Missing 'x'"); return; } value = request->getParam("x")->value().toDouble(); - int x = (int) value; + const auto x = static_cast(value); if (!request->hasParam("y")) { request->send(400, "text/plain", "Missing 'y'"); return; } value = request->getParam("y")->value().toDouble(); - int y = (int) value; + const auto y = static_cast(value); modeMove(index, x, y); @@ -190,6 +191,7 @@ inline void web_player_move(AsyncWebServerRequest *request) { } inline void web_player_fire(AsyncWebServerRequest *request) { + // ReSharper disable once CppJoinDeclarationAndAssignment double value; if (!request->hasParam("index")) { @@ -197,7 +199,7 @@ inline void web_player_fire(AsyncWebServerRequest *request) { return; } value = request->getParam("index")->value().toDouble(); - int index = (int) value; + const auto index = static_cast(value); modeFire(index); @@ -209,12 +211,12 @@ inline void web_setMode(AsyncWebServerRequest *request) { request->send(400, "text/plain", "Missing 'mode'"); return; } - double value = request->getParam("mode")->value().toDouble(); + auto value = request->getParam("mode")->value().toDouble(); if (isnan(value)) { request->send(400, "text/plain", "'mode' not a number"); return; } - setMode((ModeId) value); + setMode(static_cast(value)); request->send(200); } @@ -278,8 +280,6 @@ public: display.setup(); display.setBrightness(10); display.clear(); - display.foreground = Blue; - display.printf("Test"); } void loop() override { diff --git a/src/Vector.h b/src/Vector.h index d4c81df..926640f 100644 --- a/src/Vector.h +++ b/src/Vector.h @@ -7,49 +7,47 @@ class Vector { public: - double x; + double x; - double y; + double y; - double length; + double length; - Vector() : - x(0.0), y(0.0), length(0.0) { - // nothing - } + Vector() : x(0.0), y(0.0), length(0.0) { + // + } - Vector(double x, double y) : - x(x), y(y), length(sqrt(x * x + y * y)) { - // nothing - } + Vector(const double x, const double y) : x(x), y(y), length(sqrt(x * x + y * y)) { + // + } - static Vector polar(long degrees, double length) { - double radians = (double) degrees * DEG_TO_RAD; - return { - cos(radians) * length, - sin(radians) * length, - }; - } + static Vector polar(const long degrees, const double length) { + const auto radians = static_cast(degrees) * DEG_TO_RAD; + return { + cos(radians) * length, + sin(radians) * length, + }; + } - Vector plus(double _x, double _y) const { - return {x + _x, y + _y}; - } + Vector plus(const double _x, const double _y) const { + return {x + _x, y + _y}; + } - Vector plus(Vector vector) const { - return {x + vector.x, y + vector.y}; - } + Vector plus(const Vector vector) const { + return {x + vector.x, y + vector.y}; + } - Vector minus(double _x, double _y) const { - return {x - _x, y - _y}; - } + Vector minus(const double _x, const double _y) const { + return {x - _x, y - _y}; + } - Vector minus(Vector vector) const { - return {x - vector.x, y - vector.y}; - } + Vector minus(const Vector vector) const { + return {x - vector.x, y - vector.y}; + } - Vector multiply(double i) const { - return {x * i, y * i}; - } + Vector multiply(const double i) const { + return {x * i, y * i}; + } }; diff --git a/src/mode.cpp b/src/mode.cpp index 3b646cd..f3a57f5 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -2,14 +2,14 @@ #include "mode/Border/Border.h" #include "mode/Clock/Clock.h" -#include "mode/GameOfLife/GameOfLife.h" -#include "mode/Pong/Pong.h" -#include "mode/SpaceInvaders/SpaceInvaders.h" #include "mode/CountDown/CountDown.h" -#include "mode/Starfield/Starfield.h" -#include "mode/Matrix/Matrix.h" -#include "mode/Power/Power.h" #include "mode/Energy/Energy.h" +#include "mode/GameOfLife/GameOfLife.h" +#include "mode/Matrix/Matrix.h" +#include "mode/Pong/Pong.h" +#include "mode/Power/Power.h" +#include "mode/SpaceInvaders/SpaceInvaders.h" +#include "mode/Starfield/Starfield.h" #include "mode/Timer/Timer.h" Config config("/main.json"); @@ -147,6 +147,7 @@ void loadNewMode(Display& display) { } if (mode != nullptr) { info("Loaded mode: %s", mode->getName()); + mode->loadConfig(); mode->start(); } modeStepLastMicros = 0; diff --git a/src/mode/Border/Border.h b/src/mode/Border/Border.h index bd48687..ea0fdee 100644 --- a/src/mode/Border/Border.h +++ b/src/mode/Border/Border.h @@ -19,10 +19,10 @@ protected: void draw(Display& display) override { display.clear(); - display.drawLineWH(0, 0, display.width, 0, 1); - display.drawLineWH(0, 0, 0, display.height, 1); - display.drawLineWH(display.width - 1, display.height - 1, -display.width, 0, 1); - display.drawLineWH(display.width - 1, display.height - 1, 0, -display.height, 1); + display.drawLine(0, 0, display.width, 0, 1, White); + display.drawLine(0, 0, 0, display.height, 1, White); + display.drawLine(display.width - 1, display.height - 1, -display.width, 0, 1, White); + display.drawLine(display.width - 1, display.height - 1, 0, -display.height, 1, White); } }; diff --git a/src/mode/Clock/Clock.h b/src/mode/Clock/Clock.h index 6039d82..e0d0a51 100644 --- a/src/mode/Clock/Clock.h +++ b/src/mode/Clock/Clock.h @@ -27,9 +27,7 @@ protected: void draw(Display& display) override { display.clear(); - display.cursorX = 2; - display.cursorY = 1; - display.printf(true, "%2d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); + display.printf(2, 1, White, "%2d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); } }; diff --git a/src/mode/CountDown/CountDown.h b/src/mode/CountDown/CountDown.h index 726f8b7..dc10f9f 100644 --- a/src/mode/CountDown/CountDown.h +++ b/src/mode/CountDown/CountDown.h @@ -3,12 +3,10 @@ #define MAX_FIREWORKS 6 -#include - -#include "mode/Mode.h" #include "CountDownFirework.h" +#include "mode/Mode.h" -class CountDown : public Mode { +class CountDown final : public Mode { Firework fireworks[MAX_FIREWORKS]; @@ -45,7 +43,7 @@ public: return "CountDown (Numbers)"; } - void start() override { + void loadConfig() override { targetEpochSeconds = config.get("targetEpochSeconds", 1767222000); } @@ -74,11 +72,6 @@ protected: hours = static_cast(floor(diffSeconds / (60 * 60))) % 24; minutes = static_cast(floor(diffSeconds / 60)) % 60; seconds = static_cast(diffSeconds) % 60; - // Serial.printf("now=%4d.%02d.%02d (%ld), conf=%4d.%02d.%02d (%ld), diff=%f, %dd %2d:%02d:%02d\n", - // now.tm_year, now.tm_mon, now.tm_mday, nowEpochSeconds, - // target.tm_year, target.tm_mon, target.tm_mday, targetEpochSeconds, - // diffSeconds, - // days, hours, minutes, seconds); setMode(COUNTDOWN); if (days == 0) { loopLastDay(); @@ -148,7 +141,7 @@ private: void drawSleepingCount(Display& display) const { const auto sleepCount = days + 1; - display.printf(true, "%3d TAG%s", sleepCount, sleepCount == 1 ? "" : "E"); + display.printf(1, 1, White, "%3d %s", sleepCount, sleepCount == 1 ? "TAG" : "TAGE"); } void drawCountdownBars(Display& display) const { @@ -157,6 +150,19 @@ private: drawBar(display, 5, 30, 2, 60, seconds, Green, Yellow, 5); } + void drawCountdownNumbers(Display& display) const { + if (days >= 10) { + display.printf(1, 1, White, "%3d TAGE", days); + drawSecondsBar(display, seconds); + } else if (days > 0) { + display.printf(1, 1, White, "%d %2d:%02d", days, hours, minutes); + drawSecondsBar(display, seconds); + } else { + display.printf(1, 1, White, "%d:%02d:%02d", hours, minutes, seconds); + drawSubSecondsBar(display); + } + } + static void drawBar(Display& display, const uint8_t _y, const uint8_t _w, const uint8_t _h, const uint8_t max, const uint8_t value, const RGBA& color, const RGBA& tickColor, const uint8_t ticks) { const auto totalOnCount = static_cast(round(static_cast(value) / max * _w * _h)); uint8_t doneOnCount = 0; @@ -177,18 +183,8 @@ private: } } - void drawCountdownNumbers(Display& display) const { - if (days > 0) { - display.printf(true, "%02d. %2d:%02d", days, hours, minutes); - drawSecondsBar(display, seconds); - } else { - display.printf(true, "%2d:%02d:%02d", hours, minutes, seconds); - drawSubSecondsBar(display); - } - } - static void drawNoTime(Display& display) { - display.print("--:--:--"); + display.print(1, 1, Red, "--:--:--"); } static void drawSecondsBar(Display& display, const int seconds) { @@ -211,11 +207,9 @@ private: void drawYear(Display& display, const int year) const { if (plus1DayForSleepingCount) { - display.printf(true, "Emil 5"); - display.cursorX = 32 - 8; - display.cursorY = 0; + display.printf(1, 1, White, "EMIL 5"); } else { - display.printf(true, "%5d", year); + display.printf(1, 1, White, "%5d", year); } } diff --git a/src/mode/CountDown/CountDownFirework.h b/src/mode/CountDown/CountDownFirework.h index 226955f..5ea686b 100644 --- a/src/mode/CountDown/CountDownFirework.h +++ b/src/mode/CountDown/CountDownFirework.h @@ -89,7 +89,7 @@ public: case INITIAL: break; case RISE: - display.setPixel(static_cast(position.x), static_cast(position.y), Yellow.factor(DARKER_FACTOR)); + display.setPixel(position.x, position.y, Yellow.factor(DARKER_FACTOR)); break; case EXPLODE: drawParticle(display, +0.0, +1.0); @@ -132,7 +132,7 @@ private: void drawParticle(Display& display, const double x, const double y) const { const auto p = position.plus(x * explosion, y * explosion); - display.setPixel(static_cast(p.x), static_cast(p.y), color.factor(DARKER_FACTOR)); + display.setPixel(p.x, p.y, color.factor(DARKER_FACTOR)); } }; diff --git a/src/mode/Energy/Energy.h b/src/mode/Energy/Energy.h index a3f8ec4..16a37c4 100644 --- a/src/mode/Energy/Energy.h +++ b/src/mode/Energy/Energy.h @@ -72,23 +72,15 @@ protected: const auto amortisationPercent = selfConsumedKWh / PV_COST_AMORTISATION_KWH * 100; display.clear(); - display.cursorX = 0; - display.cursorY = 1; if (page == 0) { - display.foreground = Green; - display.printf(true, "%3.0f€", costSaved); - display.foreground = White; - display.printf(true, " %3.0f%%", amortisationPercent); + display.printf(0, 1, Green, "%3.0f€", costSaved); + display.printf(16, 1, White, "%3.0f%%", amortisationPercent); } else if (page == 1) { - display.foreground = Blue; - display.printf(true, "%3.0f", photovoltaicEnergyKWh); - display.foreground = Green; - display.printf(true, " %3.0f", selfConsumedKWh); + display.printf(0, 1, Blue, "%3.0f", photovoltaicEnergyKWh); + display.printf(16, 1, Green, "%3.0f", selfConsumedKWh); } else { - display.foreground = Yellow; - display.printf(true, "%4.0f", gridImportKWh); - display.foreground = Magenta; - display.printf(true, " %3.0f", gridExportKWh); + display.printf(0, 1, Orange, "%4.0f", gridImportKWh); + display.printf(16, 1, Magenta, "%3.0f", gridExportKWh); } } diff --git a/src/mode/Matrix/Matrix.h b/src/mode/Matrix/Matrix.h index 2767565..bf5eda3 100644 --- a/src/mode/Matrix/Matrix.h +++ b/src/mode/Matrix/Matrix.h @@ -49,10 +49,10 @@ protected: display.clear(); for (const auto& glyph: glyphs) { for (auto i = 0; i < glyph.length; ++i) { - display.setPixel(static_cast(round(glyph.x)), static_cast(round(glyph.y - i)), {64, 128, 64}); + display.setPixel(glyph.x, glyph.y - i, {64, 128, 64}); } if ((static_cast(round(glyph.y)) + glyph.length) % 2 == 0) { - display.setPixel(static_cast(round(glyph.x)), static_cast(round(glyph.y)), {0, 255, 0}); + display.setPixel(glyph.x, glyph.y, {0, 255, 0}); } } } diff --git a/src/mode/Mode.h b/src/mode/Mode.h index 2148973..10e1996 100644 --- a/src/mode/Mode.h +++ b/src/mode/Mode.h @@ -144,14 +144,14 @@ private: void realtimeMillisecondsUpdate() { if (lastSecond < 0 || lastSecond != now.tm_sec) { - lastSecond = (int8_t) now.tm_sec; + lastSecond = static_cast(now.tm_sec); lastSecondChange_Milliseconds = millis(); } realtimeMilliseconds = millis() - lastSecondChange_Milliseconds; } void handleTimers(const microseconds_t microseconds) { - for (Timer *timer = timers; timer < timers + countof(timers); timer++) { + for (auto timer = timers; timer < timers + countof(timers); timer++) { if (timer->interval > 0) { if (microseconds >= timer->rest) { timer->rest = timer->interval; diff --git a/src/mode/Pong/Pong.h b/src/mode/Pong/Pong.h index d702961..db8ac0f 100644 --- a/src/mode/Pong/Pong.h +++ b/src/mode/Pong/Pong.h @@ -94,11 +94,8 @@ protected: display.clear(); switch (status) { case SCORE: - display.foreground = Green; - display.printf(true, "%d", player0.score); - - display.foreground = Red; - display.printf(true, "%5d", player1.score); + display.printf(1, 1, Green, "%d", player0.score); + display.printf(28, 1, Red, "%d", player1.score); break; case PLAY: for (auto i = 0; i < player0.size; ++i) { @@ -111,17 +108,11 @@ protected: break; case OVER: if (player0.score > player1.score) { - display.foreground = Green; - display.printf(true, "W", player0.score); - - display.foreground = Red; - display.printf(true, " L", player1.score); + display.printf(1, 1, Green, "W", player0.score); + display.printf(28, 1, Red, "L", player1.score); } else if (player0.score < player1.score) { - display.foreground = Red; - display.printf(true, "L", player0.score); - - display.foreground = Green; - display.printf(true, " W", player1.score); + display.printf(1, 1, Red, "L", player0.score); + display.printf(26, 1, Green, "W", player1.score); } break; } @@ -155,11 +146,11 @@ private: void checkScoring() { if (ball.x < 0) { player1.score++; - Serial.println("Player 1 scored"); + Serial.printf("Player 1 scored: %d\n", player1.score); spawnBall(+1); } else if (ball.x >= width) { player0.score++; - Serial.println("Player 0 scored"); + Serial.printf("Player 0 scored: %d\n", player0.score); spawnBall(-1); } if (player0.score >= 10 || player1.score >= 10) { @@ -171,7 +162,6 @@ private: void paddleBounce() { const auto paddleHitPosition0 = ball.y - player0.y; if (ball.x >= 1 && ball.x < 2 && paddleHitPosition0 >= 0 && paddleHitPosition0 < player0.size) { - Serial.printf("Player 0 hit: paddleHitPosition0=%.2f\n", paddleHitPosition0); velocity.x = -velocity.x; velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition0 - 1)); ball.x = 3; @@ -179,7 +169,6 @@ private: } const auto paddleHitPosition1 = ball.y - player1.y; if (ball.x >= width - 2 && ball.x < width - 1 && paddleHitPosition1 >= 0 && paddleHitPosition1 < player1.size) { - Serial.printf("Player 1 hit: paddleHitPosition1=%.2f\n", paddleHitPosition1); velocity.x = -velocity.x; velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition1 - 1)); ball.x = width - 4; diff --git a/src/mode/Power/Power.h b/src/mode/Power/Power.h index 1425c77..0cbb612 100644 --- a/src/mode/Power/Power.h +++ b/src/mode/Power/Power.h @@ -58,11 +58,11 @@ protected: void draw(Display& display) override { display.clear(); - display.foreground = photovoltaicPowerW >= 100 ? Green : photovoltaicPowerW >= 20 ? Yellow : Red; - display.printf(true, "%3.0f", photovoltaicPowerW); + const auto pvColor = photovoltaicPowerW >= 100 ? Green : photovoltaicPowerW >= 20 ? Yellow : Red; + display.printf(0, 1, pvColor, "%3.0f", photovoltaicPowerW); - display.foreground = gridPowerW >= 20 ? Yellow : gridPowerW >= -20 ? Green : Magenta; - display.printf(true, " %4.0f", gridPowerW); + const auto gridColor = gridPowerW >= 20 ? Orange : gridPowerW >= -20 ? Green : Magenta; + display.printf(16, 1, gridColor, "%4.0f", gridPowerW); } }; diff --git a/src/mode/SpaceInvaders/SpaceInvaders.h b/src/mode/SpaceInvaders/SpaceInvaders.h index 08a44d9..422fa06 100644 --- a/src/mode/SpaceInvaders/SpaceInvaders.h +++ b/src/mode/SpaceInvaders/SpaceInvaders.h @@ -60,13 +60,13 @@ public: ~SpaceInvaders() override { free(swarmBegin); free(rocketsBegin); - }; + } const char *getName() override { return "Space Invaders"; } - void move(int index, int x, int y) override { + void move(int index, const int x, int y) override { randomEnabled = false; heroX = max(1, min(width - 2, heroX + x)); } @@ -78,7 +78,7 @@ public: protected: - void step(microseconds_t microseconds) override { + void step(const microseconds_t microseconds) override { stepRockets(microseconds); stepInvaders(microseconds); if (randomEnabled) { @@ -109,7 +109,7 @@ protected: private: - void stepRockets(microseconds_t microseconds) { + void stepRockets(const microseconds_t microseconds) { rocketRuntime += microseconds; if (rocketRuntime > 200000) { rocketRuntime = rocketRuntime % 200000; @@ -131,7 +131,7 @@ private: } } - void stepInvaders(microseconds_t microseconds) { + void stepInvaders(const microseconds_t microseconds) { swarmRuntime += microseconds; if (swarmDown && swarmRuntime > 500000) { @@ -158,7 +158,7 @@ private: } } - void randomStepHero(microseconds_t microseconds) { + void randomStepHero(const microseconds_t microseconds) { heroRuntime += microseconds; if (heroRuntime >= 50000) { heroRuntime = heroRuntime % 50000; @@ -182,7 +182,7 @@ private: } } - void shoot() { + void shoot() const { for (auto rocket = rocketsBegin; rocket < rocketsEnd; rocket++) { if (!rocket->alive && rocket->flash == 0) { rocket->alive = true; @@ -218,7 +218,7 @@ private: && swarmX + invader->x * 3 + 1 >= rocket->x; } - void drawInvaders(Display& display) { + void drawInvaders(Display& display) const { for (auto invader = swarmBegin; invader < swarmEnd; invader++) { if (invader->alive) { display.setPixel(swarmX + invader->x * 3 + 0, swarmY + invader->y * 2, Red); @@ -227,7 +227,7 @@ private: } } - void drawRockets(Display& display) { + void drawRockets(Display& display) const { for (auto rocket = rocketsBegin; rocket < rocketsEnd; rocket++) { if (rocket->alive) { display.setPixel(rocket->x, rocket->y, Yellow); @@ -241,7 +241,7 @@ private: } } - void drawHero(Display& display) { + void drawHero(Display& display) const { display.setPixel(heroX - 1, height - 1, Blue); display.setPixel(heroX + 0, height - 1, Blue); display.setPixel(heroX + 1, height - 1, Blue); diff --git a/src/mode/Timer/Timer.h b/src/mode/Timer/Timer.h index 3d986c1..99a0038 100644 --- a/src/mode/Timer/Timer.h +++ b/src/mode/Timer/Timer.h @@ -66,18 +66,16 @@ protected: void draw(Display& display) override { display.clear(); - display.cursorX = 1; - display.cursorY = 1; - if (days > 1) { - display.printf(true, "%4d TAGE", days); + if (days > 10) { + display.printf(1, 1, White, "%3d TAGE", days); } else if (days > 0) { - display.printf(true, "%2d. %02d:%02d", days, hours, minutes); + display.printf(1, 1, White, "%d %2d:%02d", days, hours, minutes); } else if (hours > 0) { - display.printf(true, "%2d:%02d:%02d", hours, minutes, seconds); + display.printf(1, 1, White, "%2d:%02d:%02d", hours, minutes, seconds); } else if (minutes > 0) { - display.printf(true, "%2d:%02d", minutes, seconds); + display.printf(1, 1, White, "%2d:%02d", minutes, seconds); } else { - display.printf(true, "%2d", seconds); + display.printf(1, 1, Orange, "%2d", seconds); } }