From ff0c77ee3bbd1cd551d4faf425bc88eeb9cf90a9 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 3 Feb 2024 21:01:16 +0000 Subject: [PATCH] Blitter: Do not override global screen pitch to use 8bpp blitter 8bpp blitter keep a point to pitch (default screen pitch) --- src/blitter/8bpp_base.cpp | 51 ++++++++++++++++++++++--------------- src/blitter/8bpp_base.hpp | 22 ++++++++++++++++ src/blitter/8bpp_simple.hpp | 1 + src/blitter/null.hpp | 2 +- src/gfx_func.h | 15 ----------- src/viewport.cpp | 13 +++++----- 6 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp index 4b943f631f..63ddc016ac 100644 --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.cpp @@ -17,21 +17,22 @@ void Blitter_8bppBase::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) { const uint8_t *ctab = GetNonSprite(pal, SpriteType::Recolour) + 1; + const int screen_pitch = this->GetScreenPitch(); do { for (int i = 0; i != width; i++) *((uint8_t *)dst + i) = ctab[((uint8_t *)dst)[i]]; - dst = (uint8_t *)dst + _screen.pitch; + dst = (uint8_t *)dst + screen_pitch; } while (--height); } void *Blitter_8bppBase::MoveTo(void *video, int x, int y) { - return (uint8_t *)video + x + y * _screen.pitch; + return (uint8_t *)video + x + y * this->GetScreenPitch(); } void Blitter_8bppBase::SetPixel(void *video, int x, int y, uint8_t colour) { - *((uint8_t *)video + x + y * _screen.pitch) = colour; + *((uint8_t *)video + x + y * this->GetScreenPitch()) = colour; } void Blitter_8bppBase::SetPixel32(void *video, int x, int y, uint8_t colour, uint32_t colour32) @@ -41,55 +42,60 @@ void Blitter_8bppBase::SetPixel32(void *video, int x, int y, uint8_t colour, uin void Blitter_8bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash) { + const int screen_pitch = this->GetScreenPitch(); this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [=](int x, int y) { - *((uint8_t *)video + x + y * _screen.pitch) = colour; + *((uint8_t *)video + x + y * screen_pitch) = colour; }); } void Blitter_8bppBase::SetRect(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; + const int screen_pitch = this->GetScreenPitch(); + uint8_t *dst = (uint8_t *)video + x + y * screen_pitch; do { memcpy(dst, colours, width * sizeof(uint8_t)); - dst += _screen.pitch; + dst += screen_pitch; colours += pitch; } 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; + const int screen_pitch = this->GetScreenPitch(); + 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; + dst += screen_pitch; colours += pitch; } while (--lines); } void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8_t colour) { + const int screen_pitch = this->GetScreenPitch(); do { memset(video, colour, width); - video = (uint8_t *)video + _screen.pitch; + video = (uint8_t *)video + screen_pitch; } while (--height); } void Blitter_8bppBase::DrawRectAt(void *video, int x, int y, int width, int height, uint8_t colour) { - this->Blitter_8bppBase::DrawRect((uint8_t *)video + x + y * _screen.pitch, width, height, colour); + this->Blitter_8bppBase::DrawRect((uint8_t *)video + x + y * this->GetScreenPitch(), width, height, colour); } void Blitter_8bppBase::CopyFromBuffer(void *video, const void *src, int width, int height) { uint8_t *dst = (uint8_t *)video; const uint8_t *usrc = (const uint8_t *)src; + const int screen_pitch = this->GetScreenPitch(); for (; height > 0; height--) { memcpy(dst, usrc, width * sizeof(uint8_t)); usrc += width; - dst += _screen.pitch; + dst += screen_pitch; } } @@ -97,10 +103,11 @@ void Blitter_8bppBase::CopyToBuffer(const void *video, void *dst, int width, int { uint8_t *udst = (uint8_t *)dst; const uint8_t *src = (const uint8_t *)video; + const int screen_pitch = this->GetScreenPitch(); for (; height > 0; height--) { memcpy(udst, src, width * sizeof(uint8_t)); - src += _screen.pitch; + src += screen_pitch; udst += width; } } @@ -109,10 +116,11 @@ void Blitter_8bppBase::CopyImageToBuffer(const void *video, void *dst, int width { uint8_t *udst = (uint8_t *)dst; const uint8_t *src = (const uint8_t *)video; + const int screen_pitch = this->GetScreenPitch(); for (; height > 0; height--) { memcpy(udst, src, width * sizeof(uint8_t)); - src += _screen.pitch; + src += screen_pitch; udst += dst_pitch; } } @@ -121,11 +129,12 @@ void Blitter_8bppBase::ScrollBuffer(void *video, int left, int top, int width, i { const uint8_t *src; uint8_t *dst; + const int screen_pitch = this->GetScreenPitch(); if (scroll_y > 0) { /* Calculate pointers */ - dst = (uint8_t *)video + left + (top + height - 1) * _screen.pitch; - src = dst - scroll_y * _screen.pitch; + dst = (uint8_t *)video + left + (top + height - 1) * screen_pitch; + src = dst - scroll_y * this->GetScreenPitch(); /* Decrease height and increase top */ top += scroll_y; @@ -144,13 +153,13 @@ void Blitter_8bppBase::ScrollBuffer(void *video, int left, int top, int width, i for (int h = height; h > 0; h--) { memcpy(dst, src, width * sizeof(uint8_t)); - src -= _screen.pitch; - dst -= _screen.pitch; + src -= screen_pitch; + dst -= screen_pitch; } } else { /* Calculate pointers */ - dst = (uint8_t *)video + left + top * _screen.pitch; - src = dst - scroll_y * _screen.pitch; + dst = (uint8_t *)video + left + top * screen_pitch; + src = dst - scroll_y * screen_pitch; /* Decrease height. (scroll_y is <=0). */ height += scroll_y; @@ -170,8 +179,8 @@ void Blitter_8bppBase::ScrollBuffer(void *video, int left, int top, int width, i * because source and destination may overlap */ for (int h = height; h > 0; h--) { memmove(dst, src, width * sizeof(uint8_t)); - src += _screen.pitch; - dst += _screen.pitch; + src += screen_pitch; + dst += screen_pitch; } } } diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp index 7e4e58c0b5..344c94820d 100644 --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.hpp @@ -11,13 +11,35 @@ #define BLITTER_8BPP_BASE_HPP #include "base.hpp" +#include "../gfx_type.h" /** Base for all 8bpp blitters. */ class Blitter_8bppBase : public Blitter { + const int *screen_pitch; + public: Blitter_8bppBase() { this->SetScreenDepth(8); + + extern DrawPixelInfo _screen; + this->screen_pitch = &_screen.pitch; + } + + Blitter_8bppBase(const int *screen_pitch) + { + this->SetScreenDepth(8); + + this->screen_pitch = screen_pitch; + } + + /** + * Get the screen pitch used for drawing. + * By default this is _screen.pitch. + */ + int GetScreenPitch() const + { + return *this->screen_pitch; } void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override; diff --git a/src/blitter/8bpp_simple.hpp b/src/blitter/8bpp_simple.hpp index 455d76d937..2803537a31 100644 --- a/src/blitter/8bpp_simple.hpp +++ b/src/blitter/8bpp_simple.hpp @@ -16,6 +16,7 @@ /** Most trivial 8bpp blitter. */ class Blitter_8bppSimple FINAL : public Blitter_8bppBase { public: + using Blitter_8bppBase::Blitter_8bppBase; void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; Sprite *Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator) override; diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index 770a1abf73..e73ccd8925 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -15,7 +15,7 @@ /** Blitter that does nothing. */ class Blitter_Null : public Blitter { public: - Blitter_Null() + Blitter_Null(const int *screen_pitch = nullptr) { this->SetScreenDepth(0); this->SetNoSpriteDataRequired(true); diff --git a/src/gfx_func.h b/src/gfx_func.h index 6f94d617e4..eee3afa81d 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -227,19 +227,4 @@ inline int GetCharacterHeight(FontSize size) return font_height_cache[size]; } -/* Scoped temporary screen pitch override */ -struct TemporaryScreenPitchOverride { - int old_pitch; - - TemporaryScreenPitchOverride(int new_pitch) : old_pitch(_screen.pitch) - { - _screen.pitch = new_pitch; - } - - ~TemporaryScreenPitchOverride() - { - _screen.pitch = this->old_pitch; - } -}; - #endif /* GFX_FUNC_H */ diff --git a/src/viewport.cpp b/src/viewport.cpp index 84f78bf8d7..afa6243557 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -494,10 +494,9 @@ static bool ScrollViewportPixelCacheGeneric(Viewport *vp, std::vector &cac int height = vp->height; - TemporaryScreenPitchOverride screen_pitch(width); - /* Blitter_8bppDrawing::ScrollBuffer can be used on 32 bit buffers if widths and offsets are suitably adjusted */ - Blitter_8bppDrawing blitter; + const int pitch = width; + Blitter_8bppDrawing blitter(&pitch); blitter.ScrollBuffer(cache.data(), 0, 0, width, height, offset_x, offset_y); auto fill_rect = [&](int x, int y, int w, int h) { @@ -3904,9 +3903,9 @@ void ViewportDoDraw(Viewport *vp, int left, int top, int right, int bottom, uint overlay_dpi.left = UnScaleByZoomLower(vp->virtual_left, vp->zoom); overlay_dpi.top = UnScaleByZoomLower(vp->virtual_top, vp->zoom); - Blitter_8bppDrawing blitter; + const int pitch = vp->width; + Blitter_8bppDrawing blitter(&pitch); BlitterFactory::TemporaryCurrentBlitterOverride current_blitter(&blitter); - TemporaryScreenPitchOverride screen_pitch(vp->width); vp->overlay->Draw(&overlay_dpi); } } @@ -3941,9 +3940,9 @@ void ViewportDoDraw(Viewport *vp, int left, int top, int right, int bottom, uint plan_dpi.left = UnScaleByZoomLower(vp->virtual_left, vp->zoom); plan_dpi.top = UnScaleByZoomLower(vp->virtual_top, vp->zoom); - Blitter_8bppDrawing blitter; + const int pitch = vp->width; + Blitter_8bppDrawing blitter(&pitch); BlitterFactory::TemporaryCurrentBlitterOverride current_blitter(&blitter); - TemporaryScreenPitchOverride screen_pitch(vp->width); ViewportDrawPlans(vp, &plan_dpi); } } else {