1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Fixed handling of special palette colors in palette transformations

Fixes black color turning semi-transparent in some creatures from mods
This commit is contained in:
Ivan Savenko
2023-03-25 18:55:08 +02:00
parent a0bd46c9dd
commit dcff463d36
5 changed files with 34 additions and 26 deletions

View File

@@ -88,16 +88,13 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
static const auto shifterNegative = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 1.0f, 0.2f, 0.2f );
static const auto shifterNeutral = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 1.0f, 1.0f, 0.2f );
amountNormal->adjustPalette(shifterNormal, 0);
amountPositive->adjustPalette(shifterPositive, 0);
amountNegative->adjustPalette(shifterNegative, 0);
amountEffNeutral->adjustPalette(shifterNeutral, 0);
// do not change border color
static const int32_t ignoredMask = 1 << 26;
//Restore border color {255, 231, 132, 255} to its original state
amountNormal->resetPalette(26);
amountPositive->resetPalette(26);
amountNegative->resetPalette(26);
amountEffNeutral->resetPalette(26);
amountNormal->adjustPalette(shifterNormal, ignoredMask);
amountPositive->adjustPalette(shifterPositive, ignoredMask);
amountNegative->adjustPalette(shifterNegative, ignoredMask);
amountEffNeutral->adjustPalette(shifterNeutral, ignoredMask);
std::vector<const CStack*> stacks = owner.curInt->cb->battleGetAllStacks(true);
for(const CStack * s : stacks)

View File

@@ -343,13 +343,14 @@ static SDL_Color addColors(const SDL_Color & base, const SDL_Color & over)
void CreatureAnimation::genSpecialPalette(IImage::SpecialPalette & target)
{
target[0] = genShadow(shadowAlpha / 2);
target.resize(8);
target[0] = genShadow(0);
target[1] = genShadow(shadowAlpha / 2);
target[2] = genShadow(shadowAlpha);
target[3] = genShadow(shadowAlpha);
target[4] = genBorderColor(getBorderStrength(elapsedTime), border);
target[5] = addColors(genShadow(shadowAlpha), genBorderColor(getBorderStrength(elapsedTime), border));
target[6] = addColors(genShadow(shadowAlpha / 2), genBorderColor(getBorderStrength(elapsedTime), border));
target[2] = genShadow(shadowAlpha / 2);
// colors 2 & 3 are not used in creatures
target[5] = genBorderColor(getBorderStrength(elapsedTime), border);
target[6] = addColors(genShadow(shadowAlpha), genBorderColor(getBorderStrength(elapsedTime), border));
target[7] = addColors(genShadow(shadowAlpha / 2), genBorderColor(getBorderStrength(elapsedTime), border));
}
void CreatureAnimation::nextFrame(Canvas & canvas, const ColorFilter & shifter, bool facingRight)
@@ -371,8 +372,8 @@ void CreatureAnimation::nextFrame(Canvas & canvas, const ColorFilter & shifter,
IImage::SpecialPalette SpecialPalette;
genSpecialPalette(SpecialPalette);
image->setSpecialPallete(SpecialPalette);
image->adjustPalette(shifter, 8);
image->setSpecialPallete(SpecialPalette, IImage::SPECIAL_PALETTE_MASK_CREATURES);
image->adjustPalette(shifter, IImage::SPECIAL_PALETTE_MASK_CREATURES);
canvas.draw(image, pos.topLeft(), Rect(0, 0, pos.w, pos.h));

View File

@@ -40,7 +40,8 @@ enum class EImageBlitMode : uint8_t
class IImage
{
public:
using SpecialPalette = std::array<SDL_Color, 7>;
using SpecialPalette = std::vector<SDL_Color>;
static constexpr int32_t SPECIAL_PALETTE_MASK_CREATURES = 0b11110011;
//draws image on surface "where" at position
virtual void draw(SDL_Surface * where, int posX = 0, int posY = 0, const Rect * src = nullptr) const = 0;
@@ -65,7 +66,7 @@ public:
//only indexed bitmaps, 16 colors maximum
virtual void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) = 0;
virtual void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) = 0;
virtual void adjustPalette(const ColorFilter & shifter, uint32_t colorsToSkipMask) = 0;
virtual void resetPalette(int colorID) = 0;
virtual void resetPalette() = 0;
@@ -73,7 +74,7 @@ public:
virtual void setBlitMode(EImageBlitMode mode) = 0;
//only indexed bitmaps with 7 special colors
virtual void setSpecialPallete(const SpecialPalette & SpecialPalette) = 0;
virtual void setSpecialPallete(const SpecialPalette & SpecialPalette, uint32_t colorsToSkipMask) = 0;
virtual void horizontalFlip() = 0;
virtual void verticalFlip() = 0;

View File

@@ -308,7 +308,7 @@ void SDLImage::shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32
}
}
void SDLImage::adjustPalette(const ColorFilter & shifter, size_t colorsToSkip)
void SDLImage::adjustPalette(const ColorFilter & shifter, uint32_t colorsToSkipMask)
{
if(originalPalette == nullptr)
return;
@@ -316,8 +316,11 @@ void SDLImage::adjustPalette(const ColorFilter & shifter, size_t colorsToSkip)
SDL_Palette* palette = surf->format->palette;
// Note: here we skip first colors in the palette that are predefined in H3 images
for(int i = colorsToSkip; i < palette->ncolors; i++)
for(int i = 0; i < palette->ncolors; i++)
{
if(i < std::numeric_limits<uint32_t>::digits && ((colorsToSkipMask >> i) & 1) == 1)
continue;
palette->colors[i] = shifter.shiftColor(originalPalette->colors[i]);
}
}
@@ -340,11 +343,17 @@ void SDLImage::resetPalette( int colorID )
SDL_SetPaletteColors(surf->format->palette, originalPalette->colors + colorID, colorID, 1);
}
void SDLImage::setSpecialPallete(const IImage::SpecialPalette & SpecialPalette)
void SDLImage::setSpecialPallete(const IImage::SpecialPalette & specialPalette, uint32_t colorsToSkipMask)
{
if(surf->format->palette)
{
CSDL_Ext::setColors(surf, const_cast<SDL_Color *>(SpecialPalette.data()), 1, 7);
size_t last = std::min<size_t>(specialPalette.size(), surf->format->palette->ncolors);
for (size_t i = 0; i < last; ++i)
{
if(i < std::numeric_limits<uint32_t>::digits && ((colorsToSkipMask >> i) & 1) == 1)
surf->format->palette->colors[i] = specialPalette[i];
}
}
}

View File

@@ -66,14 +66,14 @@ public:
void verticalFlip() override;
void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) override;
void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) override;
void adjustPalette(const ColorFilter & shifter, uint32_t colorsToSkipMask) override;
void resetPalette(int colorID) override;
void resetPalette() override;
void setAlpha(uint8_t value) override;
void setBlitMode(EImageBlitMode mode) override;
void setSpecialPallete(const SpecialPalette & SpecialPalette) override;
void setSpecialPallete(const SpecialPalette & SpecialPalette, uint32_t colorsToSkipMask) override;
friend class SDLImageLoader;