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 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 ); static const auto shifterNeutral = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 1.0f, 1.0f, 0.2f );
amountNormal->adjustPalette(shifterNormal, 0); // do not change border color
amountPositive->adjustPalette(shifterPositive, 0); static const int32_t ignoredMask = 1 << 26;
amountNegative->adjustPalette(shifterNegative, 0);
amountEffNeutral->adjustPalette(shifterNeutral, 0);
//Restore border color {255, 231, 132, 255} to its original state amountNormal->adjustPalette(shifterNormal, ignoredMask);
amountNormal->resetPalette(26); amountPositive->adjustPalette(shifterPositive, ignoredMask);
amountPositive->resetPalette(26); amountNegative->adjustPalette(shifterNegative, ignoredMask);
amountNegative->resetPalette(26); amountEffNeutral->adjustPalette(shifterNeutral, ignoredMask);
amountEffNeutral->resetPalette(26);
std::vector<const CStack*> stacks = owner.curInt->cb->battleGetAllStacks(true); std::vector<const CStack*> stacks = owner.curInt->cb->battleGetAllStacks(true);
for(const CStack * s : stacks) 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) void CreatureAnimation::genSpecialPalette(IImage::SpecialPalette & target)
{ {
target[0] = genShadow(shadowAlpha / 2); target.resize(8);
target[0] = genShadow(0);
target[1] = genShadow(shadowAlpha / 2); target[1] = genShadow(shadowAlpha / 2);
target[2] = genShadow(shadowAlpha); target[2] = genShadow(shadowAlpha / 2);
target[3] = genShadow(shadowAlpha); // colors 2 & 3 are not used in creatures
target[4] = genBorderColor(getBorderStrength(elapsedTime), border); target[5] = genBorderColor(getBorderStrength(elapsedTime), border);
target[5] = addColors(genShadow(shadowAlpha), genBorderColor(getBorderStrength(elapsedTime), border)); target[6] = addColors(genShadow(shadowAlpha), genBorderColor(getBorderStrength(elapsedTime), border));
target[6] = addColors(genShadow(shadowAlpha / 2), genBorderColor(getBorderStrength(elapsedTime), border)); target[7] = addColors(genShadow(shadowAlpha / 2), genBorderColor(getBorderStrength(elapsedTime), border));
} }
void CreatureAnimation::nextFrame(Canvas & canvas, const ColorFilter & shifter, bool facingRight) 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; IImage::SpecialPalette SpecialPalette;
genSpecialPalette(SpecialPalette); genSpecialPalette(SpecialPalette);
image->setSpecialPallete(SpecialPalette); image->setSpecialPallete(SpecialPalette, IImage::SPECIAL_PALETTE_MASK_CREATURES);
image->adjustPalette(shifter, 8); image->adjustPalette(shifter, IImage::SPECIAL_PALETTE_MASK_CREATURES);
canvas.draw(image, pos.topLeft(), Rect(0, 0, pos.w, pos.h)); 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 class IImage
{ {
public: 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 //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; 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 //only indexed bitmaps, 16 colors maximum
virtual void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) = 0; 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(int colorID) = 0;
virtual void resetPalette() = 0; virtual void resetPalette() = 0;
@@ -73,7 +74,7 @@ public:
virtual void setBlitMode(EImageBlitMode mode) = 0; virtual void setBlitMode(EImageBlitMode mode) = 0;
//only indexed bitmaps with 7 special colors //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 horizontalFlip() = 0;
virtual void verticalFlip() = 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) if(originalPalette == nullptr)
return; return;
@@ -316,8 +316,11 @@ void SDLImage::adjustPalette(const ColorFilter & shifter, size_t colorsToSkip)
SDL_Palette* palette = surf->format->palette; SDL_Palette* palette = surf->format->palette;
// Note: here we skip first colors in the palette that are predefined in H3 images // 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]); 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); 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) 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 verticalFlip() override;
void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) 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(int colorID) override;
void resetPalette() override; void resetPalette() override;
void setAlpha(uint8_t value) override; void setAlpha(uint8_t value) override;
void setBlitMode(EImageBlitMode mode) override; void setBlitMode(EImageBlitMode mode) override;
void setSpecialPallete(const SpecialPalette & SpecialPalette) override; void setSpecialPallete(const SpecialPalette & SpecialPalette, uint32_t colorsToSkipMask) override;
friend class SDLImageLoader; friend class SDLImageLoader;