Update to 14.0-beta1

This commit is contained in:
dP
2024-02-04 02:18:17 +05:30
parent 79037e2c65
commit 33ef333b57
1325 changed files with 138461 additions and 70983 deletions
+64 -48
View File
@@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "../video/video_driver.hpp"
#include "../palette_func.h"
#include "32bpp_anim.hpp"
#include "common.hpp"
@@ -30,26 +31,26 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
const SpriteData *src = (const SpriteData *)bp->sprite;
const Colour *src_px = (const Colour *)(src->data + src->offset[zoom][0]);
const uint16 *src_n = (const uint16 *)(src->data + src->offset[zoom][1]);
const uint16_t *src_n = (const uint16_t *)(src->data + src->offset[zoom][1]);
for (uint i = bp->skip_top; i != 0; i--) {
src_px = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
src_n = (const uint16 *)((const byte *)src_n + *(const uint32 *)src_n);
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
}
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
uint16 *anim = this->anim_buf + this->ScreenToAnimOffset((uint32 *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
uint16_t *anim = this->anim_buf + this->ScreenToAnimOffset((uint32_t *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
const byte *remap = bp->remap; // store so we don't have to access it via bp every time
for (int y = 0; y < bp->height; y++) {
Colour *dst_ln = dst + bp->pitch;
uint16 *anim_ln = anim + this->anim_buf_pitch;
uint16_t *anim_ln = anim + this->anim_buf_pitch;
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
src_px++;
const uint16 *src_n_ln = (const uint16 *)((const byte *)src_n + *(const uint32 *)src_n);
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
src_n += 2;
Colour *dst_end = dst + bp->skip_left;
@@ -144,7 +145,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
do {
uint m = *src_n;
if (m == 0) {
uint8 g = MakeDark(src_px->r, src_px->g, src_px->b);
uint8_t g = MakeDark(src_px->r, src_px->g, src_px->b);
*dst = ComposeColourRGBA(g, g, g, src_px->a, *dst);
*anim = 0;
} else {
@@ -162,7 +163,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
uint m = *src_n;
if (m == 0) {
if (src_px->a != 0) {
uint8 g = MakeDark(src_px->r, src_px->g, src_px->b);
uint8_t g = MakeDark(src_px->r, src_px->g, src_px->b);
*dst = ComposeColourRGBA(g, g, g, src_px->a, *dst);
*anim = 0;
}
@@ -190,10 +191,6 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
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:
* we produce a result the newgrf maker didn't expect ;) */
/* Make the current colour a bit more black, so it looks like this image is transparent */
src_n += n;
if (src_px->a == 255) {
@@ -215,6 +212,24 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
}
break;
case BM_TRANSPARENT_REMAP:
/* Apply custom transparency remap. */
src_n += n;
if (src_px->a != 0) {
src_px += n;
do {
*dst = this->LookupColourInPalette(remap[GetNearestColourIndex(*dst)]);
*anim = 0;
anim++;
dst++;
} while (--n != 0);
} else {
dst += n;
anim += n;
src_px += n;
}
break;
default:
if (src_px->a == 255) {
do {
@@ -264,6 +279,7 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
case BM_NORMAL: Draw<BM_NORMAL> (bp, zoom); return;
case BM_COLOUR_REMAP: Draw<BM_COLOUR_REMAP>(bp, zoom); return;
case BM_TRANSPARENT: Draw<BM_TRANSPARENT> (bp, zoom); return;
case BM_TRANSPARENT_REMAP: Draw<BM_TRANSPARENT_REMAP>(bp, zoom); return;
case BM_CRASH_REMAP: Draw<BM_CRASH_REMAP> (bp, zoom); return;
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP> (bp, zoom); return;
}
@@ -278,7 +294,7 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height,
}
Colour *udst = (Colour *)dst;
uint16 *anim = this->anim_buf + this->ScreenToAnimOffset((uint32 *)dst);
uint16_t *anim = this->anim_buf + this->ScreenToAnimOffset((uint32_t *)dst);
if (pal == PALETTE_TO_TRANSPARENT) {
do {
@@ -310,17 +326,17 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height,
Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
}
void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8_t colour)
{
*((Colour *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
/* Set the colour in the anim-buffer too, if we are rendering to the screen */
if (_screen_disable_anim) return;
this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch] = colour | (DEFAULT_BRIGHTNESS << 8);
this->anim_buf[this->ScreenToAnimOffset((uint32_t *)video) + x + y * this->anim_buf_pitch] = colour | (DEFAULT_BRIGHTNESS << 8);
}
void Blitter_32bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
void Blitter_32bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash)
{
const Colour c = LookupColourInPalette(colour);
@@ -329,8 +345,8 @@ void Blitter_32bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int
*((Colour *)video + x + y * _screen.pitch) = c;
});
} else {
uint16 * const offset_anim_buf = this->anim_buf + this->ScreenToAnimOffset((uint32 *)video);
const uint16 anim_colour = colour | (DEFAULT_BRIGHTNESS << 8);
uint16_t * const offset_anim_buf = this->anim_buf + this->ScreenToAnimOffset((uint32_t *)video);
const uint16_t anim_colour = colour | (DEFAULT_BRIGHTNESS << 8);
this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [&](int x, int y) {
*((Colour *)video + x + y * _screen.pitch) = c;
offset_anim_buf[x + y * this->anim_buf_pitch] = anim_colour;
@@ -338,7 +354,7 @@ void Blitter_32bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int
}
}
void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colour)
void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8_t colour)
{
if (_screen_disable_anim) {
/* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawRect() */
@@ -347,11 +363,11 @@ void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colou
}
Colour colour32 = LookupColourInPalette(colour);
uint16 *anim_line = this->ScreenToAnimOffset((uint32 *)video) + this->anim_buf;
uint16_t *anim_line = this->ScreenToAnimOffset((uint32_t *)video) + this->anim_buf;
do {
Colour *dst = (Colour *)video;
uint16 *anim = anim_line;
uint16_t *anim = anim_line;
for (int i = width; i > 0; i--) {
*dst = colour32;
@@ -360,7 +376,7 @@ void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colou
dst++;
anim++;
}
video = (uint32 *)video + _screen.pitch;
video = (uint32_t *)video + _screen.pitch;
anim_line += this->anim_buf_pitch;
} while (--height);
}
@@ -368,22 +384,22 @@ void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colou
void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width, int height)
{
assert(!_screen_disable_anim);
assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
assert(video >= _screen.dst_ptr && video <= (uint32_t *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
Colour *dst = (Colour *)video;
const uint32 *usrc = (const uint32 *)src;
uint16 *anim_line = this->ScreenToAnimOffset((uint32 *)video) + this->anim_buf;
const uint32_t *usrc = (const uint32_t *)src;
uint16_t *anim_line = this->ScreenToAnimOffset((uint32_t *)video) + this->anim_buf;
for (; height > 0; height--) {
/* We need to keep those for palette animation. */
Colour *dst_pal = dst;
uint16 *anim_pal = anim_line;
uint16_t *anim_pal = anim_line;
memcpy(static_cast<void *>(dst), usrc, width * sizeof(uint32));
memcpy(static_cast<void *>(dst), usrc, width * sizeof(uint32_t));
usrc += width;
dst += _screen.pitch;
/* Copy back the anim-buffer */
memcpy(anim_line, usrc, width * sizeof(uint16));
usrc = (const uint32 *)((const uint16 *)usrc + width);
memcpy(anim_line, usrc, width * sizeof(uint16_t));
usrc = (const uint32_t *)&((const uint16_t *)usrc)[width];
anim_line += this->anim_buf_pitch;
/* Okay, it is *very* likely that the image we stored is using
@@ -408,21 +424,21 @@ void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width,
void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, int height)
{
assert(!_screen_disable_anim);
assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint32 *udst = (uint32 *)dst;
const uint32 *src = (const uint32 *)video;
assert(video >= _screen.dst_ptr && video <= (uint32_t *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint32_t *udst = (uint32_t *)dst;
const uint32_t *src = (const uint32_t *)video;
if (this->anim_buf == nullptr) return;
const uint16 *anim_line = this->ScreenToAnimOffset((const uint32 *)video) + this->anim_buf;
const uint16_t *anim_line = this->ScreenToAnimOffset((const uint32_t *)video) + this->anim_buf;
for (; height > 0; height--) {
memcpy(udst, src, width * sizeof(uint32));
memcpy(udst, src, width * sizeof(uint32_t));
src += _screen.pitch;
udst += width;
/* Copy the anim-buffer */
memcpy(udst, anim_line, width * sizeof(uint16));
udst = (uint32 *)((uint16 *)udst + width);
memcpy(udst, anim_line, width * sizeof(uint16_t));
udst = (uint32_t *)&((uint16_t *)udst)[width];
anim_line += this->anim_buf_pitch;
}
}
@@ -430,8 +446,8 @@ void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, in
void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y)
{
assert(!_screen_disable_anim);
assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint16 *dst, *src;
assert(video >= _screen.dst_ptr && video <= (uint32_t *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint16_t *dst, *src;
/* We need to scroll the anim-buffer too */
if (scroll_y > 0) {
@@ -448,7 +464,7 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
uint tw = width + (scroll_x >= 0 ? -scroll_x : scroll_x);
uint th = height - scroll_y;
for (; th > 0; th--) {
memcpy(dst, src, tw * sizeof(uint16));
memcpy(dst, src, tw * sizeof(uint16_t));
src -= this->anim_buf_pitch;
dst -= this->anim_buf_pitch;
}
@@ -469,7 +485,7 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
uint tw = width + (scroll_x >= 0 ? -scroll_x : scroll_x);
uint th = height + scroll_y;
for (; th > 0; th--) {
memmove(dst, src, tw * sizeof(uint16));
memmove(dst, src, tw * sizeof(uint16_t));
src += this->anim_buf_pitch;
dst += this->anim_buf_pitch;
}
@@ -478,9 +494,9 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y);
}
int Blitter_32bppAnim::BufferSize(int width, int height)
size_t Blitter_32bppAnim::BufferSize(uint width, uint height)
{
return width * height * (sizeof(uint32) + sizeof(uint16));
return (sizeof(uint32_t) + sizeof(uint16_t)) * width * height;
}
void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)
@@ -493,7 +509,7 @@ void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)
* Especially when going between toyland and non-toyland. */
assert(this->palette.first_dirty == PALETTE_ANIM_START || this->palette.first_dirty == 0);
const uint16 *anim = this->anim_buf;
const uint16_t *anim = this->anim_buf;
Colour *dst = (Colour *)_screen.dst_ptr;
/* Let's walk the anim buffer and try to find the pixels */
@@ -502,8 +518,8 @@ void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)
const int anim_pitch_offset = this->anim_buf_pitch - width;
for (int y = this->anim_buf_height; y != 0 ; y--) {
for (int x = width; x != 0 ; x--) {
uint16 value = *anim;
uint8 colour = GB(value, 0, 8);
uint16_t value = *anim;
uint8_t colour = GB(value, 0, 8);
if (colour >= PALETTE_ANIM_START) {
/* Update this pixel */
*dst = this->AdjustBrightness(LookupColourInPalette(colour), GB(value, 8, 8));
@@ -533,9 +549,9 @@ void Blitter_32bppAnim::PostResize()
this->anim_buf_width = _screen.width;
this->anim_buf_height = _screen.height;
this->anim_buf_pitch = (_screen.width + 7) & ~7;
this->anim_alloc = CallocT<uint16>(this->anim_buf_pitch * this->anim_buf_height + 8);
this->anim_alloc = CallocT<uint16_t>(this->anim_buf_pitch * this->anim_buf_height + 8);
/* align buffer to next 16 byte boundary */
this->anim_buf = reinterpret_cast<uint16 *>((reinterpret_cast<uintptr_t>(this->anim_alloc) + 0xF) & (~0xF));
this->anim_buf = reinterpret_cast<uint16_t *>((reinterpret_cast<uintptr_t>(this->anim_alloc) + 0xF) & (~0xF));
}
}
+7 -8
View File
@@ -15,7 +15,7 @@
/** The optimised 32 bpp blitter with palette animation. */
class Blitter_32bppAnim : public Blitter_32bppOptimized {
protected:
uint16 *anim_buf; ///< In this buffer we keep track of the 8bpp indexes so we can do palette animation
uint16_t *anim_buf; ///< In this buffer we keep track of the 8bpp indexes so we can do palette animation
void *anim_alloc; ///< The raw allocated buffer, not necessarily aligned correctly
int anim_buf_width; ///< The width of the animation buffer.
int anim_buf_height; ///< The height of the animation buffer.
@@ -37,18 +37,17 @@ public:
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
void SetPixel(void *video, int x, int y, uint8 colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
void DrawRect(void *video, int width, int height, uint8 colour) override;
void SetPixel(void *video, int x, int y, uint8_t colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override;
void DrawRect(void *video, int width, int height, uint8_t colour) override;
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
int BufferSize(int width, int height) override;
size_t BufferSize(uint width, uint height) override;
void PaletteAnimate(const Palette &palette) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;
const char *GetName() override { return "32bpp-anim"; }
int GetBytesPerPixel() override { return 6; }
void PostResize() override;
/**
@@ -59,9 +58,9 @@ public:
return this->palette.palette[index];
}
inline int ScreenToAnimOffset(const uint32 *video)
inline int ScreenToAnimOffset(const uint32_t *video)
{
int raw_offset = video - (const uint32 *)_screen.dst_ptr;
int raw_offset = video - (const uint32_t *)_screen.dst_ptr;
if (_screen.pitch == this->anim_buf_pitch) return raw_offset;
int lines = raw_offset / _screen.pitch;
int across = raw_offset % _screen.pitch;
+3 -3
View File
@@ -30,7 +30,7 @@ void Blitter_32bppSSE2_Anim::PaletteAnimate(const Palette &palette)
* Especially when going between toyland and non-toyland. */
assert(this->palette.first_dirty == PALETTE_ANIM_START || this->palette.first_dirty == 0);
const uint16 *anim = this->anim_buf;
const uint16_t *anim = this->anim_buf;
Colour *dst = (Colour *)_screen.dst_ptr;
bool screen_dirty = false;
@@ -44,7 +44,7 @@ void Blitter_32bppSSE2_Anim::PaletteAnimate(const Palette &palette)
__m128i colour_mask = _mm_set1_epi16(0xFF);
for (int y = this->anim_buf_height; y != 0 ; y--) {
Colour *next_dst_ln = dst + screen_pitch;
const uint16 *next_anim_ln = anim + anim_pitch;
const uint16_t *next_anim_ln = anim + anim_pitch;
int x = width;
while (x > 0) {
__m128i data = _mm_load_si128((const __m128i *) anim);
@@ -61,7 +61,7 @@ void Blitter_32bppSSE2_Anim::PaletteAnimate(const Palette &palette)
/* slow path: < 8 pixels left or unexpected brightnesses */
for (int z = std::min<int>(x, 8); z != 0 ; z--) {
int value = _mm_extract_epi16(data, 0);
uint8 colour = GB(value, 0, 8);
uint8_t colour = GB(value, 0, 8);
if (colour >= PALETTE_ANIM_START) {
/* Update this pixel */
*dst = AdjustBrightneSSE(LookupColourInPalette(colour), GB(value, 8, 8));
+41 -24
View File
@@ -10,6 +10,7 @@
#ifdef WITH_SSE
#include "../stdafx.h"
#include "../palette_func.h"
#include "../video/video_driver.hpp"
#include "../table/sprites.h"
#include "32bpp_anim_sse4.hpp"
@@ -30,11 +31,11 @@ static FBlitter_32bppSSE4_Anim iFBlitter_32bppSSE4_Anim;
IGNORE_UNINITIALIZED_WARNING_START
template <BlitterMode mode, Blitter_32bppSSE2::ReadMode read_mode, Blitter_32bppSSE2::BlockType bt_last, bool translucent, bool animated>
GNU_TARGET("sse4.1")
inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom)
inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom)
{
const byte * const remap = bp->remap;
Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
uint16 *anim_line = this->anim_buf + this->ScreenToAnimOffset((uint32 *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
uint16_t *anim_line = this->anim_buf + this->ScreenToAnimOffset((uint32_t *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left;
int effective_width = bp->width;
/* Find where to start reading in the source sprite. */
@@ -59,7 +60,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL
Colour *dst = dst_line;
const Colour *src = src_rgba_line + META_LENGTH;
if (mode != BM_TRANSPARENT) src_mv = src_mv_line;
uint16 *anim = anim_line;
uint16_t *anim = anim_line;
if (read_mode == RM_WITH_MARGIN) {
assert(bt_last == BT_NONE); // or you must ensure block type is preserved
@@ -81,7 +82,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL
for (uint x = (uint) effective_width; x > 0; x--) {
if (src->a) {
if (animated) {
*anim = *(const uint16*) src_mv;
*anim = *(const uint16_t*) src_mv;
*dst = (src_mv->m >= PALETTE_ANIM_START) ? AdjustBrightneSSE(this->LookupColourInPalette(src_mv->m), src_mv->v) : src->data;
} else {
*anim = 0;
@@ -97,7 +98,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL
}
for (uint x = (uint) effective_width/2; x != 0; x--) {
uint32 mvX2 = *((uint32 *) const_cast<MapValue *>(src_mv));
uint32_t mvX2 = *((uint32_t *) const_cast<MapValue *>(src_mv));
__m128i srcABCD = _mm_loadl_epi64((const __m128i*) src);
__m128i dstABCD = _mm_loadl_epi64((__m128i*) dst);
@@ -117,26 +118,26 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL
/* Update anim buffer. */
const byte a0 = src[0].a;
const byte a1 = src[1].a;
uint32 anim01 = 0;
uint32_t anim01 = 0;
if (a0 == 255) {
if (a1 == 255) {
*(uint32*) anim = mvX2;
*(uint32_t*) anim = mvX2;
goto bmno_full_opacity;
}
anim01 = (uint16) mvX2;
anim01 = (uint16_t) mvX2;
} else if (a0 == 0) {
if (a1 == 0) {
goto bmno_full_transparency;
} else {
if (a1 == 255) anim[1] = (uint16) (mvX2 >> 16);
if (a1 == 255) anim[1] = (uint16_t) (mvX2 >> 16);
goto bmno_alpha_blend;
}
}
if (a1 > 0) {
if (a1 == 255) anim01 |= mvX2 & 0xFFFF0000;
*(uint32*) anim = anim01;
*(uint32_t*) anim = anim01;
} else {
anim[0] = (uint16) anim01;
anim[0] = (uint16_t) anim01;
}
} else {
if (src[0].a) anim[0] = 0;
@@ -159,7 +160,7 @@ bmno_full_transparency:
if (src->a == 0) {
/* Complete transparency. */
} else if (src->a == 255) {
*anim = *(const uint16*) src_mv;
*anim = *(const uint16_t*) src_mv;
*dst = (src_mv->m >= PALETTE_ANIM_START) ? AdjustBrightneSSE(LookupColourInPalette(src_mv->m), src_mv->v) : *src;
} else {
*anim = 0;
@@ -179,7 +180,7 @@ bmno_full_transparency:
case BM_COLOUR_REMAP:
for (uint x = (uint) effective_width / 2; x != 0; x--) {
uint32 mvX2 = *((uint32 *) const_cast<MapValue *>(src_mv));
uint32_t mvX2 = *((uint32_t *) const_cast<MapValue *>(src_mv));
__m128i srcABCD = _mm_loadl_epi64((const __m128i*) src);
__m128i dstABCD = _mm_loadl_epi64((__m128i*) dst);
@@ -201,14 +202,14 @@ bmno_full_transparency:
m_colour = m != 0 ? m_colour : srcm; \
}
#ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 dsts;
uint64_t srcs = _mm_cvtsi128_si64(srcABCD);
uint64_t dsts;
if (animated) dsts = _mm_cvtsi128_si64(dstABCD);
uint64 remapped_src = 0;
uint64_t remapped_src = 0;
CMOV_REMAP(c0, animated ? dsts : 0, srcs, mvX2);
remapped_src = c0.data;
CMOV_REMAP(c1, animated ? dsts >> 32 : 0, srcs >> 32, mvX2 >> 16);
remapped_src |= (uint64) c1.data << 32;
remapped_src |= (uint64_t) c1.data << 32;
srcABCD = _mm_cvtsi64_si128(remapped_src);
#else
Colour remapped_src[2];
@@ -226,11 +227,11 @@ bmno_full_transparency:
if (animated) {
const byte a0 = src[0].a;
const byte a1 = src[1].a;
uint32 anim01 = mvX2 & 0xFF00FF00;
uint32_t anim01 = mvX2 & 0xFF00FF00;
if (a0 == 255) {
anim01 |= r0;
if (a1 == 255) {
*(uint32*) anim = anim01 | (r1 << 16);
*(uint32_t*) anim = anim01 | (r1 << 16);
goto bmcr_full_opacity;
}
} else if (a0 == 0) {
@@ -245,9 +246,9 @@ bmno_full_transparency:
}
if (a1 > 0) {
if (a1 == 255) anim01 |= r1 << 16;
*(uint32*) anim = anim01;
*(uint32_t*) anim = anim01;
} else {
anim[0] = (uint16) anim01;
anim[0] = (uint16_t) anim01;
}
} else {
if (src[0].a) anim[0] = 0;
@@ -272,7 +273,7 @@ bmcr_full_transparency:
if (src->a == 0) break;
if (src_mv->m) {
const uint r = remap[src_mv->m];
*anim = (animated && src->a == 255) ? r | ((uint16) src_mv->v << 8 ) : 0;
*anim = (animated && src->a == 255) ? r | ((uint16_t) src_mv->v << 8 ) : 0;
if (r != 0) {
Colour remapped_colour = AdjustBrightneSSE(this->LookupColourInPalette(r), src_mv->v);
if (src->a == 255) {
@@ -317,11 +318,26 @@ bmcr_alpha_blend_single:
}
break;
case BM_TRANSPARENT_REMAP:
/* Apply custom transparency remap. */
for (uint x = (uint) bp->width; x > 0; x--) {
if (src->a != 0) {
*dst = this->LookupColourInPalette(remap[GetNearestColourIndex(*dst)]);
*anim = 0;
}
src_mv++;
dst++;
src++;
anim++;
}
break;
case BM_CRASH_REMAP:
for (uint x = (uint) bp->width; x > 0; x--) {
if (src_mv->m == 0) {
if (src->a != 0) {
uint8 g = MakeDark(src->r, src->g, src->b);
uint8_t g = MakeDark(src->r, src->g, src->b);
*dst = ComposeColourRGBA(g, g, g, src->a, *dst);
*anim = 0;
}
@@ -351,7 +367,7 @@ bmcr_alpha_blend_single:
}
next_line:
if (mode != BM_TRANSPARENT) src_mv_line += si->sprite_width;
if (mode != BM_TRANSPARENT && mode != BM_TRANSPARENT_REMAP) src_mv_line += si->sprite_width;
src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
dst_line += bp->pitch;
anim_line += this->anim_buf_pitch;
@@ -414,6 +430,7 @@ bm_normal:
}
break;
case BM_TRANSPARENT: Draw<BM_TRANSPARENT, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
case BM_TRANSPARENT_REMAP: Draw<BM_TRANSPARENT_REMAP, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
case BM_CRASH_REMAP: Draw<BM_CRASH_REMAP, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
}
+2 -2
View File
@@ -32,14 +32,14 @@
#define MARGIN_NORMAL_THRESHOLD 4
/** The SSE4 32 bpp blitter with palette animation. */
class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppSSE2_Anim, public Blitter_32bppSSE4 {
class Blitter_32bppSSE4_Anim final : public Blitter_32bppSSE2_Anim, public Blitter_32bppSSE4 {
private:
public:
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent, bool animated>
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override {
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override {
return Blitter_32bppSSE_Base::Encode(sprite, allocator);
}
const char *GetName() override { return "32bpp-sse4-anim"; }
+29 -29
View File
@@ -15,15 +15,15 @@
void *Blitter_32bppBase::MoveTo(void *video, int x, int y)
{
return (uint32 *)video + x + y * _screen.pitch;
return (uint32_t *)video + x + y * _screen.pitch;
}
void Blitter_32bppBase::SetPixel(void *video, int x, int y, uint8 colour)
void Blitter_32bppBase::SetPixel(void *video, int x, int y, uint8_t colour)
{
*((Colour *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
}
void Blitter_32bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
void Blitter_32bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash)
{
const Colour c = LookupColourInPalette(colour);
this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [=](int x, int y) {
@@ -31,7 +31,7 @@ void Blitter_32bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int
});
}
void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colour)
void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8_t colour)
{
Colour colour32 = LookupColourInPalette(colour);
@@ -41,17 +41,17 @@ void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colou
*dst = colour32;
dst++;
}
video = (uint32 *)video + _screen.pitch;
video = (uint32_t *)video + _screen.pitch;
} while (--height);
}
void Blitter_32bppBase::CopyFromBuffer(void *video, const void *src, int width, int height)
{
uint32 *dst = (uint32 *)video;
const uint32 *usrc = (const uint32 *)src;
uint32_t *dst = (uint32_t *)video;
const uint32_t *usrc = (const uint32_t *)src;
for (; height > 0; height--) {
memcpy(dst, usrc, width * sizeof(uint32));
memcpy(dst, usrc, width * sizeof(uint32_t));
usrc += width;
dst += _screen.pitch;
}
@@ -59,11 +59,11 @@ void Blitter_32bppBase::CopyFromBuffer(void *video, const void *src, int width,
void Blitter_32bppBase::CopyToBuffer(const void *video, void *dst, int width, int height)
{
uint32 *udst = (uint32 *)dst;
const uint32 *src = (const uint32 *)video;
uint32_t *udst = (uint32_t *)dst;
const uint32_t *src = (const uint32_t *)video;
for (; height > 0; height--) {
memcpy(udst, src, width * sizeof(uint32));
memcpy(udst, src, width * sizeof(uint32_t));
src += _screen.pitch;
udst += width;
}
@@ -71,11 +71,11 @@ void Blitter_32bppBase::CopyToBuffer(const void *video, void *dst, int width, in
void Blitter_32bppBase::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch)
{
uint32 *udst = (uint32 *)dst;
const uint32 *src = (const uint32 *)video;
uint32_t *udst = (uint32_t *)dst;
const uint32_t *src = (const uint32_t *)video;
for (; height > 0; height--) {
memcpy(udst, src, width * sizeof(uint32));
memcpy(udst, src, width * sizeof(uint32_t));
src += _screen.pitch;
udst += dst_pitch;
}
@@ -83,12 +83,12 @@ void Blitter_32bppBase::CopyImageToBuffer(const void *video, void *dst, int widt
void Blitter_32bppBase::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y)
{
const uint32 *src;
uint32 *dst;
const uint32_t *src;
uint32_t *dst;
if (scroll_y > 0) {
/* Calculate pointers */
dst = (uint32 *)video + left + (top + height - 1) * _screen.pitch;
dst = (uint32_t *)video + left + (top + height - 1) * _screen.pitch;
src = dst - scroll_y * _screen.pitch;
/* Decrease height and increase top */
@@ -107,13 +107,13 @@ void Blitter_32bppBase::ScrollBuffer(void *video, int &left, int &top, int &widt
}
for (int h = height; h > 0; h--) {
memcpy(dst, src, width * sizeof(uint32));
memcpy(dst, src, width * sizeof(uint32_t));
src -= _screen.pitch;
dst -= _screen.pitch;
}
} else {
/* Calculate pointers */
dst = (uint32 *)video + left + top * _screen.pitch;
dst = (uint32_t *)video + left + top * _screen.pitch;
src = dst - scroll_y * _screen.pitch;
/* Decrease height. (scroll_y is <=0). */
@@ -133,39 +133,39 @@ void Blitter_32bppBase::ScrollBuffer(void *video, int &left, int &top, int &widt
/* the y-displacement may be 0 therefore we have to use memmove,
* because source and destination may overlap */
for (int h = height; h > 0; h--) {
memmove(dst, src, width * sizeof(uint32));
memmove(dst, src, width * sizeof(uint32_t));
src += _screen.pitch;
dst += _screen.pitch;
}
}
}
int Blitter_32bppBase::BufferSize(int width, int height)
size_t Blitter_32bppBase::BufferSize(uint width, uint height)
{
return width * height * sizeof(uint32);
return sizeof(uint32_t) * width * height;
}
void Blitter_32bppBase::PaletteAnimate(const Palette &palette)
void Blitter_32bppBase::PaletteAnimate(const Palette &)
{
/* By default, 32bpp doesn't have palette animation */
}
Colour Blitter_32bppBase::ReallyAdjustBrightness(Colour colour, uint8 brightness)
Colour Blitter_32bppBase::ReallyAdjustBrightness(Colour colour, uint8_t brightness)
{
assert(DEFAULT_BRIGHTNESS == 1 << 7);
uint64 combined = (((uint64) colour.r) << 32) | (((uint64) colour.g) << 16) | ((uint64) colour.b);
uint64_t combined = (((uint64_t) colour.r) << 32) | (((uint64_t) colour.g) << 16) | ((uint64_t) colour.b);
combined *= brightness;
uint16 r = GB(combined, 39, 9);
uint16 g = GB(combined, 23, 9);
uint16 b = GB(combined, 7, 9);
uint16_t r = GB(combined, 39, 9);
uint16_t g = GB(combined, 23, 9);
uint16_t b = GB(combined, 7, 9);
if ((combined & 0x800080008000L) == 0L) {
return Colour(r, g, b, colour.a);
}
uint16 ob = 0;
uint16_t ob = 0;
/* Sum overbright */
if (r > 255) ob += r - 255;
if (g > 255) ob += g - 255;
+11 -12
View File
@@ -18,19 +18,18 @@
/** Base for all 32bpp blitters. */
class Blitter_32bppBase : public Blitter {
public:
uint8 GetScreenDepth() override { return 32; }
uint8_t GetScreenDepth() override { return 32; }
void *MoveTo(void *video, int x, int y) override;
void SetPixel(void *video, int x, int y, uint8 colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
void DrawRect(void *video, int width, int height, uint8 colour) override;
void SetPixel(void *video, int x, int y, uint8_t colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override;
void DrawRect(void *video, int width, int height, uint8_t colour) override;
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
int BufferSize(int width, int height) override;
size_t BufferSize(uint width, uint height) override;
void PaletteAnimate(const Palette &palette) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;
int GetBytesPerPixel() override { return 4; }
/**
* Look up the colour in the current palette.
@@ -118,7 +117,7 @@ public:
* @param b blue component
* @return the brightness value of the new colour, now dark grey.
*/
static inline uint8 MakeDark(uint8 r, uint8 g, uint8 b)
static inline uint8_t MakeDark(uint8_t r, uint8_t g, uint8_t b)
{
/* Magic-numbers are ~66% of those used in MakeGrey() */
return ((r * 13063) + (g * 25647) + (b * 4981)) / 65536;
@@ -131,7 +130,7 @@ public:
*/
static inline Colour MakeDark(Colour colour)
{
uint8 d = MakeDark(colour.r, colour.g, colour.b);
uint8_t d = MakeDark(colour.r, colour.g, colour.b);
return Colour(d, d, d);
}
@@ -157,9 +156,9 @@ public:
static const int DEFAULT_BRIGHTNESS = 128;
static Colour ReallyAdjustBrightness(Colour colour, uint8 brightness);
static Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness);
static inline Colour AdjustBrightness(Colour colour, uint8 brightness)
static inline Colour AdjustBrightness(Colour colour, uint8_t brightness)
{
/* Shortcut for normal brightness */
if (brightness == DEFAULT_BRIGHTNESS) return colour;
@@ -167,9 +166,9 @@ public:
return ReallyAdjustBrightness(colour, brightness);
}
static inline uint8 GetColourBrightness(Colour colour)
static inline uint8_t GetColourBrightness(Colour colour)
{
uint8 rgb_max = std::max(colour.r, std::max(colour.g, colour.b));
uint8_t rgb_max = std::max(colour.r, std::max(colour.g, colour.b));
/* Black pixel (8bpp or old 32bpp image), so use default value */
if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS;
+52 -38
View File
@@ -10,6 +10,7 @@
#include "../stdafx.h"
#include "../zoom_func.h"
#include "../settings_type.h"
#include "../palette_func.h"
#include "32bpp_optimized.hpp"
#include "../safeguards.h"
@@ -29,18 +30,18 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
{
const SpriteData *src = (const SpriteData *)bp->sprite;
/* src_px : each line begins with uint32 n = 'number of bytes in this line',
/* src_px : each line begins with uint32_t n = 'number of bytes in this line',
* then n times is the Colour struct for this line */
const Colour *src_px = (const Colour *)(src->data + src->offset[zoom][0]);
/* src_n : each line begins with uint32 n = 'number of bytes in this line',
/* src_n : each line begins with uint32_t n = 'number of bytes in this line',
* then interleaved stream of 'm' and 'n' channels. 'm' is remap,
* 'n' is number of bytes with the same alpha channel class */
const uint16 *src_n = (const uint16 *)(src->data + src->offset[zoom][1]);
const uint16_t *src_n = (const uint16_t *)(src->data + src->offset[zoom][1]);
/* skip upper lines in src_px and src_n */
for (uint i = bp->skip_top; i != 0; i--) {
src_px = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
src_n = (const uint16 *)((const byte *)src_n + *(const uint32 *)src_n);
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
}
/* skip lines in dst */
@@ -54,11 +55,11 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
Colour *dst_ln = dst + bp->pitch;
/* next src line begins here */
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
src_px++;
/* next src_n line begins here */
const uint16 *src_n_ln = (const uint16 *)((const byte *)src_n + *(const uint32 *)src_n);
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
src_n += 2;
/* we will end this line when we reach this point */
@@ -146,7 +147,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
do {
uint m = *src_n;
if (m == 0) {
uint8 g = MakeDark(src_px->r, src_px->g, src_px->b);
uint8_t g = MakeDark(src_px->r, src_px->g, src_px->b);
*dst = ComposeColourRGBA(g, g, g, src_px->a, *dst);
} else {
uint r = remap[GB(m, 0, 8)];
@@ -161,7 +162,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
uint m = *src_n;
if (m == 0) {
if (src_px->a != 0) {
uint8 g = MakeDark(src_px->r, src_px->g, src_px->b);
uint8_t g = MakeDark(src_px->r, src_px->g, src_px->b);
*dst = ComposeColourRGBA(g, g, g, src_px->a, *dst);
}
} else {
@@ -185,10 +186,6 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
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:
* we produce a result the newgrf maker didn't expect ;) */
/* Make the current colour a bit more black, so it looks like this image is transparent */
src_n += n;
if (src_px->a == 255) {
@@ -206,6 +203,21 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
}
break;
case BM_TRANSPARENT_REMAP:
/* Apply custom transparency remap. */
src_n += n;
if (src_px->a != 0) {
src_px += n;
do {
*dst = this->LookupColourInPalette(remap[GetNearestColourIndex(*dst)]);
dst++;
} while (--n != 0);
} else {
dst += n;
src_px += n;
}
break;
default:
if (src_px->a == 255) {
/* faster than memcpy(), n is usually low */
@@ -252,6 +264,7 @@ void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode,
case BM_NORMAL: Draw<BM_NORMAL, Tpal_to_rgb>(bp, zoom); return;
case BM_COLOUR_REMAP: Draw<BM_COLOUR_REMAP, Tpal_to_rgb>(bp, zoom); return;
case BM_TRANSPARENT: Draw<BM_TRANSPARENT, Tpal_to_rgb>(bp, zoom); return;
case BM_TRANSPARENT_REMAP: Draw<BM_TRANSPARENT_REMAP, Tpal_to_rgb>(bp, zoom); return;
case BM_CRASH_REMAP: Draw<BM_CRASH_REMAP, Tpal_to_rgb>(bp, zoom); return;
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, Tpal_to_rgb>(bp, zoom); return;
}
@@ -272,12 +285,12 @@ void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode,
this->Draw<false>(bp, mode, zoom);
}
template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
/* streams of pixels (a, r, g, b channels)
*
* stored in separated stream so data are always aligned on 4B boundary */
Colour *dst_px_orig[ZOOM_LVL_COUNT];
Colour *dst_px_orig[ZOOM_LVL_END];
/* interleaved stream of 'm' channel and 'n' channel
* 'n' is number of following pixels with the same alpha channel class
@@ -285,15 +298,15 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
*
* it has to be stored in one stream so fewer registers are used -
* x86 has problems with register allocation even with this solution */
uint16 *dst_n_orig[ZOOM_LVL_COUNT];
uint16_t *dst_n_orig[ZOOM_LVL_END];
/* lengths of streams */
uint32 lengths[ZOOM_LVL_COUNT][2];
uint32_t lengths[ZOOM_LVL_END][2];
ZoomLevel zoom_min;
ZoomLevel zoom_max;
if (sprite->type == ST_FONT) {
if (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font) {
zoom_min = ZOOM_LVL_NORMAL;
zoom_max = ZOOM_LVL_NORMAL;
} else {
@@ -308,24 +321,25 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
uint size = src_orig->height * src_orig->width;
dst_px_orig[z] = CallocT<Colour>(size + src_orig->height * 2);
dst_n_orig[z] = CallocT<uint16>(size * 2 + src_orig->height * 4 * 2);
dst_n_orig[z] = CallocT<uint16_t>(size * 2 + src_orig->height * 4 * 2);
uint32 *dst_px_ln = (uint32 *)dst_px_orig[z];
uint32 *dst_n_ln = (uint32 *)dst_n_orig[z];
uint32_t *dst_px_ln = (uint32_t *)dst_px_orig[z];
uint32_t *dst_n_ln = (uint32_t *)dst_n_orig[z];
const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *)src_orig->data;
for (uint y = src_orig->height; y > 0; y--) {
Colour *dst_px = (Colour *)(dst_px_ln + 1);
uint16 *dst_n = (uint16 *)(dst_n_ln + 1);
/* Index 0 of dst_px and dst_n is left as space to save the length of the row to be filled later. */
Colour *dst_px = (Colour *)&dst_px_ln[1];
uint16_t *dst_n = (uint16_t *)&dst_n_ln[1];
uint16 *dst_len = dst_n++;
uint16_t *dst_len = dst_n++;
uint last = 3;
int len = 0;
for (uint x = src_orig->width; x > 0; x--) {
uint8 a = src->a;
uint8_t a = src->a;
uint t = a > 0 && a < 255 ? 1 : a;
if (last != t || len == 65535) {
@@ -344,7 +358,7 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
*dst_n = src->m;
if (src->m != 0) {
/* Get brightest value */
uint8 rgb_max = std::max({ src->r, src->g, src->b });
uint8_t rgb_max = std::max({ src->r, src->g, src->b });
/* Black pixel (8bpp or old 32bpp image), so use default value */
if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS;
@@ -382,13 +396,13 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
}
dst_px = (Colour *)AlignPtr(dst_px, 4);
dst_n = (uint16 *)AlignPtr(dst_n, 4);
dst_n = (uint16_t *)AlignPtr(dst_n, 4);
*dst_px_ln = (uint8 *)dst_px - (uint8 *)dst_px_ln;
*dst_n_ln = (uint8 *)dst_n - (uint8 *)dst_n_ln;
*dst_px_ln = (uint8_t *)dst_px - (uint8_t *)dst_px_ln;
*dst_n_ln = (uint8_t *)dst_n - (uint8_t *)dst_n_ln;
dst_px_ln = (uint32 *)dst_px;
dst_n_ln = (uint32 *)dst_n;
dst_px_ln = (uint32_t *)dst_px;
dst_n_ln = (uint32_t *)dst_n;
}
lengths[z][0] = (byte *)dst_px_ln - (byte *)dst_px_orig[z]; // all are aligned to 4B boundary
@@ -402,10 +416,10 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(SpriteData) + len);
dest_sprite->height = sprite->height;
dest_sprite->width = sprite->width;
dest_sprite->x_offs = sprite->x_offs;
dest_sprite->y_offs = sprite->y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
SpriteData *dst = (SpriteData *)dest_sprite->data;
memset(dst, 0, sizeof(*dst));
@@ -424,10 +438,10 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
return dest_sprite;
}
template Sprite *Blitter_32bppOptimized::EncodeInternal<true>(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
template Sprite *Blitter_32bppOptimized::EncodeInternal<false>(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
template Sprite *Blitter_32bppOptimized::EncodeInternal<true>(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
template Sprite *Blitter_32bppOptimized::EncodeInternal<false>(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
return this->EncodeInternal<true>(sprite, allocator);
}
+3 -3
View File
@@ -17,12 +17,12 @@ class Blitter_32bppOptimized : public Blitter_32bppSimple {
public:
/** Data stored about a (single) sprite. */
struct SpriteData {
uint32 offset[ZOOM_LVL_COUNT][2]; ///< Offsets (from .data) to streams for different zoom levels, and the normal and remap image information.
uint32_t offset[ZOOM_LVL_END][2]; ///< Offsets (from .data) to streams for different zoom levels, and the normal and remap image information.
byte data[]; ///< Data, all zoomlevels.
};
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override;
const char *GetName() override { return "32bpp-optimized"; }
@@ -30,7 +30,7 @@ public:
protected:
template <bool Tpal_to_rgb> void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
template <bool Tpal_to_rgb> Sprite *EncodeInternal(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
template <bool Tpal_to_rgb> Sprite *EncodeInternal(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
};
/** Factory for the optimised 32 bpp blitter (without palette animation). */
+21 -15
View File
@@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "../zoom_func.h"
#include "../palette_func.h"
#include "32bpp_simple.hpp"
#include "../table/sprites.h"
@@ -48,7 +49,7 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo
case BM_CRASH_REMAP:
if (src->m == 0) {
if (src->a != 0) {
uint8 g = MakeDark(src->r, src->g, src->b);
uint8_t g = MakeDark(src->r, src->g, src->b);
*dst = ComposeColourRGBA(g, g, g, src->a, *dst);
}
} else {
@@ -63,12 +64,17 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo
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:
* we produce a result the newgrf maker didn't expect ;) */
/* Make the current colour a bit more black, so it looks like this image is transparent */
if (src->a != 0) *dst = MakeTransparent(*dst, 192);
if (src->a != 0) {
*dst = MakeTransparent(*dst, 192);
}
break;
case BM_TRANSPARENT_REMAP:
/* Apply custom transparency remap. */
if (src->a != 0) {
*dst = this->LookupColourInPalette(bp->remap[GetNearestColourIndex(*dst)]);
}
break;
default:
@@ -109,20 +115,20 @@ void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height
Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
}
Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
Blitter_32bppSimple::Pixel *dst;
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite->height * (size_t)sprite->width * sizeof(*dst));
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_NORMAL].height * (size_t)sprite[ZOOM_LVL_NORMAL].width * sizeof(*dst));
dest_sprite->height = sprite->height;
dest_sprite->width = sprite->width;
dest_sprite->x_offs = sprite->x_offs;
dest_sprite->y_offs = sprite->y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
dst = (Blitter_32bppSimple::Pixel *)dest_sprite->data;
SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite->data;
SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite[ZOOM_LVL_NORMAL].data;
for (int i = 0; i < sprite->height * sprite->width; i++) {
for (int i = 0; i < sprite[ZOOM_LVL_NORMAL].height * sprite[ZOOM_LVL_NORMAL].width; i++) {
if (src->m == 0) {
dst[i].r = src->r;
dst[i].g = src->g;
@@ -132,7 +138,7 @@ Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::Sprite *sprite, Allocato
dst[i].v = 0;
} else {
/* Get brightest value */
uint8 rgb_max = std::max({src->r, src->g, src->b});
uint8_t rgb_max = std::max({src->r, src->g, src->b});
/* Black pixel (8bpp or old 32bpp image), so use default value */
if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS;
+7 -7
View File
@@ -16,17 +16,17 @@
/** The most trivial 32 bpp blitter (without palette animation). */
class Blitter_32bppSimple : public Blitter_32bppBase {
struct Pixel {
uint8 r; ///< Red-channel
uint8 g; ///< Green-channel
uint8 b; ///< Blue-channel
uint8 a; ///< Alpha-channel
uint8 m; ///< Remap-channel
uint8 v; ///< Brightness-channel
uint8_t r; ///< Red-channel
uint8_t g; ///< Green-channel
uint8_t b; ///< Blue-channel
uint8_t a; ///< Alpha-channel
uint8_t m; ///< Remap-channel
uint8_t v; ///< Brightness-channel
};
public:
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override;
const char *GetName() override { return "32bpp-simple"; }
};
+12 -12
View File
@@ -20,15 +20,15 @@
/** Instantiation of the SSE2 32bpp blitter factory. */
static FBlitter_32bppSSE2 iFBlitter_32bppSSE2;
Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
/* First uint32 of a line = the number of transparent pixels from the left.
* Second uint32 of a line = the number of transparent pixels from the right.
/* First uint32_t of a line = the number of transparent pixels from the left.
* Second uint32_t of a line = the number of transparent pixels from the right.
* Then all RGBA then all MV.
*/
ZoomLevel zoom_min = ZOOM_LVL_NORMAL;
ZoomLevel zoom_max = ZOOM_LVL_NORMAL;
if (sprite->type != ST_FONT) {
if (sprite[ZOOM_LVL_NORMAL].type != SpriteType::Font) {
zoom_min = _settings_client.gui.zoom_min;
zoom_max = _settings_client.gui.zoom_max;
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX;
@@ -42,7 +42,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
const SpriteLoader::Sprite *src_sprite = &sprite[z];
sd.infos[z].sprite_width = src_sprite->width;
sd.infos[z].sprite_offset = all_sprites_size;
sd.infos[z].sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32) * META_LENGTH;
sd.infos[z].sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32_t) * META_LENGTH;
const uint rgba_size = sd.infos[z].sprite_line_size * src_sprite->height;
sd.infos[z].mv_offset = all_sprites_size + rgba_size;
@@ -52,10 +52,10 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
}
Sprite *dst_sprite = (Sprite *) allocator(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size);
dst_sprite->height = sprite->height;
dst_sprite->width = sprite->width;
dst_sprite->x_offs = sprite->x_offs;
dst_sprite->y_offs = sprite->y_offs;
dst_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dst_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dst_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dst_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
/* Copy colours and determine flags. */
@@ -80,7 +80,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
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 = std::max({src->r, src->g, src->b});
const uint8_t rgb_max = std::max({src->r, src->g, src->b});
dst_mv->v = (rgb_max == 0) ? Blitter_32bppBase::DEFAULT_BRIGHTNESS : rgb_max;
/* Pre-convert the mapping channel to a RGB value. */
@@ -96,7 +96,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
}
} else {
dst_rgba->data = 0;
*(uint16*) dst_mv = 0;
*(uint16_t*) dst_mv = 0;
}
dst_rgba++;
dst_mv++;
@@ -105,7 +105,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
/* Count the number of transparent pixels from the left. */
dst_rgba = dst_rgba_line + META_LENGTH;
uint32 nb_pix_transp = 0;
uint32_t nb_pix_transp = 0;
for (uint x = src_sprite->width; x != 0; x--) {
if (dst_rgba->a == 0) nb_pix_transp++;
else break;
+10 -10
View File
@@ -29,11 +29,11 @@
/** Base methods for 32bpp SSE blitters. */
class Blitter_32bppSSE_Base {
public:
virtual ~Blitter_32bppSSE_Base() {}
virtual ~Blitter_32bppSSE_Base() = default;
struct MapValue {
uint8 m;
uint8 v;
uint8_t m;
uint8_t v;
};
static_assert(sizeof(MapValue) == 2);
@@ -65,18 +65,18 @@ public:
/** Data stored about a (single) sprite. */
struct SpriteInfo {
uint32 sprite_offset; ///< The offset to the sprite data.
uint32 mv_offset; ///< The offset to the map value data.
uint16 sprite_line_size; ///< The size of a single line (pitch).
uint16 sprite_width; ///< The width of the sprite.
uint32_t sprite_offset; ///< The offset to the sprite data.
uint32_t mv_offset; ///< The offset to the map value data.
uint16_t sprite_line_size; ///< The size of a single line (pitch).
uint16_t sprite_width; ///< The width of the sprite.
};
struct SpriteData {
SpriteFlags flags;
SpriteInfo infos[ZOOM_LVL_COUNT];
SpriteInfo infos[ZOOM_LVL_END];
byte data[]; ///< Data, all zoomlevels.
};
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
};
DECLARE_ENUM_AS_BIT_SET(Blitter_32bppSSE_Base::SpriteFlags);
@@ -88,7 +88,7 @@ public:
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent>
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override {
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override {
return Blitter_32bppSSE_Base::Encode(sprite, allocator);
}
+33 -20
View File
@@ -13,7 +13,7 @@
#ifdef WITH_SSE
GNU_TARGET(SSE_TARGET)
static inline void InsertFirstUint32(const uint32 value, __m128i &into)
inline void InsertFirstUint32(const uint32_t value, __m128i &into)
{
#if (SSE_VERSION >= 4)
into = _mm_insert_epi32(into, value, 0);
@@ -24,7 +24,7 @@ static inline void InsertFirstUint32(const uint32 value, __m128i &into)
}
GNU_TARGET(SSE_TARGET)
static inline void InsertSecondUint32(const uint32 value, __m128i &into)
inline void InsertSecondUint32(const uint32_t value, __m128i &into)
{
#if (SSE_VERSION >= 4)
into = _mm_insert_epi32(into, value, 1);
@@ -35,7 +35,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into)
}
GNU_TARGET(SSE_TARGET)
static inline void LoadUint64(const uint64 value, __m128i &into)
inline void LoadUint64(const uint64_t value, __m128i &into)
{
#ifdef POINTER_IS_64BIT
into = _mm_cvtsi64_si128(value);
@@ -50,7 +50,7 @@ static inline void LoadUint64(const uint64 value, __m128i &into)
}
GNU_TARGET(SSE_TARGET)
static inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
{
#if (SSE_VERSION == 2)
from = _mm_and_si128(from, mask); // PAND, wipe high bytes to keep low bytes when packing
@@ -61,7 +61,7 @@ static inline __m128i PackUnsaturated(__m128i from, const __m128i &mask)
}
GNU_TARGET(SSE_TARGET)
static inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
{
#if (SSE_VERSION == 2)
__m128i alphaAB = _mm_shufflelo_epi16(from, 0x3F); // PSHUFLW, put alpha1 in front of each rgb1
@@ -73,9 +73,9 @@ static inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask)
}
GNU_TARGET(SSE_TARGET)
static inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &pack_mask, const __m128i &alpha_mask)
inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &pack_mask, const __m128i &alpha_mask)
{
__m128i srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128()); // PUNPCKLBW, expand each uint8 into uint16
__m128i srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128()); // PUNPCKLBW, expand each uint8_t into uint16
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
__m128i alphaMaskAB = _mm_cmpgt_epi16(srcAB, _mm_setzero_si128()); // PCMPGTW (alpha > 0) ? 0xFFFF : 0
@@ -97,7 +97,7 @@ static inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128
* rgb = rgb * ((256/4) * 4 - (alpha/4)) / ((256/4) * 4)
*/
GNU_TARGET(SSE_TARGET)
static inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &tr_nom_base)
inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &tr_nom_base)
{
__m128i srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128());
__m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128());
@@ -111,19 +111,19 @@ static inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &d
IGNORE_UNINITIALIZED_WARNING_START
GNU_TARGET(SSE_TARGET)
static Colour ReallyAdjustBrightness(Colour colour, uint8 brightness)
static Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness)
{
uint64 c16 = colour.b | (uint64) colour.g << 16 | (uint64) colour.r << 32;
uint64_t c16 = colour.b | (uint64_t) colour.g << 16 | (uint64_t) colour.r << 32;
c16 *= brightness;
uint64 c16_ob = c16; // Helps out of order execution.
uint64_t c16_ob = c16; // Helps out of order execution.
c16 /= Blitter_32bppBase::DEFAULT_BRIGHTNESS;
c16 &= 0x01FF01FF01FFULL;
/* Sum overbright (maximum for each rgb is 508, 9 bits, -255 is changed in -256 so we just have to take the 8 lower bits into account). */
c16_ob = (((c16_ob >> (8 + 7)) & 0x0100010001ULL) * 0xFF) & c16;
const uint ob = ((uint16) c16_ob + (uint16) (c16_ob >> 16) + (uint16) (c16_ob >> 32)) / 2;
const uint ob = ((uint16_t) c16_ob + (uint16_t) (c16_ob >> 16) + (uint16_t) (c16_ob >> 32)) / 2;
const uint32 alpha32 = colour.data & 0xFF000000;
const uint32_t alpha32 = colour.data & 0xFF000000;
__m128i ret;
LoadUint64(c16, ret);
if (ob != 0) {
@@ -145,7 +145,7 @@ IGNORE_UNINITIALIZED_WARNING_STOP
/** ReallyAdjustBrightness() is not called that often.
* Inlining this function implies a far jump, which has a huge latency.
*/
static inline Colour AdjustBrightneSSE(Colour colour, uint8 brightness)
inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightness)
{
/* Shortcut for normal brightness. */
if (brightness == Blitter_32bppBase::DEFAULT_BRIGHTNESS) return colour;
@@ -154,7 +154,7 @@ static inline Colour AdjustBrightneSSE(Colour colour, uint8 brightness)
}
GNU_TARGET(SSE_TARGET)
static inline __m128i AdjustBrightnessOfTwoPixels(__m128i from, uint32 brightness)
inline __m128i AdjustBrightnessOfTwoPixels([[maybe_unused]] __m128i from, [[maybe_unused]] uint32_t brightness)
{
#if (SSE_VERSION < 3)
NOT_REACHED();
@@ -298,7 +298,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
for (uint x = (uint) effective_width / 2; x > 0; x--) {
__m128i srcABCD = _mm_loadl_epi64((const __m128i*) src);
__m128i dstABCD = _mm_loadl_epi64((__m128i*) dst);
uint32 mvX2 = *((uint32 *) const_cast<MapValue *>(src_mv));
uint32_t mvX2 = *((uint32_t *) const_cast<MapValue *>(src_mv));
/* Remap colours. */
if (mvX2 & 0x00FF00FF) {
@@ -314,12 +314,12 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
m_colour = m != 0 ? m_colour : srcm; \
}
#ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 remapped_src = 0;
uint64_t srcs = _mm_cvtsi128_si64(srcABCD);
uint64_t remapped_src = 0;
CMOV_REMAP(c0, 0, srcs, mvX2);
remapped_src = c0.data;
CMOV_REMAP(c1, 0, srcs >> 32, mvX2 >> 16);
remapped_src |= (uint64) c1.data << 32;
remapped_src |= (uint64_t) c1.data << 32;
srcABCD = _mm_cvtsi64_si128(remapped_src);
#else
Colour remapped_src[2];
@@ -392,11 +392,23 @@ bmcr_alpha_blend_single:
}
break;
case BM_TRANSPARENT_REMAP:
/* Apply custom transparency remap. */
for (uint x = (uint) bp->width; x > 0; x--) {
if (src->a != 0) {
*dst = this->LookupColourInPalette(remap[GetNearestColourIndex(*dst)]);
}
src_mv++;
dst++;
src++;
}
break;
case BM_CRASH_REMAP:
for (uint x = (uint) bp->width; x > 0; x--) {
if (src_mv->m == 0) {
if (src->a != 0) {
uint8 g = MakeDark(src->r, src->g, src->b);
uint8_t g = MakeDark(src->r, src->g, src->b);
*dst = ComposeColourRGBA(g, g, g, src->a, *dst);
}
} else {
@@ -471,6 +483,7 @@ bm_normal:
Draw<BM_COLOUR_REMAP, RM_WITH_MARGIN, BT_NONE, true>(bp, zoom); return;
}
case BM_TRANSPARENT: Draw<BM_TRANSPARENT, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BM_TRANSPARENT_REMAP: Draw<BM_TRANSPARENT_REMAP, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BM_CRASH_REMAP: Draw<BM_CRASH_REMAP, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP, RM_NONE, BT_NONE, true>(bp, zoom); return;
}
+5 -5
View File
@@ -21,7 +21,7 @@
#include <smmintrin.h>
#endif
#define META_LENGTH 2 ///< Number of uint32 inserted before each line of pixels in a sprite.
#define META_LENGTH 2 ///< Number of uint32_t inserted before each line of pixels in a sprite.
#define MARGIN_NORMAL_THRESHOLD (zoom == ZOOM_LVL_OUT_32X ? 8 : 4) ///< Minimum width to use margins with BM_NORMAL.
#define MARGIN_REMAP_THRESHOLD 4 ///< Minimum width to use margins with BM_COLOUR_REMAP.
@@ -35,10 +35,10 @@
typedef union ALIGN(16) um128i {
__m128i m128i;
uint8 m128i_u8[16];
uint16 m128i_u16[8];
uint32 m128i_u32[4];
uint64 m128i_u64[2];
uint8_t m128i_u8[16];
uint16_t m128i_u16[8];
uint32_t m128i_u32[4];
uint64_t m128i_u64[2];
} um128i;
#define CLEAR_HIGH_BYTE_MASK _mm_setr_epi8(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0)
+77 -56
View File
@@ -11,6 +11,7 @@
#include "../zoom_func.h"
#include "../settings_type.h"
#include "../video/video_driver.hpp"
#include "../palette_func.h"
#include "40bpp_anim.hpp"
#include "common.hpp"
@@ -26,18 +27,19 @@ static FBlitter_40bppAnim iFBlitter_40bppAnim;
static const Colour _black_colour(0, 0, 0);
void Blitter_40bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
void Blitter_40bppAnim::SetPixel(void *video, int x, int y, uint8_t colour)
{
if (_screen_disable_anim) {
Blitter_32bppOptimized::SetPixel(video, x, y, colour);
} else {
*((Colour *)video + x + y * _screen.pitch) = _black_colour;
size_t y_offset = static_cast<size_t>(y) * _screen.pitch;
*((Colour *)video + x + y_offset) = _black_colour;
VideoDriver::GetInstance()->GetAnimBuffer()[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * _screen.pitch] = colour;
VideoDriver::GetInstance()->GetAnimBuffer()[((uint32_t *)video - (uint32_t *)_screen.dst_ptr) + x + y_offset] = colour;
}
}
void Blitter_40bppAnim::DrawRect(void *video, int width, int height, uint8 colour)
void Blitter_40bppAnim::DrawRect(void *video, int width, int height, uint8_t colour)
{
if (_screen_disable_anim) {
/* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawRect() */
@@ -46,11 +48,11 @@ void Blitter_40bppAnim::DrawRect(void *video, int width, int height, uint8 colou
}
assert(VideoDriver::GetInstance()->GetAnimBuffer() != nullptr);
uint8 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + VideoDriver::GetInstance()->GetAnimBuffer();
uint8_t *anim_line = ((uint32_t *)video - (uint32_t *)_screen.dst_ptr) + VideoDriver::GetInstance()->GetAnimBuffer();
do {
Colour *dst = (Colour *)video;
uint8 *anim = anim_line;
uint8_t *anim = anim_line;
for (int i = width; i > 0; i--) {
*dst = _black_colour;
@@ -58,12 +60,12 @@ void Blitter_40bppAnim::DrawRect(void *video, int width, int height, uint8 colou
dst++;
anim++;
}
video = (uint32 *)video + _screen.pitch;
video = (uint32_t *)video + _screen.pitch;
anim_line += _screen.pitch;
} while (--height);
}
void Blitter_40bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
void Blitter_40bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash)
{
if (_screen_disable_anim) {
/* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent DrawRect() */
@@ -72,7 +74,7 @@ void Blitter_40bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int
}
assert(VideoDriver::GetInstance()->GetAnimBuffer() != nullptr);
uint8 *anim = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + VideoDriver::GetInstance()->GetAnimBuffer();
uint8_t *anim = ((uint32_t *)video - (uint32_t *)_screen.dst_ptr) + VideoDriver::GetInstance()->GetAnimBuffer();
this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [=](int x, int y) {
*((Colour *)video + x + y * _screen.pitch) = _black_colour;
@@ -92,24 +94,24 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
{
const SpriteData *src = (const SpriteData *)bp->sprite;
/* src_px : each line begins with uint32 n = 'number of bytes in this line',
/* src_px : each line begins with uint32_t n = 'number of bytes in this line',
* then n times is the Colour struct for this line */
const Colour *src_px = (const Colour *)(src->data + src->offset[zoom][0]);
/* src_n : each line begins with uint32 n = 'number of bytes in this line',
/* src_n : each line begins with uint32_t n = 'number of bytes in this line',
* then interleaved stream of 'm' and 'n' channels. 'm' is remap,
* 'n' is number of bytes with the same alpha channel class */
const uint16 *src_n = (const uint16 *)(src->data + src->offset[zoom][1]);
const uint16_t *src_n = (const uint16_t *)(src->data + src->offset[zoom][1]);
/* skip upper lines in src_px and src_n */
for (uint i = bp->skip_top; i != 0; i--) {
src_px = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
src_n = (const uint16 *)((const byte *)src_n + *(const uint32 *)src_n);
src_px = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
src_n = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
}
/* skip lines in dst */
Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
assert(VideoDriver::GetInstance()->GetAnimBuffer() != nullptr);
uint8 *anim = VideoDriver::GetInstance()->GetAnimBuffer() + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * bp->pitch + bp->left;
uint8_t *anim = VideoDriver::GetInstance()->GetAnimBuffer() + ((uint32_t *)bp->dst - (uint32_t *)_screen.dst_ptr) + bp->top * bp->pitch + bp->left;
/* store so we don't have to access it via bp everytime (compiler assumes pointer aliasing) */
const byte *remap = bp->remap;
@@ -117,14 +119,14 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
for (int y = 0; y < bp->height; y++) {
/* next dst line begins here */
Colour *dst_ln = dst + bp->pitch;
uint8 *anim_ln = anim + bp->pitch;
uint8_t *anim_ln = anim + bp->pitch;
/* next src line begins here */
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32_t *)src_px);
src_px++;
/* next src_n line begins here */
const uint16 *src_n_ln = (const uint16 *)((const byte *)src_n + *(const uint32 *)src_n);
const uint16_t *src_n_ln = (const uint16_t *)((const byte *)src_n + *(const uint32_t *)src_n);
src_n += 2;
/* we will end this line when we reach this point */
@@ -183,7 +185,7 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
case BM_CRASH_REMAP:
if (src_px->a == 255) {
do {
uint8 m = GB(*src_n, 0, 8);
uint8_t m = GB(*src_n, 0, 8);
/* In case the m-channel is zero, only apply the crash remap by darkening the RGB colour. */
if (m == 0) {
*dst = mode == BM_CRASH_REMAP ? this->MakeDark(*src_px) : *src_px;
@@ -202,7 +204,7 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
} while (--n != 0);
} else {
do {
uint8 m = GB(*src_n, 0, 8);
uint8_t m = GB(*src_n, 0, 8);
Colour b = this->RealizeBlendedColour(*anim, *dst);
if (m == 0) {
Colour c = mode == BM_CRASH_REMAP ? this->MakeDark(*src_px) : *src_px;
@@ -233,10 +235,6 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
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:
* we produce a result the newgrf maker didn't expect ;) */
/* Make the current colour a bit more black, so it looks like this image is transparent */
src_n += n;
if (src_px->a == 255) {
@@ -262,6 +260,28 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
}
break;
case BM_TRANSPARENT_REMAP:
/* Apply custom transparency remap. */
src_n += n;
if (src_px->a != 0) {
src_px += n;
do {
if (*anim != 0) {
*anim = remap[*anim];
} else {
*dst = this->LookupColourInPalette(remap[GetNearestColourIndex(*dst)]);
*anim = 0;
}
anim++;
dst++;
} while (--n != 0);
} else {
dst += n;
anim += n;
src_px += n;
}
break;
default:
if (src_px->a == 255) {
do {
@@ -273,7 +293,7 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
break;
} else {
do {
uint8 m = GB(*src_n, 0, 8);
uint8_t m = GB(*src_n, 0, 8);
Colour b = this->RealizeBlendedColour(*anim, *dst);
if (m == 0) {
@@ -322,6 +342,7 @@ void Blitter_40bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
case BM_NORMAL: Draw<BM_NORMAL> (bp, zoom); return;
case BM_COLOUR_REMAP: Draw<BM_COLOUR_REMAP>(bp, zoom); return;
case BM_TRANSPARENT: Draw<BM_TRANSPARENT> (bp, zoom); return;
case BM_TRANSPARENT_REMAP: Draw<BM_TRANSPARENT_REMAP>(bp, zoom); return;
case BM_CRASH_REMAP: Draw<BM_CRASH_REMAP> (bp, zoom); return;
case BM_BLACK_REMAP: Draw<BM_BLACK_REMAP> (bp, zoom); return;
}
@@ -336,7 +357,7 @@ void Blitter_40bppAnim::DrawColourMappingRect(void *dst, int width, int height,
}
Colour *udst = (Colour *)dst;
uint8 *anim = VideoDriver::GetInstance()->GetAnimBuffer() + ((uint32 *)dst - (uint32 *)_screen.dst_ptr);
uint8_t *anim = VideoDriver::GetInstance()->GetAnimBuffer() + ((uint32_t *)dst - (uint32_t *)_screen.dst_ptr);
if (pal == PALETTE_TO_TRANSPARENT) {
/* If the anim buffer contains a color value, the image composition will
@@ -353,7 +374,7 @@ void Blitter_40bppAnim::DrawColourMappingRect(void *dst, int width, int height,
anim = anim - width + _screen.pitch;
} while (--height);
} else if (pal == PALETTE_NEWSPAPER) {
const uint8 *remap = GetNonSprite(pal, ST_RECOLOUR) + 1;
const uint8_t *remap = GetNonSprite(pal, SpriteType::Recolour) + 1;
do {
for (int i = 0; i != width; i++) {
if (*anim == 0) *udst = MakeGrey(*udst);
@@ -365,7 +386,7 @@ void Blitter_40bppAnim::DrawColourMappingRect(void *dst, int width, int height,
anim = anim - width + _screen.pitch;
} while (--height);
} else {
const uint8 *remap = GetNonSprite(pal, ST_RECOLOUR) + 1;
const uint8_t *remap = GetNonSprite(pal, SpriteType::Recolour) + 1;
do {
for (int i = 0; i != width; i++) {
*anim = remap[*anim];
@@ -376,7 +397,7 @@ void Blitter_40bppAnim::DrawColourMappingRect(void *dst, int width, int height,
}
}
Sprite *Blitter_40bppAnim::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
Sprite *Blitter_40bppAnim::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
return this->EncodeInternal<false>(sprite, allocator);
}
@@ -385,21 +406,21 @@ Sprite *Blitter_40bppAnim::Encode(const SpriteLoader::Sprite *sprite, AllocatorP
void Blitter_40bppAnim::CopyFromBuffer(void *video, const void *src, int width, int height)
{
assert(!_screen_disable_anim);
assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint32 *dst = (uint32 *)video;
const uint32 *usrc = (const uint32 *)src;
assert(video >= _screen.dst_ptr && video <= (uint32_t *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint32_t *dst = (uint32_t *)video;
const uint32_t *usrc = (const uint32_t *)src;
uint8 *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
uint8_t *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
if (anim_buf == nullptr) return;
uint8 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + anim_buf;
uint8_t *anim_line = ((uint32_t *)video - (uint32_t *)_screen.dst_ptr) + anim_buf;
for (; height > 0; height--) {
memcpy(dst, usrc, width * sizeof(uint32));
memcpy(dst, usrc, width * sizeof(uint32_t));
usrc += width;
dst += _screen.pitch;
/* Copy back the anim-buffer */
memcpy(anim_line, usrc, width * sizeof(uint8));
usrc = (const uint32 *)((const uint8 *)usrc + width);
memcpy(anim_line, usrc, width * sizeof(uint8_t));
usrc = (const uint32_t *)((const uint8_t *)usrc + width);
anim_line += _screen.pitch;
}
}
@@ -407,36 +428,36 @@ void Blitter_40bppAnim::CopyFromBuffer(void *video, const void *src, int width,
void Blitter_40bppAnim::CopyToBuffer(const void *video, void *dst, int width, int height)
{
assert(!_screen_disable_anim);
assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint32 *udst = (uint32 *)dst;
const uint32 *src = (const uint32 *)video;
assert(video >= _screen.dst_ptr && video <= (uint32_t *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint32_t *udst = (uint32_t *)dst;
const uint32_t *src = (const uint32_t *)video;
uint8 *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
uint8_t *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
if (anim_buf == nullptr) return;
const uint8 *anim_line = ((const uint32 *)video - (uint32 *)_screen.dst_ptr) + anim_buf;
const uint8_t *anim_line = ((const uint32_t *)video - (uint32_t *)_screen.dst_ptr) + anim_buf;
for (; height > 0; height--) {
memcpy(udst, src, width * sizeof(uint32));
memcpy(udst, src, width * sizeof(uint32_t));
src += _screen.pitch;
udst += width;
/* Copy the anim-buffer */
memcpy(udst, anim_line, width * sizeof(uint8));
udst = (uint32 *)((uint8 *)udst + width);
memcpy(udst, anim_line, width * sizeof(uint8_t));
udst = (uint32_t *)((uint8_t *)udst + width);
anim_line += _screen.pitch;
}
}
void Blitter_40bppAnim::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch)
{
uint8 *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
uint8_t *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
if (anim_buf == nullptr) {
Blitter_32bppOptimized::CopyImageToBuffer(video, dst, width, height, dst_pitch);
return;
}
uint32 *udst = (uint32 *)dst;
const uint32 *src = (const uint32 *)video;
const uint8 *anim_line = ((const uint32 *)video - (uint32 *)_screen.dst_ptr) + anim_buf;
uint32_t *udst = (uint32_t *)dst;
const uint32_t *src = (const uint32_t *)video;
const uint8_t *anim_line = ((const uint32_t *)video - (uint32_t *)_screen.dst_ptr) + anim_buf;
for (; height > 0; height--) {
for (int x = 0; x < width; x++) {
@@ -451,9 +472,9 @@ void Blitter_40bppAnim::CopyImageToBuffer(const void *video, void *dst, int widt
void Blitter_40bppAnim::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y)
{
assert(!_screen_disable_anim);
assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint8 *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
uint8 *dst, *src;
assert(video >= _screen.dst_ptr && video <= (uint32_t *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
uint8_t *anim_buf = VideoDriver::GetInstance()->GetAnimBuffer();
uint8_t *dst, *src;
/* We need to scroll the anim-buffer too */
if (scroll_y > 0) {
@@ -470,7 +491,7 @@ void Blitter_40bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
uint tw = width + (scroll_x >= 0 ? -scroll_x : scroll_x);
uint th = height - scroll_y;
for (; th > 0; th--) {
memcpy(dst, src, tw * sizeof(uint8));
memcpy(dst, src, tw * sizeof(uint8_t));
src -= _screen.pitch;
dst -= _screen.pitch;
}
@@ -491,7 +512,7 @@ void Blitter_40bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
uint tw = width + (scroll_x >= 0 ? -scroll_x : scroll_x);
uint th = height + scroll_y;
for (; th > 0; th--) {
memmove(dst, src, tw * sizeof(uint8));
memmove(dst, src, tw * sizeof(uint8_t));
src += _screen.pitch;
dst += _screen.pitch;
}
@@ -500,9 +521,9 @@ void Blitter_40bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y);
}
int Blitter_40bppAnim::BufferSize(int width, int height)
size_t Blitter_40bppAnim::BufferSize(uint width, uint height)
{
return width * height * (sizeof(uint32) + sizeof(uint8));
return (sizeof(uint32_t) + sizeof(uint8_t)) * width * height;
}
Blitter::PaletteAnimation Blitter_40bppAnim::UsePaletteAnimation()
+6 -8
View File
@@ -18,28 +18,26 @@
class Blitter_40bppAnim : public Blitter_32bppOptimized {
public:
// void *MoveTo(void *video, int x, int y) override;
void SetPixel(void *video, int x, int y, uint8 colour) override;
void DrawRect(void *video, int width, int height, uint8 colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
void SetPixel(void *video, int x, int y, uint8_t colour) override;
void DrawRect(void *video, int width, int height, uint8_t colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override;
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
int BufferSize(int width, int height) override;
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override;
size_t BufferSize(uint width, uint height) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;
bool NeedsAnimationBuffer() override;
const char *GetName() override { return "40bpp-anim"; }
int GetBytesPerPixel() override { return 5; }
template <BlitterMode mode> void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
protected:
static inline Colour RealizeBlendedColour(uint8 anim, Colour c)
static inline Colour RealizeBlendedColour(uint8_t anim, Colour c)
{
return anim != 0 ? AdjustBrightness(LookupColourInPalette(anim), GetColourBrightness(c)) : c;
}
+28 -28
View File
@@ -16,46 +16,46 @@
void Blitter_8bppBase::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal)
{
const uint8 *ctab = GetNonSprite(pal, ST_RECOLOUR) + 1;
const uint8_t *ctab = GetNonSprite(pal, SpriteType::Recolour) + 1;
do {
for (int i = 0; i != width; i++) *((uint8 *)dst + i) = ctab[((uint8 *)dst)[i]];
dst = (uint8 *)dst + _screen.pitch;
for (int i = 0; i != width; i++) *((uint8_t *)dst + i) = ctab[((uint8_t *)dst)[i]];
dst = (uint8_t *)dst + _screen.pitch;
} while (--height);
}
void *Blitter_8bppBase::MoveTo(void *video, int x, int y)
{
return (uint8 *)video + x + y * _screen.pitch;
return (uint8_t *)video + x + y * _screen.pitch;
}
void Blitter_8bppBase::SetPixel(void *video, int x, int y, uint8 colour)
void Blitter_8bppBase::SetPixel(void *video, int x, int y, uint8_t colour)
{
*((uint8 *)video + x + y * _screen.pitch) = colour;
*((uint8_t *)video + x + y * _screen.pitch) = colour;
}
void Blitter_8bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
void Blitter_8bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash)
{
this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [=](int x, int y) {
*((uint8 *)video + x + y * _screen.pitch) = colour;
*((uint8_t *)video + x + y * _screen.pitch) = colour;
});
}
void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8 colour)
void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8_t colour)
{
do {
memset(video, colour, width);
video = (uint8 *)video + _screen.pitch;
video = (uint8_t *)video + _screen.pitch;
} while (--height);
}
void Blitter_8bppBase::CopyFromBuffer(void *video, const void *src, int width, int height)
{
uint8 *dst = (uint8 *)video;
const uint8 *usrc = (const uint8 *)src;
uint8_t *dst = (uint8_t *)video;
const uint8_t *usrc = (const uint8_t *)src;
for (; height > 0; height--) {
memcpy(dst, usrc, width * sizeof(uint8));
memcpy(dst, usrc, width * sizeof(uint8_t));
usrc += width;
dst += _screen.pitch;
}
@@ -63,11 +63,11 @@ void Blitter_8bppBase::CopyFromBuffer(void *video, const void *src, int width, i
void Blitter_8bppBase::CopyToBuffer(const void *video, void *dst, int width, int height)
{
uint8 *udst = (uint8 *)dst;
const uint8 *src = (const uint8 *)video;
uint8_t *udst = (uint8_t *)dst;
const uint8_t *src = (const uint8_t *)video;
for (; height > 0; height--) {
memcpy(udst, src, width * sizeof(uint8));
memcpy(udst, src, width * sizeof(uint8_t));
src += _screen.pitch;
udst += width;
}
@@ -75,11 +75,11 @@ void Blitter_8bppBase::CopyToBuffer(const void *video, void *dst, int width, int
void Blitter_8bppBase::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch)
{
uint8 *udst = (uint8 *)dst;
const uint8 *src = (const uint8 *)video;
uint8_t *udst = (uint8_t *)dst;
const uint8_t *src = (const uint8_t *)video;
for (; height > 0; height--) {
memcpy(udst, src, width * sizeof(uint8));
memcpy(udst, src, width * sizeof(uint8_t));
src += _screen.pitch;
udst += dst_pitch;
}
@@ -87,12 +87,12 @@ void Blitter_8bppBase::CopyImageToBuffer(const void *video, void *dst, int width
void Blitter_8bppBase::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y)
{
const uint8 *src;
uint8 *dst;
const uint8_t *src;
uint8_t *dst;
if (scroll_y > 0) {
/* Calculate pointers */
dst = (uint8 *)video + left + (top + height - 1) * _screen.pitch;
dst = (uint8_t *)video + left + (top + height - 1) * _screen.pitch;
src = dst - scroll_y * _screen.pitch;
/* Decrease height and increase top */
@@ -111,13 +111,13 @@ void Blitter_8bppBase::ScrollBuffer(void *video, int &left, int &top, int &width
}
for (int h = height; h > 0; h--) {
memcpy(dst, src, width * sizeof(uint8));
memcpy(dst, src, width * sizeof(uint8_t));
src -= _screen.pitch;
dst -= _screen.pitch;
}
} else {
/* Calculate pointers */
dst = (uint8 *)video + left + top * _screen.pitch;
dst = (uint8_t *)video + left + top * _screen.pitch;
src = dst - scroll_y * _screen.pitch;
/* Decrease height. (scroll_y is <=0). */
@@ -137,19 +137,19 @@ void Blitter_8bppBase::ScrollBuffer(void *video, int &left, int &top, int &width
/* the y-displacement may be 0 therefore we have to use memmove,
* because source and destination may overlap */
for (int h = height; h > 0; h--) {
memmove(dst, src, width * sizeof(uint8));
memmove(dst, src, width * sizeof(uint8_t));
src += _screen.pitch;
dst += _screen.pitch;
}
}
}
int Blitter_8bppBase::BufferSize(int width, int height)
size_t Blitter_8bppBase::BufferSize(uint width, uint height)
{
return width * height;
return static_cast<size_t>(width) * height;
}
void Blitter_8bppBase::PaletteAnimate(const Palette &palette)
void Blitter_8bppBase::PaletteAnimate(const Palette &)
{
/* Video backend takes care of the palette animation */
}
+5 -6
View File
@@ -15,20 +15,19 @@
/** Base for all 8bpp blitters. */
class Blitter_8bppBase : public Blitter {
public:
uint8 GetScreenDepth() override { return 8; }
uint8_t GetScreenDepth() override { return 8; }
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
void *MoveTo(void *video, int x, int y) override;
void SetPixel(void *video, int x, int y, uint8 colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
void DrawRect(void *video, int width, int height, uint8 colour) override;
void SetPixel(void *video, int x, int y, uint8_t colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override;
void DrawRect(void *video, int width, int height, uint8_t colour) override;
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
int BufferSize(int width, int height) override;
size_t BufferSize(uint width, uint height) override;
void PaletteAnimate(const Palette &palette) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;
int GetBytesPerPixel() override { return 1; }
};
#endif /* BLITTER_8BPP_BASE_HPP */
+14 -13
View File
@@ -26,8 +26,8 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z
uint offset = sprite_src->offset[zoom];
/* Find where to start reading in the source sprite */
const uint8 *src = sprite_src->data + offset;
uint8 *dst_line = (uint8 *)bp->dst + bp->top * bp->pitch + bp->left;
const uint8_t *src = sprite_src->data + offset;
uint8_t *dst_line = (uint8_t *)bp->dst + bp->top * bp->pitch + bp->left;
/* Skip over the top lines in the source image */
for (int y = 0; y < bp->skip_top; y++) {
@@ -39,10 +39,10 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z
}
}
const uint8 *src_next = src;
const uint8_t *src_next = src;
for (int y = 0; y < bp->height; y++) {
uint8 *dst = dst_line;
uint8_t *dst = dst_line;
dst_line += bp->pitch;
uint skip_left = bp->skip_left;
@@ -86,7 +86,7 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z
switch (mode) {
case BM_COLOUR_REMAP:
case BM_CRASH_REMAP: {
const uint8 *remap = bp->remap;
const uint8_t *remap = bp->remap;
do {
uint m = remap[*src];
if (m != 0) *dst = m;
@@ -100,8 +100,9 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z
dst += pixels;
break;
case BM_TRANSPARENT: {
const uint8 *remap = bp->remap;
case BM_TRANSPARENT:
case BM_TRANSPARENT_REMAP: {
const uint8_t *remap = bp->remap;
src += pixels;
do {
*dst = remap[*dst];
@@ -119,7 +120,7 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z
}
}
Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
/* Make memory for all zoom-levels */
uint memory = sizeof(SpriteData);
@@ -127,7 +128,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca
ZoomLevel zoom_min;
ZoomLevel zoom_max;
if (sprite->type == ST_FONT) {
if (sprite[ZOOM_LVL_NORMAL].type == SpriteType::Font) {
zoom_min = ZOOM_LVL_NORMAL;
zoom_max = ZOOM_LVL_NORMAL;
} else {
@@ -220,10 +221,10 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca
/* Allocate the exact amount of memory we need */
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + size);
dest_sprite->height = sprite->height;
dest_sprite->width = sprite->width;
dest_sprite->x_offs = sprite->x_offs;
dest_sprite->y_offs = sprite->y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
memcpy(dest_sprite->data, temp_dst, size);
return dest_sprite;
+3 -3
View File
@@ -14,16 +14,16 @@
#include "factory.hpp"
/** 8bpp blitter optimised for speed. */
class Blitter_8bppOptimized FINAL : public Blitter_8bppBase {
class Blitter_8bppOptimized final : public Blitter_8bppBase {
public:
/** Data stored about a (single) sprite. */
struct SpriteData {
uint32 offset[ZOOM_LVL_COUNT]; ///< Offsets (from .data) to streams for different zoom levels.
uint32_t offset[ZOOM_LVL_END]; ///< Offsets (from .data) to streams for different zoom levels.
byte data[]; ///< Data, all zoomlevels.
};
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override;
const char *GetName() override { return "8bpp-optimized"; }
};
+13 -12
View File
@@ -18,12 +18,12 @@ static FBlitter_8bppSimple iFBlitter_8bppSimple;
void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
{
const uint8 *src, *src_line;
uint8 *dst, *dst_line;
const uint8_t *src, *src_line;
uint8_t *dst, *dst_line;
/* Find where to start reading in the source sprite */
src_line = (const uint8 *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
dst_line = (uint8 *)bp->dst + bp->top * bp->pitch + bp->left;
src_line = (const uint8_t *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
dst_line = (uint8_t *)bp->dst + bp->top * bp->pitch + bp->left;
for (int y = 0; y < bp->height; y++) {
dst = dst_line;
@@ -42,6 +42,7 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom
break;
case BM_TRANSPARENT:
case BM_TRANSPARENT_REMAP:
if (*src != 0) colour = bp->remap[*dst];
break;
@@ -60,19 +61,19 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom
}
}
Sprite *Blitter_8bppSimple::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
Sprite *Blitter_8bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
Sprite *dest_sprite;
dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite->height * (size_t)sprite->width);
dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + (size_t)sprite[ZOOM_LVL_NORMAL].height * (size_t)sprite[ZOOM_LVL_NORMAL].width);
dest_sprite->height = sprite->height;
dest_sprite->width = sprite->width;
dest_sprite->x_offs = sprite->x_offs;
dest_sprite->y_offs = sprite->y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
/* Copy over only the 'remap' channel, as that is what we care about in 8bpp */
for (int i = 0; i < sprite->height * sprite->width; i++) {
dest_sprite->data[i] = sprite->data[i].m;
for (int i = 0; i < sprite[ZOOM_LVL_NORMAL].height * sprite[ZOOM_LVL_NORMAL].width; i++) {
dest_sprite->data[i] = sprite[ZOOM_LVL_NORMAL].data[i].m;
}
return dest_sprite;
+2 -2
View File
@@ -14,10 +14,10 @@
#include "factory.hpp"
/** Most trivial 8bpp blitter. */
class Blitter_8bppSimple FINAL : public Blitter_8bppBase {
class Blitter_8bppSimple final : public Blitter_8bppBase {
public:
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override;
const char *GetName() override { return "8bpp-simple"; }
};
+8 -12
View File
@@ -17,7 +17,8 @@
enum BlitterMode {
BM_NORMAL, ///< Perform the simple blitting.
BM_COLOUR_REMAP, ///< Perform a colour remapping.
BM_TRANSPARENT, ///< Perform transparency colour remapping.
BM_TRANSPARENT, ///< Perform transparency darkening remapping.
BM_TRANSPARENT_REMAP, ///< Perform transparency colour remapping.
BM_CRASH_REMAP, ///< Perform a crash remapping.
BM_BLACK_REMAP, ///< Perform remapping to a completely blackened sprite
};
@@ -56,7 +57,7 @@ public:
* Get the screen depth this blitter works for.
* This is either: 8, 16, 24 or 32.
*/
virtual uint8 GetScreenDepth() = 0;
virtual uint8_t GetScreenDepth() = 0;
bool Is32BppSupported() override
{
@@ -96,7 +97,7 @@ public:
* @param y The y position within video-buffer.
* @param colour A 8bpp mapping colour.
*/
virtual void SetPixel(void *video, int x, int y, uint8 colour) = 0;
virtual void SetPixel(void *video, int x, int y, uint8_t colour) = 0;
/**
* Make a single horizontal line in a single colour on the video-buffer.
@@ -105,7 +106,7 @@ public:
* @param height The height of the line.
* @param colour A 8bpp mapping colour.
*/
virtual void DrawRect(void *video, int width, int height, uint8 colour) = 0;
virtual void DrawRect(void *video, int width, int height, uint8_t colour) = 0;
/**
* Draw a line with a given colour.
@@ -120,7 +121,7 @@ public:
* @param width Line width.
* @param dash Length of dashes for dashed lines. 0 means solid line.
*/
virtual void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash = 0) = 0;
virtual void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash = 0) = 0;
/**
* Copy from a buffer to the screen.
@@ -170,7 +171,7 @@ public:
* @param height The height of the buffer-to-be.
* @return The size needed for the buffer.
*/
virtual int BufferSize(int width, int height) = 0;
virtual size_t BufferSize(uint width, uint height) = 0;
/**
* Called when the 8bpp palette is changed; you should redraw all pixels on the screen that
@@ -198,17 +199,12 @@ public:
*/
virtual const char *GetName() = 0;
/**
* Get how many bytes are needed to store a pixel.
*/
virtual int GetBytesPerPixel() = 0;
/**
* Post resize event
*/
virtual void PostResize() { };
virtual ~Blitter() { }
virtual ~Blitter() = default;
template <typename SetPixelT> void DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel);
};
+6 -6
View File
@@ -50,11 +50,11 @@ void Blitter::DrawLineGeneric(int x1, int y1, int x2, int y2, int screen_width,
/* compute frac_diff = width * sqrt(dx*dx + dy*dy)
* Start interval:
* max(dx, dy) <= sqrt(dx*dx + dy*dy) <= sqrt(2) * max(dx, dy) <= 3/2 * max(dx, dy) */
int64 frac_sq = ((int64) width) * ((int64) width) * (((int64) dx) * ((int64) dx) + ((int64) dy) * ((int64) dy));
int64_t frac_sq = ((int64_t) width) * ((int64_t) width) * (((int64_t) dx) * ((int64_t) dx) + ((int64_t) dy) * ((int64_t) dy));
int frac_max = 3 * frac_diff / 2;
while (frac_diff < frac_max) {
int frac_test = (frac_diff + frac_max) / 2;
if (((int64) frac_test) * ((int64) frac_test) < frac_sq) {
if (((int64_t) frac_test) * ((int64_t) frac_test) < frac_sq) {
frac_diff = frac_test + 1;
} else {
frac_max = frac_test - 1;
@@ -89,8 +89,8 @@ void Blitter::DrawLineGeneric(int x1, int y1, int x2, int y2, int screen_width,
if (x1 < 0) {
dash_count = (-x1) % (dash + gap);
auto adjust_frac = [&](int64 frac, int &y_bound) -> int {
frac -= ((int64) dy) * ((int64) x1);
auto adjust_frac = [&](int64_t frac, int &y_bound) -> int {
frac -= ((int64_t) dy) * ((int64_t) x1);
if (frac >= 0) {
int quotient = frac / dx;
int remainder = frac % dx;
@@ -151,8 +151,8 @@ void Blitter::DrawLineGeneric(int x1, int y1, int x2, int y2, int screen_width,
if (y1 < 0) {
dash_count = (-y1) % (dash + gap);
auto adjust_frac = [&](int64 frac, int &x_bound) -> int {
frac -= ((int64) dx) * ((int64) y1);
auto adjust_frac = [&](int64_t frac, int &x_bound) -> int {
frac -= ((int64_t) dx) * ((int64_t) y1);
if (frac >= 0) {
int quotient = frac / dy;
int remainder = frac % dy;
+10 -16
View File
@@ -13,8 +13,6 @@
#include "base.hpp"
#include "../debug.h"
#include "../string_func.h"
#include "../core/string_compare_type.hpp"
#include <map>
/**
@@ -122,13 +120,12 @@ public:
#else
const char *default_blitter = "8bpp-optimized";
#endif
if (GetBlitters().size() == 0) return nullptr;
if (GetBlitters().empty()) return nullptr;
const char *bname = name.empty() ? default_blitter : name.c_str();
Blitters::iterator it = GetBlitters().begin();
for (; it != GetBlitters().end(); it++) {
BlitterFactory *b = (*it).second;
if (strcasecmp(bname, b->name.c_str()) == 0) {
for (auto &it : GetBlitters()) {
BlitterFactory *b = it.second;
if (StrEqualsIgnoreCase(bname, b->name)) {
return b->IsUsable() ? b : nullptr;
}
}
@@ -149,17 +146,14 @@ public:
* @param last The last element of the buffer.
* @return p The location till where we filled the buffer.
*/
static char *GetBlittersInfo(char *p, const char *last)
static void GetBlittersInfo(std::back_insert_iterator<std::string> &output_iterator)
{
p += seprintf(p, last, "List of blitters:\n");
Blitters::iterator it = GetBlitters().begin();
for (; it != GetBlitters().end(); it++) {
BlitterFactory *b = (*it).second;
p += seprintf(p, last, "%18s: %s\n", b->name.c_str(), b->GetDescription().c_str());
fmt::format_to(output_iterator, "List of blitters:\n");
for (auto &it : GetBlitters()) {
BlitterFactory *b = it.second;
fmt::format_to(output_iterator, "{:>18}: {}\n", b->name, b->GetDescription());
}
p += seprintf(p, last, "\n");
return p;
fmt::format_to(output_iterator, "\n");
}
/**
+5 -5
View File
@@ -15,15 +15,15 @@
/** Instantiation of the null blitter factory. */
static FBlitter_Null iFBlitter_Null;
Sprite *Blitter_Null::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
Sprite *Blitter_Null::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
Sprite *dest_sprite;
dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite));
dest_sprite->height = sprite->height;
dest_sprite->width = sprite->width;
dest_sprite->x_offs = sprite->x_offs;
dest_sprite->y_offs = sprite->y_offs;
dest_sprite->height = sprite[ZOOM_LVL_NORMAL].height;
dest_sprite->width = sprite[ZOOM_LVL_NORMAL].width;
dest_sprite->x_offs = sprite[ZOOM_LVL_NORMAL].x_offs;
dest_sprite->y_offs = sprite[ZOOM_LVL_NORMAL].y_offs;
return dest_sprite;
}
+14 -15
View File
@@ -15,24 +15,23 @@
/** Blitter that does nothing. */
class Blitter_Null : public Blitter {
public:
uint8 GetScreenDepth() override { return 0; }
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override {};
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override {};
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
void *MoveTo(void *video, int x, int y) override { return nullptr; };
void SetPixel(void *video, int x, int y, uint8 colour) override {};
void DrawRect(void *video, int width, int height, uint8 colour) override {};
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override {};
void CopyFromBuffer(void *video, const void *src, int width, int height) override {};
void CopyToBuffer(const void *video, void *dst, int width, int height) override {};
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {};
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override {};
int BufferSize(int width, int height) override { return 0; };
void PaletteAnimate(const Palette &palette) override { };
uint8_t GetScreenDepth() override { return 0; }
void Draw(Blitter::BlitterParams *, BlitterMode, ZoomLevel) override {};
void DrawColourMappingRect(void *, int, int, PaletteID) override {};
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override;
void *MoveTo(void *, int, int) override { return nullptr; };
void SetPixel(void *, int, int, uint8_t) override {};
void DrawRect(void *, int, int, uint8_t) override {};
void DrawLine(void *, int, int, int, int, int, int, uint8_t, int, int) override {};
void CopyFromBuffer(void *, const void *, int, int) override {};
void CopyToBuffer(const void *, void *, int, int) override {};
void CopyImageToBuffer(const void *, void *, int, int, int) override {};
void ScrollBuffer(void *, int &, int &, int &, int &, int, int) override {};
size_t BufferSize(uint, uint) override { return 0; };
void PaletteAnimate(const Palette &) override { };
Blitter::PaletteAnimation UsePaletteAnimation() override { return Blitter::PALETTE_ANIMATION_NONE; };
const char *GetName() override { return "null"; }
int GetBytesPerPixel() override { return 0; }
};
/** Factory for the blitter that does nothing. */