Emil 5. Geburtstag + Creeper
This commit is contained in:
parent
0d73d112b1
commit
6b4ed1658c
@ -1,145 +1,180 @@
|
|||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
|
||||||
bool SYMBOLS[SYMBOL_COUNT][DISPLAY_CHAR_WIDTH * DISPLAY_CHAR_HEIGHT] = {
|
bool SYMBOLS[SYMBOL_COUNT][DISPLAY_CHAR_WIDTH * DISPLAY_CHAR_HEIGHT] = {
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, X, X,
|
_, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, X, X,
|
_, X, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_, _, _,
|
_, _, _,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
_, _, _,
|
_, _, _,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
_, _, _,
|
_, _, _,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_, _, _,
|
_, _, _,
|
||||||
_, _, _,
|
_, _, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, _, _,
|
_, _, _,
|
||||||
_, _, _,
|
_, _, _,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, _, _,
|
X, _, _,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
_, _, X,
|
_, _, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_, X, _,
|
_, X, _,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_, X, X,
|
_, X, X,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, X,
|
X, _, X,
|
||||||
_, X, _,
|
_, X, _,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, _, _,
|
X, _, _,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
},
|
},
|
||||||
// this must always be the last symbol (fallback)
|
{
|
||||||
{
|
X, _, X,
|
||||||
X, X, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, X, X,
|
||||||
X, X, X,
|
X, _, X,
|
||||||
X, X, X,
|
X, _, X,
|
||||||
X, X, X,
|
},
|
||||||
},
|
{
|
||||||
|
X, X, _,
|
||||||
|
X, _, X,
|
||||||
|
X, X, _,
|
||||||
|
X, X, _,
|
||||||
|
X, _, X,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
X, _, _,
|
||||||
|
X, _, _,
|
||||||
|
X, _, _,
|
||||||
|
X, _, _,
|
||||||
|
X, _, _,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
X, _, _,
|
||||||
|
X, _, _,
|
||||||
|
X, _, _,
|
||||||
|
X, _, _,
|
||||||
|
X, X, X,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_, _, _,
|
||||||
|
_, _, _,
|
||||||
|
_, _, _,
|
||||||
|
_, _, _,
|
||||||
|
_, _, _,
|
||||||
|
},
|
||||||
|
// this must always be the last symbol (fallback)
|
||||||
|
{
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,15 +5,21 @@
|
|||||||
#include "Adafruit_NeoPixel.h"
|
#include "Adafruit_NeoPixel.h"
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
|
|
||||||
#define SYMBOL_COUNT 20
|
#define SYMBOL_COUNT 26
|
||||||
|
|
||||||
|
#define SYMBOL_J 11
|
||||||
|
#define SYMBOL_X 12
|
||||||
#define SYMBOL_DASH 13
|
#define SYMBOL_DASH 13
|
||||||
#define SYMBOL_PERCENT 14
|
#define SYMBOL_PERCENT 14
|
||||||
|
|
||||||
#define SYMBOL_T 15
|
#define SYMBOL_T 15
|
||||||
#define SYMBOL_A 16
|
#define SYMBOL_A 16
|
||||||
#define SYMBOL_G 17
|
#define SYMBOL_G 17
|
||||||
#define SYMBOL_E 18
|
#define SYMBOL_E 18
|
||||||
|
#define SYMBOL_H 19
|
||||||
|
#define SYMBOL_R 20
|
||||||
|
#define SYMBOL_I 21
|
||||||
|
#define SYMBOL_L 22
|
||||||
|
#define SYMBOL_SPACE 23
|
||||||
|
|
||||||
#define DISPLAY_CHAR_WIDTH 3
|
#define DISPLAY_CHAR_WIDTH 3
|
||||||
#define DISPLAY_CHAR_HEIGHT 5
|
#define DISPLAY_CHAR_HEIGHT 5
|
||||||
@ -48,11 +54,10 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Display(uint8_t width, uint8_t height) :
|
Display(uint8_t width, uint8_t height) : width(width), height(height),
|
||||||
width(width), height(height),
|
pixelCount(width * height),
|
||||||
pixelCount(width * height),
|
pixelByteCount(pixelCount * sizeof(Color)),
|
||||||
pixelByteCount(pixelCount * sizeof(Color)),
|
leds(pixelCount, GPIO_NUM_13) {
|
||||||
leds(pixelCount, GPIO_NUM_13) {
|
|
||||||
buffer = (Color *) malloc(pixelByteCount);
|
buffer = (Color *) malloc(pixelByteCount);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
Serial.print("+-----------------------------------------------+\n");
|
Serial.print("+-----------------------------------------------+\n");
|
||||||
@ -130,15 +135,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool showIfZero = false;
|
bool showIfZero = false;
|
||||||
// Serial.printf("x=%d, y=%d, value=%d, align=%s, digitCount=%d, divider=%d\n", x, y, value, align == LEFT ? "LEFT" : "RIGHT", digitCount, divider);
|
// Serial.printf("x=%d, y=%d, value=%d, align=%s, digitCount=%d, divider=%d\n", x, y, value, align == LEFT ? "LEFT" : "RIGHT", digitCount, divider);
|
||||||
for (int digitPos = 0; digitPos < digitCount; ++digitPos) {
|
for (int digitPos = 0; digitPos < digitCount; ++digitPos) {
|
||||||
const int digitVal = value / divider % 10;
|
const int digitVal = value / divider % 10;
|
||||||
showIfZero |= digitVal != 0 || (digitPos == digitCount - 1);
|
showIfZero |= digitVal != 0 || (digitPos == digitCount - 1);
|
||||||
x += print(x, y, digitVal, color, showIfZero) + 1;
|
x += print(x, y, digitVal, color, showIfZero) + 1;
|
||||||
// Serial.printf(" digitPos=%d, x=%d, y=%d, digitVal=%d, showIfZero=%s, divider=%d\n", digitPos, x, y, digitVal, showIfZero ? "true" : "false", divider);
|
// Serial.printf(" digitPos=%d, x=%d, y=%d, digitVal=%d, showIfZero=%s, divider=%d\n", digitPos, x, y, digitVal, showIfZero ? "true" : "false", divider);
|
||||||
divider /= 10;
|
divider /= 10;
|
||||||
}
|
}
|
||||||
// Serial.println();
|
// Serial.println();
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@ -164,6 +169,57 @@ public:
|
|||||||
return DISPLAY_CHAR_WIDTH;
|
return DISPLAY_CHAR_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO REMOVE QUICK & DIRTY
|
||||||
|
uint8_t printM(uint8_t xPos, uint8_t yPos, Color color) {
|
||||||
|
bool sym[5][5] = {
|
||||||
|
{X,_,_,_,X},
|
||||||
|
{X,X,_,X,X},
|
||||||
|
{X,_,X,_,X},
|
||||||
|
{X,_,_,_,X},
|
||||||
|
{X,_,_,_,X},
|
||||||
|
};
|
||||||
|
for (int y = 0; y < countof(sym); ++y) {
|
||||||
|
for (int x = 0; x < countof(sym[0]); ++x) {
|
||||||
|
if (sym[y][x]) {
|
||||||
|
set(xPos + x, yPos + y, color);
|
||||||
|
} else {
|
||||||
|
set(xPos + x, yPos + y, BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return countof(sym[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO REMOVE QUICK & DIRTY
|
||||||
|
uint8_t printCreeper(uint8_t xPos, uint8_t yPos) {
|
||||||
|
Color G = GREEN;
|
||||||
|
Color I = {128, 255, 128};
|
||||||
|
Color O = BLACK;
|
||||||
|
Color sym[7][7] = {
|
||||||
|
{G, G, G, G, G, G, G},
|
||||||
|
{G, I, I, I, I, I, G},
|
||||||
|
{G, I, O, I, O, I, G},
|
||||||
|
{G, I, I, I, I, I, G},
|
||||||
|
{G, I, O, O, O, I, G},
|
||||||
|
{G, I, O, I, O, I, G},
|
||||||
|
{G, G, G, G, G, G, G},
|
||||||
|
};
|
||||||
|
for (int y = 0; y < countof(sym); ++y) {
|
||||||
|
for (int x = 0; x < countof(sym[0]); ++x) {
|
||||||
|
set(xPos + x, yPos + y, sym[y][x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return countof(sym[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO REMOVE QUICK & DIRTY
|
||||||
|
uint8_t printI(uint8_t xPos, uint8_t yPos, Color color) {
|
||||||
|
for (int y = 0; y < 5; ++y) {
|
||||||
|
set(xPos, yPos + y, color);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void set(Vector pos, Color color) {
|
void set(Vector pos, Color color) {
|
||||||
set((uint8_t) round(pos.x), (uint8_t) round(pos.y), color);
|
set((uint8_t) round(pos.x), (uint8_t) round(pos.y), color);
|
||||||
}
|
}
|
||||||
@ -183,10 +239,10 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buffer[index] = {
|
buffer[index] = {
|
||||||
// yes, correct order is GRB !!!
|
// yes, correct order is GRB !!!
|
||||||
(uint8_t) (color.g * brightness >> 8),
|
(uint8_t) (color.g * brightness >> 8),
|
||||||
(uint8_t) (color.r * brightness >> 8),
|
(uint8_t) (color.r * brightness >> 8),
|
||||||
(uint8_t) (color.b * brightness >> 8)
|
(uint8_t) (color.b * brightness >> 8)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#ifndef MODE_COUNT_DOWN_H
|
#ifndef MODE_COUNT_DOWN_H
|
||||||
#define MODE_COUNT_DOWN_H
|
#define MODE_COUNT_DOWN_H
|
||||||
|
|
||||||
#define MAX_FIREWORKS 5
|
#define MAX_FIREWORKS 6
|
||||||
|
|
||||||
#include "mode/Mode.h"
|
#include "mode/Mode.h"
|
||||||
#include "CountDownFirework.h"
|
#include "CountDownFirework.h"
|
||||||
@ -10,269 +10,287 @@ class CountDown : public Mode {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Firework fireworks[MAX_FIREWORKS];
|
Firework fireworks[MAX_FIREWORKS];
|
||||||
|
|
||||||
uint16_t days = 0;
|
uint16_t days = 0;
|
||||||
|
|
||||||
uint16_t hours = 0;
|
uint16_t hours = 0;
|
||||||
|
|
||||||
uint16_t minutes = 0;
|
uint16_t minutes = 0;
|
||||||
|
|
||||||
uint16_t seconds = 0;
|
uint16_t seconds = 0;
|
||||||
|
|
||||||
uint8_t level = 0;
|
uint8_t level = 0;
|
||||||
|
|
||||||
bool bars;
|
bool bars;
|
||||||
|
|
||||||
bool plus1DayForSleepingCount;
|
bool plus1DayForSleepingCount;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CountDown(Display &display, bool bars, bool plus1DayForSleepingCount) :
|
CountDown(Display& display, bool bars, bool plus1DayForSleepingCount) : Mode(display), bars(bars), plus1DayForSleepingCount(plus1DayForSleepingCount) {
|
||||||
Mode(display), bars(bars), plus1DayForSleepingCount(plus1DayForSleepingCount) {
|
for (auto& firework: fireworks) {
|
||||||
for (auto &firework: fireworks) {
|
firework.init(display);
|
||||||
firework.init(display);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char *getName() override {
|
const char *getName() override {
|
||||||
if (bars) {
|
if (bars) {
|
||||||
return "CountDown (Bars)";
|
return "CountDown (Bars)";
|
||||||
} else {
|
} else {
|
||||||
return "CountDown (Numbers)";
|
return "CountDown (Numbers)";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void step(microseconds_t microseconds) override {
|
void step(microseconds_t microseconds) override {
|
||||||
if (!realtimeOK) {
|
if (!realtimeOK) {
|
||||||
setMode(NO_TIME);
|
setMode(NO_TIME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dateReached()) {
|
if (dateReached()) {
|
||||||
setMode(FIREWORK);
|
setMode(FIREWORK);
|
||||||
for (auto &firework: fireworks) {
|
for (auto& firework: fireworks) {
|
||||||
firework.step(microseconds);
|
firework.step(microseconds);
|
||||||
}
|
|
||||||
markDirty();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GRRRRRRR...
|
|
||||||
config.date.tm_year -= 1900;
|
|
||||||
config.date.tm_mon -= 1;
|
|
||||||
const time_t dateEpochSeconds = mktime(&config.date);
|
|
||||||
config.date.tm_year += 1900;
|
|
||||||
config.date.tm_mon += 1;
|
|
||||||
// ---
|
|
||||||
|
|
||||||
const double diffSeconds = difftime(dateEpochSeconds, nowEpochSeconds);
|
|
||||||
days = (int) floor(diffSeconds / (24 * 60 * 60));
|
|
||||||
hours = (int) floor(diffSeconds / (60 * 60)) % 24;
|
|
||||||
minutes = (int) floor(diffSeconds / 60) % 60;
|
|
||||||
seconds = (int) 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,
|
|
||||||
// config.date.tm_year, config.date.tm_mon, config.date.tm_mday, dateEpochSeconds,
|
|
||||||
// diffSeconds,
|
|
||||||
// days, hours, minutes, seconds);
|
|
||||||
setMode(COUNTDOWN);
|
|
||||||
if (days == 0) {
|
|
||||||
loopLastDay();
|
|
||||||
} else {
|
|
||||||
loopMultipleDays();
|
|
||||||
}
|
}
|
||||||
|
markDirty();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loopLastDay() {
|
// GRRRRRRR...
|
||||||
int levelTmp = (int) round(32 * realtimeMilliseconds / 1000.0);
|
config.date.tm_year -= 1900;
|
||||||
if (level != levelTmp) {
|
config.date.tm_mon -= 1;
|
||||||
level = levelTmp;
|
const time_t dateEpochSeconds = mktime(&config.date);
|
||||||
markDirty();
|
config.date.tm_year += 1900;
|
||||||
}
|
config.date.tm_mon += 1;
|
||||||
}
|
// ---
|
||||||
|
|
||||||
void loopMultipleDays() {
|
const double diffSeconds = difftime(dateEpochSeconds, nowEpochSeconds);
|
||||||
if (realtimeChanged) {
|
days = (int) floor(diffSeconds / (24 * 60 * 60));
|
||||||
markDirty();
|
hours = (int) floor(diffSeconds / (60 * 60)) % 24;
|
||||||
}
|
minutes = (int) floor(diffSeconds / 60) % 60;
|
||||||
|
seconds = (int) 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,
|
||||||
|
// config.date.tm_year, config.date.tm_mon, config.date.tm_mday, dateEpochSeconds,
|
||||||
|
// diffSeconds,
|
||||||
|
// days, hours, minutes, seconds);
|
||||||
|
setMode(COUNTDOWN);
|
||||||
|
if (days == 0) {
|
||||||
|
loopLastDay();
|
||||||
|
} else {
|
||||||
|
loopMultipleDays();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool dateReached() {
|
void loopLastDay() {
|
||||||
return now.tm_year == config.date.tm_year && now.tm_mon == config.date.tm_mon && now.tm_mday == config.date.tm_mday;
|
int levelTmp = (int) round(32 * realtimeMilliseconds / 1000.0);
|
||||||
|
if (level != levelTmp) {
|
||||||
|
level = levelTmp;
|
||||||
|
markDirty();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void draw(Display &display) override {
|
void loopMultipleDays() {
|
||||||
display.clear();
|
if (realtimeChanged) {
|
||||||
if (!realtimeOK) {
|
markDirty();
|
||||||
drawNoTime(display);
|
|
||||||
} else if (dateReached()) {
|
|
||||||
for (auto &firework: fireworks) {
|
|
||||||
firework.draw(display);
|
|
||||||
}
|
|
||||||
drawYear(display, now.tm_year);
|
|
||||||
} else {
|
|
||||||
drawCountdown(display);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dateReached() {
|
||||||
|
return now.tm_year == config.date.tm_year && now.tm_mon == config.date.tm_mon && now.tm_mday == config.date.tm_mday;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(Display& display) override {
|
||||||
|
display.clear();
|
||||||
|
if (!realtimeOK) {
|
||||||
|
drawNoTime(display);
|
||||||
|
} else if (dateReached()) {
|
||||||
|
for (auto& firework: fireworks) {
|
||||||
|
firework.draw(display);
|
||||||
|
}
|
||||||
|
drawYear(display, now.tm_year);
|
||||||
|
} else {
|
||||||
|
drawCountdown(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
NO_TIME,
|
NO_TIME,
|
||||||
COUNTDOWN,
|
COUNTDOWN,
|
||||||
FIREWORK,
|
FIREWORK,
|
||||||
};
|
};
|
||||||
|
|
||||||
State _state = NO_TIME;
|
State _state = NO_TIME;
|
||||||
|
|
||||||
void setMode(State state) {
|
void setMode(State state) {
|
||||||
if (_state != state) {
|
if (_state != state) {
|
||||||
_state = state;
|
_state = state;
|
||||||
markDirty();
|
markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawCountdown(Display& display) {
|
||||||
|
if (plus1DayForSleepingCount) {
|
||||||
|
drawSleepingCount(display);
|
||||||
|
} else if (days <= 0 && bars) {
|
||||||
|
drawCountdownBars(display);
|
||||||
|
} else {
|
||||||
|
drawCountdownNumbers(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawSleepingCount(Display& display) const {
|
||||||
|
int sleepCount = days + 1;
|
||||||
|
int y = 1;
|
||||||
|
uint8_t x = display.print2(3 * (DISPLAY_CHAR_WIDTH + 1), y, sleepCount, WHITE);
|
||||||
|
x += 2;
|
||||||
|
x += display.print(x, y, SYMBOL_T, WHITE, true) + 1;
|
||||||
|
x += display.print(x, y, SYMBOL_A, WHITE, true) + 1;
|
||||||
|
x += display.print(x, y, SYMBOL_G, WHITE, true) + 1;
|
||||||
|
if (sleepCount != 1) {
|
||||||
|
display.print(x, y, SYMBOL_E, WHITE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawCountdownBars(Display& display) const {
|
||||||
|
drawBar(display, 0, 24, 1, 24, hours, RED, MAGENTA, 0);
|
||||||
|
drawBar(display, 2, 30, 2, 60, minutes, BLUE, VIOLET, 5);
|
||||||
|
drawBar(display, 5, 30, 2, 60, seconds, GREEN, YELLOW, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawBar(Display& display, uint8_t _y, uint8_t _w, uint8_t _h, uint8_t max, uint8_t value, const Color& color, const Color& tickColor, uint8_t ticks) {
|
||||||
|
auto totalOnCount = (uint8_t) round((double) value / max * _w * _h);
|
||||||
|
uint8_t doneOnCount = 0;
|
||||||
|
for (uint8_t y = 0; y < _h; y++) {
|
||||||
|
for (uint8_t x = 0; x < _w; x++) {
|
||||||
|
if (doneOnCount >= totalOnCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doneOnCount++;
|
||||||
|
Color c = color;
|
||||||
|
if (ticks != 0) {
|
||||||
|
if (doneOnCount % ticks == 0) {
|
||||||
|
c = tickColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display.set(x, _y + y, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void drawCountdown(Display &display) {
|
void drawCountdownNumbers(Display& display) const {
|
||||||
if (plus1DayForSleepingCount) {
|
uint8_t x = 0;
|
||||||
drawSleepingCount(display);
|
if (days > 0) {
|
||||||
} else if (days <= 0 && bars) {
|
drawDay(display, days, &x);
|
||||||
drawCountdownBars(display);
|
x += display.print(x, 1, 10, WHITE, true);
|
||||||
} else {
|
} else {
|
||||||
drawCountdownNumbers(display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawSleepingCount(Display &display) const {
|
|
||||||
int sleepCount = days + 1;
|
|
||||||
int y = 1;
|
|
||||||
uint8_t x = display.print2(3 * (DISPLAY_CHAR_WIDTH + 1), y, sleepCount, WHITE);
|
|
||||||
x += 2;
|
x += 2;
|
||||||
x += display.print(x, y, SYMBOL_T, WHITE, true) + 1;
|
}
|
||||||
x += display.print(x, y, SYMBOL_A, WHITE, true) + 1;
|
drawHour(display, days, hours, &x);
|
||||||
x += display.print(x, y, SYMBOL_G, WHITE, true) + 1;
|
x += display.print(x, 1, 10, WHITE, true);
|
||||||
if (sleepCount != 1) {
|
draw2Digit(display, minutes, &x);
|
||||||
display.print(x, y, SYMBOL_E, WHITE, true);
|
if (days <= 0) {
|
||||||
|
x += display.print(x, 1, 10, WHITE, true);
|
||||||
|
draw2Digit(display, seconds, &x);
|
||||||
|
drawSubSecondsBar(display);
|
||||||
|
} else {
|
||||||
|
drawSecondsBar(display, seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawNoTime(Display& display) {
|
||||||
|
uint8_t x = 2;
|
||||||
|
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
||||||
|
x++;
|
||||||
|
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
||||||
|
x += display.print(x, 1, 10, WHITE, true);
|
||||||
|
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
||||||
|
x++;
|
||||||
|
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
||||||
|
x += display.print(x, 1, 10, WHITE, true);
|
||||||
|
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
||||||
|
x++;
|
||||||
|
display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawDay(Display& display, int days, uint8_t *x) {
|
||||||
|
if (days >= 100) {
|
||||||
|
*x += display.print(*x, 1, days / 100, WHITE, true) + 1;
|
||||||
|
} else {
|
||||||
|
*x += DISPLAY_CHAR_WIDTH + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (days >= 10) {
|
||||||
|
*x += display.print(*x, 1, days / 10 % 10, WHITE, true) + 1;
|
||||||
|
} else {
|
||||||
|
*x += DISPLAY_CHAR_WIDTH + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*x += display.print(*x, 1, days % 10, WHITE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawHour(Display& display, int days, int hours, uint8_t *x) {
|
||||||
|
if (days > 0 || hours >= 10) {
|
||||||
|
*x += display.print(*x, 1, hours / 10, WHITE, true) + 1;
|
||||||
|
} else {
|
||||||
|
*x += DISPLAY_CHAR_WIDTH + 1;
|
||||||
|
}
|
||||||
|
*x += display.print(*x, 1, hours % 10, WHITE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw2Digit(Display& display, int value, uint8_t *x) {
|
||||||
|
*x += display.print(*x, 1, value / 10, WHITE, true) + 1;
|
||||||
|
*x += display.print(*x, 1, value % 10, WHITE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawSecondsBar(Display& display, int seconds) {
|
||||||
|
for (int pos = 0; pos < 30; pos++) {
|
||||||
|
if (pos <= seconds - 30) {
|
||||||
|
display.set(pos + 1, 7, GREEN);
|
||||||
|
} else if (pos <= seconds) {
|
||||||
|
display.set(pos + 1, 7, RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void drawCountdownBars(Display &display) const {
|
void drawSubSecondsBar(Display& display) const {
|
||||||
drawBar(display, 0, 24, 1, 24, hours, RED, MAGENTA, 0);
|
for (int pos = 0; pos < 32; pos++) {
|
||||||
drawBar(display, 2, 30, 2, 60, minutes, BLUE, VIOLET, 5);
|
if (pos < 32 - level) {
|
||||||
drawBar(display, 5, 30, 2, 60, seconds, GREEN, YELLOW, 5);
|
display.set(pos, 7, GREEN);
|
||||||
}
|
|
||||||
|
|
||||||
static void drawBar(Display &display, uint8_t _y, uint8_t _w, uint8_t _h, uint8_t max, uint8_t value, const Color &color, const Color &tickColor, uint8_t ticks) {
|
|
||||||
auto totalOnCount = (uint8_t) round((double) value / max * _w * _h);
|
|
||||||
uint8_t doneOnCount = 0;
|
|
||||||
for (uint8_t y = 0; y < _h; y++) {
|
|
||||||
for (uint8_t x = 0; x < _w; x++) {
|
|
||||||
if (doneOnCount >= totalOnCount) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
doneOnCount++;
|
|
||||||
Color c = color;
|
|
||||||
if (ticks != 0) {
|
|
||||||
if (doneOnCount % ticks == 0) {
|
|
||||||
c = tickColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
display.set(x, _y + y, c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void drawCountdownNumbers(Display &display) const {
|
// ReSharper disable CppDFAUnusedValue
|
||||||
|
|
||||||
|
void drawYear(Display& display, int year) const {
|
||||||
|
if (plus1DayForSleepingCount) {
|
||||||
uint8_t x = 0;
|
uint8_t x = 0;
|
||||||
if (days > 0) {
|
x += display.print(x, 1,SYMBOL_E, WHITE, true);
|
||||||
drawDay(display, days, &x);
|
x += 1;
|
||||||
x += display.print(x, 1, 10, WHITE, true);
|
x += display.printM(x, 1, WHITE);
|
||||||
} else {
|
x += 1;
|
||||||
x += 2;
|
x += display.printI(x, 1, WHITE);
|
||||||
}
|
x += 1;
|
||||||
drawHour(display, days, hours, &x);
|
x += display.print(x, 1,SYMBOL_L, WHITE, true);
|
||||||
x += display.print(x, 1, 10, WHITE, true);
|
x += 4;
|
||||||
draw2Digit(display, minutes, &x);
|
x += display.print(x, 1, 5, WHITE, true);
|
||||||
if (days <= 0) {
|
x += 2;
|
||||||
x += display.print(x, 1, 10, WHITE, true);
|
display.printCreeper(x, 0);
|
||||||
draw2Digit(display, seconds, &x);
|
} else {
|
||||||
drawSubSecondsBar(display);
|
|
||||||
} else {
|
|
||||||
drawSecondsBar(display, seconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawNoTime(Display &display) {
|
|
||||||
uint8_t x = 2;
|
|
||||||
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
|
||||||
x++;
|
|
||||||
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
|
||||||
x += display.print(x, 1, 10, WHITE, true);
|
|
||||||
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
|
||||||
x++;
|
|
||||||
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
|
||||||
x += display.print(x, 1, 10, WHITE, true);
|
|
||||||
x += display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
|
||||||
x++;
|
|
||||||
display.print(x, 1, SYMBOL_DASH, WHITE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawDay(Display &display, int days, uint8_t *x) {
|
|
||||||
if (days >= 100) {
|
|
||||||
*x += display.print(*x, 1, days / 100, WHITE, true) + 1;
|
|
||||||
} else {
|
|
||||||
*x += DISPLAY_CHAR_WIDTH + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (days >= 10) {
|
|
||||||
*x += display.print(*x, 1, days / 10 % 10, WHITE, true) + 1;
|
|
||||||
} else {
|
|
||||||
*x += DISPLAY_CHAR_WIDTH + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*x += display.print(*x, 1, days % 10, WHITE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawHour(Display &display, int days, int hours, uint8_t *x) {
|
|
||||||
if (days > 0 || hours >= 10) {
|
|
||||||
*x += display.print(*x, 1, hours / 10, WHITE, true) + 1;
|
|
||||||
} else {
|
|
||||||
*x += DISPLAY_CHAR_WIDTH + 1;
|
|
||||||
}
|
|
||||||
*x += display.print(*x, 1, hours % 10, WHITE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw2Digit(Display &display, int value, uint8_t *x) {
|
|
||||||
*x += display.print(*x, 1, value / 10, WHITE, true) + 1;
|
|
||||||
*x += display.print(*x, 1, value % 10, WHITE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawSecondsBar(Display &display, int seconds) {
|
|
||||||
for (int pos = 0; pos < 30; pos++) {
|
|
||||||
if (pos <= seconds - 30) {
|
|
||||||
display.set(pos + 1, 7, GREEN);
|
|
||||||
} else if (pos <= seconds) {
|
|
||||||
display.set(pos + 1, 7, RED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawSubSecondsBar(Display &display) const {
|
|
||||||
for (int pos = 0; pos < 32; pos++) {
|
|
||||||
if (pos < 32 - level) {
|
|
||||||
display.set(pos, 7, GREEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawYear(Display &display, int year) {
|
|
||||||
uint8_t x = 8;
|
uint8_t x = 8;
|
||||||
x += display.print(x, 1, year / 1000 % 10, WHITE, true) + 1;
|
x += display.print(x, 1, year / 1000 % 10, WHITE, true) + 1;
|
||||||
x += display.print(x, 1, year / 100 % 10, WHITE, true) + 1;
|
x += display.print(x, 1, year / 100 % 10, WHITE, true) + 1;
|
||||||
x += display.print(x, 1, year / 10 % 10, WHITE, true) + 1;
|
x += display.print(x, 1, year / 10 % 10, WHITE, true) + 1;
|
||||||
display.print(x, 1, year / 1 % 10, WHITE, true);
|
x += display.print(x, 1, year / 1 % 10, WHITE, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper restore CppDFAUnusedValue
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user