diff --git a/32blit/graphics/blend.cpp b/32blit/graphics/blend.cpp index 503f958eb..0bc51e72e 100644 --- a/32blit/graphics/blend.cpp +++ b/32blit/graphics/blend.cpp @@ -348,27 +348,6 @@ namespace blit { uint8_t* d = dest->data + (doff * 3); uint8_t* m = dest->mask ? dest->mask->data + doff : nullptr; - // solid fill/blend - if(!m && src_step == 0 && cnt > 1) { - Pen *pen = src->palette ? &src->palette[*s] : (Pen *)s; - - uint16_t a = src->format == PixelFormat::RGB ? 255 : pen->a; - - if(!a) return; - - a = alpha(a, dest->alpha); - - if (a >= 255) { - // no alpha, just copy - copy_rgba_rgb(pen, d, cnt); - } - else { - // alpha, blend - blend_rgba_rgb(pen, d, a, cnt); - } - return; - } - do { Pen *pen = src->palette ? &src->palette[*s] : (Pen *)s; @@ -394,27 +373,6 @@ namespace blit { uint8_t* d = dest->data + (doff * 2); uint8_t* m = dest->mask ? dest->mask->data + doff : nullptr; - // solid fill/blend - if(!m && src_step == 0 && cnt > 1) { - Pen *pen = src->palette ? &src->palette[*s] : (Pen *)s; - - uint16_t a = src->format == PixelFormat::RGB ? 255 : pen->a; - - if(!a) return; - - a = alpha(a, dest->alpha); - - if (a >= 255) { - // no alpha, just copy - copy_rgba_rgb565(pen, d, cnt); - } - else { - // alpha, blend - blend_rgba_rgb565(pen, d, a, cnt); - } - return; - } - auto d16 = (uint16_t *)d; do { @@ -459,4 +417,33 @@ namespace blit { s += src_step; } while (--cnt); } + + Pen get_pen_rgb(const Surface *surf, uint32_t offset) { + auto ptr = surf->data + offset * 3; + return {ptr[0], ptr[1], ptr[2]}; + } + + Pen get_pen_rgba(const Surface *surf, uint32_t offset) { + auto ptr = surf->data + offset * 4; + return *(Pen *)ptr; + } + + Pen get_pen_p(const Surface *surf, uint32_t offset) { + auto ptr = surf->data + offset; + return surf->palette[*ptr]; + } + + Pen get_pen_m(const Surface *surf, uint32_t offset) { + auto ptr = surf->data + offset; + return {*ptr}; // mask is just alpha + } + + Pen get_pen_rgb565(const Surface *surf, uint32_t offset) { + auto ptr = surf->data + offset * 2; + + auto rgb565 = *(uint16_t *)ptr; + uint8_t r, g, b; + unpack_rgb565(rgb565, r, g, b); + return {r, g, b}; + } } diff --git a/32blit/graphics/blend.hpp b/32blit/graphics/blend.hpp index 477eebca9..108ef346a 100644 --- a/32blit/graphics/blend.hpp +++ b/32blit/graphics/blend.hpp @@ -15,6 +15,9 @@ namespace blit { // supports source alpha, global alpha, and mask alpha where needed using BlitBlendFunc = void(*)(const Surface* src, uint32_t soff, const Surface* dest, uint32_t doff, uint32_t cnt, int32_t src_step); + // reads a pixel from the surface and converts it to a Pen + using PenGetFunc = Pen(*)(const Surface* surf, uint32_t off); + extern void RGBA_RGBA(const Pen* pen, const Surface* dest, uint32_t off, uint32_t cnt); extern void RGBA_RGB(const Pen* pen, const Surface* dest, uint32_t off, uint32_t cnt); extern void RGBA_RGB565(const Pen* pen, const Surface* dest, uint32_t off, uint32_t cnt); @@ -27,4 +30,9 @@ namespace blit { extern void P_P(const Surface* src, uint32_t soff, const Surface* dest, uint32_t doff, uint32_t cnt, int32_t src_step); extern void M_M(const Surface* src, uint32_t soff, const Surface* dest, uint32_t doff, uint32_t cnt, int32_t src_step); + Pen get_pen_rgb(const Surface *surf, uint32_t offset); + Pen get_pen_rgba(const Surface *surf, uint32_t offset); + Pen get_pen_p(const Surface *surf, uint32_t offset); + Pen get_pen_m(const Surface *surf, uint32_t offset); + Pen get_pen_rgb565(const Surface *surf, uint32_t offset); } diff --git a/32blit/graphics/surface.cpp b/32blit/graphics/surface.cpp index 2e7bcddda..3d5432630 100644 --- a/32blit/graphics/surface.cpp +++ b/32blit/graphics/surface.cpp @@ -60,22 +60,27 @@ namespace blit { case PixelFormat::RGBA: { pbf = RGBA_RGBA; bbf = RGBA_RGBA; + pgf = get_pen_rgba; }break; case PixelFormat::RGB: { pbf = RGBA_RGB; bbf = RGBA_RGB; + pgf = get_pen_rgb; }break; case PixelFormat::P: { pbf = P_P; bbf = P_P; + pgf = get_pen_p; }break; case PixelFormat::M: { pbf = M_M; bbf = M_M; + pgf = get_pen_m; }break; case PixelFormat::RGB565: { pbf = RGBA_RGB565; bbf = RGBA_RGB565; + pgf = get_pen_rgb565; }break; } } @@ -419,7 +424,8 @@ namespace blit { new_x += x_step; } - bbf(src, src_offset + (x >> fix_shift) * src_step, this, dest_offset, num, 0); + auto pen = src->get_pixel(src_offset + (x >> fix_shift) * src_step); + pbf(&pen, this, dest_offset, num); dest_offset += num; x = new_x; @@ -511,7 +517,8 @@ namespace blit { new_x += scale_x; } - bbf(src, src_offset + (x >> fix_shift), this, dest_offset, num, 0); + auto pen = src->get_pixel(src_offset + (x >> fix_shift)); + pbf(&pen, this, dest_offset, num); dest_offset += num; x = new_x; diff --git a/32blit/graphics/surface.hpp b/32blit/graphics/surface.hpp index f833982f9..a39f02e74 100644 --- a/32blit/graphics/surface.hpp +++ b/32blit/graphics/surface.hpp @@ -128,6 +128,7 @@ namespace blit { // blend functions blit::PenBlendFunc pbf; blit::BlitBlendFunc bbf; + blit::PenGetFunc pgf; std::vector mipmaps; // TODO: probably too niche/specific to attach directly to surface @@ -164,6 +165,9 @@ namespace blit { void generate_mipmaps(uint8_t depth); + Pen get_pixel(uint32_t offset) {return pgf(this, offset);} + Pen get_pixel(Point p) {return pgf(this, offset(p));} + void clear(); void pixel(const Point &p); void v_span(Point p, int16_t c); diff --git a/32blit/graphics/tilemap.cpp b/32blit/graphics/tilemap.cpp index 03aae5e7b..f9ae41193 100644 --- a/32blit/graphics/tilemap.cpp +++ b/32blit/graphics/tilemap.cpp @@ -222,8 +222,8 @@ namespace blit { count++; } while(c && (wc.x >> fix_shift) == wcx && (wc.y >> fix_shift) == wcy); - int soff = src->offset(u, v); - dest->bbf(src, soff, dest, doff, count, 0); + auto pen = src->get_pixel({u, v}); + dest->pbf(&pen, dest, doff, count); doff += count;