ST7789/PicoGraphics: Fix palette bugs, add reserve.

This commit is contained in:
Phil Howard 2022-05-28 18:08:47 +01:00
parent dbd716f78f
commit c13f53092d
5 changed files with 45 additions and 12 deletions

View File

@ -37,16 +37,16 @@ namespace pimoroni {
int PicoGraphics::search_palette(RGB565 c) { int PicoGraphics::search_palette(RGB565 c) {
for(auto i = 0u; i < 256; i++) { for(auto i = 0u; i < 256; i++) {
if(palette_status[i] && palette[i] == c) return i; if((palette_status[i] & PaletteStatusUsed) && palette[i] == c) return i;
} }
return -1; return -1;
} }
int PicoGraphics::put_palette(RGB565 c) { int PicoGraphics::put_palette(RGB565 c) {
for(auto i = 0u; i < 256; i++) { for(auto i = 0u; i < 256; i++) {
if(!palette_status[i]) { if(!(palette_status[i] & (PaletteStatusUsed | PaletteStatusReserved))) {
palette[i] = c; palette[i] = c;
palette_status[i] = true; palette_status[i] = PaletteStatusUsed;
return i; return i;
} }
} }
@ -55,21 +55,33 @@ namespace pimoroni {
void PicoGraphics::set_palette(uint8_t i, uint16_t c) { void PicoGraphics::set_palette(uint8_t i, uint16_t c) {
palette[i] = c; palette[i] = c;
palette_status[i] = true; palette_status[i] |= PaletteStatusUsed;
} }
void PicoGraphics::empty_palette() { int PicoGraphics::reserve_palette() {
for (auto i = 0u; i < 255; i++) { for (auto i = 0u; i < 256; i++) {
if (!palette_status[i]) {
palette_status[i] = PaletteStatusReserved;
return i;
}
}
return -1;
}
void PicoGraphics::empty_palette() {
for (auto i = 0u; i < 256; i++) {
palette[i] = 0; palette[i] = 0;
palette_status[i] = false; palette_status[i] = 0;
} }
} }
void PicoGraphics::rgb332_palette() { void PicoGraphics::rgb332_palette() {
for (auto i = 0u; i < 255; i++) { for (auto i = 0u; i < 256; i++) {
// Convert the implicit RGB332 (i) into RGB565
// 0b11100 000 0b00011100 0b00000011
palette[i] = ((i & 0b11100000) << 8) | ((i & 0b00011100) << 6) | ((i & 0b00000011) << 3); palette[i] = ((i & 0b11100000) << 8) | ((i & 0b00011100) << 6) | ((i & 0b00000011) << 3);
palette[i] = __builtin_bswap16(palette[i]); palette[i] = __builtin_bswap16(palette[i]);
palette_status[i] = true; palette_status[i] = PaletteStatusUsed;
} }
} }

View File

@ -55,14 +55,19 @@ namespace pimoroni {
const bitmap::font_t *font; const bitmap::font_t *font;
uint16_t palette[256]; RGB565 palette[256];
bool palette_status[256]; uint8_t palette_status[256];
enum PaletteMode { enum PaletteMode {
PaletteModeRGB332 = 0, PaletteModeRGB332 = 0,
PaletteModeUSER = 1 PaletteModeUSER = 1
}; };
enum PaletteStatus : uint8_t {
PaletteStatusReserved = 1,
PaletteStatusUsed = 2
};
PaletteMode palette_mode = PaletteModeRGB332; PaletteMode palette_mode = PaletteModeRGB332;
public: public:
@ -96,6 +101,7 @@ namespace pimoroni {
int create_pen(uint8_t r, uint8_t g, uint8_t b); int create_pen(uint8_t r, uint8_t g, uint8_t b);
int reserve_palette();
void empty_palette(); void empty_palette();
void rgb332_palette(); void rgb332_palette();

View File

@ -12,6 +12,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_framebuffer_obj, GenericST7789_set_f
// Palette management // Palette management
MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_palette_mode_obj, GenericST7789_set_palette_mode); MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_palette_mode_obj, GenericST7789_set_palette_mode);
MP_DEFINE_CONST_FUN_OBJ_3(GenericST7789_set_palette_obj, GenericST7789_set_palette); MP_DEFINE_CONST_FUN_OBJ_3(GenericST7789_set_palette_obj, GenericST7789_set_palette);
MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_reserve_palette_obj, GenericST7789_reserve_palette);
// Pen // Pen
MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_pen_obj, GenericST7789_set_pen); MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_pen_obj, GenericST7789_set_pen);
@ -42,6 +43,7 @@ STATIC const mp_rom_map_elem_t GenericST7789_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_set_palette_mode), MP_ROM_PTR(&GenericST7789_set_palette_mode_obj) }, { MP_ROM_QSTR(MP_QSTR_set_palette_mode), MP_ROM_PTR(&GenericST7789_set_palette_mode_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_palette), MP_ROM_PTR(&GenericST7789_set_palette_obj) }, { MP_ROM_QSTR(MP_QSTR_set_palette), MP_ROM_PTR(&GenericST7789_set_palette_obj) },
{ MP_ROM_QSTR(MP_QSTR_reserve_palette), MP_ROM_PTR(&GenericST7789_reserve_palette_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&GenericST7789_set_backlight_obj) }, { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&GenericST7789_set_backlight_obj) },
{ MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&GenericST7789_create_pen_obj) }, { MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&GenericST7789_create_pen_obj) },

View File

@ -313,6 +313,18 @@ mp_obj_t GenericST7789_set_palette(mp_obj_t self_in, mp_obj_t index, mp_obj_t co
return mp_const_none; return mp_const_none;
} }
mp_obj_t GenericST7789_reserve_palette(mp_obj_t self_in) {
GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t);
int result = self->st7789->reserve_palette();
if (result == -1) {
mp_raise_ValueError("reserve_palette failed. No space in palette!");
}
return mp_obj_new_int(result);
}
mp_obj_t GenericST7789_create_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_t GenericST7789_create_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_r, ARG_g, ARG_b }; enum { ARG_self, ARG_r, ARG_g, ARG_b };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -334,7 +346,7 @@ mp_obj_t GenericST7789_create_pen(size_t n_args, const mp_obj_t *pos_args, mp_ma
); );
if (result == -1) { if (result == -1) {
mp_raise_ValueError("create_pen failed. No space in palette!"); mp_raise_ValueError("create_pen failed. No matching colour or space in palette!");
} }
return mp_obj_new_int(result); return mp_obj_new_int(result);

View File

@ -19,6 +19,7 @@ extern mp_obj_t GenericST7789_set_backlight(mp_obj_t self_in, mp_obj_t brightnes
// Palette management // Palette management
extern mp_obj_t GenericST7789_set_palette_mode(mp_obj_t self_in, mp_obj_t mode); extern mp_obj_t GenericST7789_set_palette_mode(mp_obj_t self_in, mp_obj_t mode);
extern mp_obj_t GenericST7789_set_palette(mp_obj_t self_in, mp_obj_t index, mp_obj_t colour); extern mp_obj_t GenericST7789_set_palette(mp_obj_t self_in, mp_obj_t index, mp_obj_t colour);
extern mp_obj_t GenericST7789_reserve_palette(mp_obj_t self_in);
// Pen // Pen
extern mp_obj_t GenericST7789_set_pen(mp_obj_t self_in, mp_obj_t pen); extern mp_obj_t GenericST7789_set_pen(mp_obj_t self_in, mp_obj_t pen);