1
0
Fork 0

Codechange: Move colour brightness methods to palette code.

This allows reuse outside of blitters.
pull/13349/head
Peter Nelson 2025-01-15 17:36:31 +00:00 committed by Peter Nelson
parent 83e9ee00f0
commit c5d3ac7a71
12 changed files with 93 additions and 82 deletions

View File

@ -109,7 +109,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
} 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));
if (r != 0) *dst = AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
anim++;
dst++;
@ -125,7 +125,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
} 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);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
anim++;
dst++;
@ -146,7 +146,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
} 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));
if (r != 0) *dst = AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
anim++;
dst++;
@ -165,7 +165,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
} 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);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
anim++;
dst++;
@ -232,7 +232,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
uint m = GB(*src_n, 0, 8);
/* Above PALETTE_ANIM_START is palette animation */
*anim++ = *src_n;
*dst++ = (m >= PALETTE_ANIM_START) ? this->AdjustBrightness(this->LookupColourInPalette(m), GB(*src_n, 8, 8)) : src_px->data;
*dst++ = (m >= PALETTE_ANIM_START) ? AdjustBrightness(this->LookupColourInPalette(m), GB(*src_n, 8, 8)) : src_px->data;
src_px++;
src_n++;
} while (--n != 0);
@ -241,7 +241,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
uint m = GB(*src_n, 0, 8);
*anim++ = 0;
if (m >= PALETTE_ANIM_START) {
*dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(m), GB(*src_n, 8, 8)), src_px->a, *dst);
*dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(m), GB(*src_n, 8, 8)), src_px->a, *dst);
} else {
*dst = ComposeColourRGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, *dst);
}
@ -408,7 +408,7 @@ void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width,
uint colour = GB(*anim_pal, 0, 8);
if (colour >= PALETTE_ANIM_START) {
/* Update this pixel */
*dst_pal = this->AdjustBrightness(LookupColourInPalette(colour), GB(*anim_pal, 8, 8));
*dst_pal = AdjustBrightness(LookupColourInPalette(colour), GB(*anim_pal, 8, 8));
}
dst_pal++;
anim_pal++;
@ -517,7 +517,7 @@ void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)
uint8_t colour = GB(value, 0, 8);
if (colour >= PALETTE_ANIM_START) {
/* Update this pixel */
*dst = this->AdjustBrightness(LookupColourInPalette(colour), GB(value, 8, 8));
*dst = AdjustBrightness(LookupColourInPalette(colour), GB(value, 8, 8));
}
dst++;
anim++;

View File

@ -40,7 +40,7 @@ void Blitter_32bppSSE2_Anim::PaletteAnimate(const Palette &palette)
const int screen_pitch = _screen.pitch;
const int anim_pitch = this->anim_buf_pitch;
__m128i anim_cmp = _mm_set1_epi16(PALETTE_ANIM_START - 1);
__m128i brightness_cmp = _mm_set1_epi16(Blitter_32bppBase::DEFAULT_BRIGHTNESS);
__m128i brightness_cmp = _mm_set1_epi16(DEFAULT_BRIGHTNESS);
__m128i colour_mask = _mm_set1_epi16(0xFF);
for (int y = this->anim_buf_height; y != 0 ; y--) {
Colour *next_dst_ln = dst + screen_pitch;

View File

@ -343,7 +343,7 @@ bmcr_alpha_blend_single:
}
} else {
uint r = remap[src_mv->m];
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
}
src_mv++;
dst++;

View File

@ -150,36 +150,6 @@ void Blitter_32bppBase::PaletteAnimate(const Palette &)
/* By default, 32bpp doesn't have palette animation */
}
Colour Blitter_32bppBase::ReallyAdjustBrightness(Colour colour, uint8_t brightness)
{
assert(DEFAULT_BRIGHTNESS == 1 << 7);
uint64_t combined = (((uint64_t) colour.r) << 32) | (((uint64_t) colour.g) << 16) | ((uint64_t) colour.b);
combined *= brightness;
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_t ob = 0;
/* Sum overbright */
if (r > 255) ob += r - 255;
if (g > 255) ob += g - 255;
if (b > 255) ob += b - 255;
/* Reduce overbright strength */
ob /= 2;
return Colour(
r >= 255 ? 255 : std::min(r + ob * (255 - r) / 256, 255),
g >= 255 ? 255 : std::min(g + ob * (255 - g) / 256, 255),
b >= 255 ? 255 : std::min(b + ob * (255 - b) / 256, 255),
colour.a);
}
Blitter::PaletteAnimation Blitter_32bppBase::UsePaletteAnimation()
{
return Blitter::PALETTE_ANIMATION_NONE;

View File

@ -11,9 +11,8 @@
#define BLITTER_32BPP_BASE_HPP
#include "base.hpp"
#include "../core/bitmath_func.hpp"
#include "../core/math_func.hpp"
#include "../gfx_func.h"
#include "../palette_func.h"
/** Base for all 32bpp blitters. */
class Blitter_32bppBase : public Blitter {
@ -153,28 +152,6 @@ public:
return Colour(grey, grey, grey);
}
static const int DEFAULT_BRIGHTNESS = 128;
static Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness);
static inline Colour AdjustBrightness(Colour colour, uint8_t brightness)
{
/* Shortcut for normal brightness */
if (brightness == DEFAULT_BRIGHTNESS) return colour;
return ReallyAdjustBrightness(colour, brightness);
}
static inline uint8_t GetColourBrightness(Colour colour)
{
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;
return rgb_max;
}
};
#endif /* BLITTER_32BPP_BASE_HPP */

