mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Support RGB string drawing.
parent
bec34c38f7
commit
6b330da74e
41
src/gfx.cpp
41
src/gfx.cpp
|
@ -73,7 +73,7 @@ int _gui_scale_cfg; ///< GUI scale in config.
|
|||
*/
|
||||
static Rect _invalid_rect;
|
||||
static const RecolourSprite *_colour_remap_ptr;
|
||||
static RecolourSprite _string_colourremap; ///< RecolourSprite for string drawing.
|
||||
static RecolourSpriteRGBA _string_colourremap; ///< RecolourSprite for string drawing.
|
||||
|
||||
static const uint DIRTY_BLOCK_HEIGHT = 8;
|
||||
static const uint DIRTY_BLOCK_WIDTH = 64;
|
||||
|
@ -470,19 +470,32 @@ void DrawRectOutline(const Rect &r, PixelColour colour, int width, int dash)
|
|||
* Set the colour remap to be for the given colour.
|
||||
* @param colour the new colour of the remap.
|
||||
*/
|
||||
static void SetColourRemap(TextColour colour)
|
||||
static BlitterMode SetColourRemap(TextColour colour)
|
||||
{
|
||||
if (colour == TC_INVALID) return;
|
||||
if (colour == TC_INVALID) return BlitterMode::ColourRemap;
|
||||
|
||||
/* Black strings have no shading ever; the shading is black, so it
|
||||
* would be invisible at best, but it actually makes it illegible. */
|
||||
bool no_shade = (colour & TC_NO_SHADE) != 0 || colour == TC_BLACK;
|
||||
|
||||
if ((colour & TC_IS_RGB_COLOUR) && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 32) {
|
||||
/* Unpack RGB TextColour */
|
||||
TextColourPacker tcp(colour);
|
||||
_string_colourremap.rgba[1] = tcp.ToColour();
|
||||
_string_colourremap.rgba[2] = _cur_palette.palette[no_shade ? 0 : PC_BLACK.p];
|
||||
_colour_remap_ptr = &_string_colourremap;
|
||||
|
||||
return BlitterMode::RGBAColourRemap;
|
||||
}
|
||||
|
||||
bool raw_colour = (colour & TC_IS_PALETTE_COLOUR) != 0;
|
||||
colour &= ~(TC_NO_SHADE | TC_IS_PALETTE_COLOUR | TC_FORCED);
|
||||
|
||||
_string_colourremap.palette[1] = raw_colour ? (uint8_t)colour : _string_colourmap[colour].p;
|
||||
_string_colourremap.palette[2] = no_shade ? 0 : 1;
|
||||
_string_colourremap.palette[2] = no_shade ? 0 : PC_BLACK.p;
|
||||
_colour_remap_ptr = &_string_colourremap;
|
||||
|
||||
return BlitterMode::ColourRemap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -602,7 +615,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
|||
/* Update the last colour for the truncation ellipsis. */
|
||||
last_colour = colour;
|
||||
if (do_shadow && (!fc->GetDrawGlyphShadow() || !colour_has_shadow)) continue;
|
||||
SetColourRemap(do_shadow ? TC_BLACK : colour);
|
||||
BlitterMode bm = SetColourRemap(do_shadow ? TC_BLACK : colour); // the last run also sets the colour for the truncation dots
|
||||
|
||||
for (int i = 0; i < run.GetGlyphCount(); i++) {
|
||||
GlyphID glyph = glyphs[i];
|
||||
|
@ -623,7 +636,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
|||
|
||||
if (do_shadow && (glyph & SPRITE_GLYPH) != 0) continue;
|
||||
|
||||
GfxMainBlitter(sprite, begin_x + (do_shadow ? shadow_offset : 0), top + (do_shadow ? shadow_offset : 0), BlitterMode::ColourRemap);
|
||||
GfxMainBlitter(sprite, begin_x + (do_shadow ? shadow_offset : 0), top + (do_shadow ? shadow_offset : 0), bm);
|
||||
}
|
||||
}
|
||||
return last_colour;
|
||||
|
@ -948,11 +961,11 @@ Dimension GetStringListBoundingBox(std::span<const StringID> list, FontSize font
|
|||
*/
|
||||
void DrawCharCentered(char32_t c, const Rect &r, TextColour colour)
|
||||
{
|
||||
SetColourRemap(colour);
|
||||
BlitterMode bm = SetColourRemap(colour);
|
||||
GfxMainBlitter(GetGlyph(FS_NORMAL, c),
|
||||
CentreBounds(r.left, r.right, GetCharacterWidth(FS_NORMAL, c)),
|
||||
CentreBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)),
|
||||
BlitterMode::ColourRemap);
|
||||
bm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1009,12 +1022,14 @@ void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSpri
|
|||
_colour_remap_ptr = GetRecolourSprite(pal);
|
||||
GfxMainBlitterViewport(GetSprite(real_sprite, SpriteType::Normal), x, y, pal == PALETTE_TO_TRANSPARENT ? BlitterMode::Transparent : BlitterMode::TransparentRemap, sub, real_sprite);
|
||||
} else if (pal != PAL_NONE) {
|
||||
BlitterMode bm;
|
||||
if (HasBit(pal, PALETTE_TEXT_RECOLOUR)) {
|
||||
SetColourRemap((TextColour)GB(pal, 0, PALETTE_WIDTH));
|
||||
bm = SetColourRemap((TextColour)GB(pal, 0, PALETTE_WIDTH));
|
||||
} else {
|
||||
_colour_remap_ptr = GetRecolourSprite(GB(pal, 0, PALETTE_WIDTH));
|
||||
bm = GetBlitterMode(pal, *_colour_remap_ptr);
|
||||
}
|
||||
GfxMainBlitterViewport(GetSprite(real_sprite, SpriteType::Normal), x, y, GetBlitterMode(pal, *_colour_remap_ptr), sub, real_sprite);
|
||||
GfxMainBlitterViewport(GetSprite(real_sprite, SpriteType::Normal), x, y, bm, sub, real_sprite);
|
||||
} else {
|
||||
GfxMainBlitterViewport(GetSprite(real_sprite, SpriteType::Normal), x, y, BlitterMode::Normal, sub, real_sprite);
|
||||
}
|
||||
|
@ -1037,12 +1052,14 @@ void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub,
|
|||
_colour_remap_ptr = GetRecolourSprite(pal);
|
||||
GfxMainBlitter(GetSprite(real_sprite, SpriteType::Normal), x, y, pal == PALETTE_TO_TRANSPARENT ? BlitterMode::Transparent : BlitterMode::TransparentRemap, sub, real_sprite, zoom);
|
||||
} else if (pal != PAL_NONE) {
|
||||
BlitterMode bm;
|
||||
if (HasBit(pal, PALETTE_TEXT_RECOLOUR)) {
|
||||
SetColourRemap((TextColour)GB(pal, 0, PALETTE_WIDTH));
|
||||
bm = SetColourRemap((TextColour)GB(pal, 0, PALETTE_WIDTH));
|
||||
} else {
|
||||
_colour_remap_ptr = GetRecolourSprite(GB(pal, 0, PALETTE_WIDTH));
|
||||
bm = GetBlitterMode(pal, *_colour_remap_ptr);
|
||||
}
|
||||
GfxMainBlitter(GetSprite(real_sprite, SpriteType::Normal), x, y, GetBlitterMode(pal, *_colour_remap_ptr), sub, real_sprite, zoom);
|
||||
GfxMainBlitter(GetSprite(real_sprite, SpriteType::Normal), x, y, bm, sub, real_sprite, zoom);
|
||||
} else {
|
||||
GfxMainBlitter(GetSprite(real_sprite, SpriteType::Normal), x, y, BlitterMode::Normal, sub, real_sprite, zoom);
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ DECLARE_INCREMENT_DECREMENT_OPERATORS(Colours)
|
|||
DECLARE_ENUM_AS_ADDABLE(Colours)
|
||||
|
||||
/** Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palette.png */
|
||||
enum TextColour : uint16_t {
|
||||
enum TextColour : uint32_t {
|
||||
TC_BEGIN = 0x00,
|
||||
TC_FROMSTRING = 0x00,
|
||||
TC_BLUE = 0x00,
|
||||
|
@ -331,9 +331,10 @@ enum TextColour : uint16_t {
|
|||
TC_IS_PALETTE_COLOUR = 0x100, ///< Colour value is already a real palette colour index, not an index of a StringColour.
|
||||
TC_NO_SHADE = 0x200, ///< Do not add shading to this text colour.
|
||||
TC_FORCED = 0x400, ///< Ignore colour changes from strings.
|
||||
TC_IS_RGB_COLOUR = 0x800, ///< Colour includes RGB component.
|
||||
|
||||
TC_COLOUR_MASK = 0xFF, ///< Mask to test if TextColour (without flags) is within limits.
|
||||
TC_FLAGS_MASK = 0x700, ///< Mask to test if TextColour (with flags) is within limits.
|
||||
TC_FLAGS_MASK = 0xF00, ///< Mask to test if TextColour (with flags) is within limits.
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(TextColour)
|
||||
|
||||
|
@ -416,7 +417,7 @@ struct PixelColour {
|
|||
|
||||
constexpr inline bool HasRGB() const { return (this->r | this->g | this->b) != 0; }
|
||||
constexpr inline Colour ToColour() const { return {this->r, this->g, this->b}; }
|
||||
constexpr inline TextColour ToTextColour() const { return static_cast<TextColour>(this->p) | TC_IS_PALETTE_COLOUR; }
|
||||
TextColour ToTextColour() const;
|
||||
};
|
||||
|
||||
#endif /* GFX_TYPE_H */
|
||||
|
|
|
@ -407,3 +407,16 @@ PixelColour::PixelColour(Colour colour) : r(colour.r), g(colour.g), b(colour.b)
|
|||
{
|
||||
this->p = GetNearestColourIndex(colour);
|
||||
}
|
||||
|
||||
TextColour PixelColour::ToTextColour() const
|
||||
{
|
||||
TextColour tc = static_cast<TextColour>(this->p) | TC_IS_PALETTE_COLOUR;
|
||||
if (this->HasRGB()) {
|
||||
tc |= TC_IS_RGB_COLOUR;
|
||||
TextColourPacker tcp(tc);
|
||||
tcp.SetR(this->r);
|
||||
tcp.SetG(this->g);
|
||||
tcp.SetB(this->b);
|
||||
}
|
||||
return tc;
|
||||
}
|
||||
|
|
|
@ -124,4 +124,43 @@ static constexpr PixelColour PC_FIELDS {0x25}; ///< Light
|
|||
static constexpr PixelColour PC_TREES {0x57}; ///< Green palette colour for trees.
|
||||
static constexpr PixelColour PC_WATER {0xC9}; ///< Dark blue palette colour for water.
|
||||
|
||||
/**
|
||||
* Stretch TNumBits to fill 8 bits.
|
||||
* The most-significant digits are repeated as least-significant digits so that the full 8 bit range is used, e.g.:
|
||||
* 000000 -> 00000000, 111100 -> 11110011, 111111 -> 11111111
|
||||
* @param v Value of TNumBits to stretch.
|
||||
* @returns 8 bit stretched value.
|
||||
*/
|
||||
template <uint TNumBits>
|
||||
inline constexpr uint8_t StretchBits(uint8_t v)
|
||||
{
|
||||
return (v << (8 - TNumBits)) | (v >> (8 - (8 - TNumBits) * 2));
|
||||
}
|
||||
|
||||
struct TextColourPacker
|
||||
{
|
||||
TextColour &tc;
|
||||
|
||||
constexpr TextColourPacker(TextColour &tc) : tc(tc) { }
|
||||
|
||||
static constexpr uint8_t R_START = 12; ///< Packed start of red component
|
||||
static constexpr uint8_t R_SIZE = 6; ///< Packed size of red component
|
||||
|
||||
static constexpr uint8_t G_START = 18; ///< Packed start of green component
|
||||
static constexpr uint8_t G_SIZE = 6; ///< Packed size of green component
|
||||
|
||||
static constexpr uint8_t B_START = 24; ///< Packed start of blue component
|
||||
static constexpr uint8_t B_SIZE = 6; ///< Packed size of blue component
|
||||
|
||||
inline constexpr uint8_t GetR() const { return StretchBits<R_SIZE>(GB(this->tc, R_START, R_SIZE)); }
|
||||
inline constexpr uint8_t GetG() const { return StretchBits<G_SIZE>(GB(this->tc, G_START, G_SIZE)); }
|
||||
inline constexpr uint8_t GetB() const { return StretchBits<B_SIZE>(GB(this->tc, B_START, B_SIZE)); }
|
||||
|
||||
inline constexpr void SetR(uint8_t v) { SB(this->tc, R_START, R_SIZE, v >> (8 - R_SIZE)); }
|
||||
inline constexpr void SetG(uint8_t v) { SB(this->tc, G_START, G_SIZE, v >> (8 - G_SIZE)); }
|
||||
inline constexpr void SetB(uint8_t v) { SB(this->tc, B_START, B_SIZE, v >> (8 - B_SIZE)); }
|
||||
|
||||
inline constexpr Colour ToColour() const { return Colour(this->GetR(), this->GetG(), this->GetB()); }
|
||||
};
|
||||
|
||||
#endif /* PALETTE_FUNC_H */
|
||||
|
|
Loading…
Reference in New Issue