2019-06-11 17:48:09 +00:00
|
|
|
#include "Window.h"
|
|
|
|
#include "functions.h"
|
|
|
|
|
|
|
|
Window* Window::getFullWindow() {
|
|
|
|
static Window win;
|
|
|
|
return &win;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::setPixel(uint8_t x, uint8_t y, CRGB* color) {
|
|
|
|
if (x>=this->width || y>=this->height) return;
|
|
|
|
leds[this->coordsToGlobalIndex(x, y)] = *color;
|
|
|
|
}
|
|
|
|
|
2019-06-19 20:29:11 +00:00
|
|
|
void Window::raisePixel(uint8_t x, uint8_t y, CRGB* color) {
|
|
|
|
if (x>=this->width || y>=this->height) return;
|
|
|
|
leds[this->coordsToGlobalIndex(x, y)] |= *color;
|
|
|
|
}
|
|
|
|
|
2019-06-11 17:48:09 +00:00
|
|
|
void Window::setPixelByIndex(uint16_t index, CRGB* color) {
|
|
|
|
uint8_t x = index % this->width;
|
|
|
|
uint8_t y = index / this->width;
|
|
|
|
this->setPixel(x, y, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t Window::coordsToGlobalIndex(uint8_t x, uint8_t y) {
|
|
|
|
return XYsafe(x + this->x, y+this->y);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t Window::localToGlobalIndex(uint16_t index) {
|
|
|
|
uint8_t x = index % this->width;
|
|
|
|
uint8_t y = index / this->width;
|
|
|
|
return coordsToGlobalIndex(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::clear() {
|
|
|
|
CRGB black(0x000000);
|
|
|
|
this->clear(&black);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::clear(CRGB* color) {
|
|
|
|
for(int x=0; x<this->width; x++) for(int y=0; y<this->height; y++) this->setPixel(x, y, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::drawChar(Font* font, uint8_t xPos, uint8_t yPos, const char c, CRGB* color, bool mask) {
|
|
|
|
if (!font->isCharAllowed(c)) return;
|
|
|
|
uint16_t position = font->getCharPosition(c);
|
|
|
|
uint8_t* data = new uint8_t[font->width];
|
|
|
|
memcpy_P(data, font->data + (position*font->width), font->width);
|
|
|
|
|
|
|
|
for(uint8_t y=0; y<font->height; y++) for(uint8_t x=0; x<font->width; x++) {
|
|
|
|
bool on = (data[x]>>(font->height - 1 - y) & 1) * 255;
|
|
|
|
if (mask) on = !on;
|
|
|
|
if (on) this->setPixel(x + xPos, y + yPos, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::addPixelColor(uint16_t index, CRGB* color) {
|
|
|
|
leds[localToGlobalIndex(index)] += *color;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::fadeToBlackBy(fract8 speed) {
|
|
|
|
for (uint8_t x=0; x<this->width; x++) for(uint8_t y=0; y<this->height; y++) {
|
|
|
|
leds[coordsToGlobalIndex(x, y)].nscale8(255 - speed);
|
|
|
|
}
|
|
|
|
}
|
2019-06-15 12:16:27 +00:00
|
|
|
|
|
|
|
void Window::line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, CRGB* color) {
|
|
|
|
// Bresenham algorithm
|
2019-09-04 03:58:36 +00:00
|
|
|
int dx = x2-x1;
|
|
|
|
int dy = y2-y1;
|
|
|
|
|
|
|
|
int x = x1;
|
|
|
|
int y = y1;
|
|
|
|
|
|
|
|
int p = 2*dy - dx;
|
|
|
|
|
|
|
|
while (x < x2) {
|
|
|
|
if (p >= 0) {
|
|
|
|
setPixel(x, y, color);
|
|
|
|
y++;
|
|
|
|
p = p + 2*dy - 2*dx;
|
|
|
|
} else {
|
|
|
|
setPixel(x, y, color);
|
|
|
|
p = p + 2*dy;
|
|
|
|
}
|
|
|
|
x++;
|
2019-06-15 12:16:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-04 03:58:36 +00:00
|
|
|
void Window::_circle_point(int x0, int y0, int x1, int y1, CRGB* color) {
|
|
|
|
setPixel(x0+x1, y0+y1, color);
|
|
|
|
setPixel(x0-x1, y0+y1, color);
|
|
|
|
setPixel(x0+x1, y0-y1, color);
|
|
|
|
setPixel(x0-x1, y0-y1, color);
|
|
|
|
setPixel(x0+y1, y0+x1, color);
|
|
|
|
setPixel(x0-y1, y0+x1, color);
|
|
|
|
setPixel(x0+y1, y0-x1, color);
|
|
|
|
setPixel(x0-y1, y0-x1, color);
|
|
|
|
}
|
|
|
|
|
2019-06-15 12:16:27 +00:00
|
|
|
void Window::circle(uint8_t x0, uint8_t y0, uint8_t radius, CRGB* color) {
|
|
|
|
// Again, Bresenham
|
2019-09-04 03:58:36 +00:00
|
|
|
int x=0, y=radius;
|
|
|
|
int d=3 - 2*radius;
|
|
|
|
_circle_point(x0, y0, x, y, color);
|
|
|
|
while (y >= x) {
|
|
|
|
x++;
|
|
|
|
if (d>0) {
|
2019-06-15 12:16:27 +00:00
|
|
|
y--;
|
2019-09-04 03:58:36 +00:00
|
|
|
d = d + 4*(x-y) + 10;
|
|
|
|
} else {
|
|
|
|
d = d + 4*x + 6;
|
2019-06-15 12:16:27 +00:00
|
|
|
}
|
2019-09-04 03:58:36 +00:00
|
|
|
_circle_point(x0, y0, x, y, color);
|
2019-06-15 12:16:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::lineWithAngle(uint8_t x, uint8_t y, uint8_t angle, uint8_t length, CRGB* color) {
|
|
|
|
lineWithAngle(x, y, angle, 0, length, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Window::lineWithAngle(uint8_t x, uint8_t y, uint8_t angle, uint8_t startdist, uint8_t length, CRGB* color) {
|
|
|
|
int16_t x1 = x;
|
|
|
|
int16_t y1 = y;
|
2019-06-19 20:29:11 +00:00
|
|
|
|
2019-06-15 12:16:27 +00:00
|
|
|
if (startdist > 0) {
|
|
|
|
x1 = x + scale8(startdist, cos8(angle));
|
|
|
|
y1 = y + scale8(startdist, sin8(angle));
|
|
|
|
}
|
2019-06-19 20:29:11 +00:00
|
|
|
|
2019-06-15 12:16:27 +00:00
|
|
|
int16_t x2 = x + scale8(startdist + length, cos8(angle));
|
|
|
|
int16_t y2 = y + scale8(startdist + length, sin8(angle));
|
2019-06-19 20:29:11 +00:00
|
|
|
|
2019-06-15 12:16:27 +00:00
|
|
|
line(x1, y1, x2, y2, color);
|
|
|
|
}
|