diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp
index deedaf34b5..532ad23cc7 100644
--- a/src/blitter/32bpp_anim.cpp
+++ b/src/blitter/32bpp_anim.cpp
@@ -39,13 +39,14 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
 	}
 
 	Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left;
-	uint16 *anim = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_width + bp->left;
+	assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'bp->dst' into an 'anim_buf' offset below.
+	uint16 *anim = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_pitch + bp->left;
 
 	const byte *remap = bp->remap; // store so we don't have to access it via bp everytime
 
 	for (int y = 0; y < bp->height; y++) {
 		Colour *dst_ln = dst + bp->pitch;
-		uint16 *anim_ln = anim + this->anim_buf_width;
+		uint16 *anim_ln = anim + this->anim_buf_pitch;
 
 		const Colour *src_px_ln = (const Colour *)((const byte *)src_px + *(const uint32 *)src_px);
 		src_px++;
@@ -279,9 +280,8 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height,
 	}
 
 	Colour *udst = (Colour *)dst;
-	uint16 *anim;
-
-	anim = this->anim_buf + ((uint32 *)dst - (uint32 *)_screen.dst_ptr);
+	assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'dst' into an 'anim_buf' offset below.
+	uint16 *anim = this->anim_buf + ((uint32 *)dst - (uint32 *)_screen.dst_ptr);
 
 	if (pal == PALETTE_TO_TRANSPARENT) {
 		do {
@@ -292,7 +292,7 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height,
 				anim++;
 			}
 			udst = udst - width + _screen.pitch;
-			anim = anim - width + this->anim_buf_width;
+			anim = anim - width + this->anim_buf_pitch;
 		} while (--height);
 		return;
 	}
@@ -305,7 +305,7 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height,
 				anim++;
 			}
 			udst = udst - width + _screen.pitch;
-			anim = anim - width + this->anim_buf_width;
+			anim = anim - width + this->anim_buf_pitch;
 		} while (--height);
 		return;
 	}
@@ -319,7 +319,8 @@ void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
 
 	/* Set the colour in the anim-buffer too, if we are rendering to the screen */
 	if (_screen_disable_anim) return;
-	this->anim_buf[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * this->anim_buf_width] = colour | (DEFAULT_BRIGHTNESS << 8);
+	assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below.
+	this->anim_buf[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * this->anim_buf_pitch] = colour | (DEFAULT_BRIGHTNESS << 8);
 }
 
 void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colour)
@@ -331,9 +332,8 @@ void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colou
 	}
 
 	Colour colour32 = LookupColourInPalette(colour);
-	uint16 *anim_line;
-
-	anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf;
+	assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below.
+	uint16 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf;
 
 	do {
 		Colour *dst = (Colour *)video;
@@ -347,7 +347,7 @@ void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colou
 			anim++;
 		}
 		video = (uint32 *)video + _screen.pitch;
-		anim_line += this->anim_buf_width;
+		anim_line += this->anim_buf_pitch;
 	} while (--height);
 }
 
@@ -357,6 +357,7 @@ void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width,
 	assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
 	Colour *dst = (Colour *)video;
 	const uint32 *usrc = (const uint32 *)src;
+	assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below.
 	uint16 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf;
 
 	for (; height > 0; height--) {
@@ -370,7 +371,7 @@ void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width,
 		/* Copy back the anim-buffer */
 		memcpy(anim_line, usrc, width * sizeof(uint16));
 		usrc = (const uint32 *)((const uint16 *)usrc + width);
-		anim_line += this->anim_buf_width;
+		anim_line += this->anim_buf_pitch;
 
 		/* Okay, it is *very* likely that the image we stored is using
 		 * the wrong palette animated colours. There are two things we
@@ -397,11 +398,11 @@ void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, in
 	assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch);
 	uint32 *udst = (uint32 *)dst;
 	const uint32 *src = (const uint32 *)video;
-	const uint16 *anim_line;
 
 	if (this->anim_buf == NULL) return;
 
-	anim_line = ((const uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf;
+	assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below.
+	const uint16 *anim_line = ((const uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf;
 
 	for (; height > 0; height--) {
 		memcpy(udst, src, width * sizeof(uint32));
@@ -410,7 +411,7 @@ void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, in
 		/* Copy the anim-buffer */
 		memcpy(udst, anim_line, width * sizeof(uint16));
 		udst = (uint32 *)((uint16 *)udst + width);
-		anim_line += this->anim_buf_width;
+		anim_line += this->anim_buf_pitch;
 	}
 }
 
