Blitter: Also use sprite flags for non-SSE 32bpp sprite encoder
This commit is contained in:
@@ -25,7 +25,7 @@ Blitter_32bppAnim::~Blitter_32bppAnim()
|
|||||||
free(this->anim_alloc);
|
free(this->anim_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <BlitterMode mode>
|
template <BlitterMode mode, bool no_anim_translucent>
|
||||||
inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
|
inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
|
||||||
{
|
{
|
||||||
const SpriteData *src = (const SpriteData *)bp->sprite;
|
const SpriteData *src = (const SpriteData *)bp->sprite;
|
||||||
@@ -217,7 +217,14 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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 {
|
do {
|
||||||
/* Compiler assumes pointer aliasing, can't optimise this on its own */
|
/* Compiler assumes pointer aliasing, can't optimise this on its own */
|
||||||
uint m = GB(*src_n, 0, 8);
|
uint m = GB(*src_n, 0, 8);
|
||||||
@@ -260,13 +267,29 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BlitterSpriteFlags sprite_flags = ((const SpriteData *) bp->sprite)->flags;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
case BM_NORMAL: Draw<BM_NORMAL> (bp, zoom); return;
|
|
||||||
case BM_COLOUR_REMAP: Draw<BM_COLOUR_REMAP>(bp, zoom); return;
|
case BM_COLOUR_REMAP:
|
||||||
case BM_TRANSPARENT: Draw<BM_TRANSPARENT> (bp, zoom); return;
|
if (!(sprite_flags & SF_NO_REMAP)) {
|
||||||
case BM_CRASH_REMAP: Draw<BM_CRASH_REMAP> (bp, zoom); return;
|
Draw<BM_COLOUR_REMAP, false>(bp, zoom);
|
||||||
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP> (bp, zoom); return;
|
return;
|
||||||
|
}
|
||||||
|
/* FALL THROUGH */
|
||||||
|
|
||||||
|
case BM_NORMAL:
|
||||||
|
if ((sprite_flags & SF_NO_ANIM) && !(sprite_flags & SF_TRANSLUCENT)) {
|
||||||
|
Draw<BM_NORMAL, true>(bp, zoom);
|
||||||
|
} else {
|
||||||
|
Draw<BM_NORMAL, false>(bp, zoom);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case BM_TRANSPARENT: Draw<BM_TRANSPARENT, false> (bp, zoom); return;
|
||||||
|
case BM_CRASH_REMAP: Draw<BM_CRASH_REMAP, false> (bp, zoom); return;
|
||||||
|
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, false> (bp, zoom); return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,7 +72,7 @@ public:
|
|||||||
return across + (lines * this->anim_buf_pitch);
|
return across + (lines * this->anim_buf_pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <BlitterMode mode> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
template <BlitterMode mode, bool no_anim_translucent> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Factory for the 32bpp blitter with animation. */
|
/** Factory for the 32bpp blitter with animation. */
|
||||||
|
@@ -367,7 +367,7 @@ IGNORE_UNINITIALIZED_WARNING_STOP
|
|||||||
*/
|
*/
|
||||||
void Blitter_32bppSSE4_Anim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
|
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) {
|
switch (mode) {
|
||||||
default: {
|
default: {
|
||||||
bm_normal:
|
bm_normal:
|
||||||
|
@@ -284,6 +284,8 @@ Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloc
|
|||||||
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_DRAW_SPR;
|
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++) {
|
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
||||||
const SpriteLoader::Sprite *src_orig = &sprite[z];
|
const SpriteLoader::Sprite *src_orig = &sprite[z];
|
||||||
|
|
||||||
@@ -323,8 +325,12 @@ Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloc
|
|||||||
|
|
||||||
if (a != 0) {
|
if (a != 0) {
|
||||||
dst_px->a = a;
|
dst_px->a = a;
|
||||||
|
if (a != 0 && a != 255) flags |= SF_TRANSLUCENT;
|
||||||
*dst_n = src->m;
|
*dst_n = src->m;
|
||||||
if (src->m != 0) {
|
if (src->m != 0) {
|
||||||
|
flags &= ~SF_NO_REMAP;
|
||||||
|
if (src->m >= PALETTE_ANIM_START) flags &= ~SF_NO_ANIM;
|
||||||
|
|
||||||
/* Get brightest value */
|
/* Get brightest value */
|
||||||
uint8 rgb_max = max(src->r, max(src->g, src->b));
|
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;
|
SpriteData *dst = (SpriteData *)dest_sprite->data;
|
||||||
memset(dst, 0, sizeof(*dst));
|
memset(dst, 0, sizeof(*dst));
|
||||||
|
/* Store sprite flags. */
|
||||||
|
dst->flags = flags;
|
||||||
|
|
||||||
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
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];
|
dst->offset[z][0] = z == zoom_min ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1];
|
||||||
|
@@ -19,6 +19,7 @@ class Blitter_32bppOptimized : public Blitter_32bppSimple {
|
|||||||
public:
|
public:
|
||||||
/** Data stored about a (single) sprite. */
|
/** Data stored about a (single) sprite. */
|
||||||
struct SpriteData {
|
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.
|
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.
|
byte data[]; ///< Data, all zoomlevels.
|
||||||
};
|
};
|
||||||
|
@@ -49,18 +49,6 @@ public:
|
|||||||
BT_NONE, ///< No specialisation for either case.
|
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. */
|
/** Data stored about a (single) sprite. */
|
||||||
struct SpriteInfo {
|
struct SpriteInfo {
|
||||||
uint32 sprite_offset; ///< The offset to the sprite data.
|
uint32 sprite_offset; ///< The offset to the sprite data.
|
||||||
@@ -69,7 +57,7 @@ public:
|
|||||||
uint16 sprite_width; ///< The width of the sprite.
|
uint16 sprite_width; ///< The width of the sprite.
|
||||||
};
|
};
|
||||||
struct SpriteData {
|
struct SpriteData {
|
||||||
SpriteFlags flags;
|
BlitterSpriteFlags flags;
|
||||||
SpriteInfo infos[ZOOM_LVL_COUNT];
|
SpriteInfo infos[ZOOM_LVL_COUNT];
|
||||||
byte data[]; ///< Data, all zoomlevels.
|
byte data[]; ///< Data, all zoomlevels.
|
||||||
};
|
};
|
||||||
@@ -77,8 +65,6 @@ public:
|
|||||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
|
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). */
|
/** The SSE2 32 bpp blitter (without palette animation). */
|
||||||
class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Base {
|
class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Base {
|
||||||
public:
|
public:
|
||||||
|
@@ -27,6 +27,19 @@ enum BlitterMode {
|
|||||||
BM_BLACK_REMAP, ///< Perform remapping to a completely blackened sprite
|
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.
|
* How all blitters should look like. Extend this class to make your own.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user