Skip to content

Commit

Permalink
Fix #14: Don't recolour 32bpp sprites to 8bpp when not tinted
Browse files Browse the repository at this point in the history
  • Loading branch information
ldpl committed Feb 17, 2024
1 parent f844546 commit 782c80b
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 178 deletions.
40 changes: 40 additions & 0 deletions src/blitter/32bpp_anim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#include "../table/sprites.h"

#include "../citymania/cm_colour.hpp"

#include "../safeguards.h"

/** Instantiation of the 32bpp with animation blitter factory. */
Expand Down Expand Up @@ -103,6 +105,43 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
draw:;

switch (mode) {
case CM_BM_TINT_REMAP:
if (src_px->a == 255) {
do {
uint m = *src_n;
/* In case the m-channel is zero, do not remap this pixel in any way */
if (m == 0) {
*dst = citymania::Remap32RGB(src_px->r, src_px->g, src_px->b, remap);
*anim = 0;
} else {
uint r = remap[GB(m, 0, 8)];
*anim = r | (m & 0xFF00);
if (r != 0) *dst = this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
anim++;
dst++;
src_px++;
src_n++;
} while (--n != 0);
} else {
do {
uint m = *src_n;
if (m == 0) {
*dst = citymania::Remap32RGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, *dst, remap);
*anim = 0;
} else {
uint r = remap[GB(m, 0, 8)];
*anim = 0;
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
anim++;
dst++;
src_px++;
src_n++;
} while (--n != 0);
}
break;

case BM_COLOUR_REMAP:
if (src_px->a == 255) {
do {
Expand Down Expand Up @@ -278,6 +317,7 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
default: NOT_REACHED();
case BM_NORMAL: Draw<BM_NORMAL> (bp, zoom); return;
case BM_COLOUR_REMAP: Draw<BM_COLOUR_REMAP>(bp, zoom); return;
case CM_BM_TINT_REMAP: Draw<CM_BM_TINT_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;
Expand Down
2 changes: 1 addition & 1 deletion src/blitter/32bpp_anim_sse4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Blitter_32bppSSE4_Anim final : public Blitter_32bppSSE2_Anim, public Blitt
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override {
return Blitter_32bppSSE2::Encode(sprite, allocator); // CM FIXME 14.0-beta1 why SSE -> SSE2
return Blitter_32bppSSE_Base::Encode(sprite, allocator);
}
const char *GetName() override { return "32bpp-sse4-anim"; }
using Blitter_32bppSSE2_Anim::LookupColourInPalette;
Expand Down
27 changes: 0 additions & 27 deletions src/blitter/32bpp_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,33 +175,6 @@ class Blitter_32bppBase : public Blitter {

return rgb_max;
}

/* CM */
uint8 cm_mdict[64*64*64] = {0};
uint8 CM_GetMForRGB(uint8 r, uint8 g, uint8 b) {
if (r==0 && g==0 && b==0) return 0;
r &= 252; g &= 252; b &= 252;
auto key = (r << 10) | (g << 4) | (b >> 2);
auto m = this->cm_mdict[key];
if (m != 0) return m;
uint md = UINT_MAX;
for (uint8 i = 1; i < 0xc0; i++) {
auto c = this->LookupColourInPalette(i);
auto rmean = (int)c.r + (int)r;
auto dr = (int)c.r - (int)r;
auto dg = (int)c.g - (int)g;
auto db = (int)c.b - (int)b;
auto dist = (1020 + rmean) * dr * dr + 2040 * dg * dg + (1530 - rmean) * db * db;
// auto dist = r * r + g * g + b * b;
if (dist < md) {
md = dist;
m = i;
}
}
this->cm_mdict[key] = m;
return m;
}

};

#endif /* BLITTER_32BPP_BASE_HPP */
35 changes: 34 additions & 1 deletion src/blitter/32bpp_optimized.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "../palette_func.h"
#include "32bpp_optimized.hpp"

#include "../citymania/cm_colour.hpp"

#include "../safeguards.h"

/** Instantiation of the optimized 32bpp blitter factory. */
Expand Down Expand Up @@ -111,6 +113,37 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
draw:;

switch (mode) {
case CM_BM_TINT_REMAP:
if (src_px->a == 255) {
do {
uint m = *src_n;
/* In case the m-channel is zero, do not remap this pixel in any way */
if (m == 0) {
*dst = citymania::Remap32RGB(src_px->r, src_px->g, src_px->b, remap);
} else {
uint r = remap[GB(m, 0, 8)];
if (r != 0) *dst = this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
dst++;
src_px++;
src_n++;
} while (--n != 0);
} else {
do {
uint m = *src_n;
if (m == 0) {
*dst = citymania::Remap32RGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, *dst, remap);
} else {
uint r = remap[GB(m, 0, 8)];
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
dst++;
src_px++;
src_n++;
} while (--n != 0);
}
break;

case BM_COLOUR_REMAP:
if (src_px->a == 255) {
do {
Expand Down Expand Up @@ -263,6 +296,7 @@ void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode,
default: NOT_REACHED();
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 CM_BM_TINT_REMAP: Draw<CM_BM_TINT_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;
Expand Down Expand Up @@ -379,7 +413,6 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
dst_px->r = src->r;
dst_px->g = src->g;
dst_px->b = src->b;
if (Tpal_to_rgb) *dst_n = this->CM_GetMForRGB(src->r, src->g, src->b) | (DEFAULT_BRIGHTNESS << 8);
}
dst_px++;
dst_n++;
Expand Down
16 changes: 14 additions & 2 deletions src/blitter/32bpp_simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include "../table/sprites.h"

#include "../citymania/cm_colour.hpp"

#include "../safeguards.h"

/** Instantiation of the simple 32bpp blitter factory. */
Expand All @@ -37,6 +39,15 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo

for (int x = 0; x < bp->width; x++) {
switch (mode) {
case CM_BM_TINT_REMAP:
/* In case the m-channel is zero, do not remap this pixel in any way */
if (src->m == 0) {
if (src->a != 0) *dst = citymania::Remap32RGBA(src->r, src->g, src->b, src->a, *dst, bp->remap);
} else {
if (bp->remap[src->m] != 0) *dst = ComposeColourPA(this->AdjustBrightness(this->LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
}
break;

case BM_COLOUR_REMAP:
/* In case the m-channel is zero, do not remap this pixel in any way */
if (src->m == 0) {
Expand Down Expand Up @@ -90,6 +101,7 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo
void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal)
{
Colour *udst = (Colour *)dst;

if (pal == PALETTE_TO_TRANSPARENT) {
do {
for (int i = 0; i != width; i++) {
Expand Down Expand Up @@ -133,8 +145,8 @@ Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite
dst[i].g = src->g;
dst[i].b = src->b;
dst[i].a = src->a;
dst[i].m = this->CM_GetMForRGB(src->r, src->g, src->b);
dst[i].v = DEFAULT_BRIGHTNESS;
dst[i].m = 0;
dst[i].v = 0;
} else {
/* Get brightest value */
uint8_t rgb_max = std::max({src->r, src->g, src->b});
Expand Down
4 changes: 1 addition & 3 deletions src/blitter/32bpp_sse2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
/** Instantiation of the SSE2 32bpp blitter factory. */
static FBlitter_32bppSSE2 iFBlitter_32bppSSE2;

Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator, Blitter_32bppSimple *base_blitter)
Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)
{
/* 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.
Expand Down Expand Up @@ -89,11 +89,9 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri
dst_rgba->g = colour.g;
dst_rgba->b = colour.b;
} else {
has_remap = true;
dst_rgba->r = src->r;
dst_rgba->g = src->g;
dst_rgba->b = src->b;
dst_mv->m = base_blitter->CM_GetMForRGB(src->r, src->g, src->b);
dst_mv->v = Blitter_32bppBase::DEFAULT_BRIGHTNESS;
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/blitter/32bpp_sse2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class Blitter_32bppSSE_Base {
byte data[]; ///< Data, all zoomlevels.
};

Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator, Blitter_32bppSimple *base_blitter);
Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator);
};

DECLARE_ENUM_AS_BIT_SET(Blitter_32bppSSE_Base::SpriteFlags);
Expand All @@ -89,7 +89,7 @@ class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Ba
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);

Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override {
return Blitter_32bppSSE_Base::Encode(sprite, allocator, this);
return Blitter_32bppSSE_Base::Encode(sprite, allocator);
}

const char *GetName() override { return "32bpp-sse2"; }
Expand Down
21 changes: 17 additions & 4 deletions src/blitter/40bpp_anim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "../table/sprites.h"

#include "../citymania/cm_colour.hpp"

#include "../safeguards.h"


Expand Down Expand Up @@ -182,14 +184,20 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel

switch (mode) {
case BM_COLOUR_REMAP:
case CM_BM_TINT_REMAP:
case BM_CRASH_REMAP:
if (src_px->a == 255) {
do {
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;
*anim = mode == BM_CRASH_REMAP ? 0 : remap[this->CM_GetMForRGB(src_px->r, src_px->g, src_px->b)];
switch (mode) {
case BM_COLOUR_REMAP: *dst = *src_px; break;
case CM_BM_TINT_REMAP: *dst = citymania::Remap32RGB(src_px->r, src_px->g, src_px->b, remap); break;
case BM_CRASH_REMAP: *dst = this->MakeDark(*src_px); break;
default: NOT_REACHED();
}
*anim = 0;
} else {
uint r = remap[m];
if (r != 0) {
Expand All @@ -207,8 +215,12 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
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;
*dst = this->ComposeColourRGBANoCheck(c.r, c.g, c.b, src_px->a, b);
switch (mode) {
case BM_COLOUR_REMAP: *dst = this->ComposeColourRGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, b); break;
case CM_BM_TINT_REMAP: *dst = citymania::Remap32RGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, b, remap); break;
case BM_CRASH_REMAP: *dst = this->ComposeColourPANoCheck(this->MakeDark(*src_px), src_px->a, b); break;
default: NOT_REACHED();
}
*anim = 0;
} else {
uint r = remap[m];
Expand Down Expand Up @@ -341,6 +353,7 @@ void Blitter_40bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
default: NOT_REACHED();
case BM_NORMAL: Draw<BM_NORMAL> (bp, zoom); return;
case BM_COLOUR_REMAP: Draw<BM_COLOUR_REMAP>(bp, zoom); return;
case CM_BM_TINT_REMAP: Draw<CM_BM_TINT_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;
Expand Down
1 change: 1 addition & 0 deletions src/blitter/8bpp_optimized.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Z
width -= pixels;

switch (mode) {
case CM_BM_TINT_REMAP:
case BM_COLOUR_REMAP:
case BM_CRASH_REMAP: {
const uint8_t *remap = bp->remap;
Expand Down
1 change: 1 addition & 0 deletions src/blitter/8bpp_simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom
uint colour = 0;

switch (mode) {
case CM_BM_TINT_REMAP:
case BM_COLOUR_REMAP:
case BM_CRASH_REMAP:
colour = bp->remap[*src];
Expand Down
Loading

0 comments on commit 782c80b

Please sign in to comment.