@@ -422,8 +423,8 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
 
 	/* We need to scroll the anim-buffer too */
 	if (scroll_y > 0) {
-		dst = this->anim_buf + left + (top + height - 1) * this->anim_buf_width;
-		src = dst - scroll_y * this->anim_buf_width;
+		dst = this->anim_buf + left + (top + height - 1) * this->anim_buf_pitch;
+		src = dst - scroll_y * this->anim_buf_pitch;
 
 		/* Adjust left & width */
 		if (scroll_x >= 0) {
@@ -436,13 +437,13 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
 		uint th = height - scroll_y;
 		for (; th > 0; th--) {
 			memcpy(dst, src, tw * sizeof(uint16));
-			src -= this->anim_buf_width;
-			dst -= this->anim_buf_width;
+			src -= this->anim_buf_pitch;
+			dst -= this->anim_buf_pitch;
 		}
 	} else {
 		/* Calculate pointers */
-		dst = this->anim_buf + left + top * this->anim_buf_width;
-		src = dst - scroll_y * this->anim_buf_width;
+		dst = this->anim_buf + left + top * this->anim_buf_pitch;
+		src = dst - scroll_y * this->anim_buf_pitch;
 
 		/* Adjust left & width */
 		if (scroll_x >= 0) {
@@ -457,8 +458,8 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
 		uint th = height + scroll_y;
 		for (; th > 0; th--) {
 			memmove(dst, src, tw * sizeof(uint16));
-			src += this->anim_buf_width;
-			dst += this->anim_buf_width;
+			src += this->anim_buf_pitch;
+			dst += this->anim_buf_pitch;
 		}
 	}
 
@@ -495,6 +496,7 @@ void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)
 			anim++;
 		}
 		dst += _screen.pitch - this->anim_buf_width;
+		anim += this->anim_buf_pitch - this->anim_buf_width;
 	}
 
 	/* Make sure the backend redraws the whole screen */
@@ -508,11 +510,13 @@ Blitter::PaletteAnimation Blitter_32bppAnim::UsePaletteAnimation()
 
 void Blitter_32bppAnim::PostResize()
 {
-	if (_screen.width != this->anim_buf_width || _screen.height != this->anim_buf_height) {
+	if (_screen.width != this->anim_buf_width || _screen.height != this->anim_buf_height ||
+			_screen.pitch != this->anim_buf_pitch) {
 		/* The size of the screen changed; we can assume we can wipe all data from our buffer */
 		free(this->anim_buf);
-		this->anim_buf = CallocT<uint16>(_screen.width * _screen.height);
 		this->anim_buf_width = _screen.width;
 		this->anim_buf_height = _screen.height;
+		this->anim_buf_pitch = _screen.pitch;
+		this->anim_buf = CallocT<uint16>(this->anim_buf_height * this->anim_buf_pitch);
 	}
 }
diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp
index 4b08429edc..1b35c17663 100644
--- a/src/blitter/32bpp_anim.hpp
+++ b/src/blitter/32bpp_anim.hpp
@@ -20,13 +20,15 @@ protected:
 	uint16 *anim_buf;    ///< In this buffer we keep track of the 8bpp indexes so we can do palette animation
 	int anim_buf_width;  ///< The width of the animation buffer.
 	int anim_buf_height; ///< The height of the animation buffer.
+	int anim_buf_pitch;  ///< The pitch of the animation buffer.
 	Palette palette;     ///< The current palette.
 
 public:
 	Blitter_32bppAnim() :
 		anim_buf(NULL),
 		anim_buf_width(0),
-		anim_buf_height(0)
+		anim_buf_height(0),
+		anim_buf_pitch(0)
 	{
 		this->palette = _cur_palette;
 	}
diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp
index 7d4b66fca6..987cb0c6ac 100644
--- a/src/blitter/32bpp_anim_sse4.cpp
+++ b/src/blitter/32bpp_anim_sse4.cpp
@@ -35,7 +35,8 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL
 {
 	const byte * const remap = bp->remap;
 	Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left;
-	uint16 *anim_line = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_width + bp->left;
+	assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'bp->dst' into an 'anim_buf' offset below.
+	uint16 *anim_line = this->anim_buf + ((uint32 *)bp->dst - (uint32 *)_screen.dst_ptr) + bp->top * this->anim_buf_pitch + bp->left;
 	int effective_width = bp->width;
 
 	/* Find where to start reading in the source sprite. */
@@ -353,7 +354,7 @@ next_line:
 		if (mode != BM_TRANSPARENT) src_mv_line += si->sprite_width;
 		src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size);
 		dst_line += bp->pitch;
-		anim_line += this->anim_buf_width;
+		anim_line += this->anim_buf_pitch;
 	}
 }
 IGNORE_UNINITIALIZED_WARNING_STOP
diff --git a/src/blitter/8bpp_simple.cpp b/src/blitter/8bpp_simple.cpp
index ed5dd3f7ae..2131a04682 100644
--- a/src/blitter/8bpp_simple.cpp
+++ b/src/blitter/8bpp_simple.cpp
@@ -48,7 +48,7 @@ void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, Zoom
 					break;
 
 				case BM_BLACK_REMAP:
