355 lines
10 KiB
C++
355 lines
10 KiB
C++
/*******************************************
|
|
* Most Awesome Renderer Ever
|
|
*******************************************/
|
|
|
|
//#include <stdio.h>
|
|
#include <pico/stdlib.h>
|
|
#include <pico/printf.h>
|
|
#include <pico/int64_ops.h>
|
|
#include <pico/float.h>
|
|
|
|
extern "C" {
|
|
#include <DEV_Config.h>
|
|
#include <EPD_2in9_V2.h>
|
|
}
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <math.h>
|
|
#include <fonts.h>
|
|
|
|
namespace Render{
|
|
|
|
typedef int32_t p_t;
|
|
|
|
struct pos_t {
|
|
friend bool operator==(const pos_t a, const pos_t b){ return a.x==b.x && a.y==b.y;};
|
|
friend bool operator!=(const pos_t a, const pos_t b){ return a.x!=b.x || a.y!=b.y;};
|
|
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
|
|
};
|
|
|
|
enum class Font {
|
|
Font8,
|
|
Font12,
|
|
Font16,
|
|
Font20,
|
|
Font24
|
|
};
|
|
|
|
typedef ScreenRotation TextRotation;
|
|
|
|
class Page;
|
|
class Drawable;
|
|
class DrawablePoint;
|
|
class DrawableLine;
|
|
class DrawableRectangle;
|
|
class DrawableCircle;
|
|
class DrawableString;
|
|
class DrawableCustom;
|
|
|
|
typedef pos_t dim_t;
|
|
typedef std::vector<std::shared_ptr<Page>> Pages;
|
|
typedef std::vector<std::shared_ptr<Drawable>> 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 <class T, class... Args>
|
|
T* addDrawable(Args... args) {
|
|
static size_t lastDrawableIndex(0);
|
|
static_assert(std::is_base_of_v<Drawable, T>, "Mare::addDrawable<T>() error, type T is not inherited from Drawable.");
|
|
auto newD = std::shared_ptr<T>(new T(lastDrawableIndex++, nullptr, this, args...));
|
|
_drawables.push_back(std::move(newD));
|
|
auto foo = _drawables.back().get();
|
|
return static_cast<T*>(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 {
|
|
public:
|
|
DrawableCircle(const size_t id, Drawable* parent, Mare* engine);
|
|
~DrawableCircle();
|
|
|
|
public:
|
|
void setThickness(uint16_t thickness) { _thickness = thickness; };
|
|
const uint16_t getThickness() {return _thickness; };
|
|
void setRadius(uint16_t radius) { _radius = radius; };
|
|
const uint16_t getRadius() { return _radius; };
|
|
void setOutline(bool outline) { _outline = outline; };
|
|
const bool getOutline() { return _outline; };
|
|
|
|
private:
|
|
void render();
|
|
|
|
// members
|
|
private:
|
|
uint16_t _thickness;
|
|
uint16_t _radius;
|
|
bool _outline;
|
|
};
|
|
|
|
class DrawableChar: public Drawable {
|
|
friend class DrawableString;
|
|
public:
|
|
DrawableChar(const size_t id, Drawable* parent, Mare* engine, char c, Font f);
|
|
~DrawableChar();
|
|
|
|
public:
|
|
|
|
private:
|
|
void render();
|
|
|
|
// members
|
|
private:
|
|
Font _fontEnum;
|
|
const _tFont* _font;
|
|
char _char;
|
|
};
|
|
|
|
class DrawableString: public Drawable {
|
|
public:
|
|
DrawableString(const size_t id, Drawable* parent, Mare* engine, std::string &s, Font f);
|
|
~DrawableString();
|
|
|
|
public:
|
|
void setString(std::string& s) { _s = s; };
|
|
const std::string& getString() { return _s; };
|
|
void setFont(Font f) { _fontEnum = f; };
|
|
const Font getFont() { return _fontEnum; };
|
|
void setRotation(TextRotation rotation) { _rotation = rotation; };
|
|
const TextRotation getRotation() { return _rotation; };
|
|
void setSpacing(uint8_t hSpace, uint8_t vSpace) {_vSpace= vSpace; _hSpace=hSpace;}
|
|
const pos_t getSpacing() { return {_hSpace,_vSpace}; };
|
|
private:
|
|
void render();
|
|
|
|
// members
|
|
private:
|
|
Font _fontEnum;
|
|
TextRotation _rotation;
|
|
std::string _s;
|
|
std::vector<DrawableChar*> _chars;
|
|
uint8_t _hSpace=2, _vSpace=2;
|
|
};
|
|
|
|
class DrawableCustom: public Drawable {
|
|
|
|
DrawableCustom();
|
|
~DrawableCustom();
|
|
|
|
public:
|
|
|
|
private:
|
|
void render() {};
|
|
|
|
// members
|
|
private:
|
|
};
|
|
|
|
|
|
class Page {
|
|
|
|
Page();
|
|
~Page();
|
|
|
|
public:
|
|
|
|
private:
|
|
Drawables _backDrawables;
|
|
Drawables _frontDrawables;
|
|
};
|
|
} |