diff --git a/Source/engine/render/dun_render.cpp b/Source/engine/render/dun_render.cpp index cf7ccbc46cd..8ff90d2c0fd 100644 --- a/Source/engine/render/dun_render.cpp +++ b/Source/engine/render/dun_render.cpp @@ -86,58 +86,29 @@ int GetTileDebugColor(TileType tile) case TileType::RightTrapezoid: return PAL16_BLUE + 5; default: return 0; } + // clang-format on } #endif // DEBUG_RENDER_COLOR -// Masks are defined by 2 template variables: -// -// 1. `OpaquePrefix`: Whether the line starts with opaque pixels -// followed by blended pixels or the other way around. -// 2. `PrefixIncrement`: The change to the prefix when going -// up 1 line. -// -// The Left mask can only be applied to LeftTrapezoid and TransparentSquare. -// The Right mask can only be applied to RightTrapezoid and TransparentSquare. -// The Left/RightFoliage masks can only be applied to TransparentSquare. - -// True if the given OpaquePrefix and PrefixIncrement represent foliage. -// For foliage, we skip transparent pixels instead of blending them. -template -constexpr bool IsFoliage = PrefixIncrement != 0 && (OpaquePrefix == (PrefixIncrement > 0)); - -// True for foliage: -template -constexpr bool SkipTransparentPixels = IsFoliage; - -// True if the entire lower half of the mask is transparent. -// True for Transparent, LeftFoliage, and RightFoliage. -template -constexpr bool LowerHalfTransparent = (OpaquePrefix == (PrefixIncrement >= 0)); +// How many pixels to increment the transparent (Left) or opaque (Right) +// prefix width after each line (drawing bottom-to-top). +template +constexpr int8_t PrefixIncrement = 0; +template <> +constexpr int8_t PrefixIncrement = 2; +template <> +constexpr int8_t PrefixIncrement = -2; -// The initial value for the prefix: -template -DVL_ALWAYS_INLINE int8_t InitPrefix() -{ - return PrefixIncrement >= 0 ? -32 : 64; -} +// Initial value for the prefix. +template +int8_t InitialPrefix = PrefixIncrement >= 0 ? -32 : 64; // The initial value for the prefix at y-th line (counting from the bottom). -template +template DVL_ALWAYS_INLINE int8_t InitPrefix(int8_t y) { - return InitPrefix() + PrefixIncrement * y; -} - -#ifdef DEBUG_STR -template -std::string prefixDebugString(int8_t prefix) { - std::string out(32, OpaquePrefix ? '0' : '1'); - const uint8_t clamped = std::clamp(prefix, 0, 32); - out.replace(0, clamped, clamped, OpaquePrefix ? '1' : '0'); - StrAppend(out, " prefix=", prefix, " OpaquePrefix=", OpaquePrefix, " PrefixIncrement=", PrefixIncrement); - return out; + return InitialPrefix + PrefixIncrement * y; } -#endif enum class LightType : uint8_t { FullyDark, @@ -215,42 +186,38 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLineTransparentOrOpaque(uint8_t * } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLineTransparentAndOpaque(uint8_t *DVL_RESTRICT dst, const uint8_t *DVL_RESTRICT src, uint_fast8_t prefixWidth, uint_fast8_t width, const uint8_t *DVL_RESTRICT tbl) { - if constexpr (OpaquePrefix) { + if constexpr (OpaqueFirst) { RenderLineOpaque(dst, src, prefixWidth, tbl); - if constexpr (!SkipTransparentPixels) - RenderLineTransparent(dst + prefixWidth, src + prefixWidth, width - prefixWidth, tbl); + RenderLineTransparent(dst + prefixWidth, src + prefixWidth, width - prefixWidth, tbl); } else { - if constexpr (!SkipTransparentPixels) - RenderLineTransparent(dst, src, prefixWidth, tbl); + RenderLineTransparent(dst, src, prefixWidth, tbl); RenderLineOpaque(dst + prefixWidth, src + prefixWidth, width - prefixWidth, tbl); } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLine(uint8_t *DVL_RESTRICT dst, const uint8_t *DVL_RESTRICT src, uint_fast8_t n, const uint8_t *DVL_RESTRICT tbl, int8_t prefix) { - if constexpr (PrefixIncrement == 0) { - RenderLineTransparentOrOpaque(dst, src, n, tbl); + if constexpr (Mask == MaskType::Solid || Mask == MaskType::Transparent) { + RenderLineTransparentOrOpaque(dst, src, n, tbl); } else if (prefix >= static_cast(n)) { // We std::clamp the prefix to (0, n] and avoid calling `RenderLineTransparent/Opaque` with width=0. - if constexpr (OpaquePrefix) { + if constexpr (Mask == MaskType::Right) { RenderLineOpaque(dst, src, n, tbl); } else { - if constexpr (!SkipTransparentPixels) - RenderLineTransparent(dst, src, n, tbl); + RenderLineTransparent(dst, src, n, tbl); } } else if (prefix <= 0) { - if constexpr (!OpaquePrefix) { + if constexpr (Mask == MaskType::Left) { RenderLineOpaque(dst, src, n, tbl); } else { - if constexpr (!SkipTransparentPixels) - RenderLineTransparent(dst, src, n, tbl); + RenderLineTransparent(dst, src, n, tbl); } } else { - RenderLineTransparentAndOpaque(dst, src, prefix, n, tbl); + RenderLineTransparentAndOpaque(dst, src, prefix, n, tbl); } } @@ -314,10 +281,10 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderSquare(uint8_t *DVL_RESTRICT dst, } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareFull(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, unsigned height) { - int8_t prefix = InitPrefix(); + int8_t prefix = InitialPrefix; DVL_ASSUME(height >= 16); DVL_ASSUME(height <= 32); for (unsigned i = 0; i < height; ++i, dst -= dstPitch + Width) { @@ -325,7 +292,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareFull(uint8_t *DV while (drawWidth > 0) { auto v = static_cast(*src++); if (v > 0) { - RenderLine(dst, src, v, tbl, prefix - (Width - drawWidth)); + RenderLine(dst, src, v, tbl, prefix - (Width - drawWidth)); src += v; } else { v = -v; @@ -333,11 +300,11 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareFull(uint8_t *DV dst += v; drawWidth -= v; } - prefix += PrefixIncrement; + prefix += PrefixIncrement; } } -template +template // NOLINTNEXTLINE(readability-function-cognitive-complexity): Actually complex and has to be fast. DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareClipped(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { @@ -359,7 +326,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareClipped(uint8_t skipRestOfTheLine(Width); } - int8_t prefix = InitPrefix(clip.bottom); + int8_t prefix = InitPrefix(clip.bottom); for (auto i = 0; i < clip.height; ++i, dst -= dstPitch + clip.width) { auto drawWidth = clip.width; @@ -371,7 +338,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareClipped(uint8_t if (v > 0) { if (v > remainingLeftClip) { const auto overshoot = v - remainingLeftClip; - RenderLine(dst, src + remainingLeftClip, overshoot, tbl, prefix - (Width - remainingLeftClip)); + RenderLine(dst, src + remainingLeftClip, overshoot, tbl, prefix - (Width - remainingLeftClip)); dst += overshoot; drawWidth -= overshoot; } @@ -392,13 +359,13 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareClipped(uint8_t auto v = static_cast(*src++); if (v > 0) { if (v > drawWidth) { - RenderLine(dst, src, drawWidth, tbl, prefix - (Width - drawWidth)); + RenderLine(dst, src, drawWidth, tbl, prefix - (Width - drawWidth)); src += v; dst += drawWidth; drawWidth -= v; break; } - RenderLine(dst, src, v, tbl, prefix - (Width - drawWidth)); + RenderLine(dst, src, v, tbl, prefix - (Width - drawWidth)); src += v; } else { v = -v; @@ -415,17 +382,17 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquareClipped(uint8_t // Skip the rest of src line if clipping on the right assert(drawWidth <= 0); skipRestOfTheLine(clip.right + drawWidth); - prefix += PrefixIncrement; + prefix += PrefixIncrement; } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTransparentSquare(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { if (clip.width == Width && clip.bottom == 0 && clip.top == 0) { - RenderTransparentSquareFull(dst, dstPitch, src, tbl, clip.height); + RenderTransparentSquareFull(dst, dstPitch, src, tbl, clip.height); } else { - RenderTransparentSquareClipped(dst, dstPitch, src, tbl, clip); + RenderTransparentSquareClipped(dst, dstPitch, src, tbl, clip); } } @@ -773,172 +740,170 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTriangle(uint8_t *DVL_RESTRI } } -template -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalf(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) { - if constexpr (PrefixIncrement != 0) { - // The first and the last line are always fully transparent/opaque (or vice-versa). - // We handle them specially to avoid calling the blitter with width=0. +template +DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalf(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) +{ + if constexpr (Mask == MaskType::Left || Mask == MaskType::Right) { + // The first line is always fully opaque. + // We handle it specially to avoid calling the blitter with width=0. const uint8_t *srcEnd = src + Width * TrapezoidUpperHeight; - constexpr bool FirstLineIsTransparent = OpaquePrefix ^ (PrefixIncrement < 0); - if constexpr (FirstLineIsTransparent) { - if constexpr (!SkipTransparentPixels) - RenderLineTransparent(dst, src, Width, tbl); - } else { - RenderLineOpaque(dst, src, Width, tbl); - } + RenderLineOpaque(dst, src, Width, tbl); src += Width; dst -= dstPitch; - uint8_t prefixWidth = (PrefixIncrement < 0 ? 32 : 0) + PrefixIncrement; + uint8_t prefixWidth = (PrefixIncrement < 0 ? 32 : 0) + PrefixIncrement; do { - RenderLineTransparentAndOpaque(dst, src, prefixWidth, Width, tbl); - prefixWidth += PrefixIncrement; + RenderLineTransparentAndOpaque(dst, src, prefixWidth, Width, tbl); + prefixWidth += PrefixIncrement; src += Width; dst -= dstPitch; } while (src != srcEnd); - } else { // PrefixIncrement == 0; + } else { // Mask == MaskType::Solid || Mask == MaskType::Transparent const uint8_t *srcEnd = src + Width * TrapezoidUpperHeight; do { - RenderLineTransparentOrOpaque(dst, src, Width, tbl); + RenderLineTransparentOrOpaque(dst, src, Width, tbl); src += Width; dst -= dstPitch; } while (src != srcEnd); } } -template -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalfClipVertical(const Clip &clip, const DiamondClipY &clipY, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) { +template +DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalfClipVertical(const Clip &clip, const DiamondClipY &clipY, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) +{ const auto upperMax = TrapezoidUpperHeight - clipY.upperTop; - int8_t prefix = InitPrefix(clip.bottom); + int8_t prefix = InitPrefix(clip.bottom); for (auto i = 1 + clipY.upperBottom; i <= upperMax; ++i, dst -= dstPitch) { - RenderLine(dst, src, Width, tbl, prefix); + RenderLine(dst, src, Width, tbl, prefix); src += Width; - prefix += PrefixIncrement; + prefix += PrefixIncrement; } } -template -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalfClipLeftAndVertical(const Clip &clip, const DiamondClipY &clipY, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) { +template +DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalfClipLeftAndVertical(const Clip &clip, const DiamondClipY &clipY, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) +{ const auto upperMax = TrapezoidUpperHeight - clipY.upperTop; - int8_t prefix = InitPrefix(clip.bottom); + int8_t prefix = InitPrefix(clip.bottom); for (auto i = 1 + clipY.upperBottom; i <= upperMax; ++i, dst -= dstPitch) { - RenderLine(dst, src, clip.width, tbl, prefix - clip.left); + RenderLine(dst, src, clip.width, tbl, prefix - clip.left); src += Width; - prefix += PrefixIncrement; + prefix += PrefixIncrement; } } -template -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalfClipRightAndVertical(const Clip &clip, const DiamondClipY &clipY, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) { +template +DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTrapezoidUpperHalfClipRightAndVertical(const Clip &clip, const DiamondClipY &clipY, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) +{ const auto upperMax = TrapezoidUpperHeight - clipY.upperTop; - int8_t prefix = InitPrefix(clip.bottom); + int8_t prefix = InitPrefix(clip.bottom); for (auto i = 1 + clipY.upperBottom; i <= upperMax; ++i, dst -= dstPitch) { - RenderLine(dst, src, clip.width, tbl, prefix); + RenderLine(dst, src, clip.width, tbl, prefix); src += Width; - prefix += PrefixIncrement; + prefix += PrefixIncrement; } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidFull(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) { - RenderLeftTriangleLower>(dst, dstPitch, src, tbl); + RenderLeftTriangleLower(dst, dstPitch, src, tbl); dst += XStep; - RenderTrapezoidUpperHalf(dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalf(dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidClipVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { const DiamondClipY clipY = CalculateDiamondClipY(clip); - RenderLeftTriangleLowerClipVertical>(clipY, dst, dstPitch, src, tbl); + RenderLeftTriangleLowerClipVertical(clipY, dst, dstPitch, src, tbl); src += clipY.upperBottom * Width; dst += XStep; - RenderTrapezoidUpperHalfClipVertical(clip, clipY, dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalfClipVertical(clip, clipY, dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { const DiamondClipY clipY = CalculateDiamondClipY(clip); - RenderLeftTriangleLowerClipLeftAndVertical>(clip.left, clipY, dst, dstPitch, src, tbl); + RenderLeftTriangleLowerClipLeftAndVertical(clip.left, clipY, dst, dstPitch, src, tbl); src += clipY.upperBottom * Width + clip.left; dst += XStep + clip.left; - RenderTrapezoidUpperHalfClipLeftAndVertical(clip, clipY, dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalfClipLeftAndVertical(clip, clipY, dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidClipRightAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { const DiamondClipY clipY = CalculateDiamondClipY(clip); - RenderLeftTriangleLowerClipRightAndVertical>(clip.right, clipY, dst, dstPitch, src, tbl); + RenderLeftTriangleLowerClipRightAndVertical(clip.right, clipY, dst, dstPitch, src, tbl); src += clipY.upperBottom * Width; dst += XStep; - RenderTrapezoidUpperHalfClipRightAndVertical(clip, clipY, dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalfClipRightAndVertical(clip, clipY, dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoid(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { if (clip.width == Width) { if (clip.height == Height) { - RenderLeftTrapezoidFull(dst, dstPitch, src, tbl); + RenderLeftTrapezoidFull(dst, dstPitch, src, tbl); } else { - RenderLeftTrapezoidClipVertical(dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoidClipVertical(dst, dstPitch, src, tbl, clip); } } else if (clip.right == 0) { - RenderLeftTrapezoidClipLeftAndVertical(dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoidClipLeftAndVertical(dst, dstPitch, src, tbl, clip); } else { - RenderLeftTrapezoidClipRightAndVertical(dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoidClipRightAndVertical(dst, dstPitch, src, tbl, clip); } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidFull(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl) { - RenderRightTriangleLower>(dst, dstPitch, src, tbl); - RenderTrapezoidUpperHalf(dst, dstPitch, src, tbl); + RenderRightTriangleLower(dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalf(dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidClipVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { const DiamondClipY clipY = CalculateDiamondClipY(clip); - RenderRightTriangleLowerClipVertical>(clipY, dst, dstPitch, src, tbl); + RenderRightTriangleLowerClipVertical(clipY, dst, dstPitch, src, tbl); src += clipY.upperBottom * Width; - RenderTrapezoidUpperHalfClipVertical(clip, clipY, dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalfClipVertical(clip, clipY, dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { const DiamondClipY clipY = CalculateDiamondClipY(clip); - RenderRightTriangleLowerClipLeftAndVertical>(clip.left, clipY, dst, dstPitch, src, tbl); + RenderRightTriangleLowerClipLeftAndVertical(clip.left, clipY, dst, dstPitch, src, tbl); src += clipY.upperBottom * Width + clip.left; - RenderTrapezoidUpperHalfClipLeftAndVertical(clip, clipY, dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalfClipLeftAndVertical(clip, clipY, dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidClipRightAndVertical(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { const DiamondClipY clipY = CalculateDiamondClipY(clip); - RenderRightTriangleLowerClipRightAndVertical>(clip.right, clipY, dst, dstPitch, src, tbl); + RenderRightTriangleLowerClipRightAndVertical(clip.right, clipY, dst, dstPitch, src, tbl); src += clipY.upperBottom * Width; - RenderTrapezoidUpperHalfClipRightAndVertical(clip, clipY, dst, dstPitch, src, tbl); + RenderTrapezoidUpperHalfClipRightAndVertical(clip, clipY, dst, dstPitch, src, tbl); } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoid(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { if (clip.width == Width) { if (clip.height == Height) { - RenderRightTrapezoidFull(dst, dstPitch, src, tbl); + RenderRightTrapezoidFull(dst, dstPitch, src, tbl); } else { - RenderRightTrapezoidClipVertical(dst, dstPitch, src, tbl, clip); + RenderRightTrapezoidClipVertical(dst, dstPitch, src, tbl, clip); } } else if (clip.right == 0) { - RenderRightTrapezoidClipLeftAndVertical(dst, dstPitch, src, tbl, clip); + RenderRightTrapezoidClipLeftAndVertical(dst, dstPitch, src, tbl, clip); } else { - RenderRightTrapezoidClipRightAndVertical(dst, dstPitch, src, tbl, clip); + RenderRightTrapezoidClipRightAndVertical(dst, dstPitch, src, tbl, clip); } } @@ -950,7 +915,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileType(TileType tile, uint8_t * RenderSquare(dst, dstPitch, src, tbl, clip); break; case TileType::TransparentSquare: - RenderTransparentSquare(dst, dstPitch, src, tbl, clip); + RenderTransparentSquare(dst, dstPitch, src, tbl, clip); break; case TileType::LeftTriangle: RenderLeftTriangle(dst, dstPitch, src, tbl, clip); @@ -959,65 +924,65 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileType(TileType tile, uint8_t * RenderRightTriangle(dst, dstPitch, src, tbl, clip); break; case TileType::LeftTrapezoid: - RenderLeftTrapezoid(dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoid(dst, dstPitch, src, tbl, clip); break; case TileType::RightTrapezoid: - RenderRightTrapezoid(dst, dstPitch, src, tbl, clip); + RenderRightTrapezoid(dst, dstPitch, src, tbl, clip); break; } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidOrTransparentSquare(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { switch (tile) { case TileType::TransparentSquare: - RenderTransparentSquare(dst, dstPitch, src, tbl, clip); + RenderTransparentSquare(dst, dstPitch, src, tbl, clip); break; case TileType::LeftTrapezoid: - RenderLeftTrapezoid(dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoid(dst, dstPitch, src, tbl, clip); break; default: app_fatal("Given mask can only be applied to TransparentSquare or LeftTrapezoid tiles"); } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidOrTransparentSquare(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { switch (tile) { case TileType::TransparentSquare: - RenderTransparentSquare(dst, dstPitch, src, tbl, clip); + RenderTransparentSquare(dst, dstPitch, src, tbl, clip); break; case TileType::RightTrapezoid: - RenderRightTrapezoid(dst, dstPitch, src, tbl, clip); + RenderRightTrapezoid(dst, dstPitch, src, tbl, clip); break; default: app_fatal("Given mask can only be applied to TransparentSquare or LeftTrapezoid tiles"); } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderLeftTrapezoidOrTransparentSquareDispatch(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { if (IsFullyDark(tbl)) { - RenderLeftTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); } else if (IsFullyLit(tbl)) { - RenderLeftTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); } else { - RenderLeftTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); } } -template +template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderRightTrapezoidOrTransparentSquareDispatch(TileType tile, uint8_t *DVL_RESTRICT dst, uint16_t dstPitch, const uint8_t *DVL_RESTRICT src, const uint8_t *DVL_RESTRICT tbl, Clip clip) { if (IsFullyDark(tbl)) { - RenderRightTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); + RenderRightTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); } else if (IsFullyLit(tbl)) { - RenderRightTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); + RenderRightTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); } else { - RenderRightTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); + RenderRightTrapezoidOrTransparentSquare(tile, dst, dstPitch, src, tbl, clip); } } @@ -1096,10 +1061,10 @@ DVL_ATTRIBUTE_HOT void RenderTileFrame(const Surface &out, const Point &position RenderTileDispatch(tile, dst, dstPitch, src, tbl, clip); break; case MaskType::Left: - RenderLeftTrapezoidOrTransparentSquareDispatch(tile, dst, dstPitch, src, tbl, clip); + RenderLeftTrapezoidOrTransparentSquareDispatch(tile, dst, dstPitch, src, tbl, clip); break; case MaskType::Right: - RenderRightTrapezoidOrTransparentSquareDispatch(tile, dst, dstPitch, src, tbl, clip); + RenderRightTrapezoidOrTransparentSquareDispatch(tile, dst, dstPitch, src, tbl, clip); break; } diff --git a/test/dun_render_benchmark.cpp b/test/dun_render_benchmark.cpp index cae62250b98..d5b4a0b993c 100644 --- a/test/dun_render_benchmark.cpp +++ b/test/dun_render_benchmark.cpp @@ -49,6 +49,11 @@ void InitOnce() for (size_t i = 0; i < 700; ++i) { for (size_t j = 0; j < 10; ++j) { if (const LevelCelBlock levelCelBlock = DPieceMicros[i].mt[j]; levelCelBlock.hasValue()) { + if ((j == 0 || j == 1) && levelCelBlock.type() == TileType::TransparentSquare) { + // This could actually be re-encoded foliage, which is a triangle followed by TransparentSquare. + // Simply skip it. + continue; + } Tiles[levelCelBlock.type()].push_back(levelCelBlock); } }