-					colour = 0;
+					if (*src != 0) *dst = 0;
 					break;
 
 				default:
diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp
index 3416762d02..f1e54f38da 100644
--- a/src/network/network_chat_gui.cpp
+++ b/src/network/network_chat_gui.cpp
@@ -110,7 +110,7 @@ void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const char *m
 void NetworkReInitChatBoxSize()
 {
 	_chatmsg_box.y       = 3 * FONT_HEIGHT_NORMAL;
-	_chatmsg_box.height  = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING) + 2;
+	_chatmsg_box.height  = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING) + 4;
 	_chatmessage_backup  = ReallocT(_chatmessage_backup, _chatmsg_box.width * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel());
 }
 
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 0652d1bd81..c554dd66c8 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -532,6 +532,7 @@ struct GameOptionsWindow : Window {
 				_gui_zoom = (ZoomLevel)(ZOOM_LVL_OUT_4X - index);
 				UpdateCursorSize();
 				LoadStringWidthTable();
+				UpdateAllVirtCoords();
 				break;
 
 			case WID_GO_BASE_GRF_DROPDOWN:
diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp
index 8ea8cda4c8..b8f0ae875d 100644
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -2451,6 +2451,7 @@ private:
 public:
 	VehicleViewWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
 	{
+		this->flags |= WF_DISABLE_VP_SCROLL;
 		this->CreateNestedTree();
 
 		/* Sprites for the 'send to depot' button indexed by vehicle type. */
diff --git a/src/widget.cpp b/src/widget.cpp
index 2c06cfe29b..39d1d8b390 100644
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -510,11 +510,13 @@ static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bo
 {
 	DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE);
 	if (at_left) {
+		Dimension d = GetSpriteSize(SPR_WINDOW_RESIZE_LEFT);
 		DrawSprite(SPR_WINDOW_RESIZE_LEFT, PAL_NONE, r.left + WD_RESIZEBOX_RIGHT + clicked,
-				 r.bottom - WD_RESIZEBOX_BOTTOM - GetSpriteSize(SPR_WINDOW_RESIZE_LEFT).height + clicked);
+				 r.bottom + 1 - WD_RESIZEBOX_BOTTOM - d.height + clicked);
 	} else {
-		DrawSprite(SPR_WINDOW_RESIZE_RIGHT, PAL_NONE, r.left + WD_RESIZEBOX_LEFT + clicked,
-				 r.bottom - WD_RESIZEBOX_BOTTOM - GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT).height + clicked);
+		Dimension d = GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT);
+		DrawSprite(SPR_WINDOW_RESIZE_RIGHT, PAL_NONE, r.right + 1 - WD_RESIZEBOX_RIGHT - d.width + clicked,
+				 r.bottom + 1 - WD_RESIZEBOX_BOTTOM - d.height + clicked);
 	}
 }
 
diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp
index e0ad96a87a..d4c229cb1f 100644
--- a/src/widgets/dropdown.cpp
+++ b/src/widgets/dropdown.cpp
@@ -363,18 +363,38 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b
 	/* Check if the dropdown will fully fit below the widget */
 	if (top + height + 4 >= screen_bottom) {
 		/* If not, check if it will fit above the widget */
-		if (w->top + wi_rect.top - height > GetMainViewTop()) {
+		int screen_top = GetMainViewTop();
+		if (w->top + wi_rect.top > screen_top + height) {
 			top = w->top + wi_rect.top - height - 4;
 		} else {
-			/* ... and lastly if it won't, enable the scroll bar and fit the
-			 * list in below the widget */
+			/* If it doesn't fit above the widget, we need to enable a scrollbar... */
 			int avg_height = height / (int)list->Length();
-			int rows = (screen_bottom - 4 - top) / avg_height;
-			height = rows * avg_height;
 			scroll = true;
+
+			/* ... and choose whether to put the list above or below the widget. */
+			bool put_above = false;
+			int available_height = screen_bottom - w->top - wi_rect.bottom;
+			if (w->top + wi_rect.top - screen_top > available_height) {
+				// Put it above.
+				available_height = w->top + wi_rect.top - screen_top;
+				put_above = true;
+			}
+
+			/* Check at least there is space for one item. */
+			assert(available_height >= avg_height);
+
+			/* And lastly, fit the list... */
+			int rows = available_height / avg_height;
+			height = rows * avg_height;
+
 			/* Add space for the scroll bar if we automatically determined
 			 * the width of the list. */
 			max_item_width += NWidgetScrollbar::GetVerticalDimension().width;
+
+			/* ... and set the top position if needed. */
+			if (put_above) {
+				top = w->top + wi_rect.top - height - 4;
+			}
 		}
 	}