mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-14 02:33:51 +02:00
Fix colors in def palette turning into transparency unconditionally
This commit is contained in:
parent
ee8c8dca7b
commit
61a8c53bb6
@ -82,9 +82,19 @@ static CFileCache animationCache;
|
|||||||
* DefFile, class used for def loading *
|
* DefFile, class used for def loading *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
bool operator== (const SDL_Color & lhs, const SDL_Color & rhs)
|
static bool colorsSimilar (const SDL_Color & lhs, const SDL_Color & rhs)
|
||||||
{
|
{
|
||||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b) &&(lhs.g == rhs.g) &&(lhs.r == rhs.r);
|
// it seems that H3 does not requires exact match to replace colors -> (255, 103, 255) gets interpreted as shadow
|
||||||
|
// exact logic is not clear and requires extensive testing with image editing
|
||||||
|
// potential reason is that H3 uses 16-bit color format (565 RGB bits), meaning that 3 least significant bits are lost in red and blue component
|
||||||
|
static const int threshold = 8;
|
||||||
|
|
||||||
|
int diffR = static_cast<int>(lhs.r) - rhs.r;
|
||||||
|
int diffG = static_cast<int>(lhs.g) - rhs.g;
|
||||||
|
int diffB = static_cast<int>(lhs.b) - rhs.b;
|
||||||
|
int diffA = static_cast<int>(lhs.a) - rhs.a;
|
||||||
|
|
||||||
|
return std::abs(diffR) < threshold && std::abs(diffG) < threshold && std::abs(diffB) < threshold && std::abs(diffA) < threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDefFile::CDefFile(std::string Name):
|
CDefFile::CDefFile(std::string Name):
|
||||||
@ -92,23 +102,34 @@ CDefFile::CDefFile(std::string Name):
|
|||||||
palette(nullptr)
|
palette(nullptr)
|
||||||
{
|
{
|
||||||
//First 8 colors in def palette used for transparency
|
//First 8 colors in def palette used for transparency
|
||||||
static SDL_Color H3Palette[8] =
|
static const SDL_Color sourcePalette[8] = {
|
||||||
{
|
{0, 255, 255, SDL_ALPHA_OPAQUE},
|
||||||
{ 0, 0, 0, 0},// transparency ( used in most images )
|
{255, 150, 255, SDL_ALPHA_OPAQUE},
|
||||||
{ 0, 0, 0, 64},// shadow border ( used in battle, adventure map def's )
|
{255, 100, 255, SDL_ALPHA_OPAQUE},
|
||||||
{ 0, 0, 0, 64},// shadow border ( used in fog-of-war def's )
|
{255, 50, 255, SDL_ALPHA_OPAQUE},
|
||||||
{ 0, 0, 0, 128},// shadow body ( used in fog-of-war def's )
|
{255, 0, 255, SDL_ALPHA_OPAQUE},
|
||||||
{ 0, 0, 0, 128},// shadow body ( used in battle, adventure map def's )
|
{255, 255, 0, SDL_ALPHA_OPAQUE},
|
||||||
{ 0, 0, 0, 0},// selection ( used in battle def's )
|
{180, 0, 255, SDL_ALPHA_OPAQUE},
|
||||||
{ 0, 0, 0, 128},// shadow body below selection ( used in battle def's )
|
{0, 255, 0, SDL_ALPHA_OPAQUE}
|
||||||
{ 0, 0, 0, 64} // shadow border below selection ( used in battle def's )
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const SDL_Color targetPalette[8] = {
|
||||||
|
{0, 0, 0, 0 }, // transparency ( used in most images )
|
||||||
|
{0, 0, 0, 64 }, // shadow border ( used in battle, adventure map def's )
|
||||||
|
{0, 0, 0, 64 }, // shadow border ( used in fog-of-war def's )
|
||||||
|
{0, 0, 0, 128}, // shadow body ( used in fog-of-war def's )
|
||||||
|
{0, 0, 0, 128}, // shadow body ( used in battle, adventure map def's )
|
||||||
|
{0, 0, 0, 0 }, // selection / owner flag ( used in battle, adventure map def's )
|
||||||
|
{0, 0, 0, 128}, // shadow body below selection ( used in battle def's )
|
||||||
|
{0, 0, 0, 64 } // shadow border below selection ( used in battle def's )
|
||||||
|
};
|
||||||
|
|
||||||
data = animationCache.getCachedFile(ResourceID(std::string("SPRITES/") + Name, EResType::ANIMATION));
|
data = animationCache.getCachedFile(ResourceID(std::string("SPRITES/") + Name, EResType::ANIMATION));
|
||||||
|
|
||||||
palette = std::unique_ptr<SDL_Color[]>(new SDL_Color[256]);
|
palette = std::unique_ptr<SDL_Color[]>(new SDL_Color[256]);
|
||||||
int it = 0;
|
int it = 0;
|
||||||
|
|
||||||
ui32 type = read_le_u32(data.get() + it);
|
//ui32 type = read_le_u32(data.get() + it);
|
||||||
it+=4;
|
it+=4;
|
||||||
//int width = read_le_u32(data + it); it+=4;//not used
|
//int width = read_le_u32(data + it); it+=4;//not used
|
||||||
//int height = read_le_u32(data + it); it+=4;
|
//int height = read_le_u32(data + it); it+=4;
|
||||||
@ -124,58 +145,15 @@ CDefFile::CDefFile(std::string Name):
|
|||||||
palette[i].a = SDL_ALPHA_OPAQUE;
|
palette[i].a = SDL_ALPHA_OPAQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(static_cast<DefType>(type))
|
// first color seems to be used unconditionally as 100% transparency
|
||||||
{
|
palette[0] = targetPalette[0];
|
||||||
case DefType::SPELL:
|
|
||||||
palette[0] = H3Palette[0];
|
|
||||||
break;
|
|
||||||
case DefType::SPRITE:
|
|
||||||
case DefType::SPRITE_FRAME:
|
|
||||||
for(ui32 i= 0; i<8; i++)
|
|
||||||
palette[i] = H3Palette[i];
|
|
||||||
break;
|
|
||||||
case DefType::CREATURE:
|
|
||||||
palette[0] = H3Palette[0];
|
|
||||||
palette[1] = H3Palette[1];
|
|
||||||
palette[4] = H3Palette[4];
|
|
||||||
palette[5] = H3Palette[5];
|
|
||||||
palette[6] = H3Palette[6];
|
|
||||||
palette[7] = H3Palette[7];
|
|
||||||
break;
|
|
||||||
case DefType::MAP_HERO:
|
|
||||||
palette[0] = H3Palette[0];
|
|
||||||
palette[1] = H3Palette[1];
|
|
||||||
palette[4] = H3Palette[4];
|
|
||||||
//5 = owner flag, handled separately
|
|
||||||
break;
|
|
||||||
case DefType::MAP:
|
|
||||||
case DefType::TERRAIN:
|
|
||||||
palette[0] = H3Palette[0];
|
|
||||||
palette[1] = H3Palette[1];
|
|
||||||
palette[2] = H3Palette[2];
|
|
||||||
palette[3] = H3Palette[3];
|
|
||||||
palette[4] = H3Palette[4];
|
|
||||||
break;
|
|
||||||
case DefType::CURSOR:
|
|
||||||
palette[0] = H3Palette[0];
|
|
||||||
break;
|
|
||||||
case DefType::INTERFACE:
|
|
||||||
palette[0] = H3Palette[0];
|
|
||||||
palette[1] = H3Palette[1];
|
|
||||||
palette[4] = H3Palette[4];
|
|
||||||
//player colors handled separately
|
|
||||||
//TODO: disallow colorizing other def types
|
|
||||||
break;
|
|
||||||
case DefType::BATTLE_HERO:
|
|
||||||
palette[0] = H3Palette[0];
|
|
||||||
palette[1] = H3Palette[1];
|
|
||||||
palette[4] = H3Palette[4];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logAnim->error("Unknown def type %d in %s", type, Name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// rest of special colors are used only if their RGB values are close to H3
|
||||||
|
for (uint32_t i = 1; i < 8; ++i)
|
||||||
|
{
|
||||||
|
if (colorsSimilar(sourcePalette[i], palette[i]))
|
||||||
|
palette[i] = targetPalette[i];
|
||||||
|
}
|
||||||
|
|
||||||
for (ui32 i=0; i<totalBlocks; i++)
|
for (ui32 i=0; i<totalBlocks; i++)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user