2022-06-13 11:26:21 +01:00
|
|
|
#include "pico_graphics.hpp"
|
|
|
|
|
|
|
|
namespace pimoroni {
|
|
|
|
PicoGraphics_PenP8::PicoGraphics_PenP8(uint16_t width, uint16_t height, void *frame_buffer)
|
|
|
|
: PicoGraphics(width, height, frame_buffer) {
|
|
|
|
this->pen_type = PEN_P8;
|
|
|
|
if(this->frame_buffer == nullptr) {
|
|
|
|
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
|
|
|
}
|
|
|
|
for(auto i = 0u; i < 256; i++) {
|
|
|
|
palette[i] = {0, 0, 0};
|
|
|
|
used[i] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void PicoGraphics_PenP8::set_pen(uint c) {
|
|
|
|
color = c;
|
|
|
|
}
|
|
|
|
void PicoGraphics_PenP8::set_pen(uint8_t r, uint8_t g, uint8_t b) {
|
|
|
|
int pen = RGB(r, g, b).closest(palette, 16);
|
|
|
|
if(pen != -1) color = pen;
|
|
|
|
}
|
|
|
|
int PicoGraphics_PenP8::update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b) {
|
|
|
|
i &= 0xff;
|
|
|
|
palette[i] = {r, g, b};
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
int PicoGraphics_PenP8::create_pen(uint8_t r, uint8_t g, uint8_t b) {
|
|
|
|
// Create a colour and place it in the palette if there's space
|
|
|
|
for(auto i = 0u; i < 256u; i++) {
|
|
|
|
if(!used[i]) {
|
|
|
|
palette[i] = {r, g, b};
|
|
|
|
used[i] = true;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int PicoGraphics_PenP8::reset_pen(uint8_t i) {
|
|
|
|
palette[i] = {0, 0, 0};
|
|
|
|
used[i] = false;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
void PicoGraphics_PenP8::set_pixel(const Point &p) {
|
|
|
|
uint8_t *buf = (uint8_t *)frame_buffer;
|
|
|
|
buf[p.y * bounds.w + p.x] = color;
|
|
|
|
}
|
|
|
|
void PicoGraphics_PenP8::scanline_convert(PenType type, conversion_callback_func callback) {
|
|
|
|
if(type == PEN_RGB565) {
|
|
|
|
// Cache the RGB888 palette as RGB565
|
|
|
|
RGB565 cache[256];
|
|
|
|
for(auto i = 0u; i < 256; i++) {
|
|
|
|
cache[i] = palette[i].to_rgb565();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Treat our void* frame_buffer as uint8_t
|
|
|
|
uint8_t *src = (uint8_t *)frame_buffer;
|
|
|
|
|
|
|
|
// Allocate a per-row temporary buffer
|
|
|
|
uint16_t row_buf[bounds.w];
|
|
|
|
for(auto y = 0; y < bounds.h; y++) {
|
|
|
|
for(auto x = 0; x < bounds.w; x++) {
|
|
|
|
row_buf[x] = cache[src[bounds.w * y + x]];
|
|
|
|
}
|
|
|
|
// Callback to the driver with the row data
|
2022-06-13 15:45:47 +01:00
|
|
|
callback(row_buf, bounds.w * sizeof(uint8_t));
|
2022-06-13 11:26:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|