diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp index 6127ff3a00..353afa14ac 100644 --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_anim.cpp @@ -175,6 +175,16 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel } break; + + case BM_BLACK_REMAP: + do { + *dst++ = Colour(0, 0, 0); + *anim++ = 0; + anim++; + dst++; + } while (--n != 0); + break; + case BM_TRANSPARENT: /* TODO -- We make an assumption here that the remap in fact is transparency, not some colour. * This is never a problem with the code we produce, but newgrfs can make it fail... or at least: @@ -251,6 +261,7 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL case BM_COLOUR_REMAP: Draw(bp, zoom); return; case BM_TRANSPARENT: Draw (bp, zoom); return; case BM_CRASH_REMAP: Draw (bp, zoom); return; + case BM_BLACK_REMAP: Draw (bp, zoom); return; } } diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp index f25683a10b..7d4b66fca6 100644 --- a/src/blitter/32bpp_anim_sse4.cpp +++ b/src/blitter/32bpp_anim_sse4.cpp @@ -334,6 +334,19 @@ bmcr_alpha_blend_single: anim++; } break; + + case BM_BLACK_REMAP: + for (uint x = (uint) bp->width; x > 0; x--) { + if (src->a != 0) { + *dst = Colour(0, 0, 0); + *anim = 0; + } + src_mv++; + dst++; + src++; + anim++; + } + break; } next_line: @@ -395,6 +408,7 @@ bm_normal: break; case BM_TRANSPARENT: Draw(bp, zoom); return; case BM_CRASH_REMAP: Draw(bp, zoom); return; + case BM_BLACK_REMAP: Draw(bp, zoom); return; } } diff --git a/src/blitter/32bpp_optimized.cpp b/src/blitter/32bpp_optimized.cpp index 9b7d7115c9..cc056f5b59 100644 --- a/src/blitter/32bpp_optimized.cpp +++ b/src/blitter/32bpp_optimized.cpp @@ -177,6 +177,15 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL } break; + case BM_BLACK_REMAP: + do { + *dst = Colour(0, 0, 0); + dst++; + src_px++; + src_n++; + } while (--n != 0); + break; + case BM_TRANSPARENT: /* TODO -- We make an assumption here that the remap in fact is transparency, not some colour. * This is never a problem with the code we produce, but newgrfs can make it fail... or at least: @@ -241,6 +250,7 @@ void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, case BM_COLOUR_REMAP: Draw(bp, zoom); return; case BM_TRANSPARENT: Draw (bp, zoom); return; case BM_CRASH_REMAP: Draw (bp, zoom); return; + case BM_BLACK_REMAP: Draw (bp, zoom); return; } } diff --git a/src/blitter/32bpp_simple.cpp b/src/blitter/32bpp_simple.cpp index 0ad7418db0..92375be165 100644 --- a/src/blitter/32bpp_simple.cpp +++ b/src/blitter/32bpp_simple.cpp @@ -58,6 +58,12 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo } break; + case BM_BLACK_REMAP: + if (src->a != 0) { + *dst = Colour(0, 0, 0); + } + break; + case BM_TRANSPARENT: /* TODO -- We make an assumption here that the remap in fact is transparency, not some colour. * This is never a problem with the code we produce, but newgrfs can make it fail... or at least: diff --git a/src/blitter/32bpp_sse_func.hpp b/src/blitter/32bpp_sse_func.hpp index 6b60ba6642..69d951cd26 100644 --- a/src/blitter/32bpp_sse_func.hpp +++ b/src/blitter/32bpp_sse_func.hpp @@ -394,6 +394,17 @@ bmcr_alpha_blend_single: src++; } break; + + case BM_BLACK_REMAP: + for (uint x = (uint) bp->width; x > 0; x--) { + if (src->a != 0) { + *dst = Colour(0, 0, 0); + } + src_mv++; + dst++; + src++; + } + break; } next_line: @@ -447,6 +458,7 @@ bm_normal: } case BM_TRANSPARENT: Draw(bp, zoom); return; case BM_CRASH_REMAP: Draw(bp, zoom); return; + case BM_BLACK_REMAP: Draw(bp, zoom); return; } } #endif /* FULL_ANIMATION */ diff --git a/src/blitter/8bpp_optimized.cpp b/src/blitter/8bpp_optimized.cpp index bcd8dc2824..0f07e7c7bb 100644 --- a/src/blitter/8bpp_optimized.cpp +++ b/src/blitter/8bpp_optimized.cpp @@ -13,6 +13,7 @@ #include "../zoom_func.h" #include "../settings_type.h" #include "../core/math_func.hpp" +#include "../core/mem_func.hpp" #include "8bpp_optimized.hpp" #include "../safeguards.h" @@ -96,6 +97,11 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z break; } + case BM_BLACK_REMAP: + MemSetT(dst, 0, pixels); + dst += pixels; + break; + case BM_TRANSPARENT: { const uint8 *remap = bp->remap; src += pixels; @@ -107,7 +113,7 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z } default: - memcpy(dst, src, pixels); + MemCpyT(dst, src, pixels); dst += pixels; src += pixels; break; } diff --git a/src/blitter/8bpp_simple.cpp b/src/blitter/8bpp_simple.cpp index d24d8caac5..ed5dd3f7ae 100644 --- a/src/blitter/8bpp_simple.cpp +++ b/src/blitter/8bpp_simple.cpp @@ -47,6 +47,10 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom if (*src != 0) colour = bp->remap[*dst]; break; + case BM_BLACK_REMAP: + colour = 0; + break; + default: colour = *src; break; diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index 3314eddfec..a9403b339d 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -21,6 +21,7 @@ enum BlitterMode { BM_COLOUR_REMAP, ///< Perform a colour remapping. BM_TRANSPARENT, ///< Perform transparency colour remapping. BM_CRASH_REMAP, ///< Perform a crash remapping. + BM_BLACK_REMAP, ///< Perform remapping to a completely blackened sprite }; /** diff --git a/src/gfx.cpp b/src/gfx.cpp index 5a1f75abc4..f6d9e0b98e 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -782,6 +782,21 @@ Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom) return d; } +/** + * Helper function to get the blitter mode for different types of palettes. + * @param pal The palette to get the blitter mode for. + * @return The blitter mode associated with the palette. + */ +static BlitterMode GetBlitterMode(PaletteID pal) +{ + switch (pal) { + case PAL_NONE: return BM_NORMAL; + case PALETTE_CRASH: return BM_CRASH_REMAP; + case PALETTE_ALL_BLACK: return BM_BLACK_REMAP; + default: return BM_COLOUR_REMAP; + } +} + /** * Draw a sprite in a viewport. * @param img Image number to draw @@ -802,7 +817,7 @@ void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSpri } else { _colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1; } - GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, pal == PALETTE_CRASH ? BM_CRASH_REMAP : BM_COLOUR_REMAP, sub, real_sprite); + GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, GetBlitterMode(pal), sub, real_sprite); } else { GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, BM_NORMAL, sub, real_sprite); } @@ -829,7 +844,7 @@ void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, } else { _colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1; } - GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, pal == PALETTE_CRASH ? BM_CRASH_REMAP : BM_COLOUR_REMAP, sub, real_sprite, zoom); + GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, GetBlitterMode(pal), sub, real_sprite, zoom); } else { GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_NORMAL, sub, real_sprite, zoom); }