diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_anim.cpp @@ -79,6 +79,43 @@ void Blitter_32bppAnim::Draw(Blitter::Bl } } +void Blitter_32bppAnim::DrawColorMappingRect(void *dst, int width, int height, int pal) +{ + uint32 *udst = (uint32 *)dst; + uint8 *anim; + + anim = this->anim_buf + ((uint32 *)dst - (uint32 *)_screen.dst_ptr); + + if (pal == PALETTE_TO_TRANSPARENT) { + do { + for (int i = 0; i != width; i++) { + *udst = MakeTransparent(*udst, 60); + *anim = 0; + udst++; + anim++; + } + udst = udst - width + _screen.pitch; + anim = anim - width + this->anim_buf_width; + } while (--height); + return; + } + if (pal == PALETTE_TO_STRUCT_GREY) { + do { + for (int i = 0; i != width; i++) { + *udst = MakeGrey(*udst); + *anim = 0; + udst++; + anim++; + } + udst = udst - width + _screen.pitch; + anim = anim - width + this->anim_buf_width; + } while (--height); + return; + } + + DEBUG(misc, 0, "32bpp blitter doesn't know how to draw this color table ('%d')", pal); +} + void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 color) { *((uint32 *)video + x + y * _screen.pitch) = LookupColourInPalette(color); @@ -119,6 +156,49 @@ void Blitter_32bppAnim::DrawRect(void *v } while (--height); } +void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width, int height) +{ + assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch); + uint32 *dst = (uint32 *)video; + uint32 *usrc = (uint32 *)src; + uint8 *anim_line; + + anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf; + + for (; height > 0; height--) { + memcpy(dst, usrc, width * sizeof(uint32)); + usrc += width; + dst += _screen.pitch; + /* Copy back the anim-buffer */ + memcpy(anim_line, usrc, width * sizeof(uint8)); + usrc = (uint32 *)((uint8 *)usrc + width); + anim_line += this->anim_buf_width; + } + + /* We update the palette (or the pixels that do animation) immediatly, to avoid graphical glitches */ + this->PaletteAnimate(217, _use_dos_palette ? 38 : 28); +} + +void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, int height) +{ + assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch); + uint32 *udst = (uint32 *)dst; + uint32 *src = (uint32 *)video; + uint8 *anim_line; + + anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf; + + for (; height > 0; height--) { + memcpy(udst, src, width * sizeof(uint32)); + src += _screen.pitch; + udst += width; + /* Copy the anim-buffer */ + memcpy(udst, anim_line, width * sizeof(uint8)); + udst = (uint32 *)((uint8 *)udst + width); + anim_line += this->anim_buf_width; + } +} + void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) { uint8 *dst, *src; diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp --- a/src/blitter/32bpp_anim.hpp +++ b/src/blitter/32bpp_anim.hpp @@ -22,9 +22,12 @@ public: {} /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); + /* virtual */ void DrawColorMappingRect(void *dst, int width, int height, int pal); /* virtual */ void SetPixel(void *video, int x, int y, uint8 color); /* virtual */ void SetPixelIfEmpty(void *video, int x, int y, uint8 color); /* virtual */ void DrawRect(void *video, int width, int height, uint8 color); + /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height); + /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); /* virtual */ void PaletteAnimate(uint start, uint count); /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.cpp @@ -81,43 +81,40 @@ void Blitter_32bppBase::DrawLine(void *v } } } -void Blitter_32bppBase::CopyFromBuffer(void *video, const void *src, int width, int height, int src_pitch) + +void Blitter_32bppBase::CopyFromBuffer(void *video, const void *src, int width, int height) { - int direction = (height < 0) ? -1 : 1; uint32 *dst = (uint32 *)video; uint32 *usrc = (uint32 *)src; - height = abs(height); for (; height > 0; height--) { memcpy(dst, usrc, width * sizeof(uint32)); - usrc += src_pitch * direction; - dst += _screen.pitch * direction; + usrc += width; + dst += _screen.pitch; } } -void Blitter_32bppBase::CopyToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) +void Blitter_32bppBase::CopyToBuffer(const void *video, void *dst, int width, int height) { - int direction = (height < 0) ? -1 : 1; uint32 *udst = (uint32 *)dst; uint32 *src = (uint32 *)video; - height = abs(height); for (; height > 0; height--) { memcpy(udst, src, width * sizeof(uint32)); - src += _screen.pitch * direction; - udst += dst_pitch * direction; + src += _screen.pitch; + udst += width; } } -void Blitter_32bppBase::MoveBuffer(void *video_dst, const void *video_src, int width, int height) +void Blitter_32bppBase::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) { - uint32 *dst = (uint32 *)video_dst; - uint32 *src = (uint32 *)video_src; + uint32 *udst = (uint32 *)dst; + uint32 *src = (uint32 *)video; for (; height > 0; height--) { - memmove(dst, src, width * sizeof(uint32)); + memcpy(udst, src, width * sizeof(uint32)); src += _screen.pitch; - dst += _screen.pitch; + udst += dst_pitch; } } @@ -146,8 +143,11 @@ void Blitter_32bppBase::ScrollBuffer(voi width += scroll_x; } - /* Negative height as we want to copy from bottom to top */ - this->CopyFromBuffer(dst, src, width, -height, _screen.pitch); + for (int h = height; h > 0; h--) { + memcpy(dst, src, width * sizeof(uint32)); + src -= _screen.pitch; + dst -= _screen.pitch; + } } else { /* Calculate pointers */ dst = (uint32 *)video + left + top * _screen.pitch; @@ -169,7 +169,11 @@ void Blitter_32bppBase::ScrollBuffer(voi /* the y-displacement may be 0 therefore we have to use memmove, * because source and destination may overlap */ - this->MoveBuffer(dst, src, width, height); + for (int h = height; h > 0; h--) { + memmove(dst, src, width * sizeof(uint32)); + src += _screen.pitch; + dst += _screen.pitch; + } } } diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.hpp @@ -18,9 +18,9 @@ public: /* virtual */ void SetPixelIfEmpty(void *video, int x, int y, uint8 color); /* virtual */ void DrawRect(void *video, int width, int height, uint8 color); /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 color); - /* 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 CopyFromBuffer(void *video, const void *src, int width, int height); + /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); + /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch); /* 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); /* virtual */ void PaletteAnimate(uint start, uint count); diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.cpp @@ -86,43 +86,39 @@ void Blitter_8bppBase::DrawLine(void *vi } } -void Blitter_8bppBase::CopyFromBuffer(void *video, const void *src, int width, int height, int src_pitch) +void Blitter_8bppBase::CopyFromBuffer(void *video, const void *src, int width, int height) { - int direction = (height < 0) ? -1 : 1; uint8 *dst = (uint8 *)video; uint8 *usrc = (uint8 *)src; - height = abs(height); for (; height > 0; height--) { - memcpy(dst, usrc, width); - usrc += src_pitch * direction; - dst += _screen.pitch * direction; + memcpy(dst, usrc, width * sizeof(uint8)); + usrc += width; + dst += _screen.pitch; } } -void Blitter_8bppBase::CopyToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) +void Blitter_8bppBase::CopyToBuffer(const void *video, void *dst, int width, int height) { - int direction = (height < 0) ? -1 : 1; uint8 *udst = (uint8 *)dst; uint8 *src = (uint8 *)video; - height = abs(height); for (; height > 0; height--) { - memcpy(udst, src, width); - src += _screen.pitch * direction; - udst += dst_pitch * direction; + memcpy(udst, src, width * sizeof(uint8)); + src += _screen.pitch; + udst += width; } } -void Blitter_8bppBase::MoveBuffer(void *video_dst, const void *video_src, int width, int height) +void Blitter_8bppBase::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) { - uint8 *dst = (uint8 *)video_dst; - uint8 *src = (uint8 *)video_src; + uint8 *udst = (uint8 *)dst; + uint8 *src = (uint8 *)video; for (; height > 0; height--) { - memmove(dst, src, width); + memcpy(udst, src, width * sizeof(uint8)); src += _screen.pitch; - dst += _screen.pitch; + udst += dst_pitch; } } @@ -151,8 +147,11 @@ void Blitter_8bppBase::ScrollBuffer(void width += scroll_x; } - /* Negative height as we want to copy from bottom to top */ - this->CopyFromBuffer(dst, src, width, -height, _screen.pitch); + for (int h = height; h > 0; h--) { + memcpy(dst, src, width * sizeof(uint8)); + src -= _screen.pitch; + dst -= _screen.pitch; + } } else { /* Calculate pointers */ dst = (uint8 *)video + left + top * _screen.pitch; @@ -174,7 +173,11 @@ void Blitter_8bppBase::ScrollBuffer(void /* the y-displacement may be 0 therefore we have to use memmove, * because source and destination may overlap */ - this->MoveBuffer(dst, src, width, height); + for (int h = height; h > 0; h--) { + memmove(dst, src, width * sizeof(uint8)); + src += _screen.pitch; + dst += _screen.pitch; + } } } diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.hpp @@ -18,9 +18,9 @@ public: /* virtual */ void SetPixelIfEmpty(void *video, int x, int y, uint8 color); /* virtual */ void DrawRect(void *video, int width, int height, uint8 color); /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 color); - /* 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 CopyFromBuffer(void *video, const void *src, int width, int height); + /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); + /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch); /* 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); /* virtual */ void PaletteAnimate(uint start, uint count); diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -121,9 +121,9 @@ public: * @param src The buffer from which the data will be read. * @param width The width of the buffer. * @param height The height of the buffer. - * @param src_pitch The pitch (byte per line) of the source buffer. + * @note You can not do anything with the content of the buffer, as the blitter can store non-pixel data in it too! */ - virtual void CopyFromBuffer(void *video, const void *src, int width, int height, int src_pitch) = 0; + virtual void CopyFromBuffer(void *video, const void *src, int width, int height) = 0; /** * Copy from the screen to a buffer. @@ -131,18 +131,19 @@ public: * @param dst The buffer in which the data will be stored. * @param width The width of the buffer. * @param height The height of the buffer. - * @param dst_pitch The pitch (byte per line) of the destination buffer. + * @note You can not do anything with the content of the buffer, as the blitter can store non-pixel data in it too! */ - virtual void CopyToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) = 0; + virtual void CopyToBuffer(const void *video, void *dst, int width, int height) = 0; /** - * Move the videobuffer some places (via memmove). - * @param video_dst The destination pointer (video-buffer). - * @param video_src The source pointer (video-buffer). - * @param width The width of the buffer to move. - * @param height The height of the buffer to move. + * Copy from the screen to a buffer in a palette format for 8bpp and RGBA format for 32bpp. + * @param video The destination pointer (video-buffer). + * @param dst The buffer in which the data will be stored. + * @param width The width of the buffer. + * @param height The height of the buffer. + * @param dst_pitch The pitch (byte per line) of the destination buffer. */ - virtual void MoveBuffer(void *video_dst, const void *video_src, int width, int height) = 0; + virtual void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) = 0; /** * Scroll the videobuffer some 'x' and 'y' value. diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -19,9 +19,9 @@ public: /* virtual */ void SetPixelIfEmpty(void *video, int x, int y, uint8 color) {}; /* virtual */ void DrawRect(void *video, int width, int height, uint8 color) {}; /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 color) {}; - /* 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 CopyFromBuffer(void *video, const void *src, int width, int height) {}; + /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height) {}; + /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) {}; /* 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; }; /* virtual */ void PaletteAnimate(uint start, uint count) { }; diff --git a/src/gfx.cpp b/src/gfx.cpp --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -836,7 +836,7 @@ void UndrawMouseCursor() if (_cursor.visible) { Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); _cursor.visible = false; - blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), _cursor_backup, _cursor.draw_size.x, _cursor.draw_size.y, _cursor.draw_size.x); + blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), _cursor_backup, _cursor.draw_size.x, _cursor.draw_size.y); _video_driver->make_dirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y); } } @@ -883,7 +883,7 @@ void DrawMouseCursor() assert(blitter->BufferSize(w, h) < (int)sizeof(_cursor_backup)); /* Make backup of stuff below cursor */ - blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), _cursor_backup, _cursor.draw_size.x, _cursor.draw_size.y, _cursor.draw_size.x); + blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), _cursor_backup, _cursor.draw_size.x, _cursor.draw_size.y); /* Draw cursor on screen */ _cur_dpi = &_screen; diff --git a/src/screenshot.cpp b/src/screenshot.cpp --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -485,7 +485,7 @@ static void CurrentScreenCallback(void * { Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); void *src = blitter->MoveTo(_screen.dst_ptr, 0, y); - blitter->CopyToBuffer(src, buf, _screen.width, n, pitch); + blitter->CopyImageToBuffer(src, buf, _screen.width, n, pitch); } /* generate a large piece of the world */ diff --git a/src/texteff.cpp b/src/texteff.cpp --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -55,7 +55,7 @@ static bool _textmessage_visible = false /* The chatbox grows from the bottom so the coordinates are pixels from * the left and pixels from the bottom. The height is the maximum height */ static const Oblong _textmsg_box = {10, 30, 500, 150}; -static uint8 _textmessage_backup[150 * 500 * 4]; // (height * width) +static uint8 _textmessage_backup[150 * 500 * 5]; // (height * width) static inline uint GetTextMessageCount() { @@ -163,7 +163,7 @@ void UndrawTextMessage() _textmessage_visible = false; /* Put our 'shot' back to the screen */ - blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _textmessage_backup, width, height, _textmsg_box.width); + blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _textmessage_backup, width, height); /* And make sure it is updated next time */ _video_driver->make_dirty(x, y, width, height); @@ -223,8 +223,10 @@ void DrawTextMessage() } if (width <= 0 || height <= 0) return; + assert(blitter->BufferSize(width, height) < (int)sizeof(_textmessage_backup)); + /* Make a copy of the screen as it is before painting (for undraw) */ - blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _textmessage_backup, width, height, _textmsg_box.width); + blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _textmessage_backup, width, height); _cur_dpi = &_screen; // switch to _screen painting