diff --git a/src/openrct2/drawing/Drawing.Sprite.BMP.cpp b/src/openrct2/drawing/Drawing.Sprite.BMP.cpp index 6a542c7e36..5f39d2d92c 100644 --- a/src/openrct2/drawing/Drawing.Sprite.BMP.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.BMP.cpp @@ -9,9 +9,103 @@ #include "Drawing.h" +template static bool FASTCALL BlitPixel(const uint8_t* src, uint8_t* dst, const PaletteMap& paletteMap) +{ + if constexpr (TBlendOp & BLEND_TRANSPARENT) + { + // Ignore transparent pixels + if (*src == 0) + { + return false; + } + } + + if constexpr (((TBlendOp & BLEND_SRC) != 0) && ((TBlendOp & BLEND_DST) != 0)) + { + auto pixel = paletteMap.Blend(*src, *dst); + if constexpr (TBlendOp & BLEND_TRANSPARENT) + { + if (pixel == 0) + { + return false; + } + } + *dst = pixel; + return true; + } + else if constexpr ((TBlendOp & BLEND_SRC) != 0) + { + auto pixel = paletteMap[*src]; + if constexpr (TBlendOp & BLEND_TRANSPARENT) + { + if (pixel == 0) + { + return false; + } + } + *dst = pixel; + return true; + } + else if constexpr ((TBlendOp & BLEND_DST) != 0) + { + auto pixel = paletteMap[*dst]; + if constexpr (TBlendOp & BLEND_TRANSPARENT) + { + if (pixel == 0) + { + return false; + } + } + *dst = pixel; + return true; + } + else + { + *dst = *src; + return true; + } +} + +template +static void FASTCALL BlitPixels(const uint8_t* src, uint8_t* dst, const PaletteMap& paletteMap, uint8_t zoom, size_t dstPitch) +{ + auto yDstSkip = dstPitch - zoom; + for (uint8_t yy = 0; yy < zoom; yy++) + { + for (uint8_t xx = 0; xx < zoom; xx++) + { + BlitPixel(src, dst, paletteMap); + dst++; + } + dst += yDstSkip; + } +} + template static void FASTCALL DrawBMPSpriteMagnify(DrawSpriteArgs& args) { - // TODO + auto& g1 = args.SourceImage; + auto src = g1.offset + ((static_cast(g1.width) * args.SrcY) + args.SrcX); + auto dst = args.DestinationBits; + auto& paletteMap = args.PalMap; + auto dpi = args.DPI; + auto zoomLevel = dpi->zoom_level; + size_t srcLineWidth = g1.width; + size_t dstLineWidth = (static_cast(dpi->width) / zoomLevel) + dpi->pitch; + uint8_t zoom = 1 / zoomLevel; + auto width = args.Width / zoomLevel; + auto height = args.Height / zoomLevel; + for (; height > 0; height -= zoom) + { + auto nextSrc = src + srcLineWidth; + auto nextDst = dst + (dstLineWidth * zoom); + for (int32_t widthRemaining = width; widthRemaining > 0; widthRemaining -= zoom, src++, dst += zoom) + { + // Copy src to a block of zoom * zoom on dst + BlitPixels(src, dst, paletteMap, zoom, dstLineWidth); + } + src = nextSrc; + dst = nextDst; + } } template static void FASTCALL DrawBMPSpriteMinify(DrawSpriteArgs& args) @@ -19,7 +113,7 @@ template static void FASTCALL DrawBMPSpriteMinify(DrawSpri auto& g1 = args.SourceImage; auto src = g1.offset + ((static_cast(g1.width) * args.SrcY) + args.SrcX); auto dst = args.DestinationBits; - [[maybe_unused]] auto& paletteMap = args.PalMap; + auto& paletteMap = args.PalMap; auto width = args.Width; auto height = args.Height; auto dpi = args.DPI; @@ -33,55 +127,7 @@ template static void FASTCALL DrawBMPSpriteMinify(DrawSpri auto nextDst = dst + dstLineWidth; for (int32_t widthRemaining = width; widthRemaining > 0; widthRemaining -= zoom, src += zoom, dst++) { - if constexpr (TBlendOp & BLEND_TRANSPARENT) - { - // Ignore transparent pixels - if (*src == 0) - { - continue; - } - } - - if constexpr (((TBlendOp & BLEND_SRC) != 0) && ((TBlendOp & BLEND_DST) != 0)) - { - auto pixel = paletteMap.Blend(*src, *dst); - if constexpr (TBlendOp & BLEND_TRANSPARENT) - { - if (pixel == 0) - { - continue; - } - } - *dst = pixel; - } - else if constexpr ((TBlendOp & BLEND_SRC) != 0) - { - auto pixel = paletteMap[*src]; - if constexpr (TBlendOp & BLEND_TRANSPARENT) - { - if (pixel == 0) - { - continue; - } - } - *dst = pixel; - } - else if constexpr ((TBlendOp & BLEND_DST) != 0) - { - auto pixel = paletteMap[*dst]; - if constexpr (TBlendOp & BLEND_TRANSPARENT) - { - if (pixel == 0) - { - continue; - } - } - *dst = pixel; - } - else - { - *dst = *src; - } + BlitPixel(src, dst, paletteMap); } src = nextSrc; dst = nextDst;