diff --git a/include/picoled.h b/include/picoled.h index 12904bc..d3ed0e5 100644 --- a/include/picoled.h +++ b/include/picoled.h @@ -2,26 +2,25 @@ #define PICOLED_H #include +#include namespace picoled { class pixel { + friend class oled; public: pixel() : - pixel(false) + pixel(0) {} - pixel(bool on) : - on(on) + pixel(uint8_t value) : + value(value) {} - bool is_on() const { return on; } - void invert() { on = !on; } - private: - bool on; + uint8_t value; }; class oled @@ -44,9 +43,13 @@ public: size_t get_width() const { return width; } size_t get_height() const { return height; } - virtual void update() const = 0; + void update() const; protected: + virtual void update_impl() const = 0; + + bool is_on(int x, int y) const; + size_t width; size_t height; diff --git a/include/picoled/SSD1306.h b/include/picoled/SSD1306.h index 950476f..d991ba6 100644 --- a/include/picoled/SSD1306.h +++ b/include/picoled/SSD1306.h @@ -16,7 +16,8 @@ public: ssd1306(i2c_inst* i2c, uint8_t address); virtual ~ssd1306(); - void update() const override; +protected: + void update_impl() const override; private: void command(uint8_t cmd) const; diff --git a/src/SSD1306.cpp b/src/SSD1306.cpp index 0c2aa83..0c26e8d 100644 --- a/src/SSD1306.cpp +++ b/src/SSD1306.cpp @@ -77,7 +77,7 @@ ssd1306::~ssd1306() delete[] buffer; } -void ssd1306::update() const +void ssd1306::update_impl() const { // clear display to zero memset(&buffer[1], 0, width * height * sizeof(*buffer)); @@ -86,7 +86,7 @@ void ssd1306::update() const { for (int y = 0; y < height; y++) { - if (!(*this)(x, y).is_on()) { continue; } + if (!is_on(x, y)) { continue; } const int index = (width - x - 1) + (y / 8) * width; const uint8_t bits = 1 << (y & 7); diff --git a/src/picoled.cpp b/src/picoled.cpp index beabab1..c5cfe9f 100644 --- a/src/picoled.cpp +++ b/src/picoled.cpp @@ -1,5 +1,14 @@ #include "picoled.h" +#include + +namespace +{ + +picoled::pixel DUMMY_PIXEL; + +} + namespace picoled { @@ -14,18 +23,29 @@ oled::~oled() delete[] pixels; } + pixel& oled::operator()(int x, int y) { - static pixel dummy; - if (x < 0 || x >= width || y < 0 || y >= height) { return dummy; } + if (x < 0 || x >= width || y < 0 || y >= height) { return DUMMY_PIXEL; } return pixels[x + y * width]; } const pixel& oled::operator()(int x, int y) const { + if (x < 0 || x >= width || y < 0 || y >= height) { return DUMMY_PIXEL; } return pixels[x + y * width]; } +void oled::update() const +{ + update_impl(); +} + +bool oled::is_on(int x, int y) const +{ + return (*this)(x, y).value > rand() % 0xFF; +} + void oled::clear() { for (int i = 0; i < width * height; i++)