mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r10043) -Change: make templates of the blitters, based on zoom and mode, which makes the optimizing better, and therefor a higher blitter speed (tnx boekabart)
-Codechange: unify the MainBlitter a bit more
This commit is contained in:
parent
4403d41934
commit
7d0a1c91d4
201
src/gfx.cpp
201
src/gfx.cpp
|
@ -51,7 +51,8 @@ enum BlitterMode {
|
||||||
BM_TRANSPARENT,
|
BM_TRANSPARENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode);
|
template <BlitterMode Tmode>
|
||||||
|
static inline void GfxMainBlitter(const Sprite *sprite, int x, int y);
|
||||||
|
|
||||||
FontSize _cur_fontsize;
|
FontSize _cur_fontsize;
|
||||||
static FontSize _last_fontsize;
|
static FontSize _last_fontsize;
|
||||||
|
@ -682,7 +683,7 @@ skip_cont:;
|
||||||
if (IsPrintable(c)) {
|
if (IsPrintable(c)) {
|
||||||
if (x >= dpi->left + dpi->width) goto skip_char;
|
if (x >= dpi->left + dpi->width) goto skip_char;
|
||||||
if (x + 26 >= dpi->left) {
|
if (x + 26 >= dpi->left) {
|
||||||
GfxMainBlitter(GetGlyph(size, c), x, y, BM_COLOUR_REMAP);
|
GfxMainBlitter<BM_COLOUR_REMAP>(GetGlyph(size, c), x, y);
|
||||||
}
|
}
|
||||||
x += GetCharacterWidth(size, c);
|
x += GetCharacterWidth(size, c);
|
||||||
} else if (c == '\n') { // newline = {}
|
} else if (c == '\n') { // newline = {}
|
||||||
|
@ -719,12 +720,12 @@ void DrawSprite(SpriteID img, SpriteID pal, int x, int y)
|
||||||
{
|
{
|
||||||
if (HASBIT(img, PALETTE_MODIFIER_TRANSPARENT)) {
|
if (HASBIT(img, PALETTE_MODIFIER_TRANSPARENT)) {
|
||||||
_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
|
_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
|
||||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_TRANSPARENT);
|
GfxMainBlitter<BM_TRANSPARENT>(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y);
|
||||||
} else if (pal != PAL_NONE) {
|
} else if (pal != PAL_NONE) {
|
||||||
_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
|
_color_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH)) + 1;
|
||||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_COLOUR_REMAP);
|
GfxMainBlitter<BM_COLOUR_REMAP>(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y);
|
||||||
} else {
|
} else {
|
||||||
GfxMainBlitter(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y, BM_NORMAL);
|
GfxMainBlitter<BM_NORMAL>(GetSprite(GB(img, 0, SPRITE_WIDTH)), x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,15 +733,15 @@ struct BlitterParams {
|
||||||
int start_x, start_y;
|
int start_x, start_y;
|
||||||
const byte *sprite;
|
const byte *sprite;
|
||||||
Pixel *dst;
|
Pixel *dst;
|
||||||
BlitterMode mode;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
int width_org;
|
int width_org;
|
||||||
int pitch;
|
int pitch;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom)
|
template <BlitterMode Tmode, ZoomLevel Tzoom>
|
||||||
|
static inline void GfxBlitZoomUncomp(BlitterParams *bp)
|
||||||
{
|
{
|
||||||
const byte *src = bp->sprite;
|
const byte *src = bp->sprite + bp->start_y * bp->width_org + bp->start_x;
|
||||||
Pixel *dst = bp->dst;
|
Pixel *dst = bp->dst;
|
||||||
int height = bp->height;
|
int height = bp->height;
|
||||||
int width = bp->width;
|
int width = bp->width;
|
||||||
|
@ -749,19 +750,19 @@ static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom)
|
||||||
assert(height > 0);
|
assert(height > 0);
|
||||||
assert(width > 0);
|
assert(width > 0);
|
||||||
|
|
||||||
height = UnScaleByZoom(height, zoom);
|
height = UnScaleByZoom(height, Tzoom);
|
||||||
|
|
||||||
switch (bp->mode) {
|
switch (Tmode) {
|
||||||
case BM_COLOUR_REMAP: {
|
case BM_COLOUR_REMAP: {
|
||||||
const byte *ctab = _color_remap_ptr;
|
const byte *ctab = _color_remap_ptr;
|
||||||
|
|
||||||
for (; height != 0; height--) {
|
for (; height != 0; height--) {
|
||||||
for (i = 0; i != UnScaleByZoom(width, zoom); i++) {
|
for (i = 0; i != UnScaleByZoom(width, Tzoom); i++) {
|
||||||
byte b = ctab[src[ScaleByZoom(i, zoom)]];
|
byte b = ctab[src[ScaleByZoom(i, Tzoom)]];
|
||||||
|
|
||||||
if (b != 0) dst[i] = b;
|
if (b != 0) dst[i] = b;
|
||||||
}
|
}
|
||||||
src += ScaleByZoom(bp->width_org, zoom);
|
src += ScaleByZoom(bp->width_org, Tzoom);
|
||||||
dst += bp->pitch;
|
dst += bp->pitch;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -771,9 +772,9 @@ static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom)
|
||||||
const byte *ctab = _color_remap_ptr;
|
const byte *ctab = _color_remap_ptr;
|
||||||
|
|
||||||
for (; height != 0; height--) {
|
for (; height != 0; height--) {
|
||||||
for (i = 0; i != UnScaleByZoom(width, zoom); i++)
|
for (i = 0; i != UnScaleByZoom(width, Tzoom); i++)
|
||||||
if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = ctab[dst[i]];
|
if (src[ScaleByZoom(i, Tzoom)] != 0) dst[i] = ctab[dst[i]];
|
||||||
src += ScaleByZoom(bp->width_org, zoom);
|
src += ScaleByZoom(bp->width_org, Tzoom);
|
||||||
dst += bp->pitch;
|
dst += bp->pitch;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -781,16 +782,17 @@ static void GfxBlitZoomUncomp(BlitterParams *bp, ZoomLevel zoom)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
for (; height != 0; height--) {
|
for (; height != 0; height--) {
|
||||||
for (i = 0; i != UnScaleByZoom(width, zoom); i++)
|
for (i = 0; i != UnScaleByZoom(width, Tzoom); i++)
|
||||||
if (src[ScaleByZoom(i, zoom)] != 0) dst[i] = src[ScaleByZoom(i, zoom)];
|
if (src[ScaleByZoom(i, Tzoom)] != 0) dst[i] = src[ScaleByZoom(i, Tzoom)];
|
||||||
src += ScaleByZoom(bp->width_org, zoom);
|
src += ScaleByZoom(bp->width_org, Tzoom);
|
||||||
dst += bp->pitch;
|
dst += bp->pitch;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
|
template <BlitterMode Tmode, ZoomLevel Tzoom>
|
||||||
|
static inline void GfxBlitTileZoom(BlitterParams *bp)
|
||||||
{
|
{
|
||||||
const byte *src_o = bp->sprite;
|
const byte *src_o = bp->sprite;
|
||||||
const byte *src;
|
const byte *src;
|
||||||
|
@ -811,28 +813,28 @@ static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
|
||||||
|
|
||||||
dst = bp->dst;
|
dst = bp->dst;
|
||||||
|
|
||||||
if (zoom >= ZOOM_LVL_OUT_2X && (skip & 1)) {
|
if (Tzoom >= ZOOM_LVL_OUT_2X && (skip & 1)) {
|
||||||
skip += 1;
|
skip += 1;
|
||||||
src += 1;
|
src += 1;
|
||||||
num -= 1;
|
num -= 1;
|
||||||
if (num <= 0) continue;
|
if (num <= 0) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zoom >= ZOOM_LVL_OUT_4X && (skip & 2)) {
|
if (Tzoom >= ZOOM_LVL_OUT_4X && (skip & 2)) {
|
||||||
skip += 2;
|
skip += 2;
|
||||||
src += 2;
|
src += 2;
|
||||||
num -= 2;
|
num -= 2;
|
||||||
if (num <= 0) continue;
|
if (num <= 0) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zoom >= ZOOM_LVL_OUT_8X && (skip & 4)) {
|
if (Tzoom >= ZOOM_LVL_OUT_8X && (skip & 4)) {
|
||||||
skip += 4;
|
skip += 4;
|
||||||
src += 4;
|
src += 4;
|
||||||
num -= 4;
|
num -= 4;
|
||||||
if (num <= 0) continue;
|
if (num <= 0) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zoom >= ZOOM_LVL_OUT_16X && (skip & 8)) {
|
if (Tzoom >= ZOOM_LVL_OUT_16X && (skip & 8)) {
|
||||||
skip += 8;
|
skip += 8;
|
||||||
src += 8;
|
src += 8;
|
||||||
num -= 8;
|
num -= 8;
|
||||||
|
@ -840,7 +842,7 @@ static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (skip -= bp->start_x) > 0) {
|
if ( (skip -= bp->start_x) > 0) {
|
||||||
dst += UnScaleByZoom(skip, zoom);
|
dst += UnScaleByZoom(skip, Tzoom);
|
||||||
} else {
|
} else {
|
||||||
src -= skip;
|
src -= skip;
|
||||||
num += skip;
|
num += skip;
|
||||||
|
@ -854,15 +856,15 @@ static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
|
||||||
if (num <= 0) continue;
|
if (num <= 0) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
num = UnScaleByZoom(num + ScaleByZoom(1, zoom) - 1, zoom);
|
num = UnScaleByZoom(num + ScaleByZoom(1, Tzoom) - 1, Tzoom);
|
||||||
|
|
||||||
switch (bp->mode) {
|
switch (Tmode) {
|
||||||
case BM_COLOUR_REMAP:
|
case BM_COLOUR_REMAP:
|
||||||
ctab = _color_remap_ptr;
|
ctab = _color_remap_ptr;
|
||||||
for (; num != 0; num--) {
|
for (; num != 0; num--) {
|
||||||
*dst = ctab[*src];
|
*dst = ctab[*src];
|
||||||
dst++;
|
dst++;
|
||||||
src += ScaleByZoom(1, zoom);
|
src += ScaleByZoom(1, Tzoom);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -875,10 +877,14 @@ static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
for (; num != 0; num--) {
|
if (Tzoom == ZOOM_LVL_NORMAL) {
|
||||||
*dst = *src;
|
memcpy(dst, src, num);
|
||||||
dst++;
|
} else {
|
||||||
src += ScaleByZoom(1, zoom);
|
for (; num != 0; num--) {
|
||||||
|
*dst = *src;
|
||||||
|
dst++;
|
||||||
|
src += ScaleByZoom(1, Tzoom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -889,7 +895,7 @@ static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
|
||||||
bp->dst += bp->pitch;
|
bp->dst += bp->pitch;
|
||||||
if (--bp->height == 0) return;
|
if (--bp->height == 0) return;
|
||||||
|
|
||||||
for (int i = 0; i < ScaleByZoom(1, zoom) - 1; i++) {
|
for (int i = 0; i < ScaleByZoom(1, Tzoom) - 1; i++) {
|
||||||
do {
|
do {
|
||||||
done = src_o[0];
|
done = src_o[0];
|
||||||
src_o += (done & 0x7F) + 2;
|
src_o += (done & 0x7F) + 2;
|
||||||
|
@ -899,7 +905,8 @@ static void GfxBlitTileZoom(BlitterParams *bp, ZoomLevel zoom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode)
|
template <BlitterMode Tmode>
|
||||||
|
static inline void GfxMainBlitter(const Sprite *sprite, int x, int y)
|
||||||
{
|
{
|
||||||
const DrawPixelInfo *dpi = _cur_dpi;
|
const DrawPixelInfo *dpi = _cur_dpi;
|
||||||
int start_x, start_y;
|
int start_x, start_y;
|
||||||
|
@ -913,92 +920,68 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode)
|
||||||
bp.height = sprite->height;
|
bp.height = sprite->height;
|
||||||
bp.sprite = sprite->data;
|
bp.sprite = sprite->data;
|
||||||
bp.dst = dpi->dst_ptr;
|
bp.dst = dpi->dst_ptr;
|
||||||
bp.mode = mode;
|
|
||||||
bp.pitch = dpi->pitch;
|
bp.pitch = dpi->pitch;
|
||||||
|
|
||||||
assert(bp.height > 0);
|
assert(bp.height > 0);
|
||||||
assert(bp.width > 0);
|
assert(bp.width > 0);
|
||||||
|
|
||||||
if (sprite->info & 8) {
|
start_y = 0;
|
||||||
/* tile blit */
|
if (dpi->zoom > ZOOM_LVL_NORMAL) {
|
||||||
start_y = 0;
|
start_y += bp.height & ~zoom_mask;
|
||||||
|
|
||||||
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;
|
bp.height &= zoom_mask;
|
||||||
if (bp.height == 0) return;
|
if (bp.height == 0) return;
|
||||||
|
|
||||||
y &= zoom_mask;
|
y &= zoom_mask;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (y -= dpi->top) < 0) {
|
if ( (y -= dpi->top) < 0) {
|
||||||
bp.height += y;
|
bp.height += y;
|
||||||
if (bp.height <= 0) return;
|
if (bp.height <= 0) return;
|
||||||
bp.sprite -= bp.width * y;
|
start_y -= y;
|
||||||
y = 0;
|
y = 0;
|
||||||
} else {
|
} else {
|
||||||
bp.dst += bp.pitch * UnScaleByZoom(y, dpi->zoom);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprite->info & 8) {
|
||||||
|
switch (dpi->zoom) {
|
||||||
|
case ZOOM_LVL_NORMAL: GfxBlitTileZoom<Tmode, ZOOM_LVL_NORMAL>(&bp); break;
|
||||||
|
case ZOOM_LVL_OUT_2X: GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_2X>(&bp); break;
|
||||||
|
case ZOOM_LVL_OUT_4X: GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_4X>(&bp); break;
|
||||||
|
case ZOOM_LVL_OUT_8X: GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_8X>(&bp); break;
|
||||||
|
case ZOOM_LVL_OUT_16X: GfxBlitTileZoom<Tmode, ZOOM_LVL_OUT_16X>(&bp); break;
|
||||||
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (bp.height > dpi->height - y) {
|
switch (dpi->zoom) {
|
||||||
bp.height = dpi->height - y;
|
case ZOOM_LVL_NORMAL: GfxBlitZoomUncomp<Tmode, ZOOM_LVL_NORMAL>(&bp); break;
|
||||||
if (bp.height <= 0) return;
|
case ZOOM_LVL_OUT_2X: GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_2X>(&bp); break;
|
||||||
|
case ZOOM_LVL_OUT_4X: GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_4X>(&bp); break;
|
||||||
|
case ZOOM_LVL_OUT_8X: GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_8X>(&bp); break;
|
||||||
|
case ZOOM_LVL_OUT_16X: GfxBlitZoomUncomp<Tmode, ZOOM_LVL_OUT_16X>(&bp); break;
|
||||||
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
x &= zoom_mask;
|
|
||||||
|
|
||||||
if ( (x -= dpi->left) < 0) {
|
|
||||||
bp.width += x;
|
|
||||||
if (bp.width <= 0) return;
|
|
||||||
bp.sprite -= x;
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
bp.dst += UnScaleByZoom(x, dpi->zoom);
|
|
||||||
|
|
||||||
if (bp.width > dpi->width - x) {
|
|
||||||
bp.width = dpi->width - x;
|
|
||||||
if (bp.width <= 0) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GfxBlitZoomUncomp(&bp, dpi->zoom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue