Double-buffer + Color
This commit is contained in:
parent
a53e3e564f
commit
4bddfab908
@ -6,6 +6,9 @@
|
|||||||
#define X true
|
#define X true
|
||||||
#define _ false
|
#define _ false
|
||||||
|
|
||||||
|
#define ____ 0
|
||||||
|
#define FULL 255
|
||||||
|
|
||||||
typedef int64_t microseconds_t;
|
typedef int64_t microseconds_t;
|
||||||
|
|
||||||
double doStep(double valueCurrent, double valueMin, double valueMax, microseconds_t millisecondsTotal, microseconds_t microsecondsDelta);
|
double doStep(double valueCurrent, double valueMin, double valueMax, microseconds_t millisecondsTotal, microseconds_t microsecondsDelta);
|
||||||
|
|||||||
@ -32,7 +32,7 @@ void config_set_dirty() {
|
|||||||
void config_loop() {
|
void config_loop() {
|
||||||
if (notify && millis() - lastDirtyMillis <= WRITE_DELAY_MS + 1000) {
|
if (notify && millis() - lastDirtyMillis <= WRITE_DELAY_MS + 1000) {
|
||||||
notify = false;
|
notify = false;
|
||||||
display.set(0, 0, 255, 0, 0);
|
display.set(0, 0, RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dirty) {
|
if (!dirty) {
|
||||||
|
|||||||
21
src/display/Color.cpp
Normal file
21
src/display/Color.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "Color.h"
|
||||||
|
|
||||||
|
const Color BLACK = {____, ____, ____};
|
||||||
|
|
||||||
|
const Color WHITE = {FULL, FULL, FULL};
|
||||||
|
|
||||||
|
const Color RED = {FULL, ____, ____};
|
||||||
|
|
||||||
|
const Color GREEN = {____, FULL, ____};
|
||||||
|
|
||||||
|
const Color BLUE = {____, ____, FULL};
|
||||||
|
|
||||||
|
const Color YELLOW = {FULL, FULL, ____};
|
||||||
|
|
||||||
|
Color gray(uint8_t brightness) {
|
||||||
|
return {brightness, brightness, brightness};
|
||||||
|
}
|
||||||
|
|
||||||
|
Color randomColor() {
|
||||||
|
return {(uint8_t) random(255), (uint8_t) random(255), (uint8_t) random(255)};
|
||||||
|
}
|
||||||
28
src/display/Color.h
Normal file
28
src/display/Color.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef PIXEL_H
|
||||||
|
#define PIXEL_H
|
||||||
|
|
||||||
|
#include "BASICS.h"
|
||||||
|
|
||||||
|
struct Color {
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
};
|
||||||
|
|
||||||
|
Color gray(uint8_t brightness);
|
||||||
|
|
||||||
|
Color randomColor();
|
||||||
|
|
||||||
|
extern const Color BLACK;
|
||||||
|
|
||||||
|
extern const Color WHITE;
|
||||||
|
|
||||||
|
extern const Color RED;
|
||||||
|
|
||||||
|
extern const Color GREEN;
|
||||||
|
|
||||||
|
extern const Color BLUE;
|
||||||
|
|
||||||
|
extern const Color YELLOW;
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -99,4 +99,12 @@ bool SYMBOLS[SYMBOL_COUNT][DISPLAY_CHAR_WIDTH * DISPLAY_CHAR_HEIGHT] = {
|
|||||||
_, _, _,
|
_, _, _,
|
||||||
_, _, _,
|
_, _, _,
|
||||||
},
|
},
|
||||||
|
// this must always be the last symbol (fallback)
|
||||||
|
{
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
X, X, X,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,26 +1,14 @@
|
|||||||
#ifndef DISPLAY_H
|
#ifndef DISPLAY_H
|
||||||
#define DISPLAY_H
|
#define DISPLAY_H
|
||||||
|
|
||||||
#include "Pixel.h"
|
#include "Color.h"
|
||||||
#include "Adafruit_NeoPixel.h"
|
#include "Adafruit_NeoPixel.h"
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
|
|
||||||
#define SYMBOL_COUNT 14
|
#define SYMBOL_COUNT 15
|
||||||
#define DISPLAY_CHAR_WIDTH 3
|
#define DISPLAY_CHAR_WIDTH 3
|
||||||
#define DISPLAY_CHAR_HEIGHT 5
|
#define DISPLAY_CHAR_HEIGHT 5
|
||||||
|
|
||||||
#define FULL 255
|
|
||||||
#define ____ 0
|
|
||||||
#define rgb(r, g, b) ((((r << 8) | g) << 8) | b)
|
|
||||||
#define COLOR_RED (rgb(FULL, ____, ____))
|
|
||||||
#define COLOR_GREEN (rgb(____, FULL, ____))
|
|
||||||
#define COLOR_BLUE (rgb(____, ____, FULL))
|
|
||||||
#define COLOR_YELLOW (rgb(FULL, FULL, ____))
|
|
||||||
#define COLOR_VIOLET (rgb(FULL, ____, FULL))
|
|
||||||
#define COLOR_TURQUOISE (rgb(____, FULL, FULL))
|
|
||||||
#define COLOR_WHITE (rgb(FULL, FULL, FULL))
|
|
||||||
#define COLOR_BLACK (rgb(____, ____, ____))
|
|
||||||
|
|
||||||
extern bool SYMBOLS[SYMBOL_COUNT][DISPLAY_CHAR_WIDTH * DISPLAY_CHAR_HEIGHT];
|
extern bool SYMBOLS[SYMBOL_COUNT][DISPLAY_CHAR_WIDTH * DISPLAY_CHAR_HEIGHT];
|
||||||
|
|
||||||
class Display {
|
class Display {
|
||||||
@ -31,9 +19,11 @@ public:
|
|||||||
|
|
||||||
const uint8_t height;
|
const uint8_t height;
|
||||||
|
|
||||||
const uint16_t pixelCount;
|
const size_t pixelCount;
|
||||||
|
|
||||||
bool fpsShow = true;
|
const size_t pixelByteCount;
|
||||||
|
|
||||||
|
bool fpsShow = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -43,94 +33,44 @@ private:
|
|||||||
|
|
||||||
int fps = 0;
|
int fps = 0;
|
||||||
|
|
||||||
|
Color *buffer = nullptr;
|
||||||
|
|
||||||
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)),
|
||||||
leds(pixelCount, GPIO_NUM_13) {
|
leds(pixelCount, GPIO_NUM_13) {
|
||||||
// nothing
|
buffer = (Color *) malloc(pixelByteCount);
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
Serial.print("+-----------------------------------------------+\n");
|
||||||
|
Serial.print("| OUT OF MEMORY: Cannot allocate double-buffer! |\n");
|
||||||
|
Serial.print("+-----------------------------------------------+\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Display() {
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
buffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
leds.begin();
|
leds.begin();
|
||||||
leds.setBrightness(8);
|
leds.setBrightness(8);
|
||||||
clear();
|
clear();
|
||||||
}
|
flush();
|
||||||
|
|
||||||
void print(uint8_t xPos, uint8_t yPos, uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
|
|
||||||
print(&xPos, yPos, index, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(uint8_t xPos, uint8_t yPos, uint8_t index) {
|
|
||||||
print(&xPos, yPos, index, 255, 255, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(uint8_t *xPos, uint8_t yPos, uint8_t index) {
|
|
||||||
print(xPos, yPos, index, 255, 255, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(uint8_t *xPos, uint8_t yPos, uint8_t index, uint32_t color) {
|
|
||||||
print(xPos, yPos, index, (uint8_t) (color >> 16), (uint8_t) (color >> 8), (uint8_t) color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(uint8_t *xPos, uint8_t yPos, uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
|
|
||||||
if (index >= SYMBOL_COUNT) {
|
|
||||||
Serial.printf("Cannot print symbol #%u.\n", index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool *symbolBit = SYMBOLS[index];
|
|
||||||
for (uint8_t y = 0; y < DISPLAY_CHAR_HEIGHT; ++y) {
|
|
||||||
for (uint8_t x = 0; x < DISPLAY_CHAR_WIDTH; ++x) {
|
|
||||||
if (*(symbolBit++)) {
|
|
||||||
set(*xPos + x, yPos + y, r, g, b);
|
|
||||||
} else {
|
|
||||||
set(*xPos + x, yPos + y, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*xPos += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(uint8_t x, uint8_t y, uint32_t color) {
|
|
||||||
setPixelColor(x, y, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b) {
|
|
||||||
setPixelColor(x, y, (((r << 8) | g) << 8) | b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(Vector *pos, uint32_t color) {
|
|
||||||
setPixelColor((uint8_t) round(pos->x), (uint8_t) round(pos->y), color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(Vector *pos, uint8_t r, uint8_t g, uint8_t b) {
|
|
||||||
setPixelColor((uint8_t) round(pos->x), (uint8_t) round(pos->y), (((r << 8) | g) << 8) | b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPixelColor(uint8_t x, uint8_t y, uint32_t color) {
|
|
||||||
if (x >= width || y >= height) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((y % 2) != 0) {
|
|
||||||
x = width - x - 1;
|
|
||||||
}
|
|
||||||
setIndex(y * width + x, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
leds.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
calculateFPS();
|
calculateFPS();
|
||||||
drawFpsBorder();
|
drawFpsBorder();
|
||||||
leds.show();
|
if (isDirty()) {
|
||||||
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateFPS() {
|
|
||||||
fps = (int) round(1000.0 / (millis() - fpsLastMillis));
|
|
||||||
fpsLastMillis = millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBrightness(uint8_t brightness) {
|
void setBrightness(uint8_t brightness) {
|
||||||
@ -141,13 +81,72 @@ public:
|
|||||||
return leds.getBrightness();
|
return leds.getBrightness();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIndex(uint16_t index, uint8_t r, uint8_t g, uint8_t b) {
|
void clear() {
|
||||||
uint32_t color = (r << 8 | g) << 8 | b;
|
if (buffer == nullptr) {
|
||||||
setIndex(index, color);
|
return;
|
||||||
|
}
|
||||||
|
memset(buffer, 0, pixelByteCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIndex(uint16_t index, uint32_t color) {
|
uint8_t print(uint8_t xPos, uint8_t yPos, uint8_t index, Color color) {
|
||||||
leds.setPixelColor(index, color);
|
if (index >= SYMBOL_COUNT) {
|
||||||
|
Serial.printf("Cannot print symbol #%u.\n", index);
|
||||||
|
index = SYMBOL_COUNT - 1;
|
||||||
|
}
|
||||||
|
bool *symbolBit = SYMBOLS[index];
|
||||||
|
for (uint8_t y = 0; y < DISPLAY_CHAR_HEIGHT; ++y) {
|
||||||
|
for (uint8_t x = 0; x < DISPLAY_CHAR_WIDTH; ++x) {
|
||||||
|
if (*(symbolBit++)) {
|
||||||
|
set(xPos + x, yPos + y, color);
|
||||||
|
} else {
|
||||||
|
set(xPos + x, yPos + y, BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DISPLAY_CHAR_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(Vector *pos, Color color) {
|
||||||
|
set((uint8_t) round(pos->x), (uint8_t) round(pos->y), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(uint8_t x, uint8_t y, Color color) {
|
||||||
|
if (x >= width || y >= height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((y % 2) != 0) {
|
||||||
|
x = width - x - 1;
|
||||||
|
}
|
||||||
|
set(y * width + x, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(uint16_t index, Color color) {
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buffer[index] = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void flush() {
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(leds.getPixels(), buffer, pixelByteCount);
|
||||||
|
leds.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDirty() const {
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return memcmp(leds.getPixels(), buffer, pixelByteCount) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calculateFPS() {
|
||||||
|
fps = (int) round(1000.0 / (millis() - fpsLastMillis));
|
||||||
|
fpsLastMillis = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFpsBorder() {
|
void drawFpsBorder() {
|
||||||
@ -157,37 +156,29 @@ public:
|
|||||||
|
|
||||||
int frames = fps;
|
int frames = fps;
|
||||||
|
|
||||||
uint8_t red = 255;
|
Color color = RED;
|
||||||
uint8_t green = 0;
|
|
||||||
uint8_t blue = 0;
|
|
||||||
if (frames > 3 * 76) {
|
if (frames > 3 * 76) {
|
||||||
frames -= 3 * 76;
|
frames -= 3 * 76;
|
||||||
red = 255;
|
color = WHITE;
|
||||||
green = 255;
|
|
||||||
blue = 255;
|
|
||||||
} else if (frames > 2 * 76) {
|
} else if (frames > 2 * 76) {
|
||||||
frames -= 2 * 76;
|
frames -= 2 * 76;
|
||||||
red = 0;
|
color = BLUE;
|
||||||
green = 0;
|
|
||||||
blue = 255;
|
|
||||||
} else if (frames > 76) {
|
} else if (frames > 76) {
|
||||||
frames -= 76;
|
frames -= 76;
|
||||||
red = 0;
|
color = GREEN;
|
||||||
green = 255;
|
|
||||||
blue = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x <= width - 1 && frames-- > 0; x++) {
|
for (int x = 0; x <= width - 1 && frames-- > 0; x++) {
|
||||||
set(x, 0, red, green, blue);
|
set(x, 0, color);
|
||||||
}
|
}
|
||||||
for (int y = 0; y <= height - 1 && frames-- > 0; y++) {
|
for (int y = 0; y <= height - 1 && frames-- > 0; y++) {
|
||||||
set(width - 1, y, red, green, blue);
|
set(width - 1, y, color);
|
||||||
}
|
}
|
||||||
for (int x = width - 1; x >= 0 && frames-- > 0; x--) {
|
for (int x = width - 1; x >= 0 && frames-- > 0; x--) {
|
||||||
set(x, height - 1, red, green, blue);
|
set(x, height - 1, color);
|
||||||
}
|
}
|
||||||
for (int y = height - 1; y >= 0 && frames-- > 0; y--) {
|
for (int y = height - 1; y >= 0 && frames-- > 0; y--) {
|
||||||
set(0, y, red, green, blue);
|
set(0, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
#ifndef PIXEL_H
|
|
||||||
#define PIXEL_H
|
|
||||||
|
|
||||||
#include "BASICS.h"
|
|
||||||
|
|
||||||
class Pixel {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
uint8_t r;
|
|
||||||
|
|
||||||
uint8_t g;
|
|
||||||
|
|
||||||
uint8_t b;
|
|
||||||
|
|
||||||
Pixel(uint8_t r, uint8_t g, uint8_t b) :
|
|
||||||
r(r), g(g), b(b) {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOn() const {
|
|
||||||
return r != 0 || g != 0 || b != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setGray(uint8_t brightness) {
|
|
||||||
r = brightness;
|
|
||||||
g = brightness;
|
|
||||||
b = brightness;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t toInt() const {
|
|
||||||
return (((r << 8) | g) << 8) | b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Pixel gray(uint8_t brightness) {
|
|
||||||
return {brightness, brightness, brightness};
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -24,11 +24,7 @@ void loop() {
|
|||||||
serial_loop();
|
serial_loop();
|
||||||
config_loop();
|
config_loop();
|
||||||
wifi_loop();
|
wifi_loop();
|
||||||
|
|
||||||
server_loop();
|
server_loop();
|
||||||
|
|
||||||
mode_loop();
|
mode_loop();
|
||||||
display.loop();
|
display.loop();
|
||||||
|
|
||||||
yield();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,9 +22,9 @@ public:
|
|||||||
for (int y = 0; y < display->height; y++) {
|
for (int y = 0; y < display->height; y++) {
|
||||||
for (int x = 0; x < display->width; x++) {
|
for (int x = 0; x < display->width; x++) {
|
||||||
if (x == 0 || x == display->width - 1 || y == 0 || y == display->height - 1) {
|
if (x == 0 || x == display->width - 1 || y == 0 || y == display->height - 1) {
|
||||||
display->set(x, y, 255, 255, 255);
|
display->set(x, y, WHITE);
|
||||||
} else {
|
} else {
|
||||||
display->set(x, y, 0, 0, 0);
|
display->set(x, y, BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,17 +27,17 @@ public:
|
|||||||
|
|
||||||
display->clear();
|
display->clear();
|
||||||
uint8_t x = 2;
|
uint8_t x = 2;
|
||||||
display->print(&x, 1, ok ? info.tm_hour / 10 : 13);
|
x += display->print(x, 1, ok ? info.tm_hour / 10 : 13, WHITE);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, ok ? info.tm_hour % 10 : 13);
|
x += display->print(x, 1, ok ? info.tm_hour % 10 : 13, WHITE);
|
||||||
display->print(&x, 1, 10);
|
x += display->print(x, 1, 10, WHITE);
|
||||||
display->print(&x, 1, ok ? info.tm_min / 10 : 13);
|
x += display->print(x, 1, ok ? info.tm_min / 10 : 13, WHITE);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, ok ? info.tm_min % 10 : 13);
|
x += display->print(x, 1, ok ? info.tm_min % 10 : 13, WHITE);
|
||||||
display->print(&x, 1, 10);
|
x += display->print(x, 1, 10, WHITE);
|
||||||
display->print(&x, 1, ok ? info.tm_sec / 10 : 13);
|
x += display->print(x, 1, ok ? info.tm_sec / 10 : 13, WHITE);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, ok ? info.tm_sec % 10 : 13);
|
x += display->print(x, 1, ok ? info.tm_sec % 10 : 13, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,7 +11,7 @@ public:
|
|||||||
|
|
||||||
double fade = 0.0;
|
double fade = 0.0;
|
||||||
|
|
||||||
uint32_t color = 0;
|
Color color = BLACK;
|
||||||
|
|
||||||
void animate(microseconds_t dt) {
|
void animate(microseconds_t dt) {
|
||||||
// TODO "doStep" does not work as expected
|
// TODO "doStep" does not work as expected
|
||||||
|
|||||||
@ -106,7 +106,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void spawn(Cell *cell) {
|
void spawn(Cell *cell) {
|
||||||
cell->color = random(16777216);
|
cell->color = randomColor();
|
||||||
cell->alive = true;
|
cell->alive = true;
|
||||||
aliveCount++;
|
aliveCount++;
|
||||||
}
|
}
|
||||||
@ -159,17 +159,17 @@ private:
|
|||||||
switch (colorMode) {
|
switch (colorMode) {
|
||||||
case BLACK_WHITE:
|
case BLACK_WHITE:
|
||||||
brightness = cell->alive ? 255 : 0;
|
brightness = cell->alive ? 255 : 0;
|
||||||
display->set(x, y, brightness, brightness, brightness);
|
display->set(x, y, gray(brightness));
|
||||||
break;
|
break;
|
||||||
case GRAYSCALE:
|
case GRAYSCALE:
|
||||||
brightness = (uint8_t) cell->fade;
|
brightness = (uint8_t) cell->fade;
|
||||||
display->set(x, y, brightness, brightness, brightness);
|
display->set(x, y, gray(brightness));
|
||||||
break;
|
break;
|
||||||
case COLOR_FADE:
|
case COLOR_FADE:
|
||||||
display->set(x, y, cell->getR(), cell->getG(), cell->getB());
|
display->set(x, y, {cell->getR(), cell->getG(), cell->getB()});
|
||||||
break;
|
break;
|
||||||
case RANDOM_COLOR:
|
case RANDOM_COLOR:
|
||||||
display->set(x, y, cell->alive ? cell->color : 0);
|
display->set(x, y, cell->alive ? cell->color : BLACK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cell++;
|
cell++;
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
#include "Mode.h"
|
|
||||||
|
|
||||||
//template<typename T>
|
|
||||||
//T *Mode<T>::instance = nullptr;
|
|
||||||
@ -13,7 +13,7 @@ class Firework {
|
|||||||
|
|
||||||
Display *display{};
|
Display *display{};
|
||||||
|
|
||||||
uint32_t color{};
|
Color color;
|
||||||
|
|
||||||
State state = RISE;
|
State state = RISE;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ public:
|
|||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
position.set((double) random(display->width), display->height);
|
position.set((double) random(display->width), display->height);
|
||||||
color = random(16777216);
|
color = randomColor();
|
||||||
state = INITIAL;
|
state = INITIAL;
|
||||||
|
|
||||||
destinationHeight = display->height / 2.0 + (double) random(5) - 2;
|
destinationHeight = display->height / 2.0 + (double) random(5) - 2;
|
||||||
@ -98,7 +98,7 @@ public:
|
|||||||
case INITIAL:
|
case INITIAL:
|
||||||
break;
|
break;
|
||||||
case RISE:
|
case RISE:
|
||||||
display->set(&position, COLOR_YELLOW);
|
display->set(&position, YELLOW);
|
||||||
break;
|
break;
|
||||||
case EXPLODE:
|
case EXPLODE:
|
||||||
drawParticle(p, +0.0, +1.0);
|
drawParticle(p, +0.0, +1.0);
|
||||||
|
|||||||
@ -46,17 +46,17 @@ class NewYear : public Mode<NewYear> {
|
|||||||
|
|
||||||
void drawNoTime() {
|
void drawNoTime() {
|
||||||
uint8_t x = 2;
|
uint8_t x = 2;
|
||||||
display->print(&x, 1, 13);
|
x += display->print(x, 1, 13, WHITE);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, 13);
|
x += display->print(x, 1, 13, WHITE);
|
||||||
display->print(&x, 1, 10);
|
x += display->print(x, 1, 10, WHITE);
|
||||||
display->print(&x, 1, 13);
|
x += display->print(x, 1, 13, WHITE);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, 13);
|
x += display->print(x, 1, 13, WHITE);
|
||||||
display->print(&x, 1, 10);
|
x += display->print(x, 1, 10, WHITE);
|
||||||
display->print(&x, 1, 13);
|
x += display->print(x, 1, 13, WHITE);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, 13);
|
x += display->print(x, 1, 13, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCountdown(const tm &time) {
|
void drawCountdown(const tm &time) {
|
||||||
@ -70,15 +70,15 @@ class NewYear : public Mode<NewYear> {
|
|||||||
|
|
||||||
if (days > 0) {
|
if (days > 0) {
|
||||||
drawDay(days, &x);
|
drawDay(days, &x);
|
||||||
display->print(&x, 1, 10, COLOR_WHITE);
|
x += display->print(x, 1, 10, WHITE);
|
||||||
} else {
|
} else {
|
||||||
x += 2;
|
x += 2;
|
||||||
}
|
}
|
||||||
drawHour(days, hours, &x);
|
drawHour(days, hours, &x);
|
||||||
display->print(&x, 1, 10, COLOR_WHITE);
|
x += display->print(x, 1, 10, WHITE);
|
||||||
draw2Digit(minutes, &x);
|
draw2Digit(minutes, &x);
|
||||||
if (days <= 0) {
|
if (days <= 0) {
|
||||||
display->print(&x, 1, 10, COLOR_WHITE);
|
x += display->print(x, 1, 10, WHITE);
|
||||||
draw2Digit(seconds, &x);
|
draw2Digit(seconds, &x);
|
||||||
drawSubSecondsBar(time.tm_sec);
|
drawSubSecondsBar(time.tm_sec);
|
||||||
} else {
|
} else {
|
||||||
@ -88,44 +88,44 @@ class NewYear : public Mode<NewYear> {
|
|||||||
|
|
||||||
void drawDay(int days, uint8_t *x) {
|
void drawDay(int days, uint8_t *x) {
|
||||||
if (days > 100) {
|
if (days > 100) {
|
||||||
display->print(x, 1, days / 100, COLOR_WHITE);
|
*x += display->print(*x, 1, days / 100, WHITE);
|
||||||
} else {
|
} else {
|
||||||
*x += 3;
|
*x += 3;
|
||||||
}
|
}
|
||||||
(*x)++;
|
(*x)++;
|
||||||
|
|
||||||
if (days > 10) {
|
if (days > 10) {
|
||||||
display->print(x, 1, days / 10 % 10, COLOR_WHITE);
|
*x += display->print(*x, 1, days / 10 % 10, WHITE);
|
||||||
} else {
|
} else {
|
||||||
*x += 3;
|
*x += 3;
|
||||||
}
|
}
|
||||||
(*x)++;
|
(*x)++;
|
||||||
|
|
||||||
display->print(x, 1, days % 10, COLOR_WHITE);
|
*x += display->print(*x, 1, days % 10, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawHour(int days, int hours, uint8_t *x) {
|
void drawHour(int days, int hours, uint8_t *x) {
|
||||||
if (days > 0 || hours >= 10) {
|
if (days > 0 || hours >= 10) {
|
||||||
display->print(x, 1, hours / 10, COLOR_WHITE);
|
*x += display->print(*x, 1, hours / 10, WHITE);
|
||||||
} else {
|
} else {
|
||||||
*x += 3;
|
*x += 3;
|
||||||
}
|
}
|
||||||
(*x)++;
|
(*x)++;
|
||||||
display->print(x, 1, hours % 10, COLOR_WHITE);
|
*x += display->print(*x, 1, hours % 10, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw2Digit(int value, uint8_t *x) {
|
void draw2Digit(int value, uint8_t *x) {
|
||||||
display->print(x, 1, value / 10, COLOR_WHITE);
|
*x += display->print(*x, 1, value / 10, WHITE);
|
||||||
(*x)++;
|
(*x)++;
|
||||||
display->print(x, 1, value % 10, COLOR_WHITE);
|
*x += display->print(*x, 1, value % 10, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSecondsBar(int seconds) {
|
void drawSecondsBar(int seconds) {
|
||||||
for (int pos = 0; pos < 30; pos++) {
|
for (int pos = 0; pos < 30; pos++) {
|
||||||
if (pos <= seconds - 30) {
|
if (pos <= seconds - 30) {
|
||||||
display->set(pos + 1, 7, 0, 255, 0);
|
display->set(pos + 1, 7, GREEN);
|
||||||
} else if (pos <= seconds) {
|
} else if (pos <= seconds) {
|
||||||
display->set(pos + 1, 7, 255, 0, 0);
|
display->set(pos + 1, 7, RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ class NewYear : public Mode<NewYear> {
|
|||||||
int level = (int) round(32 * mils / 1000.0);
|
int level = (int) round(32 * mils / 1000.0);
|
||||||
for (int pos = 0; pos < 32; pos++) {
|
for (int pos = 0; pos < 32; pos++) {
|
||||||
if (pos < 32 - level) {
|
if (pos < 32 - level) {
|
||||||
display->set(pos, 7, 0, 255, 0);
|
display->set(pos, 7, GREEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,13 +154,13 @@ class NewYear : public Mode<NewYear> {
|
|||||||
|
|
||||||
void drawYear(uint32_t counter, int year) {
|
void drawYear(uint32_t counter, int year) {
|
||||||
uint8_t x = 8;
|
uint8_t x = 8;
|
||||||
display->print(&x, 1, year / 1000 % 10, counter % 64 != 0 ? COLOR_WHITE : COLOR_BLACK);
|
x += display->print(x, 1, year / 1000 % 10, counter % 64 != 0 ? WHITE : BLACK);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, year / 100 % 10, counter % 64 != 1 ? COLOR_WHITE : COLOR_BLACK);
|
x += display->print(x, 1, year / 100 % 10, counter % 64 != 1 ? WHITE : BLACK);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, year / 10 % 10, counter % 64 != 2 ? COLOR_WHITE : COLOR_BLACK);
|
x += display->print(x, 1, year / 10 % 10, counter % 64 != 2 ? WHITE : BLACK);
|
||||||
x++;
|
x++;
|
||||||
display->print(&x, 1, year / 1 % 10, counter % 64 != 3 ? COLOR_WHITE : COLOR_BLACK);
|
x += display->print(x, 1, year / 1 % 10, counter % 64 != 3 ? WHITE : BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFirework(microseconds_t dt) const {
|
void drawFirework(microseconds_t dt) const {
|
||||||
|
|||||||
@ -103,25 +103,25 @@ private:
|
|||||||
display->clear();
|
display->clear();
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SCORE:
|
case SCORE:
|
||||||
display->print(1, 1, player0.score, 0, 255, 0);
|
display->print(1, 1, player0.score, GREEN);
|
||||||
display->print(display->width - 1 - DISPLAY_CHAR_WIDTH, 1, player1.score, 255, 0, 0);
|
display->print(display->width - 1 - DISPLAY_CHAR_WIDTH, 1, player1.score, RED);
|
||||||
break;
|
break;
|
||||||
case PLAY:
|
case PLAY:
|
||||||
for (int i = 0; i < player0.size; ++i) {
|
for (int i = 0; i < player0.size; ++i) {
|
||||||
display->set(1, (uint8_t) round(player0.position) + i, 0, 255, 0);
|
display->set(1, (uint8_t) round(player0.position) + i, GREEN);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < player1.size; ++i) {
|
for (int i = 0; i < player1.size; ++i) {
|
||||||
display->set(display->width - 2, (uint8_t) round(player1.position) + i, 255, 0, 0);
|
display->set(display->width - 2, (uint8_t) round(player1.position) + i, RED);
|
||||||
}
|
}
|
||||||
display->set((uint8_t) round(position.x), (uint8_t) round(position.y), 255, 255, 255);
|
display->set((uint8_t) round(position.x), (uint8_t) round(position.y), WHITE);
|
||||||
break;
|
break;
|
||||||
case OVER:
|
case OVER:
|
||||||
if (player0.score > player1.score) {
|
if (player0.score > player1.score) {
|
||||||
display->print(1, 1, 11, 0, 255, 0);
|
display->print(1, 1, 11, GREEN);
|
||||||
display->print(display->width - 1 - DISPLAY_CHAR_WIDTH, 1, 12, 255, 0, 0);
|
display->print(display->width - 1 - DISPLAY_CHAR_WIDTH, 1, 12, RED);
|
||||||
} else if (player0.score < player1.score) {
|
} else if (player0.score < player1.score) {
|
||||||
display->print(1, 1, 12, 255, 0, 0);
|
display->print(1, 1, 12, RED);
|
||||||
display->print(display->width - 1 - DISPLAY_CHAR_WIDTH, 1, 11, 0, 255, 0);
|
display->print(display->width - 1 - DISPLAY_CHAR_WIDTH, 1, 11, GREEN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -205,8 +205,8 @@ public:
|
|||||||
void drawInvaders() {
|
void drawInvaders() {
|
||||||
for (Invader *invader = swarmBegin; invader < swarmEnd; invader++) {
|
for (Invader *invader = swarmBegin; invader < swarmEnd; invader++) {
|
||||||
if (invader->alive) {
|
if (invader->alive) {
|
||||||
display->set(swarmX + invader->x * 3 + 0, swarmY + invader->y * 2, 255, 0, 0);
|
display->set(swarmX + invader->x * 3 + 0, swarmY + invader->y * 2, RED);
|
||||||
display->set(swarmX + invader->x * 3 + 1, swarmY + invader->y * 2, 255, 0, 0);
|
display->set(swarmX + invader->x * 3 + 1, swarmY + invader->y * 2, RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,21 +214,21 @@ public:
|
|||||||
void drawRockets() {
|
void drawRockets() {
|
||||||
for (Rocket *rocket = rocketsBegin; rocket < rocketsEnd; rocket++) {
|
for (Rocket *rocket = rocketsBegin; rocket < rocketsEnd; rocket++) {
|
||||||
if (rocket->alive) {
|
if (rocket->alive) {
|
||||||
display->set(rocket->x, rocket->y, 255, 255, 0);
|
display->set(rocket->x, rocket->y, YELLOW);
|
||||||
} else if (rocket->flash > 0) {
|
} else if (rocket->flash > 0) {
|
||||||
display->set(rocket->x - 1, rocket->y - 1, rocket->flash, rocket->flash, rocket->flash);
|
display->set(rocket->x - 1, rocket->y - 1, gray(rocket->flash));
|
||||||
display->set(rocket->x - 1, rocket->y + 1, rocket->flash, rocket->flash, rocket->flash);
|
display->set(rocket->x - 1, rocket->y + 1, gray(rocket->flash));
|
||||||
display->set(rocket->x + 0, rocket->y + 0, rocket->flash, rocket->flash, rocket->flash);
|
display->set(rocket->x + 0, rocket->y + 0, gray(rocket->flash));
|
||||||
display->set(rocket->x + 1, rocket->y + 1, rocket->flash, rocket->flash, rocket->flash);
|
display->set(rocket->x + 1, rocket->y + 1, gray(rocket->flash));
|
||||||
display->set(rocket->x + 1, rocket->y - 1, rocket->flash, rocket->flash, rocket->flash);
|
display->set(rocket->x + 1, rocket->y - 1, gray(rocket->flash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawHero() {
|
void drawHero() {
|
||||||
display->set(heroX - 1, display->height - 1, 0, 0, 255);
|
display->set(heroX - 1, display->height - 1, BLUE);
|
||||||
display->set(heroX + 0, display->height - 1, 0, 0, 255);
|
display->set(heroX + 0, display->height - 1, BLUE);
|
||||||
display->set(heroX + 1, display->height - 1, 0, 0, 255);
|
display->set(heroX + 1, display->height - 1, BLUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
|
|||||||
@ -30,7 +30,7 @@ void wifi_setup() {
|
|||||||
|
|
||||||
auto index = (uint16_t) round(ratio * (double) display.pixelCount);
|
auto index = (uint16_t) round(ratio * (double) display.pixelCount);
|
||||||
auto color = (uint8_t) round(ratio * 255.0);
|
auto color = (uint8_t) round(ratio * 255.0);
|
||||||
display.setIndex(index, 255 - color, color, 0);
|
display.set(index, {(uint8_t) (255 - color), color, 0});
|
||||||
display.loop();
|
display.loop();
|
||||||
});
|
});
|
||||||
ArduinoOTA.onEnd([]() {
|
ArduinoOTA.onEnd([]() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user