diff --git a/libraries/pico_graphics/pico_graphics.cpp b/libraries/pico_graphics/pico_graphics.cpp index 62dd91a2..340e42ab 100644 --- a/libraries/pico_graphics/pico_graphics.cpp +++ b/libraries/pico_graphics/pico_graphics.cpp @@ -37,16 +37,16 @@ namespace pimoroni { int PicoGraphics::search_palette(RGB565 c) { 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; } int PicoGraphics::put_palette(RGB565 c) { for(auto i = 0u; i < 256; i++) { - if(!palette_status[i]) { + if(!(palette_status[i] & (PaletteStatusUsed | PaletteStatusReserved))) { palette[i] = c; - palette_status[i] = true; + palette_status[i] = PaletteStatusUsed; return i; } } @@ -55,21 +55,33 @@ namespace pimoroni { void PicoGraphics::set_palette(uint8_t i, uint16_t c) { palette[i] = c; - palette_status[i] = true; + palette_status[i] |= PaletteStatusUsed; } - void PicoGraphics::empty_palette() { - for (auto i = 0u; i < 255; i++) { + int PicoGraphics::reserve_palette() { + 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_status[i] = false; + palette_status[i] = 0; } } 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] = __builtin_bswap16(palette[i]); - palette_status[i] = true; + palette_status[i] = PaletteStatusUsed; } } diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index f9fba09e..de051668 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -55,14 +55,19 @@ namespace pimoroni { const bitmap::font_t *font; - uint16_t palette[256]; - bool palette_status[256]; + RGB565 palette[256]; + uint8_t palette_status[256]; enum PaletteMode { PaletteModeRGB332 = 0, PaletteModeUSER = 1 }; + enum PaletteStatus : uint8_t { + PaletteStatusReserved = 1, + PaletteStatusUsed = 2 + }; + PaletteMode palette_mode = PaletteModeRGB332; public: @@ -96,6 +101,7 @@ namespace pimoroni { int create_pen(uint8_t r, uint8_t g, uint8_t b); + int reserve_palette(); void empty_palette(); void rgb332_palette(); diff --git a/micropython/modules/st7789/st7789.c b/micropython/modules/st7789/st7789.c index 86092b31..bdfff890 100644 --- a/micropython/modules/st7789/st7789.c +++ b/micropython/modules/st7789/st7789.c @@ -12,6 +12,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_framebuffer_obj, GenericST7789_set_f // Palette management 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_1(GenericST7789_reserve_palette_obj, GenericST7789_reserve_palette); // 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), 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_create_pen), MP_ROM_PTR(&GenericST7789_create_pen_obj) }, diff --git a/micropython/modules/st7789/st7789.cpp b/micropython/modules/st7789/st7789.cpp index 9042de7e..25dcaa8b 100644 --- a/micropython/modules/st7789/st7789.cpp +++ b/micropython/modules/st7789/st7789.cpp @@ -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; } +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) { enum { ARG_self, ARG_r, ARG_g, ARG_b }; 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) { - 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); diff --git a/micropython/modules/st7789/st7789.h b/micropython/modules/st7789/st7789.h index ab1fc771..af025054 100644 --- a/micropython/modules/st7789/st7789.h +++ b/micropython/modules/st7789/st7789.h @@ -19,6 +19,7 @@ extern mp_obj_t GenericST7789_set_backlight(mp_obj_t self_in, mp_obj_t brightnes // 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(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 extern mp_obj_t GenericST7789_set_pen(mp_obj_t self_in, mp_obj_t pen);