changeset 6366:1edd9a343502 draft

(svn r9420) -Fix [FS#701]: crashes when the chatbox would be drawn outside of the main window.
author rubidium <rubidium@openttd.org>
date Fri, 23 Mar 2007 22:20:39 +0000
parents 0d8a8ec46519
children 194e4a2640ca
files src/texteff.cpp
diffstat 1 files changed, 31 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/texteff.cpp
+++ b/src/texteff.cpp
@@ -145,15 +145,27 @@
 			}
 		}
 
+		int x      = _textmsg_box.x;
+		int y      = _screen.height - _textmsg_box.y - _textmsg_box.height;
+		int width  = _textmsg_box.width;
+		int height = _textmsg_box.height;
+		if (y < 0) {
+			height = max(height + y, min(_textmsg_box.height, _screen.height));
+			y = 0;
+		}
+		if (x + width >= _screen.width) {
+			width = _screen.width - x;
+		}
+
 		_textmessage_visible = false;
 		/* Put our 'shot' back to the screen */
 		memcpy_pitch(
-			_screen.dst_ptr + _textmsg_box.x + (_screen.height - _textmsg_box.y - _textmsg_box.height) * _screen.pitch,
+			_screen.dst_ptr + x + y * _screen.pitch,
 			_textmessage_backup,
-			_textmsg_box.width, _textmsg_box.height, _textmsg_box.width, _screen.pitch);
+			width, height, _textmsg_box.width, _screen.pitch);
 
 		/* And make sure it is updated next time */
-		_video_driver->make_dirty(_textmsg_box.x, _screen.height - _textmsg_box.y - _textmsg_box.height, _textmsg_box.width, _textmsg_box.height);
+		_video_driver->make_dirty(x, y, width, height);
 
 		_textmessage_dirty = true;
 	}
@@ -186,8 +198,6 @@
 /* Draw the textmessage-box */
 void DrawTextMessage()
 {
-	uint y, count;
-
 	if (!_textmessage_dirty) return;
 
 	/* First undraw if needed */
@@ -196,14 +206,25 @@
 	if (_iconsole_mode == ICONSOLE_FULL) return;
 
 	/* Check if we have anything to draw at all */
-	count = GetTextMessageCount();
+	uint count = GetTextMessageCount();
 	if (count == 0) return;
 
+	int x      = _textmsg_box.x;
+	int y      = _screen.height - _textmsg_box.y - _textmsg_box.height;
+	int width  = _textmsg_box.width;
+	int height = _textmsg_box.height;
+	if (y < 0) {
+		height = max(height + y, min(_textmsg_box.height, _screen.height));
+		y = 0;
+	}
+	if (x + width >= _screen.width) {
+		width = _screen.width - x;
+	}
 	/* Make a copy of the screen as it is before painting (for undraw) */
 	memcpy_pitch(
 		_textmessage_backup,
-		_screen.dst_ptr + _textmsg_box.x + (_screen.height - _textmsg_box.y - _textmsg_box.height) * _screen.pitch,
-		_textmsg_box.width, _textmsg_box.height, _screen.pitch, _textmsg_box.width);
+		_screen.dst_ptr + x + y * _screen.pitch,
+		width, height, _screen.pitch, _textmsg_box.width);
 
 	_cur_dpi = &_screen; // switch to _screen painting
 
@@ -217,12 +238,12 @@
 		);
 
 	/* Paint the messages starting with the lowest at the bottom */
-	for (y = 13; count-- != 0; y += 13) {
+	for (uint y = 13; count-- != 0; y += 13) {
 		DoDrawString(_textmsg_list[count].message, _textmsg_box.x + 3, _screen.height - _textmsg_box.y - y + 1, _textmsg_list[count].color);
  	}
 
 	/* Make sure the data is updated next flush */
-	_video_driver->make_dirty(_textmsg_box.x, _screen.height - _textmsg_box.y - _textmsg_box.height, _textmsg_box.width, _textmsg_box.height);
+	_video_driver->make_dirty(x, y, width, height);
 
 	_textmessage_visible = true;
 	_textmessage_dirty = false;