#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; } 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; xwidth; x++) for(int y=0; yheight; 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; yheight; y++) for(uint8_t x=0; xwidth; 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; xwidth; x++) for(uint8_t y=0; yheight; y++) { leds[coordsToGlobalIndex(x, y)].nscale8(255 - speed); } } void Window::line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, CRGB* color) { // Bresenham algorithm int16_t dx = abs(x2-x1); int16_t dy = abs(y2-y1); int8_t sx = x1 dy) { err += dy; x1 += sx; } if (e2 < dx) { err += dx; y1 += sy; } } } void Window::circle(uint8_t x0, uint8_t y0, uint8_t radius, CRGB* color) { // Again, Bresenham uint8_t f = 1 - radius; int16_t ddF_x = 0; int16_t ddF_y = -2 * radius; uint8_t x = 0; uint8_t y = radius; setPixel(x0, y0 + radius, color); setPixel(x0, y0 - radius, color); setPixel(x0 + radius, y0, color); setPixel(x0 - radius, y0, color); while (x < y) { if (f >= 0) { y--; ddF_y += 2; f += ddF_y; } x++; ddF_x += 2; f += ddF_x + 1; setPixel(x0 + x, y0 + y, color); setPixel(x0 - x, y0 + y, color); setPixel(x0 + x, y0 - y, color); setPixel(x0 - x, y0 - y, color); setPixel(x0 + y, y0 + x, color); setPixel(x0 - y, y0 + x, color); setPixel(x0 + y, y0 - x, color); setPixel(x0 - y, y0 - x, color); } } 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; if (startdist > 0) { x1 = x + scale8(startdist, cos8(angle)); y1 = y + scale8(startdist, sin8(angle)); } int16_t x2 = x + scale8(startdist + length, cos8(angle)); int16_t y2 = y + scale8(startdist + length, sin8(angle)); line(x1, y1, x2, y2, color); }