diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blitter/32bpp_base.cpp | 52 | ||||
-rw-r--r-- | src/blitter/32bpp_base.hpp | 1 | ||||
-rw-r--r-- | src/blitter/8bpp_base.cpp | 52 | ||||
-rw-r--r-- | src/blitter/8bpp_base.hpp | 1 | ||||
-rw-r--r-- | src/blitter/base.hpp | 12 | ||||
-rw-r--r-- | src/blitter/null.hpp | 1 | ||||
-rw-r--r-- | src/gfx.cpp | 48 |
7 files changed, 120 insertions, 47 deletions
diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp index adfc0fbef..f788b56a7 100644 --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.cpp @@ -121,6 +121,58 @@ void Blitter_32bppBase::MoveBuffer(void *video_dst, const void *video_src, int w } } +void Blitter_32bppBase::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) +{ + const uint32 *src; + uint32 *dst; + + if (scroll_y > 0) { + /*Calculate pointers */ + dst = (uint32 *)video + left + (top + height - 1) * _screen.pitch; + src = dst - scroll_y * _screen.pitch; + + /* Decrease height and increase top */ + top += scroll_y; + height -= scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + /* Negative height as we want to copy from bottom to top */ + this->CopyFromBuffer(dst, src, width, -height, _screen.pitch); + } else { + /* Calculate pointers */ + dst = (uint32 *)video + left + top * _screen.pitch; + src = dst - scroll_y * _screen.pitch; + + /* Decrese height. (scroll_y is <=0). */ + height += scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + /* the y-displacement may be 0 therefore we have to use memmove, + * because source and destination may overlap */ + this->MoveBuffer(dst, src, width, height); + } +} + int Blitter_32bppBase::BufferSize(int width, int height) { return width * height * sizeof(uint32); diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp index df593247c..0149330d8 100644 --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.hpp @@ -21,6 +21,7 @@ public: /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height, int src_pitch); /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height, int dst_pitch); /* virtual */ void MoveBuffer(void *video_dst, const void *video_src, int width, int height); + /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); /* virtual */ int BufferSize(int width, int height); static inline uint32 LookupColourInPalette(uint8 index) { diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp index 65de3b195..0a2ca6b52 100644 --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.cpp @@ -126,6 +126,58 @@ void Blitter_8bppBase::MoveBuffer(void *video_dst, const void *video_src, int wi } } +void Blitter_8bppBase::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) +{ + const uint8 *src; + uint8 *dst; + + if (scroll_y > 0) { + /*Calculate pointers */ + dst = (uint8 *)video + left + (top + height - 1) * _screen.pitch; + src = dst - scroll_y * _screen.pitch; + + /* Decrease height and increase top */ + top += scroll_y; + height -= scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + /* Negative height as we want to copy from bottom to top */ + this->CopyFromBuffer(dst, src, width, -height, _screen.pitch); + } else { + /* Calculate pointers */ + dst = (uint8 *)video + left + top * _screen.pitch; + src = dst - scroll_y * _screen.pitch; + + /* Decrese height. (scroll_y is <=0). */ + height += scroll_y; + assert(height > 0); + + /* Adjust left & width */ + if (scroll_x >= 0) { + dst += scroll_x; + left += scroll_x; + width -= scroll_x; + } else { + src -= scroll_x; + width += scroll_x; + } + + /* the y-displacement may be 0 therefore we have to use memmove, + * because source and destination may overlap */ + this->MoveBuffer(dst, src, width, height); + } +} + int Blitter_8bppBase::BufferSize(int width, int height) { return width * height; diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp index 3e93885c7..3b313bb30 100644 --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.hpp @@ -21,6 +21,7 @@ public: /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height, int src_pitch); /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height, int dst_pitch); /* virtual */ void MoveBuffer(void *video_dst, const void *video_src, int width, int height); + /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); /* virtual */ int BufferSize(int width, int height); }; diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index 6e59f4e2e..90e1dde03 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -139,6 +139,18 @@ public: virtual void MoveBuffer(void *video_dst, const void *video_src, int width, int height) = 0; /** + * Scroll the videobuffer some 'x' and 'y' value. + * @param video The buffer to scroll into. + * @param left The left value of the screen to scroll. + * @param top The top value of the screen to scroll. + * @param width The width of the screen to scroll. + * @param height The height of the screen to scroll. + * @param scroll_x How much to scroll in X. + * @param scroll_y How much to scroll in Y. + */ + virtual void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) = 0; + + /** * Calculate how much memory there is needed for an image of this size in the video-buffer. * @param width The width of the buffer-to-be. * @param height The height of the buffer-to-be. diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index 61c4f222d..6c519b023 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -22,6 +22,7 @@ public: /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height, int src_pitch) {}; /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) {}; /* virtual */ void MoveBuffer(void *video_dst, const void *video_src, int width, int height) {}; + /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) {}; /* virtual */ int BufferSize(int width, int height) { return 0; }; }; diff --git a/src/gfx.cpp b/src/gfx.cpp index 93b3e3608..6125797bf 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -61,59 +61,13 @@ static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / 8]; void GfxScroll(int left, int top, int width, int height, int xo, int yo) { Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); - const void *src; - void *dst; if (xo == 0 && yo == 0) return; if (_cursor.visible) UndrawMouseCursor(); UndrawTextMessage(); - if (yo > 0) { - /*Calculate pointers */ - dst = blitter->MoveTo(_screen.dst_ptr, left, top + height - 1); - src = blitter->MoveTo(dst, 0, -yo); - - /* Decrease height and increase top */ - top += yo; - height -= yo; - assert(height > 0); - - /* Adjust left & width */ - if (xo >= 0) { - dst = blitter->MoveTo(dst, xo, 0); - left += xo; - width -= xo; - } else { - src = blitter->MoveTo(src, -xo, 0); - width += xo; - } - - /* Negative height as we want to copy from bottom to top */ - blitter->CopyFromBuffer(dst, src, width, -height, _screen.pitch); - } else { - /* Calculate pointers */ - dst = blitter->MoveTo(_screen.dst_ptr, left, top); - src = blitter->MoveTo(dst, 0, -yo); - - /* Decrese height. (yo is <=0). */ - height += yo; - assert(height > 0); - - /* Adjust left & width */ - if (xo >= 0) { - dst = blitter->MoveTo(dst, xo, 0); - left += xo; - width -= xo; - } else { - src = blitter->MoveTo(src, -xo, 0); - width += xo; - } - - /* the y-displacement may be 0 therefore we have to use memmove, - * because source and destination may overlap */ - blitter->MoveBuffer(dst, src, width, height); - } + blitter->ScrollBuffer(_screen.dst_ptr, left, top, width, height, xo, yo); /* This part of the screen is now dirty. */ _video_driver->make_dirty(left, top, width, height); } |