From 0e581e0eebdd9ea6238dd1f5a88996f87cb05a16 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 17 Jan 2024 02:03:14 +0000 Subject: [PATCH] Blitter: Add method to set rectangle colours, skipping D7 --- src/blitter/32bpp_anim.cpp | 23 +++++++++++++++++++---- src/blitter/32bpp_anim.hpp | 2 ++ src/blitter/32bpp_base.cpp | 15 +++++++++++++++ src/blitter/32bpp_base.hpp | 1 + src/blitter/40bpp_anim.cpp | 21 +++++++++++++++++++++ src/blitter/40bpp_anim.hpp | 1 + src/blitter/8bpp_base.cpp | 12 ++++++++++++ src/blitter/8bpp_base.hpp | 1 + src/blitter/base.hpp | 12 ++++++++++++ src/blitter/null.hpp | 1 + 10 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp index b5b3809259..9395048dce 100644 --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_anim.cpp @@ -441,7 +441,8 @@ void Blitter_32bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int } } -void Blitter_32bppAnim::SetRect(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) +template +void Blitter_32bppAnim::SetRectGeneric(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch, F filter) { Colour *dst = (Colour *)video + x + y * _screen.pitch; @@ -449,7 +450,9 @@ void Blitter_32bppAnim::SetRect(void *video, int x, int y, const uint8_t *colour do { uint w = width; do { - *dst = LookupColourInPalette(*colours); + if (filter(*colours)) { + *dst = LookupColourInPalette(*colours); + } dst++; colours++; } while (--w); @@ -461,8 +464,10 @@ void Blitter_32bppAnim::SetRect(void *video, int x, int y, const uint8_t *colour do { uint w = width; do { - *dstanim = *colours | (DEFAULT_BRIGHTNESS << 8); - *dst = LookupColourInPalette(*colours); + if (filter(*colours)) { + *dstanim = *colours | (DEFAULT_BRIGHTNESS << 8); + *dst = LookupColourInPalette(*colours); + } dst++; dstanim++; colours++; @@ -474,6 +479,11 @@ void Blitter_32bppAnim::SetRect(void *video, int x, int y, const uint8_t *colour } } +void Blitter_32bppAnim::SetRect(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) +{ + this->SetRectGeneric(video, x, y, colours, lines, width, pitch, [](uint8_t colour) -> bool { return true; }); +} + void Blitter_32bppAnim::SetRect32(void *video, int x, int y, const uint32_t *colours, uint lines, uint width, uint pitch) { uint32_t *dst = (uint32_t *)video + x + y * _screen.pitch; @@ -496,6 +506,11 @@ void Blitter_32bppAnim::SetRect32(void *video, int x, int y, const uint32_t *col } } +void Blitter_32bppAnim::SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) +{ + this->SetRectGeneric(video, x, y, colours, lines, width, pitch, [](uint8_t colour) -> bool { return colour != 0xD7; }); +} + void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8_t colour) { if (_screen_disable_anim) { diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp index b22508ad45..c45cc8c24c 100644 --- a/src/blitter/32bpp_anim.hpp +++ b/src/blitter/32bpp_anim.hpp @@ -42,6 +42,7 @@ public: void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override; void SetRect(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; void SetRect32(void *video, int x, int y, const uint32_t *colours, uint lines, uint width, uint pitch) override; + void SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; void DrawRect(void *video, int width, int height, uint8_t colour) override; void DrawRectAt(void *video, int x, int y, int width, int height, uint8_t colour) override; void CopyFromBuffer(void *video, const void *src, int width, int height) override; @@ -72,6 +73,7 @@ public: } template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); + template void SetRectGeneric(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch, F filter); }; /** Factory for the 32bpp blitter with animation. */ diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp index 4115c11d4e..040720ec32 100644 --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.cpp @@ -61,6 +61,21 @@ void Blitter_32bppBase::SetRect32(void *video, int x, int y, const uint32_t *col } while (--lines); } +void Blitter_32bppBase::SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) +{ + Colour *dst = (Colour *)video + x + y * _screen.pitch; + do { + uint w = width; + do { + if (*colours != 0xD7) *dst = LookupColourInPalette(*colours); + dst++; + colours++; + } while (--w); + dst += _screen.pitch - width; + colours += pitch - width; + } while (--lines); +} + void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8_t colour) { Colour colour32 = LookupColourInPalette(colour); diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp index f1f05ee362..26b039aa0a 100644 --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.hpp @@ -29,6 +29,7 @@ public: void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override; void SetRect(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; void SetRect32(void *video, int x, int y, const uint32_t *colours, uint lines, uint width, uint pitch) override; + void SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; void DrawRect(void *video, int width, int height, uint8_t colour) override; void DrawRectAt(void *video, int x, int y, int width, int height, uint8_t colour) override; void CopyFromBuffer(void *video, const void *src, int width, int height) override; diff --git a/src/blitter/40bpp_anim.cpp b/src/blitter/40bpp_anim.cpp index 7b88f53ba6..f57c3a7f2f 100644 --- a/src/blitter/40bpp_anim.cpp +++ b/src/blitter/40bpp_anim.cpp @@ -82,6 +82,27 @@ void Blitter_40bppAnim::SetRect32(void *video, int x, int y, const uint32_t *col } } +void Blitter_40bppAnim::SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) +{ + if (_screen_disable_anim) { + Blitter_32bppOptimized::SetRectNoD7(video, x, y, colours, lines, width, pitch); + } else { + Colour *dst = (Colour *)video + x + y * _screen.pitch; + uint8_t *dstanim = ((uint32_t *)dst - (uint32_t *)_screen.dst_ptr) + VideoDriver::GetInstance()->GetAnimBuffer(); + do { + for (uint i = 0; i < width; i++) { + if (colours[i] != 0xD7) { + dst[i] = _black_colour; + dstanim[i] = colours[i]; + } + } + dst += _screen.pitch; + dstanim += _screen.pitch; + colours += pitch; + } while (--lines); + } +} + void Blitter_40bppAnim::DrawRect(void *video, int width, int height, uint8_t colour) { if (_screen_disable_anim) { diff --git a/src/blitter/40bpp_anim.hpp b/src/blitter/40bpp_anim.hpp index 38cc9c4dd2..d40f0caa1e 100644 --- a/src/blitter/40bpp_anim.hpp +++ b/src/blitter/40bpp_anim.hpp @@ -22,6 +22,7 @@ public: void SetPixel32(void *video, int x, int y, uint8_t colour, uint32_t colour32) override; void SetRect(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; void SetRect32(void *video, int x, int y, const uint32_t *colours, uint lines, uint width, uint pitch) override; + void SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; void DrawRect(void *video, int width, int height, uint8_t colour) override; void DrawRectAt(void *video, int x, int y, int width, int height, uint8_t colour) override; void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override; diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp index 455db891b1..4b943f631f 100644 --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.cpp @@ -56,6 +56,18 @@ void Blitter_8bppBase::SetRect(void *video, int x, int y, const uint8_t *colours } while (--lines); } +void Blitter_8bppBase::SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) +{ + uint8_t *dst = (uint8_t *)video + x + y * _screen.pitch; + do { + for (size_t i = 0; i < width; i++) { + if (colours[i] != 0xD7) dst[i] = colours[i]; + } + dst += _screen.pitch; + colours += pitch; + } while (--lines); +} + void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8_t colour) { do { diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp index 517a3aa215..7e4e58c0b5 100644 --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.hpp @@ -26,6 +26,7 @@ public: void SetPixel32(void *video, int x, int y, uint8_t colour, uint32_t colour32) override; void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override; void SetRect(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; + void SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override; void DrawRect(void *video, int width, int height, uint8_t colour) override; void DrawRectAt(void *video, int x, int y, int width, int height, uint8_t colour) override; void CopyFromBuffer(void *video, const void *src, int width, int height) override; diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index 35e7639799..7b5b54d7c1 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -160,6 +160,18 @@ public: */ virtual void SetRect32(void *video, int x, int y, const uint32_t *colours, uint lines, uint width, uint pitch) { NOT_REACHED(); }; + /** + * Draw a rectangle of pixels on the video-buffer, skipping any pixels with the value 0xD7. + * @param video The destination pointer (video-buffer). + * @param x The x position within video-buffer. + * @param y The y position within video-buffer. + * @param colours A 8bpp colour mapping buffer. + * @param lines The number of lines. + * @param width The length of the lines. + * @param pitch The pitch of the colours buffer + */ + virtual void SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) = 0; + /** * Make a single horizontal line in a single colour on the video-buffer. * @param video The destination pointer (video-buffer). diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index f6e737ab4c..770a1abf73 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -32,6 +32,7 @@ public: void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) override {}; void SetRect(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override {}; void SetRect32(void *video, int x, int y, const uint32_t *colours, uint lines, uint width, uint pitch) override {}; + void SetRectNoD7(void *video, int x, int y, const uint8_t *colours, uint lines, uint width, uint pitch) override {}; void CopyFromBuffer(void *video, const void *src, int width, int height) override {}; void CopyToBuffer(const void *video, void *dst, int width, int height) override {}; void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {};