diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp index 65030b40ba..a2b3e0709b 100644 --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_anim.cpp @@ -25,7 +25,7 @@ Blitter_32bppAnim::~Blitter_32bppAnim() free(this->anim_alloc); } -template +template inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom) { const SpriteData *src = (const SpriteData *)bp->sprite; @@ -217,7 +217,14 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel break; default: - if (src_px->a == 255) { + if (no_anim_translucent) { + do { + *anim++ = 0; + *dst++ = src_px->data; + src_px++; + src_n++; + } while (--n != 0); + } else if (src_px->a == 255) { do { /* Compiler assumes pointer aliasing, can't optimise this on its own */ uint m = GB(*src_n, 0, 8); @@ -260,13 +267,29 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL return; } + const BlitterSpriteFlags sprite_flags = ((const SpriteData *) bp->sprite)->flags; + switch (mode) { default: NOT_REACHED(); - case BM_NORMAL: Draw (bp, zoom); return; - 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; + + case BM_COLOUR_REMAP: + if (!(sprite_flags & SF_NO_REMAP)) { + Draw(bp, zoom); + return; + } + /* FALL THROUGH */ + + case BM_NORMAL: + if ((sprite_flags & SF_NO_ANIM) && !(sprite_flags & SF_TRANSLUCENT)) { + Draw(bp, zoom); + } else { + 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.hpp b/src/blitter/32bpp_anim.hpp index 58fb16490b..466628684c 100644 --- a/src/blitter/32bpp_anim.hpp +++ b/src/blitter/32bpp_anim.hpp @@ -72,7 +72,7 @@ public: return across + (lines * this->anim_buf_pitch); } - template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); + template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); }; /** Factory for the 32bpp blitter with animation. */ diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp index 219fb466bb..9611cf09e7 100644 --- a/src/blitter/32bpp_anim_sse4.cpp +++ b/src/blitter/32bpp_anim_sse4.cpp @@ -367,7 +367,7 @@ IGNORE_UNINITIALIZED_WARNING_STOP */ void Blitter_32bppSSE4_Anim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) { - const Blitter_32bppSSE_Base::SpriteFlags sprite_flags = ((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags; + const BlitterSpriteFlags sprite_flags = ((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags; switch (mode) { default: { bm_normal: diff --git a/src/blitter/32bpp_optimized.cpp b/src/blitter/32bpp_optimized.cpp index 649b27312c..ec05a72328 100644 --- a/src/blitter/32bpp_optimized.cpp +++ b/src/blitter/32bpp_optimized.cpp @@ -284,6 +284,8 @@ Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloc if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_DRAW_SPR; } + BlitterSpriteFlags flags = SF_NO_REMAP | SF_NO_ANIM; + for (ZoomLevel z = zoom_min; z <= zoom_max; z++) { const SpriteLoader::Sprite *src_orig = &sprite[z]; @@ -323,8 +325,12 @@ Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloc if (a != 0) { dst_px->a = a; + if (a != 0 && a != 255) flags |= SF_TRANSLUCENT; *dst_n = src->m; if (src->m != 0) { + flags &= ~SF_NO_REMAP; + if (src->m >= PALETTE_ANIM_START) flags &= ~SF_NO_ANIM; + /* Get brightest value */ uint8 rgb_max = max(src->r, max(src->g, src->b)); @@ -385,6 +391,8 @@ Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloc SpriteData *dst = (SpriteData *)dest_sprite->data; memset(dst, 0, sizeof(*dst)); + /* Store sprite flags. */ + dst->flags = flags; for (ZoomLevel z = zoom_min; z <= zoom_max; z++) { dst->offset[z][0] = z == zoom_min ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1]; diff --git a/src/blitter/32bpp_optimized.hpp b/src/blitter/32bpp_optimized.hpp index c261aa33d6..2c08096582 100644 --- a/src/blitter/32bpp_optimized.hpp +++ b/src/blitter/32bpp_optimized.hpp @@ -19,6 +19,7 @@ class Blitter_32bppOptimized : public Blitter_32bppSimple { public: /** Data stored about a (single) sprite. */ struct SpriteData { + BlitterSpriteFlags flags; uint32 offset[ZOOM_LVL_COUNT][2]; ///< Offsets (from .data) to streams for different zoom levels, and the normal and remap image information. byte data[]; ///< Data, all zoomlevels. }; diff --git a/src/blitter/32bpp_sse2.hpp b/src/blitter/32bpp_sse2.hpp index d6b17f679c..7afae87546 100644 --- a/src/blitter/32bpp_sse2.hpp +++ b/src/blitter/32bpp_sse2.hpp @@ -49,18 +49,6 @@ public: BT_NONE, ///< No specialisation for either case. }; - /** Helper for using specialised functions designed to prevent whenever it's possible things like: - * - IO (reading video buffer), - * - calculations (alpha blending), - * - heavy branching (remap lookups and animation buffer handling). - */ - enum SpriteFlags { - SF_NONE = 0, - SF_TRANSLUCENT = 1 << 1, ///< The sprite has at least 1 translucent pixel. - SF_NO_REMAP = 1 << 2, ///< The sprite has no remappable colour pixel. - SF_NO_ANIM = 1 << 3, ///< The sprite has no palette animated pixel. - }; - /** Data stored about a (single) sprite. */ struct SpriteInfo { uint32 sprite_offset; ///< The offset to the sprite data. @@ -69,7 +57,7 @@ public: uint16 sprite_width; ///< The width of the sprite. }; struct SpriteData { - SpriteFlags flags; + BlitterSpriteFlags flags; SpriteInfo infos[ZOOM_LVL_COUNT]; byte data[]; ///< Data, all zoomlevels. }; @@ -77,8 +65,6 @@ public: Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator); }; -DECLARE_ENUM_AS_BIT_SET(Blitter_32bppSSE_Base::SpriteFlags); - /** The SSE2 32 bpp blitter (without palette animation). */ class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Base { public: diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index ce01a14e78..b15915c5ee 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -27,6 +27,19 @@ enum BlitterMode { BM_BLACK_REMAP, ///< Perform remapping to a completely blackened sprite }; +/** Helper for using specialised functions designed to prevent whenever it's possible things like: + * - IO (reading video buffer), + * - calculations (alpha blending), + * - heavy branching (remap lookups and animation buffer handling). + */ +enum BlitterSpriteFlags { + SF_NONE = 0, + SF_TRANSLUCENT = 1 << 1, ///< The sprite has at least 1 translucent pixel. + SF_NO_REMAP = 1 << 2, ///< The sprite has no remappable colour pixel. + SF_NO_ANIM = 1 << 3, ///< The sprite has no palette animated pixel. +}; +DECLARE_ENUM_AS_BIT_SET(BlitterSpriteFlags); + /** * How all blitters should look like. Extend this class to make your own. */