diff -r 0b8b245a2391 -r 1ac8aac92385 src/gfx.cpp --- a/src/gfx.cpp Wed Jun 13 11:45:14 2007 +0000 +++ b/src/gfx.cpp Wed Jun 13 12:05:56 2007 +0000 @@ -19,6 +19,7 @@ #include "genworld.h" #include "debug.h" #include "zoom.hpp" +#include "blitter/blitter.hpp" #ifdef _DEBUG bool _dbg_screen_rect; @@ -45,12 +46,6 @@ Colour _cur_palette[256]; byte _stringwidth_table[FS_END][224]; -enum BlitterMode { - BM_NORMAL, - BM_COLOUR_REMAP, - BM_TRANSPARENT, -}; - static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode); FontSize _cur_fontsize; @@ -728,278 +723,72 @@ } } -struct BlitterParams { - int start_x, start_y; - const byte *sprite; - Pixel *dst; - BlitterMode mode; - int width, height; - int width_org; - int pitch; -}; - -static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom) -{ - const byte *src = bp->sprite; - Pixel *dst = bp->dst; - int height = bp->height; - int width = bp->width; - int i; - - assert(height > 0); - assert(width > 0); - - height = UnScaleByZoom(height, zoom); - - switch (bp->mode) { - case BM_COLOUR_REMAP: { - const byte *ctab = _color_remap_ptr; - - for (; height != 0; height--) { - for (i = 0; i != UnScaleByZoom(width, zoom); i++) { - byte b = ctab[src[ScaleByZoom(i, zoom)]]; - - if (b != 0) dst[i] = b; - } - src += ScaleByZoom(bp->width_org, zoom); - dst += bp->pitch; - } - break; - } - - case BM_TRANSPARENT: { - const byte *ctab = _color_remap_ptr; - - for (; height != 0; height--) { - for (i = 0; i != UnScaleByZoom(width, zoom); i++) - if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = ctab[dst[i]]; - src += ScaleByZoom(bp->width_org, zoom); - dst += bp->pitch; - } - break; - } - - default: - for (; height != 0; height--) { - for (i = 0; i != UnScaleByZoom(width, zoom); i++) - if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = src[ScaleByZoom(i, zoom)]; - src += ScaleByZoom(bp->width_org, zoom); - dst += bp->pitch; - } - break; - } -} - -static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom) -{ - const byte *src_o = bp->sprite; - const byte *src; - int num, skip; - byte done; - Pixel *dst; - const byte *ctab; - - src_o += ReadLE16Aligned(src_o + bp->start_y * 2); - - for (;;) { - do { - done = src_o[0]; - num = done & 0x7F; - skip = src_o[1]; - src = src_o + 2; - src_o += num + 2; - - dst = bp->dst; - - if (zoom >= ZOOM_LVL_OUT_2X && (skip & 1)) { - skip += 1; - src += 1; - num -= 1; - if (num <= 0) continue; - } - - if (zoom >= ZOOM_LVL_OUT_4X && (skip & 2)) { - skip += 2; - src += 2; - num -= 2; - if (num <= 0) continue; - } - - if (zoom >= ZOOM_LVL_OUT_8X && (skip & 4)) { - skip += 4; - src += 4; - num -= 4; - if (num <= 0) continue; - } - - if (zoom >= ZOOM_LVL_OUT_16X && (skip & 8)) { - skip += 8; - src += 8; - num -= 8; - if (num <= 0) continue; - } - - if ( (skip -= bp->start_x) > 0) { - dst += UnScaleByZoom(skip, zoom); - } else { - src -= skip; - num += skip; - if (num <= 0) continue; - skip = 0; - } - - skip = skip + num - bp->width; - if (skip > 0) { - num -= skip; - if (num <= 0) continue; - } - - num = UnScaleByZoom(num + ScaleByZoom(1, zoom) - 1, zoom); - - switch (bp->mode) { - case BM_COLOUR_REMAP: - ctab = _color_remap_ptr; - for (; num != 0; num--) { - *dst = ctab[*src]; - dst++; - src += ScaleByZoom(1, zoom); - } - break; - - case BM_TRANSPARENT: - ctab = _color_remap_ptr; - for (; num != 0; num--) { - *dst = ctab[*dst]; - dst++; - } - break; - - default: - for (; num != 0; num--) { - *dst = *src; - dst++; - src += ScaleByZoom(1, zoom); - } - break; - } - - - } while (!(done & 0x80)); - - bp->dst += bp->pitch; - if (--bp->height == 0) return; - - for (int i = 0; i < ScaleByZoom(1, zoom) - 1; i++) { - do { - done = src_o[0]; - src_o += (done & 0x7F) + 2; - } while (!(done & 0x80)); - if (--bp->height == 0) return; - } - } -} - -static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode) +static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode) { const DrawPixelInfo *dpi = _cur_dpi; - int start_x, start_y; - BlitterParams bp; - int zoom_mask = ~(ScaleByZoom(1, dpi->zoom) - 1); + Blitter::BlitterParams bp; - /* decode sprite header */ + /* Move to the correct offset */ x += sprite->x_offs; y += sprite->y_offs; - bp.width_org = bp.width = sprite->width; - bp.height = sprite->height; - bp.sprite = sprite->data; - bp.dst = dpi->dst_ptr; - bp.mode = mode; - bp.pitch = dpi->pitch; - - assert(bp.height > 0); - assert(bp.width > 0); - - if (sprite->info & 8) { - /* tile blit */ - start_y = 0; - - if (dpi->zoom > ZOOM_LVL_NORMAL) { - start_y += bp.height & ~zoom_mask; - bp.height &= zoom_mask; - if (bp.height == 0) return; - y &= zoom_mask; - } - - if ( (y -= dpi->top) < 0) { - bp.height += y; - if (bp.height <= 0) return; - start_y -= y; - y = 0; - } else { - bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom); - } - bp.start_y = start_y; - - if ( (y = y + bp.height - dpi->height) > 0) { - bp.height -= y; - if (bp.height <= 0) return; - } - start_x = 0; - x &= zoom_mask; - if ( (x -= dpi->left) < 0) { - bp.width += x; - if (bp.width <= 0) return; - start_x -= x; - x = 0; - } - bp.start_x = start_x; - bp.dst += UnScaleByZoom(x, dpi->zoom); - - if ( (x = x + bp.width - dpi->width) > 0) { - bp.width -= x; - if (bp.width <= 0) return; - } - - GfxBlitTileZoom(&bp, dpi->zoom); - } else { - bp.sprite += bp.width * (bp.height & ~zoom_mask); - bp.height &= zoom_mask; - if (bp.height == 0) return; - - y &= zoom_mask; + /* Copy the main data directly from the sprite */ + bp.sprite = sprite->data; + bp.sprite_width = sprite->width; + bp.sprite_height = sprite->height; + bp.width = UnScaleByZoom(sprite->width, dpi->zoom); + bp.height = UnScaleByZoom(sprite->height, dpi->zoom); + bp.top = 0; + bp.left = 0; + bp.skip_left = 0; + bp.skip_top = 0; + bp.dst = dpi->dst_ptr; + bp.pitch = dpi->pitch; + bp.remap = _color_remap_ptr; - if ( (y -= dpi->top) < 0) { - bp.height += y; - if (bp.height <= 0) return; - bp.sprite -= bp.width * y; - y = 0; - } else { - bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom); - } - - if (bp.height > dpi->height - y) { - bp.height = dpi->height - y; - if (bp.height <= 0) return; - } + assert(sprite->width > 0); + assert(sprite->height > 0); - x &= zoom_mask; + if (bp.width <= 0) return; + if (bp.height <= 0) return; - if ( (x -= dpi->left) < 0) { - bp.width += x; - if (bp.width <= 0) return; - bp.sprite -= x; - x = 0; - } - bp.dst += UnScaleByZoom(x, dpi->zoom); + y -= dpi->top; + /* Check for top overflow */ + if (y < 0) { + bp.height -= -UnScaleByZoom(y, dpi->zoom); + if (bp.height <= 0) return; + bp.skip_top += -UnScaleByZoom(y, dpi->zoom); + y = 0; + } else { + bp.top = UnScaleByZoom(y, dpi->zoom); + } - if (bp.width > dpi->width - x) { - bp.width = dpi->width - x; - if (bp.width <= 0) return; - } + /* Check for bottom overflow */ + y += ScaleByZoom(bp.height, dpi->zoom) - dpi->height; + if (y > 0) { + bp.height -= UnScaleByZoom(y, dpi->zoom); + if (bp.height <= 0) return; + } - GfxBlitZoomUncomp(&bp, dpi->zoom); + x -= dpi->left; + /* Check for left overflow */ + if (x < 0) { + bp.width -= -UnScaleByZoom(x, dpi->zoom); + if (bp.width <= 0) return; + bp.skip_left += -UnScaleByZoom(x, dpi->zoom); + x = 0; + } else { + bp.left = UnScaleByZoom(x, dpi->zoom); } + + /* Check for right overflow */ + x += ScaleByZoom(bp.width, dpi->zoom) - dpi->width; + if (x > 0) { + bp.width -= UnScaleByZoom(x, dpi->zoom); + if (bp.width <= 0) return; + } + + BlitterFactoryBase::GetCurrentBlitter()->Draw(&bp, mode, dpi->zoom); } void DoPaletteAnimations();