PicoGraphics: Basic 128x128 RGB332 spritesheet support.

This commit is contained in:
Phil Howard 2022-06-13 17:54:12 +01:00
parent 24f4b6fc83
commit 5d7113e8c9
7 changed files with 76 additions and 15 deletions

View File

@ -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};

View File

@ -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;
}

View File

@ -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);
}
}
}
}

View File

@ -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;
}

View File

@ -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) },

View File

@ -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));

View File

@ -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);