diff --git a/libraries/pico_graphics/pico_graphics.cpp b/libraries/pico_graphics/pico_graphics.cpp index 551fb34d..3cde4729 100644 --- a/libraries/pico_graphics/pico_graphics.cpp +++ b/libraries/pico_graphics/pico_graphics.cpp @@ -11,6 +11,7 @@ namespace pimoroni { void PicoGraphics::set_pixel_dither(const Point &p, const RGB &c) {}; void PicoGraphics::set_pixel_dither(const Point &p, const RGB565 &c) {}; void PicoGraphics::scanline_convert(PenType type, conversion_callback_func callback) {}; + void PicoGraphics::sprite(void* data, const Point &sprite, const Point &dest, const int transparent) {}; void PicoGraphics::set_dimensions(int width, int height) { bounds = clip = {0, 0, width, height}; diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index e3bcad8f..23c94ae3 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -100,6 +100,12 @@ namespace pimoroni { Point clamp(const Rect &r) const; }; + inline bool operator== (const Point &lhs, const Point &rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } + inline bool operator!= (const Point &lhs, const Point &rhs) { return !(lhs == rhs); } + inline Point operator- (Point lhs, const Point &rhs) { lhs -= rhs; return lhs; } + inline Point operator- (const Point &rhs) { return Point(-rhs.x, -rhs.y); } + inline Point operator+ (Point lhs, const Point &rhs) { lhs += rhs; return lhs; } + struct Rect { int32_t x = 0, y = 0, w = 0, h = 0; @@ -185,6 +191,7 @@ namespace pimoroni { virtual void set_pixel_dither(const Point &p, const RGB &c); virtual void set_pixel_dither(const Point &p, const RGB565 &c); virtual void scanline_convert(PenType type, conversion_callback_func callback); + virtual void sprite(void* data, const Point &sprite, const Point &dest, const int transparent); void set_font(const bitmap::font_t *font); void set_font(const hershey::font_t *font); @@ -262,6 +269,7 @@ namespace pimoroni { void set_pixel_dither(const Point &p, const RGB &c) override; void set_pixel_dither(const Point &p, const RGB565 &c) override; void scanline_convert(PenType type, conversion_callback_func callback) override; + void sprite(void* data, const Point &sprite, const Point &dest, const int transparent) override; static size_t buffer_size(uint w, uint h) { return w * h; } diff --git a/libraries/pico_graphics/pico_graphics_pen_rgb332.cpp b/libraries/pico_graphics/pico_graphics_pen_rgb332.cpp index 8141e430..9b21f894 100644 --- a/libraries/pico_graphics/pico_graphics_pen_rgb332.cpp +++ b/libraries/pico_graphics/pico_graphics_pen_rgb332.cpp @@ -106,4 +106,20 @@ namespace pimoroni { } } } + void PicoGraphics_PenRGB332::sprite(void* data, const Point &sprite, const Point &dest, const int transparent) { + //int sprite_x = (sprite & 0x0f) << 3; + //int sprite_y = (sprite & 0xf0) >> 1; + Point s { + sprite.x << 3, + sprite.y << 3 + }; + RGB332 *ptr = (RGB332 *)data; + Point o = {0, 0}; + for(o.y = 0; o.y < 8; o.y++) { + for(o.x = 0; o.x < 8; o.x++) { + color = ptr[(s.y + o.y) * 128 + (s.x + o.x)]; + if(color != transparent) set_pixel(dest + o); + } + } + } } \ No newline at end of file diff --git a/libraries/pico_graphics/types.cpp b/libraries/pico_graphics/types.cpp index 91d8fb27..53dac95e 100644 --- a/libraries/pico_graphics/types.cpp +++ b/libraries/pico_graphics/types.cpp @@ -12,20 +12,6 @@ namespace pimoroni { ); } - Point operator- (Point lhs, const Point &rhs) { - lhs -= rhs; - return lhs; - } - - Point operator- (const Point &rhs) { - return Point(-rhs.x, -rhs.y); - } - - Point operator+ (Point lhs, const Point &rhs) { - lhs += rhs; - return lhs; - } - bool Rect::empty() const { return w <= 0 || h <= 0; } diff --git a/micropython/modules/picographics/picographics.c b/micropython/modules/picographics/picographics.c index bd2253b9..158e0655 100644 --- a/micropython/modules/picographics/picographics.c +++ b/micropython/modules/picographics/picographics.c @@ -35,6 +35,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(ModPicoGraphics_polygon_obj, 2, ModPicoGraphics_polyg MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ModPicoGraphics_triangle_obj, 7, 7, ModPicoGraphics_triangle); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ModPicoGraphics_line_obj, 5, 5, ModPicoGraphics_line); +// Sprites +MP_DEFINE_CONST_FUN_OBJ_2(ModPicoGraphics_set_spritesheet_obj, ModPicoGraphics_set_spritesheet); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ModPicoGraphics_sprite_obj, 6, 6, ModPicoGraphics_sprite); + // Utility //MP_DEFINE_CONST_FUN_OBJ_2(ModPicoGraphics_set_scanline_callback_obj, ModPicoGraphics_set_scanline_callback); MP_DEFINE_CONST_FUN_OBJ_1(ModPicoGraphics_get_bounds_obj, ModPicoGraphics_get_bounds); @@ -59,6 +63,9 @@ STATIC const mp_rom_map_elem_t ModPicoGraphics_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_triangle), MP_ROM_PTR(&ModPicoGraphics_triangle_obj) }, { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&ModPicoGraphics_line_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_spritesheet), MP_ROM_PTR(&ModPicoGraphics_set_spritesheet_obj) }, + { MP_ROM_QSTR(MP_QSTR_sprite), MP_ROM_PTR(&ModPicoGraphics_sprite_obj) }, + { MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&ModPicoGraphics_create_pen_obj) }, { MP_ROM_QSTR(MP_QSTR_update_pen), MP_ROM_PTR(&ModPicoGraphics_update_pen_obj) }, { MP_ROM_QSTR(MP_QSTR_reset_pen), MP_ROM_PTR(&ModPicoGraphics_reset_pen_obj) }, diff --git a/micropython/modules/picographics/picographics.cpp b/micropython/modules/picographics/picographics.cpp index 6888b286..8d4a9c27 100644 --- a/micropython/modules/picographics/picographics.cpp +++ b/micropython/modules/picographics/picographics.cpp @@ -24,6 +24,7 @@ typedef struct _ModPicoGraphics_obj_t { mp_obj_base_t base; PicoGraphics *graphics; DisplayDriver *display; + void *spritedata; void *buffer; //mp_obj_t scanline_callback; // Not really feasible in MicroPython } ModPicoGraphics_obj_t; @@ -139,7 +140,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size } // Create or fetch buffer - size_t required_size = get_required_buffer_size(pen_type, width, height); + size_t required_size = get_required_buffer_size((PicoGraphicsPenType)pen_type, width, height); if(required_size == 0) mp_raise_ValueError("Unsupported pen type!"); if (args[ARG_buffer].u_obj != mp_const_none) { @@ -174,6 +175,8 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size //self->scanline_callback = mp_const_none; + self->spritedata = nullptr; + // Clear the buffer self->graphics->set_pen(0); self->graphics->clear(); @@ -184,6 +187,42 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size return MP_OBJ_FROM_PTR(self); } +mp_obj_t ModPicoGraphics_set_spritesheet(mp_obj_t self_in, mp_obj_t spritedata) { + ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(self_in, ModPicoGraphics_obj_t); + if(spritedata == mp_const_none) { + self->spritedata = nullptr; + } else { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(spritedata, &bufinfo, MP_BUFFER_RW); + + int required_size = get_required_buffer_size((PicoGraphicsPenType)self->graphics->pen_type, 128, 128); + + if(bufinfo.len != (size_t)(required_size)) { + mp_raise_ValueError("Spritesheet the wrong size!"); + } + + self->spritedata = bufinfo.buf; + } + return mp_const_none; +} + +mp_obj_t ModPicoGraphics_sprite(size_t n_args, const mp_obj_t *args) { + enum { ARG_self, ARG_sprite_x, ARG_sprite_y, ARG_x, ARG_y, ARG_transparent }; + + ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self], ModPicoGraphics_obj_t); + + if(self->spritedata == nullptr) return mp_const_false; + + self->graphics->sprite( + self->spritedata, + {mp_obj_get_int(args[ARG_sprite_x]), mp_obj_get_int(args[ARG_sprite_y])}, + {mp_obj_get_int(args[ARG_x]), mp_obj_get_int(args[ARG_y])}, + mp_obj_get_int(args[ARG_transparent]) + ); + + return mp_const_true; +} + mp_obj_t ModPicoGraphics_set_font(mp_obj_t self_in, mp_obj_t font) { ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(self_in, ModPicoGraphics_obj_t); self->graphics->set_font(mp_obj_to_string_r(font)); diff --git a/micropython/modules/picographics/picographics.h b/micropython/modules/picographics/picographics.h index 62955a96..0ee79823 100644 --- a/micropython/modules/picographics/picographics.h +++ b/micropython/modules/picographics/picographics.h @@ -60,6 +60,10 @@ extern mp_obj_t ModPicoGraphics_polygon(size_t n_args, const mp_obj_t *pos_args, extern mp_obj_t ModPicoGraphics_triangle(size_t n_args, const mp_obj_t *args); extern mp_obj_t ModPicoGraphics_line(size_t n_args, const mp_obj_t *args); +// Sprites +extern mp_obj_t ModPicoGraphics_set_spritesheet(mp_obj_t self_in, mp_obj_t spritedata); +extern mp_obj_t ModPicoGraphics_sprite(size_t n_args, const mp_obj_t *args); + // Utility //extern mp_obj_t ModPicoGraphics_set_scanline_callback(mp_obj_t self_in, mp_obj_t cb_in); extern mp_obj_t ModPicoGraphics_set_font(mp_obj_t self_in, mp_obj_t font);