/******************************************* * Most Awesome Renderer Ever *******************************************/ #include "mare.h" namespace Render { Mare::Mare(dim_t size, ScreenRotation rot) : _screenSize(size), _screenBufferBackground(nullptr), _screenBufferForeground(nullptr), _rotation(rot) { int rv; _bufferDim = (_screenSize.x >> 3) * _screenSize.y; _screenBufferBackground = (uint8_t*)malloc(sizeof(uint8_t)* _bufferDim); _screenBufferForeground = (uint8_t*)malloc(sizeof(uint8_t)* _bufferDim); clearBuffer(_screenBufferForeground, _bufferDim, Color::White); clearBuffer(_screenBufferBackground, _bufferDim, Color::White); // init display DEV_Delay_ms(500); if((rv=DEV_Module_Init())!=0){ printf("Init Failed, %d\n",rv); return; } EPD_2IN9_V2_Init(); EPD_2IN9_V2_Clear(); printf("Mare render engine created\n"); } Mare::~Mare(){ for (auto &d :_drawables) { d.reset(); } for (auto &p : _pages){ p.reset(); } free(_screenBufferBackground); free(_screenBufferForeground); } void Mare::render() { clearBuffer(_screenBufferBackground, _bufferDim, Color::White); for (auto d: _drawables) { if (d != nullptr) d->render(); } EPD_2IN9_V2_Display_Partial(_screenBufferBackground); } void Mare::clearBuffer(uint8_t* buffer, uint16_t len, Color col){ assert(buffer != nullptr); std::memset(buffer, col == Color::White ? 0xff : 0x00, len); } bool Mare::applyRotation(uint16_t* x, uint16_t* y) { uint16_t ax,ay; switch(_rotation){ case ScreenRotation::Rot0 : { if (*x >= _screenSize.x || *y >= _screenSize.y) return false; break; } case ScreenRotation::Rot90 : { if (*x >= _screenSize.y || *y >= _screenSize.x) return false; ax = *x; ay = *y; *x = _screenSize.x - ay; *y = ax; break; } case ScreenRotation::Rot180 : { if (*x >= _screenSize.x || *y >= _screenSize.y) return false; ax = *x; ay = *y; *x = _screenSize.x - ax; *y = _screenSize.y - ay; break; } case ScreenRotation::Rot270 : { if (*x >= _screenSize.y || *y >= _screenSize.x) return false; ax = *x; ay = *y; *x = ay; *y = _screenSize.y - ax; break; } } if (*x < 0 || *y < 0) return false; return true; } // Public const dim_t Mare::getCenter() { dim_t rv; if (_rotation == ScreenRotation::Rot0 || _rotation == ScreenRotation::Rot180){ rv.x = _screenSize.x >> 1; rv.y = _screenSize.y >> 1; } else { rv.x = _screenSize.y >> 1; rv.y = _screenSize.x >> 1; } return rv; } void Mare::setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value) { if (!applyRotation(&x,&y)) return; // from here the coordinates are natural for the screen img += (sizeof(uint8_t)*y*(_screenSize.x>>3) + sizeof(uint8_t)*(x>>3)); if (value) *img &= ~(0x80 >> (x%8)); else *img |= (0x80 >> (x%8)); } void Mare::clearScreen() { EPD_2IN9_V2_Clear(); clearBuffer(_screenBufferBackground, _bufferDim, Color::White); EPD_2IN9_V2_Display(_screenBufferBackground); } }