/******************************************* * Most Awesome Renderer Ever *******************************************/ //#include #include #include #include #include extern "C" { #include #include } #include #include #include #include #include namespace Render{ typedef int32_t p_t; struct pos_t { p_t x; p_t y; }; struct bbox2d_t { uint16_t xMin, Ymin; uint16_t Xmax, Ymax; }; enum class ScreenRotation { Rot0 = 0, Rot90 = 90, Rot180 = 180, Rot270 = 270 }; enum class BlendMode { Add, Intersect }; enum class Color { White, Black }; class Page; class Drawable; class DrawablePoint; class DrawableLine; class DrawableRectangle; typedef pos_t dim_t; typedef std::vector> Pages; typedef std::vector> Drawables; class Mare { friend class Drawable; friend class Page; public: Mare(dim_t size, ScreenRotation rot); ~Mare(); // getters, setters public: void setSize(const dim_t size); const dim_t getSize() {return _screenSize;}; const dim_t getCenter(); void setRotation(const ScreenRotation r); const ScreenRotation getRotation() {return _rotation;}; void setCurrentPage(const uint8_t p); const Page& getCurrentPage() {return *_pages.at(0).get();}; // drawables, pages public: template T* addDrawable(Args... args) { static size_t lastDrawableIndex(0); static_assert(std::is_base_of_v, "Mare::addDrawable() error, type T is not inherited from Drawable."); auto newD = std::shared_ptr(new T(lastDrawableIndex++, nullptr, this, args...)); _drawables.push_back(std::move(newD)); auto foo = _drawables.back().get(); return static_cast(foo); } void removeDrawable(const size_t id) {}; void addPage() {}; void removePage(const uint8_t num) {}; const Drawables& getDrawables() {return _drawables;}; const Pages& getPages() {return _pages;}; //render private: void clearBuffer(uint8_t* buffer, uint16_t len, Color col); bool applyScreenRotation(uint16_t* x, uint16_t* y); void visitDrawables(Drawable* parent) {}; public: void render(); void setPixel(uint8_t* img, uint16_t x, uint16_t y, BlendMode bm); pos_t rotateXY(int16_t x, int16_t y, float rot); void clearScreen(); // members private: dim_t _screenSize; Pages _pages; uint8_t* _screenBufferForeground; uint8_t* _screenBufferBackground; uint16_t _bufferDim; Drawables _drawables; // background drawables for all the pages ScreenRotation _rotation; bool _full; public: uint8_t* bBuffer() { return _screenBufferBackground; } uint8_t* fBuffer() { return _screenBufferForeground; } }; class Drawable { public: Drawable(const size_t id, Drawable* parent, Mare* engine); ~Drawable(); public: virtual void render() {}; public: void setId(const size_t id) { _id = id; }; void setOrigin(const pos_t origin) { _origin = origin; }; void setDirty() {_dirty = true;}; void resetDirty() {_dirty = false;}; void setBlendMode(const BlendMode mode) { _blendMode = mode; }; const bool isDirty() {return _dirty;} const pos_t getOrigin() { return _origin; }; const bbox2d_t getBBox() { return _bbox; }; const BlendMode getBlendMode() { return _blendMode; }; uint8_t* getBuffer() { if (_parent == nullptr) return engine()->bBuffer(); else return engine()->fBuffer(); } Mare* engine() { return _engine; }; Drawable* parent() { return _parent; }; private: Drawable* _parent; Mare* _engine; bool _dirty; size_t _id; pos_t _origin; bbox2d_t _bbox; BlendMode _blendMode; Drawables _children; }; class DrawablePoint: public Drawable { public: DrawablePoint(const size_t id, Drawable* parent, Mare* engine, dim_t size); ~DrawablePoint(); public: void setSize(dim_t size) { _size = size; }; const dim_t getSize() { return _size; }; private: void render(); // members private: dim_t _size; }; class DrawableLine: public Drawable { friend class DrawableRectangle; public: DrawableLine(const size_t id, Drawable* parent, Mare* engine); ~DrawableLine(); public: void setThickness(uint16_t thickness) { uint8_t d = thickness >> 1; _thickness = thickness; _ofst = (d % 2)==0 ? d + 1: d; }; const uint16_t getThickness() {return _thickness;}; void setRotation(uint16_t rotation) {_rotation = rotation;}; const uint16_t getRotation() {return _rotation;}; void setLength(uint16_t length) {_length = length;}; const uint16_t getLength() {return _length;}; private: void render(); // difficult business // members private: uint16_t _thickness; uint16_t _length; uint16_t _rotation; uint8_t _ofst; }; class DrawableRectangle: public Drawable { public: DrawableRectangle(const size_t id, Drawable* parent, Mare* engine); ~DrawableRectangle(); public: void setThickness(uint16_t thickness) {_thickness = thickness;}; const uint16_t getThickness() {return _thickness;}; void setRotation(uint16_t rotation) {_rotation = rotation;}; const uint16_t getRotation() {return _rotation;}; void setDimension(dim_t dim) {_dim = dim;}; const dim_t getDimension() {return _dim;}; void setOutline(bool outline) {_outline = outline;}; const bool getOutline() {return _outline;}; private: void createOutline(); void render(); // members private: DrawableLine* l1 = nullptr; DrawableLine* l2 = nullptr; DrawableLine* l3 = nullptr; DrawableLine* l4 = nullptr; uint16_t _thickness; uint16_t _rotation; dim_t _dim; bool _outline; }; class DrawableCircle: public Drawable { DrawableCircle(); ~DrawableCircle(); public: private: void render() {}; // members private: }; class DrawableChar: public Drawable { DrawableChar(); ~DrawableChar(); public: private: void render() {}; // members private: }; class DrawableString: public Drawable { DrawableString(); ~DrawableString(); public: private: void render() {}; // members private: }; class DrawableCustom: public Drawable { DrawableCustom(); ~DrawableCustom(); public: private: void render() {}; // members private: }; class Page { Page(); ~Page(); public: private: Drawables _backDrawables; Drawables _frontDrawables; }; }