From 5c62d4740b6691ad0cd05863da47ec92e5f0cd7f Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 28 Oct 2013 23:01:28 +0000 Subject: Add tiled bitmap plotting function. --- src/plot/16bpp.c | 1 + src/plot/24bpp.c | 1 + src/plot/32bpp-xbgr8888.c | 1 + src/plot/32bpp-xrgb8888.c | 1 + src/plot/8bpp.c | 1 + src/plot/api.c | 7 +++- src/plot/common.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 93 insertions(+), 1 deletion(-) (limited to 'src/plot') diff --git a/src/plot/16bpp.c b/src/plot/16bpp.c index d629944..4f9134f 100644 --- a/src/plot/16bpp.c +++ b/src/plot/16bpp.c @@ -114,6 +114,7 @@ const nsfb_plotter_fns_t _nsfb_16bpp_plotters = { .fill = fill, .point = point, .bitmap = bitmap, + .bitmap_tiles = bitmap_tiles, .glyph8 = glyph8, .glyph1 = glyph1, .readrect = readrect, diff --git a/src/plot/24bpp.c b/src/plot/24bpp.c index 0fa53e9..dc67f04 100644 --- a/src/plot/24bpp.c +++ b/src/plot/24bpp.c @@ -430,6 +430,7 @@ const nsfb_plotter_fns_t _nsfb_24bpp_plotters = { .fill = fill, .point = point, .bitmap = bitmap, + .bitmap_tiles = bitmap_tiles, .glyph8 = glyph8, .glyph1 = glyph1, .readrect = readrect, diff --git a/src/plot/32bpp-xbgr8888.c b/src/plot/32bpp-xbgr8888.c index 9050903..4c19688 100644 --- a/src/plot/32bpp-xbgr8888.c +++ b/src/plot/32bpp-xbgr8888.c @@ -62,6 +62,7 @@ const nsfb_plotter_fns_t _nsfb_32bpp_xbgr8888_plotters = { .fill = fill, .point = point, .bitmap = bitmap, + .bitmap_tiles = bitmap_tiles, .glyph8 = glyph8, .glyph1 = glyph1, .readrect = readrect, diff --git a/src/plot/32bpp-xrgb8888.c b/src/plot/32bpp-xrgb8888.c index 548c970..9b3d551 100644 --- a/src/plot/32bpp-xrgb8888.c +++ b/src/plot/32bpp-xrgb8888.c @@ -62,6 +62,7 @@ const nsfb_plotter_fns_t _nsfb_32bpp_xrgb8888_plotters = { .fill = fill, .point = point, .bitmap = bitmap, + .bitmap_tiles = bitmap_tiles, .glyph8 = glyph8, .glyph1 = glyph1, .readrect = readrect, diff --git a/src/plot/8bpp.c b/src/plot/8bpp.c index 0245542..4fef119 100644 --- a/src/plot/8bpp.c +++ b/src/plot/8bpp.c @@ -73,6 +73,7 @@ const nsfb_plotter_fns_t _nsfb_8bpp_plotters = { .fill = fill, .point = point, .bitmap = bitmap, + .bitmap_tiles = bitmap_tiles, .glyph8 = glyph8, .glyph1 = glyph1, .readrect = readrect, diff --git a/src/plot/api.c b/src/plot/api.c index 2b5b974..ba6afc8 100644 --- a/src/plot/api.c +++ b/src/plot/api.c @@ -165,7 +165,12 @@ nsfb_plot_copy(nsfb_t *srcfb, bool nsfb_plot_bitmap(nsfb_t *nsfb, const nsfb_bbox_t *loc, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha) { - return nsfb->plotter_fns->bitmap(nsfb, loc, pixel, bmp_width, bmp_height, bmp_stride, alpha); + return nsfb->plotter_fns->bitmap(nsfb, loc, pixel, bmp_width, bmp_height, bmp_stride, alpha); +} + +bool nsfb_plot_bitmap_tiles(nsfb_t *nsfb, const nsfb_bbox_t *loc, int tiles_x, int tiles_y, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha) +{ + return nsfb->plotter_fns->bitmap_tiles(nsfb, loc, tiles_x, tiles_y, pixel, bmp_width, bmp_height, bmp_stride, alpha); } /** Plot an 8 bit glyph. diff --git a/src/plot/common.c b/src/plot/common.c index 998e3a6..e1f4a7a 100644 --- a/src/plot/common.c +++ b/src/plot/common.c @@ -491,6 +491,88 @@ bitmap(nsfb_t *nsfb, return true; } +static bool +bitmap_tiles(nsfb_t *nsfb, + const nsfb_bbox_t *loc, + int tiles_x, + int tiles_y, + const nsfb_colour_t *pixel, + int bmp_width, + int bmp_height, + int bmp_stride, + bool alpha) +{ + nsfb_bbox_t render_area; + nsfb_bbox_t tloc; + int tx, ty; + int width = loc->x1 - loc->x0; + int height = loc->y1 - loc->y0; + bool ok = true; + bool set_dither = false; /* true iff we enabled dithering here */ + + /* Avoid pointless rendering */ + if (width == 0 || height == 0) + return true; + + render_area.x0 = loc->x0; + render_area.y0 = loc->y0; + render_area.x1 = loc->x0 + width * tiles_x; + render_area.y1 = loc->y0 + height * tiles_y; + + if (!nsfb_plot_clip_ctx(nsfb, &render_area)) + return true; + + /* Enable error diffusion for paletted screens, if not already on, + * if not repeating in x direction */ + if (tiles_x == 1 && nsfb->palette != NULL && + nsfb_palette_dithering_on(nsfb->palette) == false) { + nsfb_palette_dither_init(nsfb->palette, + render_area.x1 - render_area.x0); + set_dither = true; + } + + /* Given tile location is top left; start with that one. */ + tloc = *loc; + + if (width != bmp_width || height != bmp_height) { + /* Scaled */ + for (ty = 0; ty < tiles_y; ty++) { + for (tx = 0; tx < tiles_x; tx++) { + ok &= bitmap_scaled(nsfb, &tloc, pixel, + bmp_width, bmp_height, + bmp_stride, alpha); + tloc.x0 += width; + tloc.x1 += width; + } + tloc.x0 = loc->x0; + tloc.y0 += height; + tloc.x1 = loc->x1; + tloc.y1 += height; + } + } else { + /* Unscaled */ + for (ty = 0; ty < tiles_y; ty++) { + for (tx = 0; tx < tiles_x; tx++) { + ok &= bitmap(nsfb, &tloc, pixel, + bmp_width, bmp_height, + bmp_stride, alpha); + tloc.x0 += width; + tloc.x1 += width; + } + tloc.x0 = loc->x0; + tloc.y0 += height; + tloc.x1 = loc->x1; + tloc.y1 += height; + } + } + + if (set_dither) { + nsfb_palette_dither_fini(nsfb->palette); + } + + return ok; +} + static bool readrect(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t *buffer) { PLOT_TYPE *pvideo; -- cgit v1.2.3