From 1cdd76b617653d631ac7c7840d333b3c14de11e8 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 19 Jul 2022 15:36:14 +0100 Subject: [PATCH] Remove PCX rendering code We no longer render PCX --- Source/CMakeLists.txt | 2 - Source/engine/pcx_sprite.cpp | 34 ------ Source/engine/pcx_sprite.hpp | 171 ---------------------------- Source/engine/render/common_impl.h | 122 -------------------- Source/engine/render/pcx_render.cpp | 49 -------- Source/engine/render/pcx_render.hpp | 31 ----- Source/utils/pcx_to_cl2.hpp | 4 +- 7 files changed, 2 insertions(+), 411 deletions(-) delete mode 100644 Source/engine/pcx_sprite.cpp delete mode 100644 Source/engine/pcx_sprite.hpp delete mode 100644 Source/engine/render/pcx_render.cpp delete mode 100644 Source/engine/render/pcx_render.hpp diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c8a87b383..221bd310d 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -104,7 +104,6 @@ set(libdevilutionx_SRCS engine/load_pcx.cpp engine/palette.cpp engine/path.cpp - engine/pcx_sprite.cpp engine/random.cpp engine/surface.cpp engine/trn.cpp @@ -112,7 +111,6 @@ set(libdevilutionx_SRCS engine/render/automap_render.cpp engine/render/cl2_render.cpp engine/render/dun_render.cpp - engine/render/pcx_render.cpp engine/render/scrollrt.cpp engine/render/text_render.cpp diff --git a/Source/engine/pcx_sprite.cpp b/Source/engine/pcx_sprite.cpp deleted file mode 100644 index 9b69dcf69..000000000 --- a/Source/engine/pcx_sprite.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "engine/pcx_sprite.hpp" - -namespace devilution { - -std::unique_ptr OwnedPcxSpriteSheet::calculateFrameOffsets(PcxSprite sprite, uint16_t numFrames) -{ - uint16_t frameHeight = sprite.height() / numFrames; - std::unique_ptr 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(data - sprite.data()); - } - return frameOffsets; -} - -} // namespace devilution diff --git a/Source/engine/pcx_sprite.hpp b/Source/engine/pcx_sprite.hpp deleted file mode 100644 index fdb60138d..000000000 --- a/Source/engine/pcx_sprite.hpp +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once - -#include -#include -#include - -#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 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 transparentColor() const - { - return transparent_color_; - } - -private: - const uint8_t *data_; - uint16_t width_; - uint16_t height_; - std::optional transparent_color_; -}; - -class OwnedPcxSprite { -public: - OwnedPcxSprite(std::unique_ptr &&data, uint16_t width, uint16_t height, std::optional 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 data_; - uint16_t width_; - uint16_t height_; - std::optional 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 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 transparent_color_; -}; - -class OwnedPcxSpriteSheet { -public: - OwnedPcxSpriteSheet(std::unique_ptr &&data, std::unique_ptr &&frameOffsets, uint16_t numFrames, uint16_t width, uint16_t frameHeight, std::optional 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 calculateFrameOffsets(PcxSprite sprite, uint16_t numFrames); - - std::unique_ptr data_; - std::unique_ptr frame_offsets_; - uint16_t num_frames_; - uint16_t width_; - uint16_t frame_height_; - std::optional 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 diff --git a/Source/engine/render/common_impl.h b/Source/engine/render/common_impl.h index 7ff0ca1ed..9fcdf21c6 100644 --- a/Source/engine/render/common_impl.h +++ b/Source/engine/render/common_impl.h @@ -59,17 +59,6 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT SkipSize GetSkipSize(int_fast16_t overrun, i using GetBlitCommandFn = BlitCommand (*)(const uint8_t *src); -template -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT const uint8_t *SkipRestOfLine(const uint8_t *src, unsigned remainingWidth) -{ - while (remainingWidth > 0) { - const BlitCommand cmd = GetBlitCommand(src); - src = cmd.srcEnd; - remainingWidth -= cmd.length; - } - return src; -} - template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT const uint8_t *SkipRestOfLineWithOverrun( const uint8_t *src, int_fast16_t srcWidth, SkipSize &skipSize) @@ -104,16 +93,6 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT int_fast16_t SkipLinesForRenderBackwardsWith return skipSize.xOffset; } -template -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void SkipLinesForRenderForwards(Point &position, RenderSrcForwards &src, unsigned lineEndPadding) -{ - while (position.y < 0 && src.height != 0) { - src.begin = SkipRestOfLine(src.begin, src.width) + lineEndPadding; - ++position.y; - --src.height; - } -} - template void DoRenderBackwardsClipY( const Surface &out, Point position, RenderSrcBackwards src, BlitFn &&blitFn) @@ -235,107 +214,6 @@ void DoRenderBackwards( } } -template < - GetBlitCommandFn GetBlitCommand, - typename BlitFn, - typename TransformBlitCommandFn> -void DoRenderForwardsClipY( - const Surface &out, Point position, RenderSrcForwards src, - BlitFn &&blitFn, TransformBlitCommandFn &&transformBlitCommandFn) -{ - // Even padding byte is specific to PCX which is the only renderer that uses this function currently. - const unsigned srcLineEndPadding = src.width % 2; - SkipLinesForRenderForwards(position, src, srcLineEndPadding); - src.height = static_cast(std::min(out.h() - position.y, src.height)); - - const auto dstSkip = static_cast(out.pitch()); - uint8_t *dst = &out[position]; - for (unsigned y = 0; y < src.height; y++) { - for (unsigned x = 0; x < src.width;) { - BlitCommand cmd = GetBlitCommand(src.begin); - cmd = transformBlitCommandFn(cmd); - blitFn(cmd, dst + x, src.begin + 1); - src.begin = cmd.srcEnd; - x += cmd.length; - } - src.begin += srcLineEndPadding; - dst += dstSkip; - } -} - -template < - GetBlitCommandFn GetBlitCommand, - typename BlitFn, - typename TransformBlitCommandFn> -void DoRenderForwardsClipXY( - const Surface &out, Point position, RenderSrcForwards src, ClipX clipX, - BlitFn &&blitFn, TransformBlitCommandFn &&transformBlitCommandFn) -{ - const unsigned srcLineEndPadding = src.width % 2; - SkipLinesForRenderForwards(position, src, srcLineEndPadding); - src.height = static_cast(std::min(out.h() - position.y, src.height)); - - position.x += static_cast(clipX.left); - const auto dstSkip = static_cast(out.pitch() - clipX.width); - uint8_t *dst = &out[position]; - for (unsigned y = 0; y < src.height; y++) { - // Skip initial src if clipping on the left. - // Handles overshoot, i.e. when the RLE segment goes into the unclipped area. - int_fast16_t remainingWidth = clipX.width; - auto remainingLeftClip = clipX.left; - while (remainingLeftClip > 0) { - BlitCommand cmd = GetBlitCommand(src.begin); - if (static_cast(cmd.length) > remainingLeftClip) { - const uint_fast16_t overshoot = cmd.length - remainingLeftClip; - cmd.length = std::min(overshoot, remainingWidth); - cmd = transformBlitCommandFn(cmd); - blitFn(cmd, dst, src.begin + 1 + remainingLeftClip); - src.begin = cmd.srcEnd; - dst += cmd.length; - remainingWidth -= static_cast(overshoot); - break; - } - src.begin = cmd.srcEnd; - remainingLeftClip -= cmd.length; - } - while (remainingWidth > 0) { - BlitCommand cmd = GetBlitCommand(src.begin); - const unsigned unclippedLength = cmd.length; - cmd = transformBlitCommandFn(cmd); - cmd.length = std::min(cmd.length, remainingWidth); - blitFn(cmd, dst, src.begin + 1); - src.begin = cmd.srcEnd; - dst += cmd.length; - remainingWidth -= unclippedLength; // result can be negative - } - src.begin = SkipRestOfLine(src.begin, clipX.right + remainingWidth) + srcLineEndPadding; - dst += dstSkip; - } -} - -template < - GetBlitCommandFn GetBlitCommand, - typename BlitFn, - typename TransformBlitCommandFn> -void DoRenderForwards( - const Surface &out, Point position, const uint8_t *src, unsigned srcWidth, unsigned srcHeight, - BlitFn &&blitFn, TransformBlitCommandFn &&transformBlitCommandFn) -{ - if (position.y >= out.h() || position.y + srcHeight <= 0) - return; - const ClipX clipX = CalculateClipX(position.x, srcWidth, out); - if (clipX.width <= 0) - return; - RenderSrcForwards srcForForwards { src, static_cast(srcWidth), static_cast(srcHeight) }; - if (static_cast(clipX.width) == srcWidth) { - DoRenderForwardsClipY( - out, position, srcForForwards, std::forward(blitFn), std::forward(transformBlitCommandFn)); - } else { - DoRenderForwardsClipXY( - out, position, srcForForwards, clipX, std::forward(blitFn), std::forward(transformBlitCommandFn)); - } -} - template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderOutlineForPixel(uint8_t *dst, int dstPitch, uint8_t color) { diff --git a/Source/engine/render/pcx_render.cpp b/Source/engine/render/pcx_render.cpp deleted file mode 100644 index 037711471..000000000 --- a/Source/engine/render/pcx_render.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "engine/render/pcx_render.hpp" - -#include -#include - -#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(out, position, sprite.data(), sprite.width(), sprite.height(), BlitDirect {}, - TransformBlitCommandTransparentColor { *sprite.transparentColor() }); - } else { - DoRenderForwards(out, position, sprite.data(), sprite.width(), sprite.height(), BlitDirect {}, - TransformBlitCommandNoop); - } -} - -void RenderPcxSpriteWithColorMap(const Surface &out, PcxSprite sprite, Point position, const std::array &colorMap) -{ - if (sprite.transparentColor()) { - DoRenderForwards(out, position, sprite.data(), sprite.width(), sprite.height(), BlitWithMap { colorMap.data() }, - TransformBlitCommandTransparentColor { *sprite.transparentColor() }); - } else { - DoRenderForwards(out, position, sprite.data(), sprite.width(), sprite.height(), BlitWithMap { colorMap.data() }, - TransformBlitCommandNoop); - } -} - -} // namespace devilution diff --git a/Source/engine/render/pcx_render.hpp b/Source/engine/render/pcx_render.hpp deleted file mode 100644 index f2fbe4976..000000000 --- a/Source/engine/render/pcx_render.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include -#include - -#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 &colorMap); - -} // namespace devilution diff --git a/Source/utils/pcx_to_cl2.hpp b/Source/utils/pcx_to_cl2.hpp index 4e8fff316..d2e7f7ec0 100644 --- a/Source/utils/pcx_to_cl2.hpp +++ b/Source/utils/pcx_to_cl2.hpp @@ -9,8 +9,8 @@ namespace devilution { -/** @brief Loads a PCX file as a CL2 sprite. - * +/** + * @brief Loads a PCX file as a CL2 sprite. * * @param handle A non-null SDL_RWops handle. Closed by this function. * @param numFramesOrFrameHeight Pass a positive value with the number of frames, or the frame height as a negative value.