diff options
-rw-r--r-- | src/blitter/32bpp_sse2.cpp | 17 | ||||
-rw-r--r-- | src/blitter/32bpp_sse2.hpp | 15 |
2 files changed, 31 insertions, 1 deletions
diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp index 2f1dc3828..40b3620a2 100644 --- a/src/blitter/32bpp_sse2.cpp +++ b/src/blitter/32bpp_sse2.cpp @@ -57,7 +57,10 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca dst_sprite->y_offs = sprite->y_offs; memcpy(dst_sprite->data, &sd, sizeof(SpriteData)); - /* Copy colours. */ + /* Copy colours and determine flags. */ + bool has_remap = false; + bool has_anim = false; + bool has_translucency = false; for (ZoomLevel z = zoom_min; z <= zoom_max; z++) { const SpriteLoader::Sprite *src_sprite = &sprite[z]; const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *) src_sprite->data; @@ -68,8 +71,13 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca for (uint x = src_sprite->width; x != 0; x--) { if (src->a != 0) { dst_rgba->a = src->a; + if (src->a != 0 && src->a != 255) has_translucency = true; dst_mv->m = src->m; if (src->m != 0) { + /* Do some accounting for flags. */ + has_remap = true; + if (src->m >= PALETTE_ANIM_START) has_anim = true; + /* Get brightest value (or default brightness if it's a black pixel). */ const uint8 rgb_max = max(src->r, max(src->g, src->b)); dst_mv->v = (rgb_max == 0) ? Blitter_32bppBase::DEFAULT_BRIGHTNESS : rgb_max; @@ -119,6 +127,13 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca } } + /* Store sprite flags. */ + sd.flags = SF_NONE; + if (has_translucency) sd.flags |= SF_TRANSLUCENT; + if (!has_remap) sd.flags |= SF_NO_REMAP; + if (!has_anim) sd.flags |= SF_NO_ANIM; + memcpy(dst_sprite->data, &sd, sizeof(SpriteData)); + return dst_sprite; } diff --git a/src/blitter/32bpp_sse2.hpp b/src/blitter/32bpp_sse2.hpp index 3caf7ba76..43a5fc400 100644 --- a/src/blitter/32bpp_sse2.hpp +++ b/src/blitter/32bpp_sse2.hpp @@ -49,6 +49,18 @@ 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. @@ -57,6 +69,7 @@ public: uint16 sprite_width; ///< The width of the sprite. }; struct SpriteData { + SpriteFlags flags; SpriteInfo infos[ZOOM_LVL_COUNT]; byte data[]; ///< Data, all zoomlevels. }; @@ -64,6 +77,8 @@ 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: |