7 changed files with 2 additions and 411 deletions
@ -1,34 +0,0 @@
|
||||
#include "engine/pcx_sprite.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
std::unique_ptr<uint32_t[]> OwnedPcxSpriteSheet::calculateFrameOffsets(PcxSprite sprite, uint16_t numFrames) |
||||
{ |
||||
uint16_t frameHeight = sprite.height() / numFrames; |
||||
std::unique_ptr<uint32_t[]> frameOffsets { new uint32_t[numFrames] }; |
||||
frameOffsets[0] = 0; |
||||
const unsigned width = sprite.width(); |
||||
const unsigned srcSkip = width % 2; |
||||
const uint8_t *data = sprite.data(); |
||||
for (unsigned frame = 1; frame < numFrames; ++frame) { |
||||
for (unsigned y = 0; y < frameHeight; ++y) { |
||||
for (unsigned x = 0; x < width;) { |
||||
constexpr uint8_t PcxMaxSinglePixel = 0xBF; |
||||
const uint8_t byte = *data++; |
||||
if (byte <= PcxMaxSinglePixel) { |
||||
++x; |
||||
continue; |
||||
} |
||||
constexpr uint8_t PcxRunLengthMask = 0x3F; |
||||
const uint8_t runLength = (byte & PcxRunLengthMask); |
||||
++data; |
||||
x += runLength; |
||||
} |
||||
data += srcSkip; |
||||
} |
||||
frameOffsets[frame] = static_cast<uint32_t>(data - sprite.data()); |
||||
} |
||||
return frameOffsets; |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -1,171 +0,0 @@
|
||||
#pragma once |
||||
|
||||
#include <cstdint> |
||||
#include <memory> |
||||
#include <utility> |
||||
|
||||
#include "utils/stdcompat/optional.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
class OwnedPcxSprite; |
||||
class OwnedPcxSpriteSheet; |
||||
|
||||
/**
|
||||
* @brief An 8-bit PCX sprite. |
||||
*/ |
||||
class PcxSprite { |
||||
public: |
||||
PcxSprite(const uint8_t *data, uint16_t width, uint16_t height, std::optional<uint8_t> transparentColor = std::nullopt) |
||||
: data_(data) |
||||
, width_(width) |
||||
, height_(height) |
||||
, transparent_color_(transparentColor) |
||||
{ |
||||
} |
||||
|
||||
explicit PcxSprite(const OwnedPcxSprite &owned); |
||||
|
||||
[[nodiscard]] const uint8_t *data() const |
||||
{ |
||||
return data_; |
||||
} |
||||
|
||||
[[nodiscard]] uint16_t width() const |
||||
{ |
||||
return width_; |
||||
} |
||||
|
||||
[[nodiscard]] uint16_t height() const |
||||
{ |
||||
return height_; |
||||
} |
||||
|
||||
[[nodiscard]] std::optional<uint8_t> transparentColor() const |
||||
{ |
||||
return transparent_color_; |
||||
} |
||||
|
||||
private: |
||||
const uint8_t *data_; |
||||
uint16_t width_; |
||||
uint16_t height_; |
||||
std::optional<uint8_t> transparent_color_; |
||||
}; |
||||
|
||||
class OwnedPcxSprite { |
||||
public: |
||||
OwnedPcxSprite(std::unique_ptr<uint8_t[]> &&data, uint16_t width, uint16_t height, std::optional<uint8_t> transparentColor = std::nullopt) |
||||
: data_(std::move(data)) |
||||
, width_(width) |
||||
, height_(height) |
||||
, transparent_color_(transparentColor) |
||||
{ |
||||
} |
||||
|
||||
OwnedPcxSprite(OwnedPcxSprite &&) noexcept = default; |
||||
OwnedPcxSprite &operator=(OwnedPcxSprite &&) noexcept = default; |
||||
|
||||
private: |
||||
std::unique_ptr<uint8_t[]> data_; |
||||
uint16_t width_; |
||||
uint16_t height_; |
||||
std::optional<uint8_t> transparent_color_; |
||||
|
||||
friend class PcxSprite; |
||||
friend class OwnedPcxSpriteSheet; |
||||
}; |
||||
|
||||
inline PcxSprite::PcxSprite(const OwnedPcxSprite &owned) |
||||
: PcxSprite(owned.data_.get(), owned.width_, owned.height_, owned.transparent_color_) |
||||
{ |
||||
} |
||||
|
||||
/**
|
||||
* @brief An 8-bit PCX sprite sheet consisting of vertically stacked frames. |
||||
*/ |
||||
class PcxSpriteSheet { |
||||
public: |
||||
PcxSpriteSheet(const uint8_t *data, const uint32_t *frameOffsets, uint16_t numFrames, uint16_t width, uint16_t frameHeight, std::optional<uint8_t> transparentColor = std::nullopt) |
||||
: data_(data) |
||||
, frame_offsets_(frameOffsets) |
||||
, num_frames_(numFrames) |
||||
, width_(width) |
||||
, frame_height_(frameHeight) |
||||
, transparent_color_(transparentColor) |
||||
{ |
||||
} |
||||
|
||||
explicit PcxSpriteSheet(const OwnedPcxSpriteSheet &owned); |
||||
|
||||
[[nodiscard]] PcxSprite sprite(uint16_t frame) const |
||||
{ |
||||
return PcxSprite { data_ + frame_offsets_[frame], width_, frame_height_, transparent_color_ }; |
||||
} |
||||
|
||||
[[nodiscard]] uint16_t numFrames() const |
||||
{ |
||||
return num_frames_; |
||||
} |
||||
|
||||
[[nodiscard]] uint16_t width() const |
||||
{ |
||||
return width_; |
||||
} |
||||
|
||||
[[nodiscard]] uint16_t frameHeight() const |
||||
{ |
||||
return frame_height_; |
||||
} |
||||
|
||||
private: |
||||
const uint8_t *data_; |
||||
const uint32_t *frame_offsets_; |
||||
uint16_t num_frames_; |
||||
uint16_t width_; |
||||
uint16_t frame_height_; |
||||
std::optional<uint8_t> transparent_color_; |
||||
}; |
||||
|
||||
class OwnedPcxSpriteSheet { |
||||
public: |
||||
OwnedPcxSpriteSheet(std::unique_ptr<uint8_t[]> &&data, std::unique_ptr<uint32_t[]> &&frameOffsets, uint16_t numFrames, uint16_t width, uint16_t frameHeight, std::optional<uint8_t> transparentColor = std::nullopt) |
||||
: data_(std::move(data)) |
||||
, frame_offsets_(std::move(frameOffsets)) |
||||
, num_frames_(numFrames) |
||||
, width_(width) |
||||
, frame_height_(frameHeight) |
||||
, transparent_color_(transparentColor) |
||||
{ |
||||
} |
||||
|
||||
OwnedPcxSpriteSheet(OwnedPcxSprite &&sprite, uint16_t numFrames) |
||||
: OwnedPcxSpriteSheet( |
||||
std::move(sprite.data_), |
||||
calculateFrameOffsets(PcxSprite { sprite.data_.get(), sprite.width_, sprite.height_ }, numFrames), |
||||
numFrames, sprite.width_, sprite.height_ / numFrames, sprite.transparent_color_) |
||||
{ |
||||
} |
||||
|
||||
OwnedPcxSpriteSheet(OwnedPcxSpriteSheet &&) noexcept = default; |
||||
OwnedPcxSpriteSheet &operator=(OwnedPcxSpriteSheet &&) noexcept = default; |
||||
|
||||
private: |
||||
static std::unique_ptr<uint32_t[]> calculateFrameOffsets(PcxSprite sprite, uint16_t numFrames); |
||||
|
||||
std::unique_ptr<uint8_t[]> data_; |
||||
std::unique_ptr<uint32_t[]> frame_offsets_; |
||||
uint16_t num_frames_; |
||||
uint16_t width_; |
||||
uint16_t frame_height_; |
||||
std::optional<uint8_t> transparent_color_; |
||||
|
||||
friend class PcxSpriteSheet; |
||||
}; |
||||
|
||||
inline PcxSpriteSheet::PcxSpriteSheet(const OwnedPcxSpriteSheet &owned) |
||||
: PcxSpriteSheet(owned.data_.get(), owned.frame_offsets_.get(), owned.num_frames_, owned.width_, owned.frame_height_, owned.transparent_color_) |
||||
{ |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -1,49 +0,0 @@
|
||||
#include "engine/render/pcx_render.hpp" |
||||
|
||||
#include <algorithm> |
||||
#include <cstring> |
||||
|
||||
#include "engine/render/common_impl.h" |
||||
#include "utils/log.hpp" |
||||
|
||||
namespace devilution { |
||||
namespace { |
||||
|
||||
constexpr uint8_t PcxMaxSinglePixel = 0xBF; |
||||
constexpr uint8_t PcxRunLengthMask = 0x3F; |
||||
|
||||
BlitCommand PcxGetBlitCommand(const uint8_t *src) |
||||
{ |
||||
const uint8_t value = *src++; |
||||
if (value <= PcxMaxSinglePixel) |
||||
return BlitCommand { BlitType::Pixel, src, 1, value }; |
||||
const uint8_t runLength = value & PcxRunLengthMask; |
||||
const uint8_t color = *src++; |
||||
return BlitCommand { BlitType::Fill, src, runLength, color }; |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
void RenderPcxSprite(const Surface &out, PcxSprite sprite, Point position) |
||||
{ |
||||
if (sprite.transparentColor()) { |
||||
DoRenderForwards<PcxGetBlitCommand>(out, position, sprite.data(), sprite.width(), sprite.height(), BlitDirect {}, |
||||
TransformBlitCommandTransparentColor { *sprite.transparentColor() }); |
||||
} else { |
||||
DoRenderForwards<PcxGetBlitCommand>(out, position, sprite.data(), sprite.width(), sprite.height(), BlitDirect {}, |
||||
TransformBlitCommandNoop); |
||||
} |
||||
} |
||||
|
||||
void RenderPcxSpriteWithColorMap(const Surface &out, PcxSprite sprite, Point position, const std::array<uint8_t, 256> &colorMap) |
||||
{ |
||||
if (sprite.transparentColor()) { |
||||
DoRenderForwards<PcxGetBlitCommand>(out, position, sprite.data(), sprite.width(), sprite.height(), BlitWithMap { colorMap.data() }, |
||||
TransformBlitCommandTransparentColor { *sprite.transparentColor() }); |
||||
} else { |
||||
DoRenderForwards<PcxGetBlitCommand>(out, position, sprite.data(), sprite.width(), sprite.height(), BlitWithMap { colorMap.data() }, |
||||
TransformBlitCommandNoop); |
||||
} |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -1,31 +0,0 @@
|
||||
#pragma once |
||||
|
||||
#include <array> |
||||
#include <cstdint> |
||||
|
||||
#include "engine/pcx_sprite.hpp" |
||||
#include "engine/point.hpp" |
||||
#include "engine/surface.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
/**
|
||||
* @brief Renders a PCX sprite to surface. |
||||
* |
||||
* @param out Output surface. |
||||
* @param sprite Source sprite. |
||||
* @param position Top-left position of the sprite on the surface. |
||||
*/ |
||||
void RenderPcxSprite(const Surface &out, PcxSprite sprite, Point position); |
||||
|
||||
/**
|
||||
* @brief Renders a PCX sprite to surface, translating the colors per the given map. |
||||
* |
||||
* @param out Output surface. |
||||
* @param sprite Source sprite. |
||||
* @param position Top-left position of the sprite on the surface. |
||||
* @param colorMap Palette translation map. |
||||
*/ |
||||
void RenderPcxSpriteWithColorMap(const Surface &out, PcxSprite sprite, Point position, const std::array<uint8_t, 256> &colorMap); |
||||
|
||||
} // namespace devilution
|
||||
Loading…
Reference in new issue