Skip to content

Commit

Permalink
Merge pull request #828 from Daft-Freak/get_pixel-tilemap-blend
Browse files Browse the repository at this point in the history
Add Surface::get_pixel and remove special case from blit code
  • Loading branch information
Gadgetoid authored Jul 17, 2023
2 parents eaf25f8 + 7d7efe4 commit eed9a43
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 46 deletions.
71 changes: 29 additions & 42 deletions 32blit/graphics/blend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 {
Expand Down Expand Up @@ -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};
}
}
8 changes: 8 additions & 0 deletions 32blit/graphics/blend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
11 changes: 9 additions & 2 deletions 32blit/graphics/surface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions 32blit/graphics/surface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ namespace blit {
// blend functions
blit::PenBlendFunc pbf;
blit::BlitBlendFunc bbf;
blit::PenGetFunc pgf;

std::vector<Surface *> mipmaps; // TODO: probably too niche/specific to attach directly to surface

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions 32blit/graphics/tilemap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit eed9a43

Please sign in to comment.