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:
@@ -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)
|
||||
|
@@ -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));
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user