diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index 49b11142..b0d81f30 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -85,19 +85,39 @@ namespace pimoroni { static constexpr RGB565 rgb332_to_rgb565(RGB332 c) { uint16_t p = ((c & 0b11100000) << 8) | - ((c & 0b00011100) << 6) | - ((c & 0b00000011) << 3); + ((c & 0b00011100) << 6) | + ((c & 0b00000011) << 3); return __builtin_bswap16(p); } + static constexpr RGB565 rgb565_to_rgb332(RGB565 c) { + c = __builtin_bswap16(c); + return ((c & 0b1110000000000000) >> 8) | + ((c & 0b0000011100000000) >> 6) | + ((c & 0b0000000000011000) >> 3); + } + static constexpr RGB565 rgb_to_rgb565(uint8_t r, uint8_t g, uint8_t b) { uint16_t p = ((r & 0b11111000) << 8) | - ((g & 0b11111100) << 3) | - ((b & 0b11111000) >> 3); + ((g & 0b11111100) << 3) | + ((b & 0b11111000) >> 3); return __builtin_bswap16(p); } + static constexpr void rgb332_to_rgb(RGB332 c, uint8_t &r, uint8_t &g, uint8_t &b) { + r = (c & 0b11100000) >> 0; + g = (c & 0b00011100) << 3; + b = (c & 0b00000011) << 6; + }; + + static constexpr void rgb565_to_rgb(RGB565 c, uint8_t &r, uint8_t &g, uint8_t &b) { + c = __builtin_bswap16(c); + r = (c & 0b1111100000000000) >> 8; + g = (c & 0b0000011111100000) >> 3; + b = (c & 0b0000000000011111) << 3; + }; + PicoGraphics(uint16_t width, uint16_t height, void *frame_buffer) : frame_buffer(frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height) { set_font(&font6); @@ -141,8 +161,8 @@ namespace pimoroni { class PicoGraphics_PenP4 : public PicoGraphics { public: uint8_t color; - PaletteEntry palette[8]; - const RGB565 default_palette[8] = { + PaletteEntry palette[16]; + const RGB565 default_palette[16] = { rgb_to_rgb565(57, 48, 57), // Black rgb_to_rgb565(255, 255, 255), // White rgb_to_rgb565(58, 91, 70), // Green @@ -158,6 +178,9 @@ namespace pimoroni { if(this->frame_buffer == nullptr) { this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]); } + for(auto i = 0u; i < 16; i++) { + palette[i].used = false; + } for(auto i = 0u; i < 8; i++) { palette[i].color = default_palette[i]; palette[i].used = true; diff --git a/micropython/modules/picographics/picographics.c b/micropython/modules/picographics/picographics.c index c8e00cc2..c42c804b 100644 --- a/micropython/modules/picographics/picographics.c +++ b/micropython/modules/picographics/picographics.c @@ -1,8 +1,10 @@ #include "picographics.h" // Module functions -STATIC MP_DEFINE_CONST_FUN_OBJ_3(ModPicoGraphics_module_RGB332_obj, ModPicoGraphics_module_RGB332); -STATIC MP_DEFINE_CONST_FUN_OBJ_3(ModPicoGraphics_module_RGB565_obj, ModPicoGraphics_module_RGB565); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(ModPicoGraphics_module_RGB_to_RGB332_obj, ModPicoGraphics_module_RGB_to_RGB332); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(ModPicoGraphics_module_RGB_to_RGB565_obj, ModPicoGraphics_module_RGB_to_RGB565); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(ModPicoGraphics_module_RGB332_to_RGB_obj, ModPicoGraphics_module_RGB332_to_RGB); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(ModPicoGraphics_module_RGB565_to_RGB_obj, ModPicoGraphics_module_RGB565_to_RGB); STATIC MP_DEFINE_CONST_FUN_OBJ_2(ModPicoGraphics_get_required_buffer_size_obj, ModPicoGraphics_get_required_buffer_size); // Class Methods @@ -74,6 +76,7 @@ const mp_obj_type_t ModPicoGraphics_type = { { &mp_type_type }, .name = MP_QSTR_picographics, .make_new = ModPicoGraphics_make_new, + .buffer_p = { .get_buffer = ModPicoGraphics_get_framebuffer }, .locals_dict = (mp_obj_dict_t*)&ModPicoGraphics_locals_dict, }; @@ -83,8 +86,11 @@ STATIC const mp_map_elem_t picographics_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PicoGraphics), (mp_obj_t)&ModPicoGraphics_type }, { MP_ROM_QSTR(MP_QSTR_get_buffer_size), MP_ROM_PTR(&ModPicoGraphics_get_required_buffer_size_obj) }, - { MP_ROM_QSTR(MP_QSTR_RGB332), MP_ROM_PTR(&ModPicoGraphics_module_RGB332_obj) }, - { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_PTR(&ModPicoGraphics_module_RGB565_obj) }, + // Colour conversion + { MP_ROM_QSTR(MP_QSTR_RGB_to_RGB332), MP_ROM_PTR(&ModPicoGraphics_module_RGB_to_RGB332_obj) }, + { MP_ROM_QSTR(MP_QSTR_RGB_to_RGB565), MP_ROM_PTR(&ModPicoGraphics_module_RGB_to_RGB565_obj) }, + { MP_ROM_QSTR(MP_QSTR_RGB332_to_RGB), MP_ROM_PTR(&ModPicoGraphics_module_RGB332_to_RGB_obj) }, + { MP_ROM_QSTR(MP_QSTR_RGB565_to_RGB), MP_ROM_PTR(&ModPicoGraphics_module_RGB565_to_RGB_obj) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_LCD_240X240), MP_ROM_INT(DISPLAY_LCD_240X240) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_ROUND_LCD_240X240), MP_ROM_INT(DISPLAY_ROUND_LCD_240X240) }, diff --git a/micropython/modules/picographics/picographics.cpp b/micropython/modules/picographics/picographics.cpp index 33a15cf9..fb108a63 100644 --- a/micropython/modules/picographics/picographics.cpp +++ b/micropython/modules/picographics/picographics.cpp @@ -182,6 +182,15 @@ mp_obj_t ModPicoGraphics_set_font(mp_obj_t self_in, mp_obj_t font) { return mp_const_none; } +mp_int_t ModPicoGraphics_get_framebuffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(self_in, ModPicoGraphics_obj_t); + (void)flags; + bufinfo->buf = self->graphics->frame_buffer; + bufinfo->len = get_required_buffer_size((PicoGraphicsPenType)self->graphics->pen_type, self->graphics->bounds.w, self->graphics->bounds.h); + bufinfo->typecode = 'B'; + return 0; +} + mp_obj_t ModPicoGraphics_set_framebuffer(mp_obj_t self_in, mp_obj_t framebuffer) { ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(self_in, ModPicoGraphics_obj_t); @@ -245,7 +254,29 @@ mp_obj_t ModPicoGraphics_set_backlight(mp_obj_t self_in, mp_obj_t brightness) { return mp_const_none; } -mp_obj_t ModPicoGraphics_module_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b) { +mp_obj_t ModPicoGraphics_module_RGB332_to_RGB(mp_obj_t rgb332) { + uint8_t r, g, b; + PicoGraphics::rgb332_to_rgb(mp_obj_get_int(rgb332), r, g, b); + mp_obj_t t[] = { + mp_obj_new_int(r), + mp_obj_new_int(g), + mp_obj_new_int(b), + }; + return mp_obj_new_tuple(3, t); +} + +mp_obj_t ModPicoGraphics_module_RGB565_to_RGB(mp_obj_t rgb565) { + uint8_t r, g, b; + PicoGraphics::rgb565_to_rgb(mp_obj_get_int(rgb565), r, g, b); + mp_obj_t t[] = { + mp_obj_new_int(r), + mp_obj_new_int(g), + mp_obj_new_int(b), + }; + return mp_obj_new_tuple(3, t); +} + +mp_obj_t ModPicoGraphics_module_RGB_to_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b) { return mp_obj_new_int(PicoGraphics::rgb_to_rgb332( mp_obj_get_int(r), mp_obj_get_int(g), @@ -253,7 +284,7 @@ mp_obj_t ModPicoGraphics_module_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b) { )); } -mp_obj_t ModPicoGraphics_module_RGB565(mp_obj_t r, mp_obj_t g, mp_obj_t b) { +mp_obj_t ModPicoGraphics_module_RGB_to_RGB565(mp_obj_t r, mp_obj_t g, mp_obj_t b) { return mp_obj_new_int(PicoGraphics::rgb_to_rgb565( mp_obj_get_int(r), mp_obj_get_int(g), diff --git a/micropython/modules/picographics/picographics.h b/micropython/modules/picographics/picographics.h index ded38c35..9f18fdcb 100644 --- a/micropython/modules/picographics/picographics.h +++ b/micropython/modules/picographics/picographics.h @@ -24,8 +24,10 @@ enum PicoGraphicsPenType { extern const mp_obj_type_t ModPicoGraphics_type; // Module functions -extern mp_obj_t ModPicoGraphics_module_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b); -extern mp_obj_t ModPicoGraphics_module_RGB565(mp_obj_t r, mp_obj_t g, mp_obj_t b); +extern mp_obj_t ModPicoGraphics_module_RGB_to_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b); +extern mp_obj_t ModPicoGraphics_module_RGB_to_RGB565(mp_obj_t r, mp_obj_t g, mp_obj_t b); +extern mp_obj_t ModPicoGraphics_module_RGB332_to_RGB(mp_obj_t rgb332); +extern mp_obj_t ModPicoGraphics_module_RGB565_to_RGB(mp_obj_t rgb565); extern mp_obj_t ModPicoGraphics_get_required_buffer_size(mp_obj_t display_in, mp_obj_t pen_type_in); // Class methods @@ -61,4 +63,6 @@ extern mp_obj_t ModPicoGraphics_line(size_t n_args, const mp_obj_t *args); // Utility extern mp_obj_t ModPicoGraphics_set_font(mp_obj_t self_in, mp_obj_t font); extern mp_obj_t ModPicoGraphics_get_bounds(mp_obj_t self_in); -extern mp_obj_t ModPicoGraphics_set_framebuffer(mp_obj_t self_in, mp_obj_t framebuffer); \ No newline at end of file +extern mp_obj_t ModPicoGraphics_set_framebuffer(mp_obj_t self_in, mp_obj_t framebuffer); + +extern mp_int_t ModPicoGraphics_get_framebuffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags); \ No newline at end of file