mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r10241) -Codechange: CopyToBuffer now produces a buffer that is unreadable from outside the blitter, so the blitter can store anything he likes
-Codechange: added CopyImageToBuffer, which produces a readable buffer for screenshots -Fix: 32bpp-anim now holds animation on transparent objects to avoid strange graphical effects -Fix: 32bpp-anim now works correct on mouse-movement (it holds the palette animation correctly)
This commit is contained in:
parent
3b12e7b6b0
commit
3fa3d2e365
|
@ -79,6 +79,43 @@ void Blitter_32bppAnim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
|
|||
}
|
||||
}
|
||||
|
||||
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 *video, int width, int height, uint8 color
|
|||
} 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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -81,43 +81,40 @@ void Blitter_32bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int
|
|||
}
|
||||
}
|
||||
}
|
||||
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(void *video, int &left, int &top, int &widt
|
|||
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(void *video, int &left, int &top, int &widt
|
|||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -86,43 +86,39 @@ void Blitter_8bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int s
|
|||
}
|
||||
}
|
||||
|
||||
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 *video, int &left, int &top, int &width
|
|||
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 *video, int &left, int &top, int &width
|
|||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) { };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -485,7 +485,7 @@ static void CurrentScreenCallback(void *userdata, void *buf, uint y, uint pitch,
|
|||
{
|
||||
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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue