mirror of
https://github.com/libretro/devilutionX.git
synced 2026-11-11 23:41:00 -10:00
The format is almost identical to CL2, except it uses the frame header to store frame width and height instead of 5 32-line offsets. This means we always have access to frame dimensions, so we can use it as an on-disk format for our graphics as well. Additionally, we may be able to optimize the rendering even more in the future now that we have guaranteed knowledge of frame dimensions.
115 lines
2.9 KiB
C++
115 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
|
|
#include "engine/palette.h"
|
|
#include "utils/attributes.h"
|
|
|
|
namespace devilution {
|
|
|
|
enum class BlitType : uint8_t {
|
|
Transparent,
|
|
Pixels,
|
|
Fill
|
|
};
|
|
|
|
struct BlitCommand {
|
|
BlitType type;
|
|
const uint8_t *srcEnd; // Pointer past the end of the command.
|
|
unsigned length; // Number of pixels this command will write.
|
|
uint8_t color; // For `BlitType::Pixel` and `BlitType::Fill` only.
|
|
};
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitFillDirect(uint8_t *dst, unsigned length, uint8_t color)
|
|
{
|
|
std::memset(dst, color, length);
|
|
}
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitPixelsDirect(uint8_t *dst, const uint8_t *src, unsigned length)
|
|
{
|
|
std::memcpy(dst, src, length);
|
|
}
|
|
|
|
struct BlitDirect {
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void operator()(BlitCommand cmd, uint8_t *dst, const uint8_t *src)
|
|
{
|
|
switch (cmd.type) {
|
|
case BlitType::Fill:
|
|
BlitFillDirect(dst, cmd.length, cmd.color);
|
|
return;
|
|
case BlitType::Pixels:
|
|
BlitPixelsDirect(dst, src, cmd.length);
|
|
return;
|
|
case BlitType::Transparent:
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitFillWithMap(uint8_t *dst, unsigned length, uint8_t color, const uint8_t *colorMap)
|
|
{
|
|
std::memset(dst, colorMap[color], length);
|
|
}
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitPixelsWithMap(uint8_t *dst, const uint8_t *src, unsigned length, const uint8_t *colorMap)
|
|
{
|
|
while (length-- > 0)
|
|
*dst++ = colorMap[*src++];
|
|
}
|
|
|
|
struct BlitWithMap {
|
|
const uint8_t *colorMap;
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void operator()(BlitCommand cmd, uint8_t *dst, const uint8_t *src) const
|
|
{
|
|
switch (cmd.type) {
|
|
case BlitType::Fill:
|
|
BlitFillWithMap(dst, cmd.length, cmd.color, colorMap);
|
|
return;
|
|
case BlitType::Pixels:
|
|
BlitPixelsWithMap(dst, src, cmd.length, colorMap);
|
|
return;
|
|
case BlitType::Transparent:
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitFillBlendedWithMap(uint8_t *dst, unsigned length, uint8_t color, const uint8_t *colorMap)
|
|
{
|
|
color = colorMap[color];
|
|
while (length-- > 0) {
|
|
*dst = paletteTransparencyLookup[*dst][color];
|
|
++dst;
|
|
}
|
|
}
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void BlitPixelsBlendedWithMap(uint8_t *dst, const uint8_t *src, unsigned length, const uint8_t *colorMap)
|
|
{
|
|
while (length-- > 0) {
|
|
*dst = paletteTransparencyLookup[*dst][colorMap[*src++]];
|
|
++dst;
|
|
}
|
|
}
|
|
|
|
struct BlitBlendedWithMap {
|
|
const uint8_t *colorMap;
|
|
|
|
DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void operator()(BlitCommand cmd, uint8_t *dst, const uint8_t *src) const
|
|
{
|
|
switch (cmd.type) {
|
|
case BlitType::Fill:
|
|
BlitFillBlendedWithMap(dst, cmd.length, cmd.color, colorMap);
|
|
return;
|
|
case BlitType::Pixels:
|
|
BlitPixelsBlendedWithMap(dst, src, cmd.length, colorMap);
|
|
return;
|
|
case BlitType::Transparent:
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace devilution
|