diff --git a/Source/engine/render/dun_render.cpp b/Source/engine/render/dun_render.cpp index b32bcdede..ca2e570b3 100644 --- a/Source/engine/render/dun_render.cpp +++ b/Source/engine/render/dun_render.cpp @@ -146,16 +146,6 @@ std::string prefixDebugString(int8_t prefix) { } #endif -enum class MaskType { - Invalid, - Solid, - Transparent, - Right, - Left, - RightFoliage, - LeftFoliage, -}; - enum class LightType : uint8_t { FullyDark, PartiallyLit, @@ -1010,39 +1000,6 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderTileDispatch(uint8_t lightTableIn } } -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT MaskType GetMask(TileType tile, uint16_t levelPieceId, ArchType archType, bool transparency, bool foliage) -{ -#ifdef _DEBUG - if ((SDL_GetModState() & KMOD_ALT) != 0) { - return MaskType::Solid; - } -#endif - - if (transparency) { - if (archType == ArchType::None) { - return MaskType::Transparent; - } - if (archType == ArchType::Left && tile != TileType::LeftTriangle) { - if (TileHasAny(levelPieceId, TileProperties::TransparentLeft)) { - return MaskType::Left; - } - } - if (archType == ArchType::Right && tile != TileType::RightTriangle) { - if (TileHasAny(levelPieceId, TileProperties::TransparentRight)) { - return MaskType::Right; - } - } - } else if (archType != ArchType::None && foliage) { - if (tile != TileType::TransparentSquare) - return MaskType::Invalid; - if (archType == ArchType::Left) - return MaskType::LeftFoliage; - if (archType == ArchType::Right) - return MaskType::RightFoliage; - } - return MaskType::Solid; -} - // Blit with left and vertical clipping. void RenderBlackTileClipLeftAndVertical(uint8_t *DVL_RESTRICT dst, int dstPitch, int sx, DiamondClipY clipY) { @@ -1153,11 +1110,10 @@ string_view TileTypeToString(TileType tileType) // clang-format on } -string_view MaskTypeToString(uint8_t maskType) +string_view MaskTypeToString(MaskType maskType) { // clang-format off - switch (static_cast(maskType)) { - case MaskType::Invalid: return "Invalid"; + switch (maskType) { case MaskType::Solid: return "Solid"; case MaskType::Transparent: return "Transparent"; case MaskType::Right: return "Right"; @@ -1171,9 +1127,8 @@ string_view MaskTypeToString(uint8_t maskType) #endif void RenderTile(const Surface &out, Point position, - LevelCelBlock levelCelBlock, uint16_t levelPieceId, - uint8_t lightTableIndex, ArchType archType, - bool transparency, bool foliage) + uint16_t levelPieceId, LevelCelBlock levelCelBlock, + MaskType maskType, uint8_t lightTableIndex) { const TileType tile = levelCelBlock.type(); @@ -1191,7 +1146,6 @@ void RenderTile(const Surface &out, Point position, if (clip.width <= 0 || clip.height <= 0) return; - MaskType maskType = GetMask(tile, levelPieceId, archType, transparency, foliage); const uint8_t *tbl = &LightTables[256 * lightTableIndex]; const auto *pFrameTable = reinterpret_cast(pDungeonCels.get()); const auto *src = reinterpret_cast(&pDungeonCels[pFrameTable[levelCelBlock.frame()]]); @@ -1199,12 +1153,10 @@ void RenderTile(const Surface &out, Point position, const auto dstPitch = out.pitch(); #ifdef DUN_RENDER_STATS - ++DunRenderStats[DunRenderType { tile, static_cast(maskType) }]; + ++DunRenderStats[DunRenderType { tile, maskType }]; #endif switch (maskType) { - case MaskType::Invalid: - break; case MaskType::Solid: RenderTileDispatch(lightTableIndex, tile, dst, dstPitch, src, tbl, clip); break; diff --git a/Source/engine/render/dun_render.hpp b/Source/engine/render/dun_render.hpp index ed6880c62..e4e913b50 100644 --- a/Source/engine/render/dun_render.hpp +++ b/Source/engine/render/dun_render.hpp @@ -85,12 +85,124 @@ enum class TileType : uint8_t { }; /** - * Specifies the type of arches to render. + * @brief Specifies the mask to use for rendering. */ -enum class ArchType { - None, +enum class MaskType : uint8_t { + /** @brief The entire tile is opaque. */ + Solid, + + /** @brief The entire tile is blended with transparency. */ + Transparent, + + /** + * @brief Upper-right triangle is blended with transparency. + * + * Can only be used with `TileType::LeftTrapezoid` and + * `TileType::TransparentSquare`. + * + * The lower 16 rows are opaque. + * The upper 16 rows are arranged like this (🮆 = opaque, 🮐 = blended): + * + * 🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + */ + Right, + + /** + * @brief Upper-left triangle is blended with transparency. + * + * Can only be used with `TileType::RightTrapezoid` and + * `TileType::TransparentSquare`. + * + * The lower 16 rows are opaque. + * The upper 16 rows are arranged like this (🮆 = opaque, 🮐 = blended): + * + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + */ Left, - Right + + /** + * @brief Only the upper-left triangle is rendered. + * + * Can only be used with `TileType::TransparentSquare`. + * + * The lower 16 rows are skipped. + * The upper 16 rows are arranged like this (🮆 = opaque, 🮐 = not rendered): + * + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆🮆🮆 + * 🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮆🮆 + */ + RightFoliage, + + /** + * @brief Only the upper right triangle is rendered. + * + * Can only be used with `TileType::TransparentSquare`. + * + * The lower 16 rows are skipped. + * The upper 16 rows are arranged like this (🮆 = opaque, 🮐 = not rendered): + * + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + * 🮆🮆🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐🮐 + */ + LeftFoliage, }; /** @@ -125,7 +237,7 @@ private: #ifdef DUN_RENDER_STATS struct DunRenderType { TileType tileType; - uint8_t maskType; + MaskType maskType; bool operator==(const DunRenderType &other) const { return tileType == other.tileType && maskType == other.maskType; @@ -134,14 +246,14 @@ struct DunRenderType { struct DunRenderTypeHash { size_t operator()(DunRenderType t) const noexcept { - return std::hash {}((static_cast(t.tileType) << 1) | t.maskType); + return std::hash {}((1 < static_cast(t.tileType)) | static_cast(t.maskType)); } }; extern std::unordered_map DunRenderStats; string_view TileTypeToString(TileType tileType); -string_view MaskTypeToString(uint8_t maskType); +string_view MaskTypeToString(MaskType maskType); #endif /** @@ -150,15 +262,12 @@ string_view MaskTypeToString(uint8_t maskType); * @param position Target buffer coordinates * @param levelCelBlock The MIN block of the level CEL file. * @param levelPieceId The piece ID (index into SOLData and DPieceMicros). + * @param maskType The mask to use, * @param lightTableIndex The light level to use for rendering (index into LightTables / 256). - * @param archType The type of arch to render. - * @param transparency Specifies whether transparency is active for the CEL sprite. - * @param foliage Specifies whether the tile has foliage. Foliage is extra content that overlaps the previous tile. */ void RenderTile(const Surface &out, Point position, - LevelCelBlock levelCelBlock, uint16_t levelPieceId, - uint8_t lightTableIndex, ArchType archType, - bool transparency, bool foliage); + uint16_t levelPieceId, LevelCelBlock levelCelBlock, + MaskType maskType, uint8_t lightTableIndex); /** * @brief Render a black 64x31 tile ◆ diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp index 0a3489921..0a472c6b4 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/Source/engine/render/scrollrt.cpp @@ -497,31 +497,98 @@ static void DrawDungeon(const Surface & /*out*/, Point /*tilePosition*/, Point / void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition) { const uint16_t levelPieceId = dPiece[tilePosition.x][tilePosition.y]; - MICROS *pMap = &DPieceMicros[levelPieceId]; + const MICROS *pMap = &DPieceMicros[levelPieceId]; + bool transparency = TileHasAny(levelPieceId, TileProperties::Transparent) && TransList[dTransVal[tilePosition.x][tilePosition.y]]; #ifdef _DEBUG - // Turn transparency off here for debugging - transparency = transparency && (SDL_GetModState() & KMOD_ALT) == 0; + if ((SDL_GetModState() & KMOD_ALT) != 0) + transparency = false; #endif - const bool foliage = !TileHasAny(levelPieceId, TileProperties::Solid); - for (int i = 0; i < (MicroTileLen / 2); i++) { + + const auto getFirstTileMaskLeft = [=](TileType tile) -> MaskType { + if (transparency) { + switch (tile) { + case TileType::LeftTrapezoid: + case TileType::TransparentSquare: + return TileHasAny(levelPieceId, TileProperties::TransparentLeft) + ? MaskType::Left + : MaskType::Solid; + case TileType::LeftTriangle: + return MaskType::Solid; + default: + return MaskType::Transparent; + } + } + if (foliage) + return MaskType::LeftFoliage; + return MaskType::Solid; + }; + + const auto getFirstTileMaskRight = [=](TileType tile) -> MaskType { + if (transparency) { + switch (tile) { + case TileType::RightTrapezoid: + case TileType::TransparentSquare: + return TileHasAny(levelPieceId, TileProperties::TransparentRight) + ? MaskType::Right + : MaskType::Solid; + case TileType::RightTriangle: + return MaskType::Solid; + default: + return MaskType::Transparent; + } + } + if (foliage) + return MaskType::RightFoliage; + return MaskType::Solid; + }; + + // The first micro tile may be rendered with a foliage mask. + // Only `TransparentSquare` tiles are rendered when `foliage` is true. + { + { + const LevelCelBlock levelCelBlock { pMap->mt[0] }; + const TileType tileType = levelCelBlock.type(); + const MaskType maskType = getFirstTileMaskLeft(tileType); + if (levelCelBlock.hasValue()) { + if (maskType != MaskType::LeftFoliage || tileType == TileType::TransparentSquare) { + RenderTile(out, targetBufferPosition, + levelPieceId, levelCelBlock, maskType, LightTableIndex); + } + } + } + { + const LevelCelBlock levelCelBlock { pMap->mt[1] }; + const TileType tileType = levelCelBlock.type(); + const MaskType maskType = getFirstTileMaskRight(tileType); + if (levelCelBlock.hasValue()) { + if (transparency || !foliage || levelCelBlock.type() == TileType::TransparentSquare) { + if (maskType != MaskType::RightFoliage || tileType == TileType::TransparentSquare) { + RenderTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 }, + levelPieceId, levelCelBlock, maskType, LightTableIndex); + } + } + } + } + targetBufferPosition.y -= TILE_HEIGHT; + } + + for (uint_fast8_t i = 2, n = MicroTileLen; i < n; i += 2) { { - const LevelCelBlock levelCelBlock { pMap->mt[2 * i] }; + const LevelCelBlock levelCelBlock { pMap->mt[i] }; if (levelCelBlock.hasValue()) { RenderTile(out, targetBufferPosition, - levelCelBlock, levelPieceId, LightTableIndex, - i == 0 ? ArchType::Left : ArchType::None, - transparency, foliage); + levelPieceId, levelCelBlock, + transparency ? MaskType::Transparent : MaskType::Solid, LightTableIndex); } } { - const LevelCelBlock levelCelBlock { pMap->mt[2 * i + 1] }; + const LevelCelBlock levelCelBlock { pMap->mt[i + 1] }; if (levelCelBlock.hasValue()) { RenderTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 }, - levelCelBlock, levelPieceId, LightTableIndex, - i == 0 ? ArchType::Right : ArchType::None, - transparency, foliage); + levelPieceId, levelCelBlock, + transparency ? MaskType::Transparent : MaskType::Solid, LightTableIndex); } } targetBufferPosition.y -= TILE_HEIGHT; @@ -543,16 +610,14 @@ void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPositio const LevelCelBlock levelCelBlock { DPieceMicros[levelPieceId].mt[0] }; if (levelCelBlock.hasValue()) { RenderTile(out, targetBufferPosition, - levelCelBlock, levelPieceId, LightTableIndex, ArchType::Left, - /*transparency=*/false, /*foliage=*/false); + levelPieceId, levelCelBlock, MaskType::Solid, LightTableIndex); } } { const LevelCelBlock levelCelBlock { DPieceMicros[levelPieceId].mt[1] }; if (levelCelBlock.hasValue()) { RenderTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 }, - levelCelBlock, levelPieceId, LightTableIndex, ArchType::Right, - /*transparency=*/false, /*foliage=*/false); + levelPieceId, levelCelBlock, MaskType::Solid, LightTableIndex); } } } @@ -1031,7 +1096,7 @@ void DrawGame(const Surface &fullOut, Point position) [](const std::pair &a, const std::pair &b) { return a.first.maskType == b.first.maskType ? static_cast(a.first.tileType) < static_cast(b.first.tileType) - : a.first.maskType < b.first.maskType; + : static_cast(a.first.maskType) < static_cast(b.first.maskType); }); Point pos { 100, 20 }; for (size_t i = 0; i < sortedStats.size(); ++i) { diff --git a/Source/levels/gendung.cpp b/Source/levels/gendung.cpp index f7a8ebcbc..04d99b554 100644 --- a/Source/levels/gendung.cpp +++ b/Source/levels/gendung.cpp @@ -34,7 +34,7 @@ bool setlevel; _setlevels setlvlnum; dungeon_type setlvltype; Point ViewPosition; -int MicroTileLen; +uint_fast8_t MicroTileLen; char TransVal; bool TransList[256]; uint16_t dPiece[MAXDUNX][MAXDUNY]; diff --git a/Source/levels/gendung.h b/Source/levels/gendung.h index 2a37e478c..d2d337f7d 100644 --- a/Source/levels/gendung.h +++ b/Source/levels/gendung.h @@ -182,7 +182,7 @@ extern _setlevels setlvlnum; extern dungeon_type setlvltype; /** Specifies the player viewpoint X,Y-coordinates of the map. */ extern DVL_API_FOR_TEST Point ViewPosition; -extern int MicroTileLen; +extern uint_fast8_t MicroTileLen; extern char TransVal; /** Specifies the active transparency indices. */ extern bool TransList[256];