View File

@ -120,7 +120,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
*dst = src_px->data;
} else {
uint r = remap[GB(m, 0, 8)];
if (r != 0) *dst = this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
if (r != 0) *dst = AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
dst++;
src_px++;
@ -133,7 +133,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
*dst = ComposeColourRGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, *dst);
} 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);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
dst++;
src_px++;
@ -151,7 +151,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
*dst = ComposeColourRGBA(g, g, g, src_px->a, *dst);
} else {
uint r = remap[GB(m, 0, 8)];
if (r != 0) *dst = this->AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
if (r != 0) *dst = AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8));
}
dst++;
src_px++;
@ -167,7 +167,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
}
} 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);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), GB(m, 8, 8)), src_px->a, *dst);
}
dst++;
src_px++;
@ -224,7 +224,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
do {
if (Tpal_to_rgb && *src_n != 0) {
/* Convert the mapping channel to a RGB value */
*dst = this->AdjustBrightness(this->LookupColourInPalette(GB(*src_n, 0, 8)), GB(*src_n, 8, 8)).data;
*dst = AdjustBrightness(this->LookupColourInPalette(GB(*src_n, 0, 8)), GB(*src_n, 8, 8)).data;
} else {
*dst = src_px->data;
}
@ -236,7 +236,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL
do {
if (Tpal_to_rgb && *src_n != 0) {
/* Convert the mapping channel to a RGB value */
Colour colour = this->AdjustBrightness(this->LookupColourInPalette(GB(*src_n, 0, 8)), GB(*src_n, 8, 8));
Colour colour = AdjustBrightness(this->LookupColourInPalette(GB(*src_n, 0, 8)), GB(*src_n, 8, 8));
*dst = ComposeColourRGBANoCheck(colour.r, colour.g, colour.b, src_px->a, *dst);
} else {
*dst = ComposeColourRGBANoCheck(src_px->r, src_px->g, src_px->b, src_px->a, *dst);
@ -366,7 +366,7 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
if (Tpal_to_rgb) {
/* Pre-convert the mapping channel to a RGB value */
Colour colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), rgb_max);
Colour colour = AdjustBrightness(this->LookupColourInPalette(src->m), rgb_max);
dst_px->r = colour.r;
dst_px->g = colour.g;
dst_px->b = colour.b;

View File

@ -42,7 +42,7 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo
if (src->m == 0) {
if (src->a != 0) *dst = ComposeColourRGBA(src->r, src->g, src->b, src->a, *dst);
} else {
if (bp->remap[src->m] != 0) *dst = ComposeColourPA(this->AdjustBrightness(this->LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
if (bp->remap[src->m] != 0) *dst = ComposeColourPA(AdjustBrightness(this->LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
}
break;
@ -53,7 +53,7 @@ void Blitter_32bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoo
*dst = ComposeColourRGBA(g, g, g, src->a, *dst);
}
} else {
if (bp->remap[src->m] != 0) *dst = ComposeColourPA(this->AdjustBrightness(this->LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
if (bp->remap[src->m] != 0) *dst = ComposeColourPA(AdjustBrightness(this->LookupColourInPalette(bp->remap[src->m]), src->v), src->a, *dst);
}
break;
@ -145,7 +145,7 @@ Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::SpriteCollection &sprite
dst[i].v = rgb_max;
/* Pre-convert the mapping channel to a RGB value */
Colour colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), dst[i].v);
Colour colour = AdjustBrightness(this->LookupColourInPalette(src->m), dst[i].v);
dst[i].r = colour.r;
dst[i].g = colour.g;
dst[i].b = colour.b;

View File

@ -81,7 +81,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri
/* Get brightest value (or default brightness if it's a black pixel). */
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;
dst_mv->v = (rgb_max == 0) ? DEFAULT_BRIGHTNESS : rgb_max;
/* Pre-convert the mapping channel to a RGB value. */
const Colour colour = AdjustBrightneSSE(Blitter_32bppBase::LookupColourInPalette(src->m), dst_mv->v);
@ -92,7 +92,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &spri
dst_rgba->r = src->r;
dst_rgba->g = src->g;
dst_rgba->b = src->b;
dst_mv->v = Blitter_32bppBase::DEFAULT_BRIGHTNESS;
dst_mv->v = DEFAULT_BRIGHTNESS;
}
} else {
dst_rgba->data = 0;

View File

@ -123,7 +123,7 @@ INTERNAL_LINKAGE Colour ReallyAdjustBrightness(Colour colour, uint8_t brightness
uint64_t c16 = colour.b | (uint64_t) colour.g << 16 | (uint64_t) colour.r << 32;
c16 *= brightness;
uint64_t c16_ob = c16; // Helps out of order execution.
c16 /= Blitter_32bppBase::DEFAULT_BRIGHTNESS;
c16 /= 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). */
@ -155,7 +155,7 @@ IGNORE_UNINITIALIZED_WARNING_STOP
INTERNAL_LINKAGE inline Colour AdjustBrightneSSE(Colour colour, uint8_t brightness)
{
/* Shortcut for normal brightness. */
if (brightness == Blitter_32bppBase::DEFAULT_BRIGHTNESS) return colour;
if (brightness == DEFAULT_BRIGHTNESS) return colour;
return ReallyAdjustBrightness(colour, brightness);
}
@ -171,7 +171,7 @@ INTERNAL_LINKAGE inline __m128i AdjustBrightnessOfTwoPixels([[maybe_unused]] __m
* OK, not a 1 but DEFAULT_BRIGHTNESS to compensate the div.
*/
brightness &= 0xFF00FF00;
brightness += Blitter_32bppBase::DEFAULT_BRIGHTNESS;
brightness += DEFAULT_BRIGHTNESS;
__m128i colAB = _mm_unpacklo_epi8(from, _mm_setzero_si128());
__m128i briAB = _mm_cvtsi32_si128(brightness);
@ -420,7 +420,7 @@ bmcr_alpha_blend_single:
}
} else {
uint r = remap[src_mv->m];
if (r != 0) *dst = ComposeColourPANoCheck(this->AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
if (r != 0) *dst = ComposeColourPANoCheck(AdjustBrightness(this->LookupColourInPalette(r), src_mv->v), src->a, *dst);
}
src_mv++;
dst++;

View File

@ -243,7 +243,7 @@ inline void Blitter_40bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
/* If the anim buffer contains a color value, the image composition will
* only look at the RGB brightness value. As such, we can simply darken the
* RGB value to darken the anim color. */
Colour b = *anim != 0 ? Colour(this->GetColourBrightness(*dst), 0, 0) : *dst;
Colour b = *anim != 0 ? Colour(GetColourBrightness(*dst), 0, 0) : *dst;
*dst = this->MakeTransparent(b, 3, 4);
anim++;
dst++;
@ -365,7 +365,7 @@ void Blitter_40bppAnim::DrawColourMappingRect(void *dst, int width, int height,
* RGB value to darken the anim color. */
do {
for (int i = 0; i != width; i++) {
Colour b = *anim != 0 ? Colour(this->GetColourBrightness(*udst), 0, 0) : *udst;
Colour b = *anim != 0 ? Colour(GetColourBrightness(*udst), 0, 0) : *udst;
*udst = MakeTransparent(b, 154);
udst++;
anim++;

View File

@ -131,6 +131,42 @@ uint8_t GetNearestColourIndex(uint8_t r, uint8_t g, uint8_t b)
return _palette_lookup[key];
}
/**
* Adjust brightness of colour.
* @param colour Colour to adjust.
* @param brightness Brightness to apply to colour.
* @returns Adjusted colour.
*/
Colour ReallyAdjustBrightness(Colour colour, int brightness)
{
if (brightness == DEFAULT_BRIGHTNESS) return colour;
uint64_t combined = (static_cast<uint64_t>(colour.r) << 32) | (static_cast<uint64_t>(colour.g) << 16) | static_cast<uint64_t>(colour.b);
combined *= brightness;
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_t ob = 0;
/* Sum overbright */
if (r > 255) ob += r - 255;
if (g > 255) ob += g - 255;
if (b > 255) ob += b - 255;
/* Reduce overbright strength */
ob /= 2;
return Colour(
r >= 255 ? 255 : std::min(r + ob * (255 - r) / 256, 255),
g >= 255 ? 255 : std::min(g + ob * (255 - g) / 256, 255),
b >= 255 ? 255 : std::min(b + ob * (255 - b) / 256, 255),
colour.a);
}
void DoPaletteAnimations();
void GfxInitPalettes()

View File

@ -27,6 +27,34 @@ inline uint8_t GetNearestColourIndex(const Colour colour)
return GetNearestColourIndex(colour.r, colour.g, colour.b);
}
static constexpr int DEFAULT_BRIGHTNESS = 128;
Colour ReallyAdjustBrightness(Colour colour, int brightness);
static inline Colour AdjustBrightness(Colour colour, uint8_t brightness)
{
/* Shortcut for normal brightness */
if (brightness == DEFAULT_BRIGHTNESS) return colour;
return ReallyAdjustBrightness(colour, brightness);
}
/**
* Get the brightness of a colour.
* This uses the maximum value of R, G or B channel, instead of perceptual brightness.
* @param colour Colour to get the brightness of.
* @returns Brightness of colour.
*/
static inline uint8_t GetColourBrightness(Colour colour)
{
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;
return rgb_max;
}
/**
* Checks if a Colours value is valid.
*