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
54 lines
1.4 KiB
|
5 years ago
|
#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
|