You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
1.4 KiB

#include "engine/surface.hpp"
#include <cstring>
namespace devilution {
namespace {
template <bool SkipColorIndexZero>
void SurfaceBlit(const Surface &src, SDL_Rect srcRect, const Surface &dst, Point dstPosition)
{
// We do not use `SDL_BlitSurface` here because the palettes may be different objects
// and SDL would attempt to map them.
dst.Clip(&srcRect, &dstPosition);
if (srcRect.w <= 0 || srcRect.h <= 0)
return;
const std::uint8_t *srcBuf = src.at(srcRect.x, srcRect.y);
const auto srcPitch = src.pitch();
std::uint8_t *dstBuf = &dst[dstPosition];
const auto dstPitch = dst.pitch();
for (unsigned h = srcRect.h; h != 0; --h) {
if (SkipColorIndexZero) {
for (unsigned w = srcRect.w; w != 0; --w) {
if (*srcBuf != 0)
*dstBuf = *srcBuf;
++srcBuf, ++dstBuf;
}
srcBuf += srcPitch - srcRect.w;
dstBuf += dstPitch - srcRect.w;
} else {
std::memcpy(dstBuf, srcBuf, srcRect.w);
srcBuf += srcPitch;
dstBuf += dstPitch;
}
}
}
} // namespace
void Surface::BlitFrom(const Surface &src, SDL_Rect srcRect, Point targetPosition) const
{
SurfaceBlit</*SkipColorIndexZero=*/false>(src, srcRect, *this, targetPosition);
}
void Surface::BlitFromSkipColorIndexZero(const Surface &src, SDL_Rect srcRect, Point targetPosition) const
{
SurfaceBlit</*SkipColorIndexZero=*/true>(src, srcRect, *this, targetPosition);
}
} // namespace devilution